📄 ddr2_model.v
字号:
reg [`BANKS-1:0] write_precharge_bank; reg [`BANKS-1:0] read_precharge_bank; reg [ROW_BITS-1:0] active_row [`BANKS-1:0]; reg in_power_down; reg in_self_refresh; reg precharge_all; reg [3:0] init_mode_reg; reg init_done; integer init_step; reg er_trfc_max; reg odt_state; reg prev_odt; // cmd timers/counters integer ref_cntr; integer ck_cntr; integer ck_load_mode; integer ck_write; integer ck_read; integer ck_power_down; integer ck_slow_exit_pd; integer ck_self_refresh; integer ck_cke; integer ck_odt; integer ck_dll_reset; integer ck_bank_write [`BANKS-1:0]; integer ck_bank_read [`BANKS-1:0]; time tm_refresh; time tm_precharge; time tm_activate; time tm_write_end; time tm_self_refresh; time tm_odt_en; time tm_bank_precharge [`BANKS-1:0]; time tm_bank_activate [`BANKS-1:0]; time tm_bank_write_end [`BANKS-1:0]; time tm_bank_read_end [`BANKS-1:0]; // pipelines reg [`MAX_PIPE:0] al_pipeline; reg [`MAX_PIPE:0] wr_pipeline; reg [`MAX_PIPE:0] rd_pipeline; reg [`MAX_PIPE:0] odt_pipeline; reg [BA_BITS-1:0] ba_pipeline [`MAX_PIPE:0]; reg [ROW_BITS-1:0] row_pipeline [`MAX_PIPE:0]; reg [COL_BITS-1:0] col_pipeline [`MAX_PIPE:0]; reg prev_cke; // data state reg [BL_MAX*DQ_BITS-1:0] memory_data; reg [BL_MAX*DQ_BITS-1:0] bit_mask; reg [BL_BITS-1:0] burst_position; reg [BL_BITS:0] burst_cntr; reg [DQ_BITS-1:0] dq_temp; reg [31:0] check_write_postamble; reg [31:0] check_write_preamble; reg [31:0] check_write_dqs_high; reg [31:0] check_write_dqs_low; reg [15:0] check_dm_tdipw; reg [63:0] check_dq_tdipw; // data timers/counters time tm_cke; time tm_odt; time tm_tdqss; time tm_dm [15:0]; time tm_dqs [15:0]; time tm_dqs_pos [31:0]; time tm_dqss_pos [31:0]; time tm_dqs_neg [31:0]; time tm_dq [63:0]; time tm_cmd_addr [22:0]; reg [8*7-1:0] cmd_addr_string [22:0]; initial begin cmd_addr_string[ 0] = "CS_N "; cmd_addr_string[ 1] = "RAS_N "; cmd_addr_string[ 2] = "CAS_N "; cmd_addr_string[ 3] = "WE_N "; cmd_addr_string[ 4] = "BA 0 "; cmd_addr_string[ 5] = "BA 1 "; cmd_addr_string[ 6] = "BA 2 "; cmd_addr_string[ 7] = "ADDR 0"; cmd_addr_string[ 8] = "ADDR 1"; cmd_addr_string[ 9] = "ADDR 2"; cmd_addr_string[10] = "ADDR 3"; cmd_addr_string[11] = "ADDR 4"; cmd_addr_string[12] = "ADDR 5"; cmd_addr_string[13] = "ADDR 6"; cmd_addr_string[14] = "ADDR 7"; cmd_addr_string[15] = "ADDR 8"; cmd_addr_string[16] = "ADDR 9"; cmd_addr_string[17] = "ADDR 10"; cmd_addr_string[18] = "ADDR 11"; cmd_addr_string[19] = "ADDR 12"; cmd_addr_string[20] = "ADDR 13"; cmd_addr_string[21] = "ADDR 14"; cmd_addr_string[22] = "ADDR 15"; end reg [8*5-1:0] dqs_string [1:0]; initial begin dqs_string[0] = "DQS "; dqs_string[1] = "DQS_N"; end // Memory Storage`ifdef MAX_MEM reg [BL_MAX*DQ_BITS-1:0] memory [0:`MAX_SIZE-1];`else reg [BL_MAX*DQ_BITS-1:0] memory [0:`MEM_SIZE-1]; reg [`MAX_BITS-1:0] address [0:`MEM_SIZE-1]; reg [MEM_BITS:0] memory_index; reg [MEM_BITS:0] memory_used;`endif // receive reg ck_in; reg ck_n_in; reg cke_in; reg cs_n_in; reg ras_n_in; reg cas_n_in; reg we_n_in; reg [15:0] dm_in; reg [2:0] ba_in; reg [15:0] addr_in; reg [63:0] dq_in; reg [31:0] dqs_in; reg odt_in; reg [15:0] dm_in_pos; reg [15:0] dm_in_neg; reg [63:0] dq_in_pos; reg [63:0] dq_in_neg; reg dq_in_valid; reg dqs_in_valid; integer wdqs_cntr; integer wdq_cntr; integer wdqs_pos_cntr [31:0]; reg b2b_write; reg [31:0] prev_dqs_in; reg diff_ck; always @(ck ) ck_in <= #BUS_DELAY ck; always @(ck_n ) ck_n_in <= #BUS_DELAY ck_n; always @(cke ) cke_in <= #BUS_DELAY cke; always @(cs_n ) cs_n_in <= #BUS_DELAY cs_n; always @(ras_n ) ras_n_in <= #BUS_DELAY ras_n; always @(cas_n ) cas_n_in <= #BUS_DELAY cas_n; always @(we_n ) we_n_in <= #BUS_DELAY we_n; always @(dm_rdqs) dm_in <= #BUS_DELAY dm_rdqs; always @(ba ) ba_in <= #BUS_DELAY ba; always @(addr ) addr_in <= #BUS_DELAY addr; always @(dq ) dq_in <= #BUS_DELAY dq; always @(dqs or dqs_n) dqs_in <= #BUS_DELAY (dqs_n<<16) | dqs; always @(odt ) odt_in <= #BUS_DELAY odt; // create internal clock always @(posedge ck_in) diff_ck <= ck_in; always @(posedge ck_n_in) diff_ck <= ~ck_n_in; wire [15:0] dqs_even = dqs_in[15:0]; wire [15:0] dqs_odd = dqs_n_en ? dqs_in[31:16] : ~dqs_in[15:0]; wire [3:0] cmd_n_in = !cs_n_in ? {ras_n_in, cas_n_in, we_n_in} : NOP; //deselect = nop // transmit reg dqs_out_en; reg [DQS_BITS-1:0] dqs_out_en_dly; reg dqs_out; reg [DQS_BITS-1:0] dqs_out_dly; reg dq_out_en; reg [DQ_BITS-1:0] dq_out_en_dly; reg [DQ_BITS-1:0] dq_out; reg [DQ_BITS-1:0] dq_out_dly; integer rdqsen_cntr; integer rdqs_cntr; integer rdqen_cntr; integer rdq_cntr; bufif1 buf_dqs [DQS_BITS-1:0] (dqs, dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}}); bufif1 buf_dm [DM_BITS-1:0] (dm_rdqs, dqs_out_dly, dqs_out_en_dly & {DM_BITS {out_en}} & {DM_BITS{rdqs_en}}); bufif1 buf_dqs_n [DQS_BITS-1:0] (dqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}}); bufif1 buf_rdqs_n [DQS_BITS-1:0] (rdqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}} & {DQS_BITS{rdqs_en}}); bufif1 buf_dq [DQ_BITS-1:0] (dq, dq_out_dly, dq_out_en_dly & {DQ_BITS {out_en}}); initial begin if (BL_MAX < 2) $display("%m ERROR: BL_MAX parameter must be >= 2. \nBL_MAX = %d", BL_MAX); if ((1<<BO_BITS) > BL_MAX) $display("%m ERROR: 2^BO_BITS cannot be greater than BL_MAX parameter."); $timeformat (-12, 1, " ps", 1); reset_task; seed = RANDOM_SEED; ck_cntr = 0; end // calculate the absolute value of a real number function real abs_value; input arg; real arg; begin if (arg < 0.0) abs_value = -1.0 * arg; else abs_value = arg; end endfunction`ifdef MAX_MEM`else function get_index; input [`MAX_BITS-1:0] addr; begin : index get_index = 0; for (memory_index=0; memory_index<memory_used; memory_index=memory_index+1) begin if (address[memory_index] == addr) begin get_index = 1; disable index; end end end endfunction`endif task memory_write; input [BA_BITS-1:0] bank; input [ROW_BITS-1:0] row; input [COL_BITS-1:0] col; input [BL_MAX*DQ_BITS-1:0] data; reg [`MAX_BITS-1:0] addr; begin // chop off the lowest address bits addr = {bank, row, col}/BL_MAX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -