📄 bench.v
字号:
///////////////////////////////////////////////////////////////////////// //////// OpenCores Memory Controller Testbench //////// Main testbench //////// //////// Author: Richard Herveille //////// richard@asics.ws //////// //////// //////// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //////// ///////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2001 Richard Herveille //////// richard@asics.ws //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer.//////// //////// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //////// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //////// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //////// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //////// 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. //////// /////////////////////////////////////////////////////////////////////////// ToDo:// 1) add power-on configuration// 2) test SSRAM// 3) test synchronous devices ???//// CVS Log//// $Id: bench.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $//// $Date: 2002/03/06 15:10:34 $// $Revision: 1.1 $// $Author: rherveille $// $Locker: $// $State: Exp $//// Change History:// $Log: bench.v,v $// Revision 1.1 2002/03/06 15:10:34 rherveille// Initial release////`include "timescale.v"`define SDRAM_ROWA_HI 12 // row address hi-bit`define SDRAM_COLA_HI 8 // column address hi-bit`define BA_MASK 32'h0000_00e0 // base address mask`define SDRAM1_LOC 32'h0400_0000 // location of sdram1 in address-space`define SDRAM2_LOC 32'h0800_0000 // location of sdram2 in address-space`define SRAM_LOC 32'h0C00_0000 // location of srams in address-space`define SSRAM_LOC 32'h1000_0000 // location of ssrams in address-spacemodule bench_top(); // // internal wires // reg wb_clk; reg mc_clk; reg wb_rst; wire [31:0] wb_dat_i, wb_dat_o; wire [31:0] wb_adr_o; wire wb_cyc_o, wb_stb_o; wire [ 3:0] wb_sel_o; wire wb_ack_i, wb_err_i, wb_rty_i; wire wb_mc_stb; wire [23:0] mc_adr_o; wire [31:0] mc_dq, mc_dq_o; wire [ 3:0] mc_dp, mc_dp_o, pbus_o, pbus_i; reg [ 3:0] set_par; wire [31:0] par_con; reg sel_par, sel_pbus; wire par_sdram_cs; wire mc_doe_o; wire [ 3:0] mc_dqm_o; wire mc_we_o, mc_oe_o; wire mc_ras_o, mc_cas_o, mc_cke_o; wire [ 7:0] mc_cs_o; wire mc_pad_oe; wire mc_adsc_o, mc_adv_o, mc_zz_o; // ssram connections wire ext_br, ext_bg; // // hookup modules // // hookup watch-dog counter watch_dog #(1024) wdog ( .clk(wb_clk), .cyc_i(wb_cyc_o), .ack_i(wb_ack_i), .adr_i(wb_adr_o) ); // hookup external bus-master model bm_model ext_bm( .br(ext_br), .bg(ext_bg), .chk(mc_pad_oe) ); // hookup ERR checker err_check err_chk(wb_err_i, sel_par); // hookup CSn checker cs_check cs_chec(mc_cs_o); // hookup memory controller mc_top dut ( // wishbone interface .clk_i(wb_clk), .rst_i(wb_rst), .wb_data_i(wb_dat_o), .wb_data_o(wb_dat_i), .wb_addr_i(wb_adr_o), .wb_sel_i(wb_sel_o), .wb_we_i(wb_we_o), .wb_cyc_i(wb_cyc_o), .wb_stb_i(wb_stb_o), .wb_ack_o(wb_ack_i), .wb_err_o(wb_err_i), // memory controller .susp_req_i(1'b0), .resume_req_i(1'b0), .suspended_o(), .poc_o(), .mc_clk_i(mc_clk), .mc_br_pad_i(ext_br), .mc_bg_pad_o(ext_bg), .mc_ack_pad_i(1'b0), .mc_addr_pad_o(mc_adr_o), .mc_data_pad_i(mc_dq), .mc_data_pad_o(mc_dq_o), .mc_dp_pad_i(pbus_i), // attach parity bus .mc_dp_pad_o(mc_dp_o), .mc_doe_pad_doe_o(mc_doe_o), .mc_dqm_pad_o(mc_dqm_o), .mc_oe_pad_o_(mc_oe_o), .mc_we_pad_o_(mc_we_o), .mc_cas_pad_o_(mc_cas_o), .mc_ras_pad_o_(mc_ras_o), .mc_cke_pad_o_(mc_cke_o), .mc_cs_pad_o_(mc_cs_o), .mc_sts_pad_i(1'b0), .mc_rp_pad_o_(), .mc_vpen_pad_o(), .mc_adsc_pad_o_(mc_adsc_o), .mc_adv_pad_o_(mc_adv_o), .mc_zz_pad_o(mc_zz_o), .mc_coe_pad_coe_o(mc_pad_oe) ); // assign memory controller stb_signal assign wb_mc_stb = wb_adr_o[31]; // generate output buffers for memory controller assign mc_dq = mc_doe_o ? mc_dq_o : 32'bz; assign mc_dp = mc_doe_o ? mc_dp_o : 4'bz; // hookup ssrams (CHIP SELECT 4) mt58l1my18d ssram0 ( .Dq( {par_con[24], par_con[16], mc_dq[31:16]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[3]), .Bwb_n(mc_dqm_o[2]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), // ?? .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); mt58l1my18d ssram1 ( .Dq( {par_con[8], par_con[0], mc_dq[15:0]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[1]), .Bwb_n(mc_dqm_o[0]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); // hookup sdrams (CHIP SELECT 3) mt48lc16m16a2 sdram0_3( .Dq(mc_dq[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_3( .Dq(mc_dq[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup sdrams (CHIP SELECT 2 or PARITY) assign pbus_o = sel_pbus ? (sel_par ? mc_dp : set_par) : mc_dq; assign par_con = {7'bz, pbus_o[3], 7'bz, pbus_o[2], 7'bz, pbus_o[1], 7'bz, pbus_o[0]}; assign pbus_i = {par_con[24], par_con[16], par_con[8], par_con[0]}; assign par_sdram_cs = sel_pbus ? mc_cs_o[3] : mc_cs_o[2]; mt48lc16m16a2 sdram0_2( .Dq(par_con[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_2( .Dq(par_con[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup asynchronous srams (CHIP SELECT 1) A8Kx8 asram0 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[31:24]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram1 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[23:16]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram2 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[15: 8]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram3 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[ 7: 0]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); // hookup wishbone master wb_master_model wbm( .clk(wb_clk), .rst(wb_rst), .adr(wb_adr_o), .din(wb_dat_i), .dout(wb_dat_o), .cyc(wb_cyc_o), .stb(wb_stb_o), .we(wb_we_o), .sel(wb_sel_o), .ack(wb_ack_i), .err(wb_err_i), .rty(wb_rty_i) ); // // testbench body // assign wb_rty_i = 1'b0; // no retries from memory controller // generate clock always #2.5 wb_clk <= ~wb_clk; always@(posedge wb_clk)// mc_clk <= #1 ~mc_clk; mc_clk <= #0 ~mc_clk; // initial statements initial begin wb_clk = 0; // start with low-level clock wb_rst = 1; // assert reset mc_clk = 0; sel_par = 1; // do not modify parity bits sel_pbus = 1; // use second SDRAMS set as parity sdrams repeat(20) @(posedge wb_clk); wb_rst = 0; // negate reset @(posedge wb_clk); run_tests; // show total errors detected wbm.show_tot_err_cnt; $stop; end ////////////////////// // // Internal tasks // task run_tests; begin prg_mc; // program memory controller BA-mask and CSR registers// force sdram0_3.Debug = 1'b1; // turn on SDRAM debug option force sdram0_3.Debug = 1'b0; // turn off SDRAM debug option /////////////// // SDRAM tests// tst_sdram_memfill; // test sdrams: Fill entire memory and verify// tst_sdram_parity; // test sdrams: Parity generation// tst_sdram_seq; // test sdrams: Fill-Verify, sequential access// tst_sdram_rnd; // test sdrams: Fill-Verify, random access// tst_sdram_rmw_seq; // test sdrams: Read-Modify-Write test, sequential access// tst_sdram_rmw_rnd; // test sdrams: Read-Modify-Write test, random access// tst_sdram_blk_cpy1; // test sdrams: Perform block copy, different src and dest. address// tst_sdram_blk_cpy2; // test sdrams: Perform block copy, src and dest same address// tst_sdram_bytes; // test sdrams: Peform byte accesses ////////////////////////////// // ASYNCHRONOUS MEMORIES TEST// tst_amem_seq; // test asynchronous memory tst_amem_b2b; // test asynchronous memory back-2-back //////////////// // SSRAMS TESTS tst_ssram_seq; ////////////////////// // MULTI MEMORY TESTS// tst_blk_cpy1; // test block-copy: access sdrams + asrams // The next test (tst_blk_cyp2) is, saddly to say, useless. // It tests n-by-n situations for multiple SDRAMS, testing all possible settings for each SDRAM. // It is supposed to test the independence for each SDRAM chip-select. // However it is to time-consuming; it runs for about a month on an Athlon-XP 1800 system// tst_blk_cpy2; // test block-copy: access multiple sdrams ///////////////////////////// // EXTERNAL BUS MASTER TESTS // turn on external bus-master and rerun some tests// force ext_bm.on_off = 1'b1;// tst_sdram_seq; // test sdrams: Fill-Verify, sequential access// tst_amem_seq; // test asynchronous memory// tst_amem_b2b; // test asynchronous memory back-2-back// tst_blk_cpy1; // test block-copy: access sdrams + asrams end endtask // run_tests task prg_mc; begin wbm.wb_write(0, 0, 32'h6000_0008, `BA_MASK); // program base address register wbm.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR // check written data wbm.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); end endtask //prg_mc //////////////////////////////// // Register test // task reg_test; begin end endtask // reg_test ///////////////////////// // include memory tests // `include "tst_sdram.v" `include "tst_asram.v" `include "tst_ssram.v" `include "tst_multi_mem.v"endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -