⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_mem_ctrl.v

📁 DDR2 的控制器
💻 V
📖 第 1 页 / 共 2 页
字号:
// ===========================================================================
// 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 + -