OpenCores
URL https://opencores.org/ocsvn/mem_ctrl/mem_ctrl/trunk

Subversion Repositories mem_ctrl

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/trunk/bench/richard/verilog/mc_defines.v
0,0 → 1,228
/////////////////////////////////////////////////////////////////////
//// ////
//// WISHBONE Memory Controller Definitions ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// rudi@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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: mc_defines.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: not supported by cvs2svn $
// Revision 1.6 2001/12/12 06:35:15 rudi
// *** empty log message ***
//
// Revision 1.5 2001/12/11 02:47:19 rudi
//
// - Made some changes not to expect clock during reset ...
//
// Revision 1.4 2001/11/29 02:16:28 rudi
//
//
// - More Synthesis cleanup, mostly for speed
// - Several bug fixes
// - Changed code to avoid auto-precharge and
// burst-terminate combinations (apparently illegal ?)
// Now we will do a manual precharge ...
//
// Revision 1.3 2001/09/10 13:44:17 rudi
// *** empty log message ***
//
// Revision 1.2 2001/08/10 08:16:21 rudi
//
// - Changed IO names to be more clear.
// - Uniquifyed define names to be core specific.
// - Removed "Refresh Early" configuration
//
// Revision 1.1 2001/07/29 07:34:41 rudi
//
//
// 1) Changed Directory Structure
// 2) Fixed several minor bugs
//
// Revision 1.3 2001/06/12 15:19:49 rudi
//
//
// Minor changes after running lint, and a small bug
// fix reading csr and ba_mask registers.
//
// Revision 1.2 2001/06/03 11:37:17 rudi
//
//
// 1) Fixed Chip Select Mask Register
// - Power On Value is now all ones
// - Comparison Logic is now correct
//
// 2) All resets are now asynchronous
//
// 3) Converted Power On Delay to an configurable item
//
// 4) Added reset to Chip Select Output Registers
//
// 5) Forcing all outputs to Hi-Z state during reset
//
// Revision 1.1.1.1 2001/05/13 09:39:38 rudi
// Created Directory Structure
//
//
//
//
 
`timescale 1ns / 10ps
 
/////////////////////////////////////////////////////////////////////
//
// This define selects how the WISHBONE interface determines if
// the internal register file is selected.
// This should be a simple address decoder. "wb_addr_i" is the
// WISHBONE address bus (32 bits wide).
`define MC_REG_SEL (wb_addr_i[31:29] == 3'b011)
 
// This define selects how the WISHBONE interface determines if
// the memory is selected.
// This should be a simple address decoder. "wb_addr_i" is the
// WISHBONE address bus (32 bits wide).
`define MC_MEM_SEL (wb_addr_i[31:29] == 3'h0)
 
/////////////////////////////////////////////////////////////////////
//
// This are the default Power-On Reset values for Chip Select
//
 
// This will be defined by the run script for my test bench ...
// Alternatively force here for synthesis ...
`define RUDIS_TB 1
 
// Defines which chip select is used for Power On booting
 
// To run my default testbench default boot CS must be 3 !!!
`ifdef RUDIS_TB
`define MC_DEF_SEL 3'h3
`else
`define MC_DEF_SEL 3'h0
`endif
 
// Defines the default (reset) TMS value for the DEF_SEL chip select
`define MC_DEF_POR_TMS 32'hffff_ffff
 
 
/////////////////////////////////////////////////////////////////////
//
// Define how many Chip Selects to Implement
//
`define MC_HAVE_CS1 1
//`define MC_HAVE_CS2 1
//`define MC_HAVE_CS3 1
//`define MC_HAVE_CS4 1
//`define MC_HAVE_CS5 1
//`define MC_HAVE_CS6 1
//`define MC_HAVE_CS7 1
 
 
// To run my default testbench those need to there !!!
`ifdef RUDIS_TB
`define MC_HAVE_CS2 1
`define MC_HAVE_CS3 1
`define MC_HAVE_CS4 1
`define MC_HAVE_CS5 1
`endif
 
/////////////////////////////////////////////////////////////////////
//
// Init Refresh
//
// Number of Refresh Cycles to perform during SDRAM initialization.
// This varies between SDRAM manufacturer. Typically this value is
// between 2 and 8. This number must be smaller than 16.
`define MC_INIT_RFRC_CNT 2
 
/////////////////////////////////////////////////////////////////////
//
// Power On Delay
//
// Most if SDRAMs require some time to initialize before they can be used
// after power on. If the Memory Controller shall stall after power on to
// allow SDRAMs to finish the initialization process uncomment the below
// define statement
`define MC_POR_DELAY 1
 
// This value defines how many MEM_CLK cycles the Memory Controller should
// stall. Default is 2.5uS. At a 10nS MEM_CLK cycle time, this would 250
// cycles.
`define MC_POR_DELAY_VAL 8'd250
 
 
// ===============================================================
// ===============================================================
// Various internal defines (DO NOT MODIFY !)
// ===============================================================
// ===============================================================
 
// Register settings encodings
`define MC_BW_8 2'h0
`define MC_BW_16 2'h1
`define MC_BW_32 2'h2
 
`define MC_MEM_TYPE_SDRAM 3'h0
`define MC_MEM_TYPE_SRAM 3'h1
`define MC_MEM_TYPE_ACS 3'h2
`define MC_MEM_TYPE_SCS 3'h3
 
`define MC_MEM_SIZE_64 2'h0
`define MC_MEM_SIZE_128 2'h1
`define MC_MEM_SIZE_256 2'h2
 
// Command Valid, Ras_, Cas_, We_
`define MC_CMD_NOP 4'b0111
`define MC_CMD_PC 4'b1010
`define MC_CMD_ACT 4'b1011
`define MC_CMD_WR 4'b1100
`define MC_CMD_RD 4'b1101
`define MC_CMD_BT 4'b1110
`define MC_CMD_ARFR 4'b1001
`define MC_CMD_LMR 4'b1000
`define MC_CMD_XRD 4'b1111
`define MC_CMD_XWR 4'b1110
 
`define MC_SINGLE_BANK 1'b0
`define MC_ALL_BANKS 1'b1
 
/trunk/bench/richard/verilog/tst_asram.v
0,0 → 1,265
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores Memory Controller Testbench ////
//// Asynchronous memory devices tests ////
//// This file is being included by the main testbench ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: tst_asram.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: not supported by cvs2svn $
//
 
 
///////////////////////////////////////
// Asynchronous memory sequential test
//
 
// 1) Fill entire SRAM memory using sequential accesses
// 2) Test 8/16/32 bit wide asynchronous accesses
// 2) Verify memory contents
//
// THIS IS A FULL MEMORY TEST, TAKES A WHILE
task tst_amem_seq;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SRAM_STARTA = `SRAM_LOC;
parameter [ 7:0] SRAM_SEL = SRAM_STARTA[28:21];
parameter SRAM_TST_RUN = 1<<11; // entire sram memory
 
integer n, cnt;
reg [1:0] tmp;
reg [31:0] my_adr;
reg [31:0] my_dat;
 
reg[1:0] bw;
reg [31:0] csr_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- ASYNCHRONOUS MEMORY SEQUENTIAL/FILL TEST ---\n\n");
 
bw = 2;
for (bw = 0; bw < 3; bw = bw +1)
begin
csr_data = {
8'h00, // reserved
SRAM_SEL, // SEL base address (a[28:21] == 8'b0100_0000)
4'h0, // reserved
1'b0, // PEN no parity
1'b0, // KRO ---
1'b0, // BAS ---
1'b0, // WP no write protection
2'b00, // MS ---
bw, // BW Bus width
3'h2, // MEM memory type == asynchronous
1'b1 // EN enable chip select
};
 
tms_data = {
6'h0, // reserved
6'h0, // Twwd = 5ns => 0ns
4'h0, // Twd = 0ns => 0ns
4'h1, // Twpw = 15ns => 20ns
4'h0, // Trdz = 8ns => 10ns
8'h02 // Trdv = 20ns => 20ns
};
 
// program chip select registers
wbm.wb_write(0, 0, 32'h6000_0018, csr_data); // program cs1 config register
wbm.wb_write(0, 0, 32'h6000_001c, tms_data); // program cs1 timing register
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0018, csr_data);
wbm.wb_cmp(0, 0, 32'h6000_001c, tms_data);
 
cyc_delay = 1;
stb_delay = 1;
for (cyc_delay = 0; cyc_delay < MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay < MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("Asynchronous memory sequential test. CYC-delay = %d, STB-delay = %d, BW = %d", cyc_delay, stb_delay, bw);
// fill srams
tmp = ~(bw +1);
 
my_dat = 0;
for (n=0; n < (SRAM_TST_RUN<<tmp); n=n+1)
begin
my_adr = SRAM_STARTA + (n << bw);
 
cnt = (n >> tmp) + cyc_delay + stb_delay;
 
case (bw)
2'b00: // 8bit asynchronous memory connected
case (n[1:0])
2'b00: my_dat[7:0] = ~cnt[ 7:0];
2'b01: my_dat[7:0] = ~cnt[15:8];
2'b10: my_dat[7:0] = cnt[ 7:0];
2'b11: my_dat[7:0] = cnt[15:8];
endcase
2'b01: // 16bit asynchronous memory connected
if (n[0])
my_dat[15:0] = cnt;
else
my_dat[15:0] = ~cnt;
2'b10: // 32bit asynchronous memory connected
begin
my_dat[31:16] = cnt;
my_dat[15: 0] = ~cnt;
end
2'b11: // reserved
begin
end
endcase
 
wbm.wb_write(cyc_delay, stb_delay, my_adr, my_dat);
end
 
// read srams
my_dat = 0;
for (n=0; n < SRAM_TST_RUN; n=n+1)
begin
my_adr = SRAM_STARTA + (n<<2); // always read 32bits
my_dat[31:16] = (n + cyc_delay + stb_delay);
my_dat[15: 0] = ~(n + cyc_delay + stb_delay);
 
wbm.wb_cmp(cyc_delay, stb_delay, my_adr, my_dat);
end
end
end
 
$display("\nAsynchronous memory sequential test ended");
 
end
endtask // tst_amem_seq
 
 
///////////////////////////////////////
// Asynchronous memory back2back test
//
 
// 1) Test back-2-back read/write accesses to asynchronous memory
task tst_amem_b2b;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SRAM_STARTA = `SRAM_LOC;
parameter [ 7:0] SRAM_SEL = SRAM_STARTA[28:21];
parameter SRAM_TST_RUN = 64; // only do a few accesses
 
integer n, cnt;
reg [1:0] tmp;
reg [31:0] my_adr;
reg [31:0] my_dat;
 
reg [31:0] csr_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
csr_data = {
8'h00, // reserved
SRAM_SEL, // SEL base address (a[28:21] == 8'b0100_0000)
4'h0, // reserved
1'b0, // PEN no parity
1'b0, // KRO ---
1'b0, // BAS ---
1'b0, // WP no write protection
2'b00, // MS ---
2'h2, // BW 32bit Bus width
3'h2, // MEM memory type == asynchronous
1'b1 // EN enable chip select
};
 
tms_data = {
6'h0, // reserved
6'h0, // Twwd = 5ns => 0ns
4'h0, // Twd = 0ns => 0ns
4'h1, // Twpw = 15ns => 20ns
4'h0, // Trdz = 8ns => 10ns
8'h02 // Trdv = 20ns => 20ns
};
 
// program chip select registers
wbm.wb_write(0, 0, 32'h6000_0018, csr_data); // program cs1 config register
wbm.wb_write(0, 0, 32'h6000_001c, tms_data); // program cs1 timing register
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0018, csr_data);
wbm.wb_cmp(0, 0, 32'h6000_001c, tms_data);
 
cyc_delay = 1;
stb_delay = 1;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("Asynchronous memory back-2-back test. CYC-delay = %d, STB-delay = %d", cyc_delay, stb_delay);
// fill srams
 
my_dat = 0;
for (n=0; n < SRAM_TST_RUN; n=n+1)
begin
my_adr = SRAM_STARTA + (n << 2);
 
cnt = n + cyc_delay + stb_delay;
 
my_dat[31:16] = cnt;
my_dat[15: 0] = ~cnt;
 
wbm.wb_write(cyc_delay, stb_delay, my_adr, my_dat);
 
// read srams
my_adr = SRAM_STARTA + (n<<2); // always read 32bits
wbm.wb_cmp(cyc_delay, stb_delay, my_adr, my_dat);
end
end
 
$display("\nAsynchronous memory back-2-back test ended");
end
endtask // tst_amem_b2b
 
/trunk/bench/richard/verilog/bench.v
0,0 → 1,458
/////////////////////////////////////////////////////////////////////
//// ////
//// 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: not supported by cvs2svn $
//
 
`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-space
 
module 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
 
/trunk/bench/richard/verilog/tst_ssram.v
0,0 → 1,167
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores Memory Controller Testbench ////
//// SSRAM memory devices tests ////
//// This file is being included by the main testbench ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: tst_ssram.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: not supported by cvs2svn $
//
 
 
////////////////////////////////
// SSRAM Sequential access test
//
 
// 1) Tests ssram sequential address access
// 2) Tests page switch
// 3) Test burst-action by filling memory backwards (high addresses first)
task tst_ssram_seq;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
parameter SSRAM_TST_RUN = 128;
parameter [31:0] SSRAM_TST_STARTA = `SSRAM_LOC + (SSRAM_TST_RUN<<2);
parameter [ 7:0] SSRAM_SEL = SSRAM_TST_STARTA[28:21];
 
integer n, k;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
reg [15:0] tmp0, tmp1;
 
// SSRAM Mode Register bits
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay, bl;
 
begin
 
$display("\n\n --- SSRAM SEQUENTIAL ACCESS TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
csc_data = {
8'h00, // reserved
SSRAM_SEL, // SEL
4'h0, // reserved
1'b1, // parity enabled
1'b0, // KRO, no meaning for ssram
1'b0, // BAS, no meaning for ssram
1'b0, // WP
2'b00, // MS, no meaning for ssram
2'b10, // BW == 32bit bus. Always for ssram (maybe hardwire ???)
3'b001, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
// tms_data is unused for ssrams
tms_data = {
32'hx
};
 
// program chip select registers
$display("\nProgramming SSRAM chip select register.");
wbm.wb_write(0, 0, 32'h6000_0030, csc_data); // program cs4 config register (CSC4)
 
$display("Programming SSRAM timing register.");
wbm.wb_write(0, 0, 32'h6000_0034, tms_data); // program cs4 timing register (TMS4)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0030, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_0034, tms_data);
 
cyc_delay = 0;
stb_delay = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
for (bl = 1; bl <= 8 ; bl = bl +1)
begin
 
$display("\nSSRAM sequential test. BL = %d, CYC-delay = %d, STB-delay = ", bl, cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SSRAM memory...");
my_dat = 0;
for (n=0; n < SSRAM_TST_RUN; n=n+1)
begin
my_adr = SSRAM_TST_STARTA + ( (SSRAM_TST_RUN -n -bl) <<2);
for (k=0; k < bl; k=k+1)
begin
// fill destination backwards, but with linear bursts
dest_adr = my_adr + (k<<2);
 
tmp0 = ~dest_adr[15:0] + bl + cyc_delay + stb_delay;
tmp1 = dest_adr[15:0] + bl + cyc_delay + stb_delay;
my_dat = {tmp0, tmp1};
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
 
// read sdrams
$display("Verifying SSRAM memory contents...");
my_dat = 0;
for (n=0; n < SSRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SSRAM_TST_STARTA + my_adr;
 
tmp0 = ~dest_adr[15:0] + bl + cyc_delay + stb_delay;
tmp1 = dest_adr[15:0] + bl + cyc_delay + stb_delay;
my_dat = {tmp0, tmp1};
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
repeat(10) @(posedge wb_clk); //wait a while
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask // test_ssram_seq
/trunk/bench/richard/verilog/tst_sdram.v
0,0 → 1,1475
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores Memory Controller Testbench ////
//// SDRAM memory devices tests ////
//// This file is being included by the main testbench ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: tst_sdram.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: not supported by cvs2svn $
//
 
 
////////////////////////////////
// SDRAM memory fill test
//
 
// Test memory contents overwrite
// 1) Fill entire SDRAM memory
// 2) Verify memory contents
// 3) Test for BAS setting
//
// THIS IS A FULL MEMORY TEST
// MAY RUN FOR A FEW DAYS
task tst_sdram_memfill;
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC; // start at address 0
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = ( 1<<(`SDRAM_COLA_HI+1)<<(`SDRAM_ROWA_HI+1) ) *4;
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
integer bank_cnt, col_cnt;
 
begin
 
$display("\n\n --- SDRAM MEMORY FILL TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
// choose some settings, other settings will be tested
// in next tests
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 2; // burst length = 4
 
// variables for CSC register
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
// only select cyc_delay = 0
// only select stb_delay = 0
// --> fastest test_run.
// other possibilities will be tested by next tests
cyc_delay = 0;
stb_delay = 0;
 
begin
// fill sdrams
$display("Filling SDRAM memory... (This takes a while)");
my_dat = 0;
bank_cnt = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SDRAM_TST_RUN -1 - my_adr; // fill backward
my_dat = my_adr;
 
if (n % (1<<(`SDRAM_COLA_HI+1)<<(`SDRAM_ROWA_HI+1)) == 0)
begin
col_cnt = 0;
bank_cnt = bank_cnt +1;
end
 
if (n % (1<<(`SDRAM_COLA_HI+1)) == 0)
begin
$display("Filling bank %d, column %d", bank_cnt, col_cnt);
col_cnt = col_cnt +1;
end
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_dat = 0;
bank_cnt = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr;
 
if (n % (1<<(`SDRAM_COLA_HI+1)) == 0)
begin
$display("Verifying bank %d", bank_cnt);
bank_cnt = bank_cnt +1;
end
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
repeat(10) @(posedge wb_clk); //wait a while
end
 
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask // test_sdram_memfill
 
 
////////////////////////////////
// SDRAM parity test
//
 
// 1) This is practically the 'SDRAM sequential access test'
// 2) First check parity operation
// 3) Then introduce some parity errors
task tst_sdram_parity;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC + (1<<`SDRAM_COLA_HI) + (1<<`SDRAM_COLA_HI>>1); // start at 75% of page
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = 16; // a few runs
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
integer mod_par;
 
begin
 
$display("\n\n --- SDRAM PARITY TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 1; // burst length = 8
 
// simply set the parity bits to zero, when introducing parity errors
set_par = 4'b0;
 
// use second SDRAMS set as parity sdrams
sel_pbus = 1;
 
for(mod_par = 0; mod_par <= 1; mod_par = mod_par +1)
begin
 
// switch between parity and parity errors
sel_par = mod_par;
 
if(sel_par)
$display("\n-- Checking parity generation --");
else
$display("\n-- Introducing parity errors --");
 
// variables for TMS register
// skip these settings, since they are not relevant to parity
// for (cl = 2; cl <= 3; cl = cl +1)
// for (wbl = 0; wbl <= 1; wbl = wbl +1)
// for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
// for (kro = 0; kro <= 1; kro = kro +1)
// for (bas = 0; bas <= 1; bas = bas +1)
 
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b1, // parity enabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 0;
stb_delay = 0;
 
// skip cyc_delay and stb_delay.
// They are not relevant to parity generation
// for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
// for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM parity test. CYC-delay = %d, STB-delay = ", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
repeat(10) @(posedge wb_clk); //wait a while
end
 
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask // test_sdram_parity
 
////////////////////////////////
// SDRAM Sequential access test
//
 
// 1) Tests sdram sequential address access
// 2) Tests page switch
// 3) Tests bank-switching using BAS-bit
// 4) Test burst-action by filling SDRAM backwards (high addresses first)
// 5) Run test for all possible CS settings for SDRAMS
task tst_sdram_seq;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC + (1<<`SDRAM_COLA_HI) + (1<<`SDRAM_COLA_HI>>1); // start at 75% of page
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = (1<<`SDRAM_COLA_HI>>1); // run for half page length
 
integer n, k;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
reg [15:0] tmp0, tmp1;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM SEQUENTIAL ACCESS TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 2; // burst length
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 0;
stb_delay = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM sequential test. CYC-delay = %d, STB-delay = ", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+(1<<bl) )
begin
my_adr = SDRAM_TST_STARTA +( (SDRAM_TST_RUN -n -(1<<bl)) <<2);
for (k=0; k < (1<<bl); k=k+1)
begin
// fill destination backwards, but with linear bursts
dest_adr = my_adr + (k<<2);
 
tmp0 = ~dest_adr[15:0] + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
tmp1 = dest_adr[15:0] + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
my_dat = {tmp0, tmp1};
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = n<<2;
dest_adr = SDRAM_TST_STARTA + my_adr;
 
tmp0 = ~dest_adr[15:0] + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
tmp1 = dest_adr[15:0] + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
my_dat = {tmp0, tmp1};
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
 
repeat(10) @(posedge wb_clk); //wait a while
end
 
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask // test_sdram_seq
 
 
/////////////////////////////
// SDRAM Random access test
//
 
// 1) Tests sdram random address access
// 2) Run test for all possible CS settings for SDRAMS
task tst_sdram_rnd;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC; // start somewhere in memory
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = 64; // run a few accesses
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM RANDOM ACCESS TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 2; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("\nProgramming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
// random access requires CYC signal to be broken up (delay >= 1)
// otherwise MemoryController expects sequential burst
cyc_delay = 1;
stb_delay = 0;
for (cyc_delay = 1; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM random test. CYC-delay = %d, STB-delay = ", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory...");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2) + my_adr;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// read sdrams
$display("Verifying SDRAM memory contents...\n");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2) + my_adr;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask //tst_sdram_rnd
 
 
/////////////////////////
// SDRAM seq RMW test
//
 
// 1) Tests sdram RMW cycle using sequential address accesses
// 2) Run test for all possible CS settings for SDRAMS
task tst_sdram_rmw_seq;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC; // start somewhere in memory (at dword boundary)
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = 64; // only do a few runs
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM SEQUENTIAL ACCESS READ-MODIFY-WRITE TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 1; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("\nProgramming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 1;
stb_delay = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM sequential Read-Modify-Write test. CYC-delay = %d, STB-delay = %d", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory with initial contents ...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
$display("Performing RMW cycle ...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, dest_adr, my_dat);
 
// modify memory contents
my_dat = my_dat +1;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
 
end
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat +1);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask //tst_sdram_rmw_seq
 
/////////////////////////
// SDRAM Random RMW test
//
 
// 1) Tests sdram RMW cycle using random address accesses
// 2) Run test for all possible CS settings for SDRAMS
task tst_sdram_rmw_rnd;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM_TST_STARTA = `SDRAM1_LOC; // start somewhere in memory
parameter [ 7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = 64; // only do a few runs
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM RANDOM ACCESS READ-MODIFY-WRITE TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 2; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("\nProgramming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
// random access requires CYC signal to be broken up (delay >= 1)
// otherwise MemoryController expects sequential burst
cyc_delay = 1;
stb_delay = 0;
for (cyc_delay = 1; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM random Read-Modify-Write test. CYC-delay = %d, STB-delay = %d", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory with initial contents ...");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2) + my_adr;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
$display("Performing RMW cycle ...");
my_adr = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2) + my_adr;
dest_adr = SDRAM_TST_STARTA + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, dest_adr, my_dat);
 
// modify memory contents
my_dat = my_dat +1;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
 
end
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2) + my_adr;
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat +1);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask //tst_sdram_rmw_rnd
 
 
//////////////////////////
// SDRAM Block copy test1
//
 
// 1) Copy block of memory inside same memory block (chip select)
// 2) Run test for all possible CS settings for SDRAM
task tst_sdram_blk_cpy1;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM1_STARTA = `SDRAM1_LOC;
parameter [ 7:0] SDRAM1_SEL = SDRAM1_STARTA[28:21];
parameter SDRAM_TST_RUN = 64; // only do a few runs
 
parameter MAX_BSIZE = 8;
 
parameter SDRAM_SRC = SDRAM1_STARTA;
parameter SDRAM_DST = SDRAM1_STARTA + 32'h0001_0000;
 
integer n, wcnt, bsize;
reg [31:0] my_adr, src_adr, dest_adr;
reg [31:0] my_dat;
reg [31:0] tmp [MAX_BSIZE -1 :0];
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM block copy TEST-1- ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 1; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 0;
stb_delay = 0;
bsize = 2;
wcnt = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
for (bsize = 0; bsize < MAX_BSIZE; bsize = bsize +1)
begin
if (cyc_delay == 0)
while ( ((bsize +1) % (1 << bl) != 0) && (bsize < (MAX_BSIZE -1)) )
bsize = bsize +1;
 
$display("Block copy test-1-. CYC-delay = %d, STB-delay = %d, burst-size = %d", cyc_delay, stb_delay, bsize);
 
// fill sdrams
my_dat = 0;
for (n = 0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_SRC + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
n = 0;
while (n < SDRAM_TST_RUN)
begin
// read data from sdrams
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = SDRAM_SRC + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat +1;
end
 
// copy data into sdrams; new location
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = SDRAM_DST + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
n = n + bsize +1;
end
 
// read sdrams
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_DST + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat +1);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
$display("\nSDRAM block copy test-1- ended");
 
end
endtask // tst_sdram_blk_cpy1
 
 
 
//////////////////////////
// SDRAM Block copy test2
//
 
// 1) Copy a modified block of memory to the same memory location
// 2) Run test for all possible CS settings for SDRAM
task tst_sdram_blk_cpy2;
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter [31:0] SDRAM1_STARTA = `SDRAM1_LOC;
parameter [ 7:0] SDRAM1_SEL = SDRAM1_STARTA[28:21];
 
parameter SDRAM_TST_RUN = 64; // only do a few runs
 
parameter MAX_BSIZE = 8;
 
parameter SDRAM_SRC = SDRAM1_STARTA;
 
integer n, wcnt, bsize;
reg [31:0] my_adr, src_adr, dest_adr;
reg [31:0] my_dat;
reg [31:0] tmp [MAX_BSIZE -1 :0];
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM block copy TEST-2- ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 1; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 0;
stb_delay = 0;
bsize = 2;
wcnt = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
for (bsize = 0; bsize < MAX_BSIZE; bsize = bsize +1)
begin
 
if (cyc_delay == 0)
while ( ((bsize +1) % (1 << bl) != 0) && (bsize < (MAX_BSIZE -1)) )
bsize = bsize +1;
 
$display("Block copy test-2-. CYC-delay = %d, STB-delay = %d, burst-size = %d", cyc_delay, stb_delay, bsize);
 
// fill sdrams
my_dat = 0;
for (n = 0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_SRC + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
n = 0;
while (n < SDRAM_TST_RUN)
begin
// read data from sdrams
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = SDRAM_SRC + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat +1;
end
 
// copy data into sdrams; new location
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = SDRAM_SRC + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
n = n + bsize +1;
end
 
// read sdrams
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_SRC + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat +1);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
$display("\nSDRAM block copy test-2- ended");
 
end
endtask // tst_sdram_blk_cpy
 
 
/////////////////////////////
// SDRAM byte access test
//
 
// 1) Test byte/word writes (SDRAM DQM lines)
// 2) Run for all CS settings for SDRAMS
// 3) This test also checks the parity bits
task tst_sdram_bytes;
 
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
 
parameter SDRAM_TST_STARTA = `SDRAM1_LOC; // start at address 0
parameter [7:0] SDRAM1_SEL = SDRAM_TST_STARTA[28:21];
parameter SDRAM_TST_RUN = 64; // only do a few runs
 
integer n;
reg [31:0] my_adr, dest_adr;
reg [31:0] my_dat;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer sel;
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- SDRAM BYTE ACCESS TEST ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
// use second SDRAMS set as parity sdrams
sel_pbus = 1;
 
// choose some default settings
kro = 0;
bas = 0;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency = 2
bl = 2; // burst length = 4
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
// for (bas = 0; bas <= 1; bas = bas +1) // ignore BAS for this test
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b1, // parity enabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("\nProgramming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
cyc_delay = 1;
stb_delay = 0;
for (cyc_delay = 1; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
begin
$display("\nSDRAM byte test. CYC-delay = %d, STB-delay = ", cyc_delay, stb_delay);
 
// fill sdrams
$display("Filling SDRAM memory...");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
my_dat = {my_dat[7:0] +8'd3, my_dat[7:0] +8'd2, my_dat[7:0] +8'd1, my_dat[7:0]};
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// switch memory contents
$display("Swapping bytes...");
my_adr = 0;
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
for (sel=0; sel < 16; sel=sel+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
wbm.wb_read(cyc_delay, stb_delay, dest_adr, my_dat);
 
my_dat = {my_dat[31:24] +8'd1, my_dat[23:16] +8'd1, my_dat[15:8] +8'd1, my_dat[7:0] +8'd1};
wbm.wb_write_sel(cyc_delay, stb_delay, sel, dest_adr, my_dat);
 
end
 
// read sdrams
$display("Verifying SDRAM memory contents...");
my_dat = 0;
for (n=0; n < SDRAM_TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_TST_STARTA + my_adr;
my_dat = my_adr + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
my_dat = {my_dat[7:0] +8'd3, my_dat[7:0] +8'd2, my_dat[7:0] +8'd1, my_dat[7:0]};
my_dat = {my_dat[31:24] +8'd8, my_dat[23:16] +8'd8, my_dat[15:8] +8'd8, my_dat[7:0] +8'd8};
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
end
endtask //tst_sdram_bytes
/trunk/bench/richard/verilog/tst_multi_mem.v
0,0 → 1,588
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores Memory Controller Testbench ////
//// Multiple memory devices tests ////
//// This file is being included by the main testbench ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: tst_multi_mem.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: not supported by cvs2svn $
//
 
///////////////////////////////
// SDRAM/SRAM Block copy test1
//
 
// Test multi-memory accesses (SDRAM & SRAM)
// 1) Copy memory-block from SDRAM to SRAM
// 2) Copy block from SRAM to SDRAM
// 3) Run test for all CS settings for SDRAMS
task tst_blk_cpy1;
 
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
parameter MAX_BSIZE = 8;
 
parameter [31:0] SDRAM_STARTA = `SDRAM1_LOC;
parameter [ 7:0] SDRAM_SEL = SDRAM_STARTA[28:21];
parameter [31:0] SRAM_STARTA = `SRAM_LOC;
parameter [ 7:0] SRAM_SEL = SRAM_STARTA[28:21];
parameter TST_RUN = 64; // only perform a few accesses
 
parameter SDRAM_SRC = SDRAM_STARTA;
parameter SRAM_SRC = SRAM_STARTA;
 
integer n, wcnt, bsize;
reg [31:0] my_adr, src_adr, dest_adr;
reg [31:0] my_dat;
reg [31:0] tmp [MAX_BSIZE -1 :0];
reg [31:0] sdram_dest;
 
// config register mode bits
reg [1:0] kro, bas; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl; // a single register doesn't work with the for-loops
reg [2:0] cl, bl;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- Multiple memory block copy TEST-1- ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
// program asynchronous SRAMs
csc_data = {
8'h00, // reserved
SRAM_SEL, // SEL base address (a[28:21] == 8'b0100_0000)
4'h0, // reserved
1'b0, // PEN no parity
1'b0, // KRO ---
1'b0, // BAS ---
1'b0, // WP no write protection
2'b00, // MS ---
2'h2, // BW Bus width
3'h2, // MEM memory type == asynchronous
1'b1 // EN enable chip select
};
 
tms_data = {
6'h0, // reserved
6'h0, // Twwd = 5ns => 0ns
4'h0, // Twd = 0ns => 0ns
4'h1, // Twpw = 15ns => 20ns
4'h0, // Trdz = 8ns => 10ns
8'h02 // Trdv = 20ns => 20ns
};
 
// program chip select registers
wbm.wb_write(0, 0, 32'h6000_0018, csc_data); // program cs1 config register
wbm.wb_write(0, 0, 32'h6000_001c, tms_data); // program cs1 timing register
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0018, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_001c, tms_data);
 
 
// SDRAMS
kro = 1;
bas = 1;
 
wbl = 0; // programmed burst length
cl = 2; // cas latency
bl = 0; // burst length
 
// variables for TMS register
for (cl = 2; cl <= 3; cl = cl +1)
for (wbl = 0; wbl <= 1; wbl = wbl +1)
for (bl = 0; bl <= 3; bl = bl +1)
 
// variables for CSC register
for (kro = 0; kro <= 1; kro = kro +1)
for (bas = 0; bas <= 1; bas = bas +1)
begin
csc_data = {
8'h00, // reserved
SDRAM_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro[0], // KRO
bas[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01 , // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl[0], // write burst length
2'b00, // OM == normal operation
cl, // cas latency
1'b0, // BT == sequential burst type
bl
};
 
// program chip select registers
$display("\nProgramming SDRAM chip select register. KRO = %d, BAS = %d", kro, bas);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM timing register. WBL = %d, CL = %d, BL = %d\n", wbl, cl, bl);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
// calculate sdram destination address
if (bas)
sdram_dest = SDRAM_SRC + 32'h0001_0000; // add row address
else
sdram_dest = SDRAM_SRC + 32'h0000_0800; // add column address
 
cyc_delay = 1;
stb_delay = 2;
bsize = 0;
wcnt = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
for (bsize = 0; bsize < MAX_BSIZE; bsize = bsize +1)
begin
 
if (cyc_delay == 0)
while ( ((bsize +1) % (1 << bl) != 0) && (bsize < (MAX_BSIZE -1)) )
bsize = bsize +1;
 
$display("SDRAM/SRAM block copy test-1-. CYC-delay = %d, STB-delay = %d, burst-size = %d", cyc_delay, stb_delay, bsize);
 
// fill sdrams
my_dat = 0;
for (n = 0; n < TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM_SRC + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
n = 0;
while (n < TST_RUN)
begin
// copy from sdrams into srams
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = SDRAM_SRC + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat +1;
end
 
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = SRAM_SRC + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
// copy from srams into sdrams
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = SRAM_SRC + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat -1;
end
 
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = sdram_dest + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
n = n + bsize +1;
end
 
// read sdrams
my_dat = 0;
for (n=0; n < TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = sdram_dest + my_adr;
my_dat = my_adr + my_dat + kro + bas + wbl + cl + bl + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat);
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
 
$display("\nSDRAM/SRAM block copy test-1- ended");
 
end
endtask // tst_blk_cpy1
 
 
///////////////////////////////
// SDRAM/SDRAM Block copy test2
//
 
// Test multimemory accesses (SDRAM & SDRAM)
// 1) Copy memory block from SDRAM1 to SDRAM2
// 2) Copy block from SDRAM2 to SDRAM1
// 3) Use different pages/banks for copy (4 runs)
// 4) Run test for all CS settings for SDRAM1 & SDRAM2
//
// THIS IS A VERY LONG TEST !!!!
// MAY RUN FOR A COUPLE OF WEEKS
task tst_blk_cpy2;
 
// if the MAX_ numbers are larger than 15, adjust the appropriate _reg registers (see below)
parameter MAX_CYC_DELAY = 5;
parameter MAX_STB_DELAY = 5;
parameter MAX_BSIZE = 8;
 
parameter [31:0] SDRAM1_STARTA = `SDRAM1_LOC;
parameter [ 7:0] SDRAM1_SEL = SDRAM1_STARTA[28:21];
parameter [31:0] SDRAM2_STARTA = `SDRAM2_LOC;
parameter [ 7:0] SDRAM2_SEL = SDRAM2_STARTA[28:21];
parameter TST_RUN = 32; // only perform a few accesses
 
parameter SDRAM0 = SDRAM1_STARTA;
parameter SDRAM1 = SDRAM2_STARTA;
 
integer n, wcnt, bsize, opt;
reg [31:0] my_adr, src_adr, dest_adr, dest_adr0, dest_adr1;
reg [31:0] my_dat;
reg [31:0] tmp [MAX_BSIZE -1 :0];
 
// display registers (convert integers into regs)
reg [1:0] opt_reg;
reg [3:0] cyc_reg, stb_reg, bsz_reg;
 
// config register mode bits
reg [1:0] kro0, bas0, kro1, bas1; // a single register doesn't work with the for-loops
 
// SDRAM Mode Register bits
reg [1:0] wbl0, wbl1; // a single register doesn't work with the for-loops
reg [2:0] cl0, bl0, cl1, bl1;
 
reg [31:0] csc_data, tms_data;
 
integer cyc_delay, stb_delay;
 
begin
 
$display("\n\n --- Multiple memory block copy TEST-2- ---\n\n");
 
// clear Wishbone-Master-model current-error-counter
wbm.set_cur_err_cnt(0);
 
for(opt = 0; opt <= 4; opt = opt +1)
begin
// SDRAM1
kro0 = 0;
bas0 = 0;
 
wbl0 = 0;
cl0 = 2; // cas latency = 2
bl0 = 1;
 
// variables for TMS register
for (cl0 = 2; cl0 <= 3; cl0 = cl0 +1)
for (wbl0 = 0; wbl0 <= 1; wbl0 = wbl0 +1)
for (bl0 = 0; bl0 <= 3; bl0 = bl0 +1)
 
// variables for CSC register
for (kro0 = 0; kro0 <= 1; kro0 = kro0 +1)
// for (bas0 = 0; bas0 <= 1; bas0 = bas0 +1) // ignore bas, speed up test
begin
csc_data = {
8'h00, // reserved
SDRAM1_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro0[0], // KRO
bas0[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl0[0],// write burst length
2'b00, // OM == normal operation
cl0, // cas latency
1'b0, // BT == sequential burst type
bl0 // BL == burst length
};
 
// program chip select registers
$display("\nProgramming SDRAM1 chip select register. KRO = %d, BAS = %d", kro0, bas0);
wbm.wb_write(0, 0, 32'h6000_0028, csc_data); // program cs3 config register (CSC3)
 
$display("Programming SDRAM1 timing register. WBL = %d, CL = %d, BL = %d\n", wbl0, cl0, bl0);
wbm.wb_write(0, 0, 32'h6000_002c, tms_data); // program cs3 timing register (TMS3)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0028, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_002c, tms_data);
 
// calculate sdram destination address
if (!opt[0])
dest_adr0 = SDRAM0;
else
if (bas0)
dest_adr0 = SDRAM0 + 32'h0001_0000; // add row address
else
dest_adr0 = SDRAM0 + 32'h0000_0800; // add column address
 
//SDRAM1
kro1 = 0;
bas1 = 0;
 
wbl1 = 1;
cl1 = 2; // cas latency = 2
bl1 = 2;
 
// variables for TMS register
for (cl1 = 2; cl1 <= 3; cl1 = cl1 +1)
for (wbl1 = 0; wbl1 <= 1; wbl1 = wbl1 +1)
for (bl1 = 0; bl1 <= 3; bl1 = bl1 +1)
 
// variables for CSC register
for (kro1 = 0; kro1 <= 1; kro1 = kro1 +1)
// for (bas1 = 0; bas1 <= 1; bas1 = bas1 +1) // ignore bas, speed up test
begin
csc_data = {
8'h00, // reserved
SDRAM2_SEL, // SEL
4'h0, // reserved
1'b0, // parity disabled
kro1[0], // KRO
bas1[0], // BAS
1'b0, // WP
2'b10, // MS == 256MB
2'b01, // BW == 16bit bus per device
3'b000, // MEM_TYPE == SDRAM
1'b1 // EN == chip select enabled
};
tms_data = {
4'h0, // reserved
4'h8, // Trfc == 7 (+1)
4'h4, // Trp == 2 (+1) ?????
3'h3, // Trcd == 2 (+1)
2'b11, // Twr == 2 (+1)
5'h0, // reserved
wbl1[0],// write burst length
2'b00, // OM == normal operation
cl1, // cas latency
1'b0, // BT == sequential burst type
bl1 // BL == burst length
};
 
// program chip select registers
$display("\nProgramming SDRAM2 chip select register. KRO = %d, BAS = %d", kro1, bas1);
wbm.wb_write(0, 0, 32'h6000_0020, csc_data); // program cs3 config register (CSC2)
 
$display("Programming SDRAM2 timing register. WBL = %d, CL = %d, BL = %d\n", wbl1, cl1, bl1);
wbm.wb_write(0, 0, 32'h6000_0024, tms_data); // program cs3 timing register (TMS2)
 
// check written data
wbm.wb_cmp(0, 0, 32'h6000_0020, csc_data);
wbm.wb_cmp(0, 0, 32'h6000_0024, tms_data);
// calculate sdram destination address
if (!opt[1])
dest_adr1 = SDRAM1;
else
if (bas1)
dest_adr1 = SDRAM1 + 32'h0001_0000; // add row address
else
dest_adr1 = SDRAM1 + 32'h0000_0800; // add column address
 
cyc_delay = 0;
stb_delay = 0;
bsize = 2;
wcnt = 0;
for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1)
for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1)
for (bsize = 0; bsize < MAX_BSIZE; bsize = bsize +1)
begin
if (cyc_delay == 0)
while ( ( ((bsize +1) % (1 << bl0) !=0) && ((1 << bl0) % (bsize +1) !=0) ) ||
( ((bsize +1) % (1 << bl1) !=0) && ((1 << bl1) % (bsize +1) !=0) )
)
bsize = bsize +1;
 
 
// convert integers into regs (for display)
opt_reg = opt;
cyc_reg = cyc_delay;
stb_reg = stb_delay;
bsz_reg = bsize;
 
 
$display("SDRAM multi-memory block copy test-2-. Opt = %d, CYC-delay = %d, STB-delay = %d, burst-size = %d", opt_reg, cyc_reg, stb_reg, bsz_reg);
 
// fill sdram0
my_dat = 0;
for (n = 0; n < TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = SDRAM0 + my_adr;
my_dat = my_adr + my_dat + kro0 + kro1 + bas0 + bas1 + wbl0 + wbl1 + cl0 + cl1 + bl0 + bl1 + cyc_delay + stb_delay;
 
wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat);
end
 
// perform Read-Modify-Write cycle
n = 0;
while (n < TST_RUN)
begin
// copy from sdram0 into sdram1
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = SDRAM0 + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat +1;
end
 
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = dest_adr1 + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
// copy from sdram1 into sdram0
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
src_adr = dest_adr1 + my_adr;
 
// read memory contents
wbm.wb_read(cyc_delay, stb_delay, src_adr, my_dat);
 
// modify memory contents
tmp[wcnt] = my_dat +1;
end
 
for (wcnt = 0; wcnt <= bsize; wcnt = wcnt +1)
begin
my_adr = (n + wcnt) << 2;
dest_adr = dest_adr0 + my_adr;
 
// write contents back into memory
wbm.wb_write(cyc_delay, stb_delay, dest_adr, tmp[wcnt]);
end
 
n = n + bsize +1;
end
 
// read sdrams
my_dat = 0;
for (n=0; n < TST_RUN; n=n+1)
begin
my_adr = (n << 2);
dest_adr = dest_adr0 + my_adr;
my_dat = my_adr + my_dat + kro0 + kro1 + bas0 + bas1 + wbl0 + wbl1 + cl0 + cl1 + bl0 + bl1 + cyc_delay + stb_delay;
 
wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat +2);
end
end
end
end
end
 
// show Wishbone-Master-model current-error-counter
wbm.show_cur_err_cnt;
$display("\nSDRAM/SRAM block copy test-2- ended");
 
end
endtask // tst_blk_cpy2
 
/trunk/bench/richard/verilog/wb_master_model.v
0,0 → 1,408
///////////////////////////////////////////////////////////////////////
//// ////
//// WISHBONE rev.B2 Wishbone Master model ////
//// ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
//// Downloaded from: http://www.opencores.org/projects/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. ////
//// ////
///////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: wb_master_model.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:
//
`include "timescale.v"
 
module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty);
 
//
// parameters
//
parameter dwidth = 32;
parameter awidth = 32;
 
//
// inputs & outputs
//
input clk, rst;
output [awidth -1:0] adr;
input [dwidth -1:0] din;
output [dwidth -1:0] dout;
output cyc, stb;
output we;
output [dwidth/8 -1:0] sel;
input ack, err, rty;
 
//
// variables
//
reg [awidth -1:0] adr;
reg [dwidth -1:0] dout;
reg cyc, stb;
reg we;
reg [dwidth/8 -1:0] sel;
 
reg [dwidth -1:0] q;
 
integer err_cur_cnt, err_tot_cnt, err_wb_cnt, err_watchdog;
 
 
//
// module body
//
 
// check ack, err and rty assertion
always@(ack or err or rty)
begin
case ({ack, err, rty})
// ok-states
// 3'b000: // none asserted
// 3'b001: // only rty asserted
// 3'b010: // only err asserted
// 3'b100: // only ack asserted
 
// fault-states
3'b011: // oops, err and rty
begin
err_wb_cnt = err_wb_cnt +1;
$display("Wishbone error: ERR_I and RTY_I are both asserted at time %t.", $time);
end
3'b101: // oops, ack and rty
begin
err_wb_cnt = err_wb_cnt +1;
$display("Wishbone error: ACK_I and RTY_I are both asserted at time %t.", $time);
end
3'b110: // oops, ack and err
begin
err_wb_cnt = err_wb_cnt +1;
$display("Wishbone error: ACK_I and ERR_I are both asserted at time %t.", $time);
end
3'b111: // oops, ack, err and rty
begin
err_wb_cnt = err_wb_cnt +1;
$display("Wishbone error: ACK_I, ERR_I and RTY_I are all asserted at time %t.", $time);
end
endcase
if (err_wb_cnt > err_watchdog)
begin
$display("\nTestbench stopped. More than %d wishbone errors detected.\n", err_watchdog);
$stop;
end
end
 
// initial settings
initial
begin
//adr = 32'hxxxx_xxxx;
//adr = 0;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
cyc = 1'b0;
stb = 1'bx;
we = 1'hx;
sel = {dwidth/8{1'bx}};
 
err_tot_cnt = 0;
err_cur_cnt = 0;
err_wb_cnt = 0;
err_watchdog = 10;
 
#1;
$display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n");
end
 
 
////////////////////////////
//
// Wishbone write cycle
//
 
task wb_write;
input delay;
integer delay;
input stb_delay;
integer stb_delay;
 
input [awidth -1:0] a;
input [dwidth -1:0] d;
 
begin
 
// wait initial delay
repeat(delay) @(posedge clk);
 
#1;
// assert cyc_signal
cyc = 1'b1;
stb = 1'b0;
 
// wait for stb_assertion
repeat(stb_delay) @(posedge clk);
 
// assert wishbone signals
adr = a;
dout = d;
stb = 1'b1;
we = 1'b1;
sel = {dwidth/8{1'b1}};
@(posedge clk);
 
// wait for acknowledge from slave
// err is treated as normal ack
// rty is ignored (thus retrying cycle)
while(~ (ack || err)) @(posedge clk);
 
// negate wishbone signals
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
 
end
endtask
 
task wb_write_sel;
input delay;
integer delay;
input stb_delay;
integer stb_delay;
 
input [dwidth/8 -1:0] s;
input [awidth -1:0] a;
input [dwidth -1:0] d;
 
begin
 
// wait initial delay
repeat(delay) @(posedge clk);
 
#1;
// assert cyc_signal
cyc = 1'b1;
stb = 1'b0;
 
// wait for stb_assertion
repeat(stb_delay) @(posedge clk);
 
// assert wishbone signals
adr = a;
dout = d;
stb = 1'b1;
we = 1'b1;
sel = s;
@(posedge clk);
 
// wait for acknowledge from slave
// err is treated as normal ack
// rty is ignored (thus retrying cycle)
while(~ (ack || err)) @(posedge clk);
 
// negate wishbone signals
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
 
end
endtask
 
////////////////////////////
//
// Wishbone read cycle
//
 
task wb_read;
input delay;
integer delay;
input stb_delay;
integer stb_delay;
 
input [awidth -1:0] a;
output [dwidth -1:0] d;
 
begin
 
// wait initial delay
repeat(delay) @(posedge clk);
 
#1;
// assert cyc_signal
cyc = 1'b1;
stb = 1'b0;
 
// wait for stb_assertion
repeat(stb_delay) @(posedge clk);
 
// assert wishbone signals
adr = a;
dout = {dwidth{1'bx}};
stb = 1'b1;
we = 1'b0;
sel = {dwidth/8{1'b1}};
@(posedge clk);
 
// wait for acknowledge from slave
// err is treated as normal ack
// rty is ignored (thus retrying cycle)
while(~ (ack || err)) @(posedge clk);
 
// negate wishbone signals
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
d = din;
 
end
endtask
 
task wb_read_sel;
input delay;
integer delay;
input stb_delay;
integer stb_delay;
 
input [dwidth/8 -1:0] s;
input [awidth -1:0] a;
output [dwidth -1:0] d;
 
begin
 
// wait initial delay
repeat(delay) @(posedge clk);
 
#1;
// assert cyc_signal
cyc = 1'b1;
stb = 1'b0;
 
// wait for stb_assertion
repeat(stb_delay) @(posedge clk);
 
// assert wishbone signals
adr = a;
dout = {dwidth{1'bx}};
stb = 1'b1;
we = 1'b0;
sel = s;
@(posedge clk);
 
// wait for acknowledge from slave
// err is treated as normal ack
// rty is ignored (thus retrying cycle)
while(~ (ack || err)) @(posedge clk);
 
// negate wishbone signals
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
d = din;
 
end
endtask
 
////////////////////////////
//
// Wishbone compare cycle
// read data from location and compare with expected data
//
 
task wb_cmp;
input delay;
integer delay;
input stb_delay;
integer stb_delay;
 
input [awidth -1:0] a;
input [dwidth -1:0] d_exp;
 
begin
wb_read (delay, stb_delay, a, q);
 
if (d_exp !== q)
begin
err_tot_cnt = err_tot_cnt +1;
err_cur_cnt = err_cur_cnt +1;
$display("Data compare error(%d) at time %t. Received %h, expected %h at address %h", err_tot_cnt, $time, q, d_exp, a);
end
 
if (err_tot_cnt > err_watchdog)
begin
$display("\nTestbench stopped. More than %d errors detected.\n", err_watchdog);
$stop;
end
end
endtask
 
 
////////////////////////////
//
// Error counter handlers
//
task set_cur_err_cnt;
input value;
begin
err_cur_cnt = value;
end
endtask
 
task show_cur_err_cnt;
$display("\nCurrent errors detected: %d\n", err_cur_cnt);
endtask
 
task show_tot_err_cnt;
$display("\nTotal errors detected: %d\n", err_tot_cnt);
endtask
 
endmodule
 
/trunk/bench/richard/verilog/timescale.v
0,0 → 1,2
`timescale 1ns / 10ps
 
/trunk/bench/richard/verilog/checkers.v
0,0 → 1,226
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores Memory Controller Testbench ////
//// Additional checks ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: checkers.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: not supported by cvs2svn $
//
 
`include "timescale.v"
 
//////////////////////////////
// external bus-master model
//
 
module bm_model(br, bg, chk);
 
// parameters
reg on_off;
 
// inputs
output br;
reg br;
input bg;
input chk;
 
integer delay;
 
initial
begin
on_off = 0;
br = 1'b0;
end
 
always
begin
wait(on_off)
 
delay = ($random >> 24) +10;
 
// wait a random moment
# delay;
 
// assert bus_request
br = 1'b1;
$display("External bus-master requesting bus at time %t... ", $time);
 
// wait for assertion of bus_grant
wait(bg);
$display("Bus granted at time %t.", $time);
 
// check the memory controller output_enable signal, should be negated
if (chk)
$display("Memory controller output signals not in tri-state.");
 
delay = ($random >> 24) +10;
// wait a random moment
# delay;
 
// negate bus_request
br = 1'b0;
$display("External bus-master releasing bus at time %t ...", $time);
 
// wait for negation of bus_grant
wait(!bg);
$display("Bus released at time %t.", $time);
 
end
endmodule
 
 
//
// WISHBONE Bus Watchdog
//
module watch_dog(clk, cyc_i, ack_i, adr_i);
 
// parameters
parameter count = 1000;
 
// inputs
input clk;
input cyc_i;
input ack_i;
input [31:0] adr_i;
 
// variables
integer cnt;
 
// module body
always@(posedge clk)
if (!cyc_i || ack_i)
cnt <= #1 count;
else
begin
cnt <= #1 cnt -1;
 
if (cnt == 0)
begin
$display("\n\n WATCHDOG TIMER EXPIRED \n\n");
$display("Time: %t, address: %h", $time, adr_i);
$stop;
end
end
endmodule
 
 
//
// Check status of Wishbone ERR_O line
//
 
module err_check(err, sel_par);
 
//
// inputs
//
input err;
input sel_par;
 
//
// module body
//
always@(err)
case (err)
1'b1:
if(sel_par)
begin
$display("*");
$display("* ERROR: WISHBONE ERR_O asserted at time %t", $time);
$display("*");
end
else
$display("Wishbone ERR_O asserted (ok)");
1'bx:
begin
$display("*");
$display("* ERROR: WISHBONE ERR_O undefined at time %t", $time);
$display("*");
end
endcase
endmodule
 
//
// Check status of Wishbone ERR_O line
//
 
module cs_check(cs);
 
//
// inputs
//
input [7:0] cs;
 
//
// module body
//
always@(cs)
begin
if ((cs[7] == 1'bx) | (cs[6] == 1'bx) | (cs[5] == 1'bx) | (cs[4] == 1'bx) |
(cs[3] == 1'bx) | (cs[2] == 1'bx) | (cs[1] == 1'bx) | (cs[0] == 1'bx) )
begin
$display("*");
$display("* ERROR: CHIP SELECT SIGNAL UNDEFINED at time %t", $time);
$display("*");
end
 
if ((!cs[7] & !(&cs[6:0]) ) |
(!cs[6] & !(&{cs[7] , cs[5:0]}) ) |
(!cs[5] & !(&{cs[7:6], cs[4:0]}) ) |
(!cs[4] & !(&{cs[7:5], cs[3:0]}) ) |
(!cs[3] & !(&{cs[7:4], cs[2:0]}) ) |
(!cs[2] & !(&{cs[7:3], cs[1:0]}) ) |
(!cs[1] & !(&{cs[7:2], cs[0]} ) ) |
(!cs[0] & !(&cs[7:1]) ) )
begin
$display("*");
$display("* ERROR: MULTIPLE CHIP SELECT SIGNALS ASSERTED at time %t", $time);
$display("*");
end
end
 
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.