//====================================================================== // // tb_fmc_arbiter.v // ------------- // Test bench for FMC Arbiter module, read and write transactions // from STM32 are simulated in this file. // // Author: Pavel Shatov // Copyright (c) 2015, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // - Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // - Neither the name of the NORDUnet nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //====================================================================== module tb_fmc_arbiter; // // FMC Side // reg fmc_clk; reg [21: 0] fmc_a; wire [31: 0] fmc_d; reg [31: 0] fmc_d_reg; reg fmc_d_drive; reg fmc_ne1; reg fmc_nl; reg fmc_nwe; reg fmc_noe; wire fmc_nwait; // // Data Bus // assign fmc_d = fmc_d_drive ? fmc_d_reg : {32{1'bZ}}; // // System Side // reg sys_clk = 1'b0; wire [21: 0] sys_addr; wire sys_wr_en; reg [31: 0] sys_data_in = 32'hCA53CA53; wire sys_rd_en; wire [31: 0] sys_data_out; reg [31: 0] test_reg; always @(posedge sys_clk) // if (sys_wr_en) begin // test_reg <= (sys_addr == {22{1'b0}}) ? sys_data_out : {{10{1'b0}}, sys_addr}; // end else if (sys_rd_en) begin // sys_data_in <= test_reg; // end // // UUT // fmc_arbiter # ( .NUM_ADDR_BITS(22) ) uut ( .fmc_clk (fmc_clk), .fmc_a (fmc_a), .fmc_d (fmc_d), .fmc_ne1 (fmc_ne1), .fmc_nl (fmc_nl), .fmc_nwe (fmc_nwe), .fmc_noe (fmc_noe), .fmc_nwait (fmc_nwait), .sys_clk (sys_clk), .sys_addr (sys_addr), .sys_wr_en (sys_wr_en), .sys_data_out (sys_data_out), .sys_rd_en (sys_rd_en), .sys_data_in (sys_data_in) ); // // System Clock (50 MHz) // always #10 sys_clk = ~sys_clk; // // FMC Clock (100 MHz) // always #5.5 fmc_clk = ~fmc_clk; // // Initial FMC State // initial begin fmc_clk = 1'b0; fmc_a = {22{1'bX}}; fmc_d_reg = {32{1'bX}}; fmc_d_drive = 1'b0; fmc_ne1 = 1'b1; fmc_nl = 1'b1; fmc_nwe = 1'b1; fmc_noe = 1'b1; end // // Script // reg [31: 0] rd; initial begin // #500; // fmc_write(22'h3ABCDE, 32'hFEDCBA98); while (fmc_nwait == 1'b0) #0.1; // #1000; // fmc_read(22'h3ABCDE, rd); while (fmc_nwait == 1'b0) #0.1; fmc_read(22'h3ABCDE, rd); // #1000; // end // // Write Transaction // integer tick; task fmc_write; input [21: 0] addr; input [31: 0] data; begin // fmc_wait_posedge; fmc_wait_negedge; // fmc_ne1 = 1'b0; // select device fmc_nwe = 1'b0; // transaction type is write fmc_nl = 1'b0; // address is valid fmc_a = addr; // set address // fmc_wait_posedge; fmc_wait_negedge; // fmc_nl = 1'b1; // address is no longer valid // for (tick=0; tick<2; tick=tick+1) begin fmc_wait_posedge; fmc_wait_negedge; end // fmc_d_reg = data; // set data fmc_d_drive = 1'b1; // enable driver // fmc_wait_posedge; fmc_wait_negedge; // fmc_ne1 = 1'b1; // deselect device fmc_nwe = 1'b1; // clear fmc_d_drive = 1'b0; // disable driver // end endtask; // // Read Transaction // task fmc_read; input [21: 0] addr; output [31: 0] data; begin // fmc_wait_posedge; fmc_wait_negedge; // fmc_ne1 = 1'b0; // select device fmc_nl = 1'b0; // address is valid fmc_a = addr; // set address // fmc_wait_posedge; fmc_wait_negedge; // fmc_nl = 1'b1; // address is no longer valid // for (tick=0; tick<2; tick=tick+1) begin fmc_wait_posedge; fmc_wait_negedge; end // fmc_noe = 1'b0; // reverse bus direction fmc_wait_posedge; data = fmc_d; fmc_wait_negedge; // fmc_ne1 = 1'b1; // deselect device fmc_noe = 1'b1; // reverse bus direction // /* fmc_ne1 = 1'b0; fmc_nl = 1'b0; fmc_a = addr; #5 fmc_clk = 1'b1; #5 fmc_nl = 1'b1; fmc_clk = 1'b0; #5 fmc_clk = 1'b1; #5 fmc_clk = 1'b0; fmc_noe = 1'b0; #5 fmc_clk = 1'b1; #5 fmc_clk = 1'b0; #5 while (fmc_nwait == 1'b0) begin fmc_clk = 1'b1; #5 fmc_clk = 1'b0; #5; end data = fmc_d; fmc_clk = 1'b1; #5 fmc_clk = 1'b0; #5 fmc_ne1 = 1'b1; fmc_noe = 1'b1; #10; */ end endtask; task fmc_wait_posedge; begin while (fmc_clk != 1'b1) #0.1; #0.1; end endtask; task fmc_wait_negedge; begin while (fmc_clk != 1'b0) #0.1; #0.1; end endtask; endmodule //====================================================================== // EOF tb_fmc_arbiter.v //======================================================================