module axi_dram_fifo_tb; reg clk; // Global AXI clock reg reset; // Global reset, active high. reg clear; wire aresetn; // Global AXI reset, active low. // // AXI Write address channel // wire [0 : 0] axi_awid; // Write address ID. This signal is the identification tag for the write address signals wire [31 : 0] axi_awaddr; // Write address. The write address gives the address of the first transfer in a write burst wire [7 : 0] axi_awlen; // Burst length. The burst length gives the exact number of transfers in a burst. wire [2 : 0] axi_awsize; // Burst size. This signal indicates the size of each transfer in the burst. wire [1 : 0] axi_awburst; // Burst type. The burst type and the size information, determine how the address is calculated wire [0 : 0] axi_awlock; // Lock type. Provides additional information about the atomic characteristics of the transfer. wire [3 : 0] axi_awcache; // Memory type. This signal indicates how transactions are required to progress wire [2 : 0] axi_awprot; // Protection type. This signal indicates the privilege and security level of the transaction wire [3 : 0] axi_awqos; // Quality of Service, QoS. The QoS identifier sent for each write transaction wire [3 : 0] axi_awregion; // Region identifier. Permits a single physical interface on a slave to be re-used. wire [0 : 0] axi_awuser; // User signal. Optional User-defined signal in the write address channel. wire axi_awvalid; // Write address valid. This signal indicates that the channel is signaling valid write addr wire axi_awready; // Write address ready. This signal indicates that the slave is ready to accept an address // // AXI Write data channel. // wire [63 : 0] axi_wdata; // Write data wire [7 : 0] axi_wstrb; // Write strobes. This signal indicates which byte lanes hold valid data. wire axi_wlast; // Write last. This signal indicates the last transfer in a write burst wire [0 : 0] axi_wuser; // User signal. Optional User-defined signal in the write data channel. wire axi_wvalid; // Write valid. This signal indicates that valid write data and strobes are available. wire axi_wready; // Write ready. This signal indicates that the slave can accept the write data. // // AXI Write response channel signals // wire [0 : 0] axi_bid; // Response ID tag. This signal is the ID tag of the write response. wire [1 : 0] axi_bresp; // Write response. This signal indicates the status of the write transaction. wire [0 : 0] axi_buser; // User signal. Optional User-defined signal in the write response channel. wire axi_bvalid; // Write response valid. This signal indicates that the channel is signaling a valid response wire axi_bready; // Response ready. This signal indicates that the master can accept a write response // // AXI Read address channel // wire [0 : 0] axi_arid; // Read address ID. This signal is the identification tag for the read address group of signals wire [31 : 0] axi_araddr; // Read address. The read address gives the address of the first transfer in a read burst wire [7 : 0] axi_arlen; // Burst length. This signal indicates the exact number of transfers in a burst. wire [2 : 0] axi_arsize; // Burst size. This signal indicates the size of each transfer in the burst. wire [1 : 0] axi_arburst; // Burst type. The burst type and the size information determine how the address for each transfer wire [0 : 0] axi_arlock; // Lock type. This signal provides additional information about the atomic characteristics wire [3 : 0] axi_arcache; // Memory type. This signal indicates how transactions are required to progress wire [2 : 0] axi_arprot; // Protection type. This signal indicates the privilege and security level of the transaction wire [3 : 0] axi_arqos; // Quality of Service, QoS. QoS identifier sent for each read transaction. wire [3 : 0] axi_arregion; // Region identifier. Permits a single physical interface on a slave to be re-used wire [0 : 0] axi_aruser; // User signal. Optional User-defined signal in the read address channel. wire axi_arvalid; // Read address valid. This signal indicates that the channel is signaling valid read addr wire axi_arready; // Read address ready. This signal indicates that the slave is ready to accept an address // // AXI Read data channel // wire [0 : 0] axi_rid; // Read ID tag. This signal is the identification tag for the read data group of signals wire [63 : 0] axi_rdata; // Read data. wire [1 : 0] axi_rresp; // Read response. This signal indicates the status of the read transfer wire axi_rlast; // Read last. This signal indicates the last transfer in a read burst. wire [0 : 0] axi_ruser; // User signal. Optional User-defined signal in the read data channel. wire axi_rvalid; // Read valid. This signal indicates that the channel is signaling the required read data. wire axi_rready; // Read ready. This signal indicates that the master can accept the read data and response // // CHDR friendly AXI stream input // wire [63:0] i_tdata; wire i_tlast; wire i_tvalid; wire i_tready; // // CHDR friendly AXI Stream output // wire [63:0] o_tdata; wire o_tlast; wire o_tvalid; wire o_tready; // // These registers optionaly used // to drive nets through procedural assignments in test bench. // These drivers default to tri-stated. // reg [63:0] i_tdata_r; reg i_tlast_r; reg i_tvalid_r; reg o_tready_r; assign i_tdata = i_tdata_r; assign i_tlast = i_tlast_r; assign i_tvalid = i_tvalid_r; assign o_tready = o_tready_r; initial begin i_tdata_r <= 64'hzzzz_zzzz_zzzz_zzzz; i_tlast_r <= 1'bz; i_tvalid_r <= 1'bz; o_tready_r <= 1'bz; end axi_dram_fifo #(.SIZE(13)) axi_dram_fifo_i1 ( .bus_clk(clk), // input s_aclk .bus_reset(reset), // input s_aresetn .clear(clear), .dram_clk(clk), // input s_aclk .dram_reset(reset), // input s_aresetn // Write control .m_axi_awid(axi_awid), // input [0 : 0] s_axi_awid .m_axi_awaddr(axi_awaddr), // input [31 : 0] s_axi_awaddr .m_axi_awlen(axi_awlen), // input [7 : 0] s_axi_awlen .m_axi_awsize(axi_awsize), // input [2 : 0] s_axi_awsize .m_axi_awburst(axi_awburst), // input [1 : 0] s_axi_awburst .m_axi_awvalid(axi_awvalid), // input s_axi_awvalid .m_axi_awready(axi_awready), // output s_axi_awready .m_axi_awlock(), .m_axi_awcache(), .m_axi_awprot(), .m_axi_awqos(), .m_axi_awregion(), .m_axi_awuser(), // Write Data .m_axi_wdata(axi_wdata), // input [63 : 0] s_axi_wdata .m_axi_wstrb(axi_wstrb), // input [7 : 0] s_axi_wstrb .m_axi_wlast(axi_wlast), // input s_axi_wlast .m_axi_wvalid(axi_wvalid), // input s_axi_wvalid .m_axi_wready(axi_wready), // output s_axi_wready .m_axi_wuser(), // Write Response .m_axi_bid(axi_bid), // output [0 : 0] s_axi_bid .m_axi_bresp(axi_bresp), // output [1 : 0] s_axi_bresp .m_axi_bvalid(axi_bvalid), // output s_axi_bvalid .m_axi_bready(axi_bready), // input s_axi_bready .m_axi_buser(), // Read Control .m_axi_arid(axi_arid), // input [0 : 0] s_axi_arid .m_axi_araddr(axi_araddr), // input [31 : 0] s_axi_araddr .m_axi_arlen(axi_arlen), // input [7 : 0] s_axi_arlen .m_axi_arsize(axi_arsize), // input [2 : 0] s_axi_arsize .m_axi_arburst(axi_arburst), // input [1 : 0] s_axi_arburst .m_axi_arvalid(axi_arvalid), // input s_axi_arvalid .m_axi_arready(axi_arready), // output s_axi_arready .m_axi_arlock(), .m_axi_arcache(), .m_axi_arprot(), .m_axi_arqos(), .m_axi_arregion(), .m_axi_aruser(), // Read Data .m_axi_rid(axi_rid), // output [0 : 0] s_axi_rid .m_axi_rdata(axi_rdata), // output [63 : 0] s_axi_rdata .m_axi_rresp(axi_rresp), // output [1 : 0] s_axi_rresp .m_axi_rlast(axi_rlast), // output s_axi_rlast .m_axi_rvalid(axi_rvalid), // output s_axi_rvalid .m_axi_rready(axi_rready), // input s_axi_rready .m_axi_ruser(), // CHDR in .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready), // CHDR out .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready), // .supress_threshold(16'h0), .supress_enable(1'b0) ); axi4_bram_1kx64 axi4_bram_1kx64_i1 ( .s_aclk(clk), // input s_aclk .s_aresetn(aresetn), // input s_aresetn .s_axi_awid(axi_awid), // input [0 : 0] s_axi_awid .s_axi_awaddr(axi_awaddr), // input [31 : 0] s_axi_awaddr .s_axi_awlen(axi_awlen), // input [7 : 0] s_axi_awlen .s_axi_awsize(axi_awsize), // input [2 : 0] s_axi_awsize .s_axi_awburst(axi_awburst), // input [1 : 0] s_axi_awburst .s_axi_awvalid(axi_awvalid), // input s_axi_awvalid .s_axi_awready(axi_awready), // output s_axi_awready .s_axi_wdata(axi_wdata), // input [63 : 0] s_axi_wdata .s_axi_wstrb(axi_wstrb), // input [7 : 0] s_axi_wstrb .s_axi_wlast(axi_wlast), // input s_axi_wlast .s_axi_wvalid(axi_wvalid), // input s_axi_wvalid .s_axi_wready(axi_wready), // output s_axi_wready .s_axi_bid(axi_bid), // output [0 : 0] s_axi_bid .s_axi_bresp(axi_bresp), // output [1 : 0] s_axi_bresp .s_axi_bvalid(axi_bvalid), // output s_axi_bvalid .s_axi_bready(axi_bready), // input s_axi_bready .s_axi_arid(axi_arid), // input [0 : 0] s_axi_arid .s_axi_araddr(axi_araddr), // input [31 : 0] s_axi_araddr .s_axi_arlen(axi_arlen), // input [7 : 0] s_axi_arlen .s_axi_arsize(axi_arsize), // input [2 : 0] s_axi_arsize .s_axi_arburst(axi_arburst), // input [1 : 0] s_axi_arburst .s_axi_arvalid(axi_arvalid), // input s_axi_arvalid .s_axi_arready(axi_arready), // output s_axi_arready .s_axi_rid(axi_rid), // output [0 : 0] s_axi_rid .s_axi_rdata(axi_rdata), // output [63 : 0] s_axi_rdata .s_axi_rresp(axi_rresp), // output [1 : 0] s_axi_rresp .s_axi_rlast(axi_rlast), // output s_axi_rlast .s_axi_rvalid(axi_rvalid), // output s_axi_rvalid .s_axi_rready(axi_rready) // input s_axi_rready ); // // // task send_ramp; input [31:0] burst_count; input [31:0] len; input [31:0] sid; reg [31:0] data; reg [11:0] seqno; begin seqno = 0; data = 0; send_packet(len, data, 0, seqno, (burst_count==1), 0, sid); seqno = seqno + 1; data <= data + len; if(burst_count > 2) repeat (burst_count - 2) begin send_packet(len, data, 64'h0, seqno, 0, 0, sid); seqno = seqno + 1; data <= data + len; end if(burst_count > 1) send_packet(len, data, 64'h0, seqno, 1, 0, sid); end endtask // send_ramp task send_dc; input [31:0] burst_count; input [31:0] len; input [31:0] sid; reg [31:0] data; reg [11:0] seqno; begin seqno = 0; data = 1 << 14; send_packet(len, data, 0, seqno, (burst_count==1), 0, sid); seqno = seqno + 1; if(burst_count > 2) repeat (burst_count - 2) begin send_packet(len, data, 64'h0, seqno, 0, 0, sid); seqno = seqno + 1; end if(burst_count > 1) send_packet(len, data, 64'h0, seqno, 1, 0, sid); end endtask // send_ramp task send_burst; input [31:0] burst_count; input [31:0] len; input [31:0] start_data; input [63:0] send_time; input [11:0] start_seqnum; input send_at; input [31:0] sid; reg [11:0] seqno; begin seqno = start_seqnum; send_packet(len, {seqno,start_data[15:0]}, send_time, seqno, (burst_count==1), send_at, sid); seqno = seqno + 1; if(burst_count > 2) repeat (burst_count - 2) begin send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 0, 0, sid); seqno = seqno + 1; end if(burst_count > 1) send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 1, 0, sid); end endtask // send_burst task send_packet; input [31:0] len; input [31:0] start_data; input [63:0] send_time; input [11:0] pkt_seqnum; input eob; input send_at; input [31:0] sid; reg [31:0] samp0, samp1; begin // Send a packet samp0 <= start_data; samp1 <= start_data + 1; @(posedge clk); i_tlast_r <= 0; i_tdata_r <= { 1'b0, 1'b0 /*trl*/, send_at, eob, pkt_seqnum, len[15:0]+16'd2+send_at+send_at, sid }; i_tvalid_r <= 1; @(posedge clk) if(send_at) begin i_tdata_r <= send_time; @(posedge clk); end repeat (len[31:1]+len[0]-1) begin i_tdata_r <= {samp0,samp1}; samp0 <= samp0 + 2; samp1 <= samp1 + 2; @(posedge clk); end i_tdata_r <= {samp0,samp1}; i_tlast_r <= 1'b1; @(posedge clk); i_tvalid_r <= 0; @(posedge clk); end endtask // send_packet task send_raw_packet; input [31:0] len; reg [63:0] data; begin data = 0; @(posedge clk); repeat (len-1) begin i_tlast_r <= 0; i_tdata_r <= data; i_tvalid_r <= 1; @(posedge clk); while (~i_tready) @(posedge clk); data = data + 1; end i_tlast_r <= 1; i_tdata_r <= data; i_tvalid_r <= 1; @(posedge clk); while (~i_tready) @(posedge clk); i_tvalid_r <= 0; @(posedge clk); end endtask // send_raw_packet task receive_raw_packet; input [31:0] len; output fail; reg [63:0] data; begin data = 0; fail = 0; @(posedge clk); repeat (len-1) begin o_tready_r <= 1; @(posedge clk); while (~o_tvalid) @(posedge clk); //$display("Data = %d, o_tdata = %d, o_tlast = %d",data,o_tdata,o_tlast); fail = fail || (data !== o_tdata); fail = fail || ~(o_tlast === 0); data = data + 1; end o_tready_r <= 1; @(posedge clk); while (~o_tvalid) @(posedge clk); //$display("Data = %d, o_tdata = %d, o_tlast = %d",data,o_tdata,o_tlast); fail = fail || (data !== o_tdata); fail = fail || ~(o_tlast === 1); o_tready_r <= 0; @(posedge clk); if (fail) $display("receive_raw_packet size %d failed",len); end endtask // receive_raw_packet assign aresetn = ~reset; // // Bring in a simulation script here // `include "simulation_script.v" endmodule // axi_dram_fifo_tb