`resetall
`timescale 1ns / 1ps
`default_nettype none

module data_gen #
(
	parameter NUM_CH = 2 
)
(
    // AXI4L Config Interface
    axi4l_intf.slave    ctrl_if,
	input  wire          trigger,

    // Output Data
    axi4s_intf.master    data_out[NUM_CH]
);

// ------------------------------
// AXIL Decode
// ------------------------------
wire [ctrl_if.AXI_ADDR_WIDTH-1 : 0]		raddr;
wire [ctrl_if.AXI_ADDR_WIDTH-1 : 0]		waddr;
wire 						    rden;
wire 						    wren;
wire [ctrl_if.AXI_DATA_WIDTH-1 : 0]		wdata;
reg [ctrl_if.AXI_DATA_WIDTH-1 : 0]		rdata;


axil_slave 
# (
	.DATA_WIDTH(ctrl_if.AXI_DATA_WIDTH),
	.ADDR_WIDTH(ctrl_if.AXI_ADDR_WIDTH)
) axil_slave_i 
(
	// AXIL Slave
	.S_AXI_ACLK(ctrl_if.clk),
	.S_AXI_ARESETN(ctrl_if.resetn),
	.S_AXI_AWADDR(ctrl_if.awaddr),
	.S_AXI_AWPROT(ctrl_if.awprot),
	.S_AXI_AWVALID(ctrl_if.awvalid),
	.S_AXI_AWREADY(ctrl_if.awready),
	.S_AXI_WDATA(ctrl_if.wdata),
	.S_AXI_WSTRB(ctrl_if.wstrb),
	.S_AXI_WVALID(ctrl_if.wvalid),
	.S_AXI_WREADY(ctrl_if.wready),
	.S_AXI_BRESP(ctrl_if.bresp),
	.S_AXI_BVALID(ctrl_if.bvalid),
	.S_AXI_BREADY(ctrl_if.bready),
	.S_AXI_ARADDR(ctrl_if.araddr),
	.S_AXI_ARPROT(ctrl_if.arprot),
	.S_AXI_ARVALID(ctrl_if.arvalid),
	.S_AXI_ARREADY(ctrl_if.arready),
	.S_AXI_RDATA(ctrl_if.rdata),
	.S_AXI_RRESP(ctrl_if.rresp),
	.S_AXI_RVALID(ctrl_if.rvalid),
	.S_AXI_RREADY(ctrl_if.rready),	
	
	.raddr(raddr),
	.waddr(waddr),
	.wren(wren),
	.rden(rden),
	.wdata(wdata),
	.rdata(rdata)
);

// ------------------------------
// Config Registers
// ------------------------------
wire reset;
assign reset = ~ctrl_if.resetn;
reg [31:0]  num_samples; 


always @ (posedge ctrl_if.clk) begin
    if (~ctrl_if.resetn) begin

    end else begin
        if (wren) begin
            if ( waddr[15:0] == 'h000 ) 
                num_samples <= wdata;
        end
    end
end   

always @ (posedge ctrl_if.clk) begin
    if (rden) begin
        if (raddr[11:0] == 'h000)
            rdata <= num_samples;
    end
end

// ------------------------------
// Data Generation
// ------------------------------
wire valid;
wire tlast;
pulse_generator pulse_generator_i(
	.clk(ctrl_if.clk),
	.rst(reset),
	.pulse_length(num_samples),
	.start_of_pulse(trigger),
	.pulse_out(valid),
	.pulse_tlast(tlast)
);

reg [63:0] cnt_data; 
always @ (posedge ctrl_if.clk) begin
	cnt_data <= cnt_data + 1;
end

genvar ch_ind;
generate
    for (ch_ind=0; ch_ind < NUM_CH; ch_ind++) begin   
		wire [7:0] ch_num = ch_ind;
		wire [127:0] ch_data = {ch_num, 24'h000000, 32'h00000000, cnt_data};

		ch_data_buffer ch_data_buffer_i (
			.s_axis_aresetn(ctrl_if.resetn),  
			.s_axis_aclk(ctrl_if.clk),   
			.s_axis_tvalid(valid),  
			.s_axis_tready(),  
			.s_axis_tdata(ch_data), 
			.s_axis_tlast(tlast),
			.m_axis_tvalid(data_out[ch_ind].tvalid),  
			.m_axis_tready(data_out[ch_ind].tready),  
			.m_axis_tdata(data_out[ch_ind].tdata),
			.m_axis_tlast(data_out[ch_ind].tlast)    
		);		

		assign data_out[ch_ind].tkeep = 16'hFFFF;

	end
endgenerate

endmodule


`resetall