📄 test_mem_ctrl.v
字号:
// ===========================================================================
// Verilog module generated by IPexpress
// Filename: test_mem_ctrl.v
// Copyright 2006 (c) Lattice Semiconductor Corporation. All rights reserved.
// ===========================================================================
`timescale 1 ps / 1 ps
module test_mem_ctrl;
`include "tb_config_params.v"
`define CDL_READ 4'b0001
`define CDL_WRITE 4'b0010
`define READA 4'b0011
`define WRITEA 4'b0100
`define PWRDN 4'b0101
`define LOAD_MR 4'b0110
`define SEFL_REF 4'b0111
`define LOAD_CFG1 4'b1001
`define LOAD_CFG2 4'b1010
parameter LOW = 1'b0;
parameter HIGH = 1'b1;
parameter DDR_CS_WIDTH = `CS_WIDTH;
parameter DDR_ADR_WIDTH = `ROW_WIDTH;
parameter DDR_CS_NOP = {DDR_CS_WIDTH{HIGH}};
parameter BL_2 = 2;
parameter BL_4 = 4;
parameter BL_8 = 8;
parameter TB_DDR_REDUCED_ROW = (20 - `COL_WIDTH) ;
// ====================================================================
// Internal signals
// ====================================================================
wire [`ROW_WIDTH-1:0] ddr_ad_tmp; // Address bus
reg [`ROW_WIDTH-1:0] ddr_ad; // Address bus
//wire [`DATA_WIDTH-1:0] ddr_dq; // Data bus output
//wire [(`DATA_WIDTH/8)-1:0] ddr_dqs; // Data strobe output
// ====================================================================
// Registers used by the tasks to drive the input signals of the
// FPGA bridge
// ====================================================================
reg rst_n;
reg write_en;
reg [3:0] cmd;
reg cmd_valid;
reg init_start;
reg ff_burst_term;
reg [4:0] ff_burst_count;
reg [4:0] burst_count;
reg [((`DATA_WIDTH*2)/8)-1:0] dmsel;
reg [`ADDR_WIDTH-1:0] addr;
reg [(`DATA_WIDTH*2)-1:0] datain;
// ====================================================================
// The following are the static parameters that can be set by the
// parameter bus. These are set to default values within the
// test bench.
// ====================================================================
reg [4:0] tras;
reg [4:0] trc;
reg [2:0] trcd;
reg [2:0] trrd;
reg [4:0] trfc;
reg [2:0] trp;
reg [2:0] tmrd;
reg [2:0] twr;
reg [15:0] trefi;
wire [2:0] ar_burst_en;
reg [2:0] db_size;
reg ext_reg_en;
// ====================================================================
// Output signals from the controller
// ====================================================================
wire [(`DATA_WIDTH*2)-1:0] usr_data_out;
wire cmd_rdy;
wire init_done;
wire usr_data_out_en;
wire datain_valid;
wire [`CKE_WIDTH-1:0] ddr_cke_tmp;
wire ddr_ras_n_tmp;
wire ddr_cas_n_tmp;
wire ddr_we_n_tmp;
wire [`CS_WIDTH-1:0] ddr_cs_n_tmp;
reg ddr_cke;
reg ddr_ras_n;
reg ddr_cas_n;
reg ddr_we_n;
reg [`CS_WIDTH-1:0] ddr_cs_n;
`ifdef CS_WIDTH_1
wire [`CS_WIDTH -1 :0] ddr_odt;
`else
wire [`CS_WIDTH -1 :0] ddr_odt;
`endif
wire [`ROW_WIDTH-1:0] ddr_addr;
wire [`BNK_WDTH-1:0] ddr_ba_tmp;
reg [`BNK_WDTH-1:0] ddr_ba;
wire [`DATA_WIDTH*2-1:0] ddr_write_data;
wire [`USER_DM:0] ddr_DM;
wire ddr_write_valid;
wire data_rdy;
reg data_rdy_d;
// ====================================================================
// Clock generation logic and Parameters
// ====================================================================
reg mem_clk; // memory controller clock
reg mem_clk_2; // memory controller clock
wire clk; // clock connected to FPGA bridge
wire [`CLKO_WIDTH-1:0] ddr_clk; // clock connected to the memory
`ifdef DDR2_MODE
`ifdef SLAYER
`ifdef GATE_SIM
parameter c = 8000;
`else
parameter c = 3750;
`endif
`else
`ifdef GATE_SIM
parameter c = 6000;
`else
parameter c = 5000;
`endif
`endif
`else
`ifdef ECP
`ifdef GATE_SIM
parameter c = 8000;
`else
parameter c = 6000;
`endif
`else
`ifdef GATE_SIM
parameter c = 6000;
`else
parameter c = 5000;
`endif
`endif
`endif
initial begin
mem_clk = 0;
mem_clk_2 = 0;
init_start = 0;
addr = 0;
ff_burst_count = 1;
ff_burst_term = 0;
cmd = 0;
dmsel = 0;
datain = 0;
cmd_valid = 0;
end
// ====================================================================
// This will provide display of the current settings, good for debugging
// ====================================================================
initial begin
$display ("// ==================================================");
$display ("INFO: Current data bus width is %0d bits", `DATA_WIDTH);
$display ("INFO: Current Addr bus width is %0d bits", `ADDR_WIDTH);
$display ("INFO: Current User Data bus width is %0d bits", `DSIZE);
$display ("INFO: Current User Data Mask bus width is %0d bits", `USER_DM);
$display ("INFO: Current frequency is %0d MHz", (1000000/c));
$display ("INFO: Current CLK_PERIOD is %2f ns", c/1000.0);
`ifdef GATE_SIM
$display ("INFO: Doing Gate Level Simulation");
`endif
`ifdef DUMMY_LOGIC
$display ("INFO: Dummy Logic is used.");
`endif
$display ("// ==================================================");
end
always #(c/2) mem_clk = ~mem_clk;
always #(c) mem_clk_2 = ~mem_clk_2;
`ifdef GATE_SIM
`ifdef SLAYER
assign clk = U1_ddr_sdram_mem_top.k_clk;
`else
assign clk = mem_clk;
`endif
`else
`ifdef SLAYER
`ifdef DDR2_MODE
assign clk = U1_ddr_sdram_mem_top.k_clk;
`else
assign clk = mem_clk;
`endif
`else
assign clk = U1_ddr_sdram_mem_top.k_clk;
`endif
`endif
// ====================================================================
// Instantiate the memory controller module
// ====================================================================
wire [`DATA_WIDTH-1:0] ddr_dataout;
integer i,j;
wire [`DATA_WIDTH-1:0] ddr_dq_int; // Data bus output
wire [`DATA_WIDTH/8-1:0] inv_ddr_dqs_int; // DQS bus
`ifndef DQSD_4
`ifdef DATA_SIZE_8
wire ddr_dqs_int; // DQS bus
`else
wire [`DATA_WIDTH/8-1:0] ddr_dqs_int; // DQS bus
`endif
`endif
wand [`DQS_WIDTH-1:0] ddr_dqs_int_temp;
//wire [`DATA_WIDTH/8-1:0] ddr_dqsout; // DQS bus
wire [(`DATA_WIDTH/8)-1:0] ddr_dqm; // Data mask lines
wire [`DATA_WIDTH-1:0] dataout_pos;
wire [`DATA_WIDTH-1:0] dataout_neg;
wire [127:0] ib_read_data;
wire [`ADDR_WIDTH-1:0] addr_dly;
wire [31:0] new_addr_dly;
wire [3:0] cmd_dly;
wire cmd_valid_dly;
// ====================================================================
// Delay the following signals to seperate them out from the clock edge.
// ====================================================================
`ifdef DQSD_4
wand [`DATA_WIDTH/8-1:0] ddr_dqs_int; // DQS bus
genvar jd;
`ifdef GATE_SIM
`define dqs_io em_ddr_dqs_0_MGIOL.IOLTO
`else
`define dqs_io U1_ddr_dqs_io.u[0].bidi_dqs
`endif
`ifdef ECP2
assign dqs_tri_en_n_a = U1_ddr_sdram_mem_top.U1_ddr_sdram_mem_io_top.`dqs_io.tri_en_reg; // Low for write
`else
`ifdef ECP
assign dqs_tri_en_n_a = U1_ddr_sdram_mem_top.U1_ddr_sdram_mem_io_top.`dqs_io.tri_en_reg; // Low for write
`else
assign dqs_tri_en_n_a = U1_ddr_sdram_mem_top.U1_mem_ctrl_io_top.U1_ddr_dqs_io.u[0].dqs.tri_en_reg;
`endif
`endif
generate
for (jd=0; jd<`DATA_WIDTH/8; jd=jd+1) begin:abc
// ====================================================================
// Write
// During write controller drives two dqs signals which are to be combined to one signal
// eg: ddr_dqs_int_temp[0], [1] are to assigned to ddr_dqs_int[0]
// ====================================================================
assign ddr_dqs_int[jd] = dqs_tri_en_n_a ? 1'bz : ddr_dqs_int_temp[jd];
assign ddr_dqs_int[jd] = dqs_tri_en_n_a ? 1'bz : ddr_dqs_int_temp[`DATA_WIDTH/8+jd];
// ====================================================================
// Read
// During READ, DRAM will generate one dqs, that should go as two dws to the
// controller.
// ====================================================================
assign ddr_dqs_int_temp[jd] = dqs_tri_en_n_a ? ddr_dqs_int[jd] : 1'bz;
assign ddr_dqs_int_temp[`DATA_WIDTH/8+jd] = dqs_tri_en_n_a ? ddr_dqs_int[jd] : 1'bz;
end
endgenerate
`endif
assign inv_ddr_dqs_int = ~ddr_dqs_int;
assign #1 addr_dly = addr;
assign #1 cmd_dly = cmd;
assign #1 cmd_valid_dly = cmd_valid;
GSR GSR_INST (.GSR(rst_n));
PUR PUR_INST (.PUR(rst_n));
// =======================================================
// Instantiations
// =======================================================
ddr_sdram_mem_top U1_ddr_sdram_mem_top (
// Clock and reset
`ifdef SLAYER
.clk_in (mem_clk_2),
`else
.clk_in (mem_clk),
`endif
.rst_n (rst_n),
// Inputs signals from the User Interface
.cmd (cmd_dly),
.addr (addr_dly),
.cmd_valid (cmd_valid_dly),
`ifdef BRST_CNT_EN
.burst_count (ff_burst_count),
`endif
.init_start (init_start),
`ifdef DUMMY_LOGIC
.write_data (datain[`DATA_WIDTH -1 :0]),
`else
.write_data (datain),
`endif
.data_mask (dmsel),
// User Interface Output signals
.cmd_rdy (cmd_rdy),
.data_rdy (data_rdy),
.init_done (init_done),
`ifdef DUMMY_LOGIC
.read_data (usr_data_out[`DATA_WIDTH -1 :0]),
`else
.read_data (usr_data_out),
`endif
.read_data_valid (usr_data_out_en),
.k_clk (),
// Bi-directional databus to external memory
`ifdef DQSD_4
.em_ddr_dqs (ddr_dqs_int_temp),
`else
.em_ddr_dqs (ddr_dqs_int),
`endif
.em_ddr_data (ddr_dq_int),
// Output to External memory
// SDRAM Address, controls and clock
.em_ddr_clk (ddr_clk),
.em_ddr_cke (ddr_cke_tmp),
.em_ddr_ras_n (ddr_ras_n_tmp),
.em_ddr_cas_n (ddr_cas_n_tmp),
.em_ddr_we_n (ddr_we_n_tmp),
.em_ddr_cs_n (ddr_cs_n_tmp),
`ifdef DDR2_MODE
.em_ddr_odt (ddr_odt),
`else
.burst_term (ff_burst_term),
`endif
.em_ddr_dm (ddr_dqm),
.em_ddr_ba (ddr_ba_tmp),
.em_ddr_addr (ddr_ad_tmp)
);
always @(negedge rst_n or posedge clk) begin
if (!rst_n) data_rdy_d <= 0;
else data_rdy_d <= data_rdy;
end
assign datain_valid = (`WrRqDDelay == 2'd2) ? data_rdy_d : data_rdy;
`ifdef BUFDIMM
// =======================================================
// Since we don't have a model with buffered memory,
// emulate the behavior of DIMM by registering in testbench
// and using a regular unbuffered model.
// =======================================================
always @ (negedge rst_n or posedge ddr_clk[0]) begin
if (!rst_n) begin
ddr_cke <= LOW;
ddr_cs_n <= DDR_CS_NOP;
ddr_we_n <= HIGH;
ddr_cas_n <= HIGH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -