📄 ddr2.v
字号:
input RAS_N ;
input CAS_N ;
input WE_N ;
input [DM_BITS - 1 : 0] DM_RDQS ;
input [BA_BITS - 1 : 0] BA ;
input [ADDR_BITS - 1 : 0] ADDR ;
inout [DQ_BITS - 1 : 0] DQ ;
inout [DQS_BITS - 1 : 0] DQS ;
inout [DQS_BITS - 1 : 0] DQS_N ;
output [DM_BITS - 1 : 0] RDQS_N ; input ODT ;
reg [3 : 0] command [0 : MAX_CMD_QUEUE];
reg [COL_BITS - 1 : 0] col_addr [0 : MAX_CMD_QUEUE];
reg [BA_BITS - 1 : 0] bank_addr [0 : MAX_CMD_QUEUE];
reg [ROW_BITS - 1 : 0] bank_row_addr [0 : (1<<BA_BITS)-1];
reg [MODE_BITS - 1 : 0] mode_reg ;
reg [MODE_BITS - 1 : 0] ext_mode_reg_1 ;
reg [(1<<BA_BITS) - 1 : 0] precharged_banks ;
reg [(1<<BA_BITS) - 1 : 0] activated_banks ;
reg [(1<<BA_BITS) - 1 : 0] auto_precharge ; // RW AutoPrecharge Bank
reg [(1<<BA_BITS) - 1 : 0] read_precharge ; // R AutoPrecharge Command
reg [(1<<BA_BITS) - 1 : 0] write_precharge ; // W AutoPrecharge Command
reg [DQ_BITS - 1 : 0] dq_out ;
reg [DQS_BITS - 1 : 0] dqs_out ;
reg [DQS_BITS - 1 : 0] dqs_n_out ;
reg [7 : 0] dq_in_pos [3 : 0] ;
reg [7 : 0] dq_in_neg [3 : 0] ;
reg [31 : 0] dq_temp ;
reg [3 : 0] dm_in_pos ;
reg [3 : 0] dm_in_neg ;
reg [3:0] check_dm_tdipw ; reg [31:0] check_dq_tdipw ;
// Commands Decode
integer read_latency ; // Read latency is based on the write latency being passed in
integer write_latency ; // Write latency is based on the write latency being passed in
integer burst_order ; // Burst order (sequential = 0 / interleaved = 1)
integer burst_clocks ; // Burst length divided by 2 to give number of clk_in used in burst
integer cas_latency_clocks ; // Cas Latency integer add_latency_clocks ; integer write_recovery ;
integer i ; // temp variable for looping assignments
reg low_power ; reg [3 : 0] check_write_postamble ;
reg [3 : 0] check_write_preamble ;
reg [3 : 0] check_write_dqs_high ;
reg [3 : 0] check_write_dqs_low ;
reg data_in_enable ; // active high when receiving write data
reg data_out_enable ; // active high when sending read data
reg data_dqs_out_enable ;
reg [BA_BITS - 1 : 0] bank ;
reg [ROW_BITS - 1 : 0] row ;
reg [COL_BITS - 1 : 0] col ;
reg [COL_BITS - 1 : 0] col_brst ;
integer burst_counter ;
reg dll_enabled ; integer dll_reset_clocks ; reg dll_reset ;
reg dll_locked ;
reg power_up_done ;
reg [BA_BITS - 1 : 0] previous_bank ;
reg self_refresh_enter ;
reg power_down_enter ;
reg cke_in_one_clk_back ;
reg [8*DQ_BITS-1 : 0] dq_burst ;
reg found ;
`ifdef FULL_MEM
reg [8*DQ_BITS-1 : 0] MEM [0 : (1<<BA_BITS+ROW_BITS+COL_BITS-3)-1];
reg [BA_BITS+ROW_BITS+COL_BITS-3-1 : 0] mem_index;
`else
reg [8*DQ_BITS-1 : 0] MEM [0 : (1<<MEM_BITS)-1] ;
reg [BA_BITS+ROW_BITS+COL_BITS-3-1 : 0] ADD [0 : (1<<MEM_BITS)-1];
reg [MEM_BITS : 0] mem_index ;
reg [MEM_BITS : 0] mem_used ;
`endif
// DDR2 specific registers
reg [MODE_BITS - 1 : 0] ext_mode_reg_2 ;
reg [MODE_BITS - 1 : 0] ext_mode_reg_3 ;
reg ext_mode_reg_2_set ;
reg ext_mode_reg_3_set ;
reg data_dqs_in_enable ;
integer num_activated_banks ;
reg trfc_max_violation ; reg dqs_n_enabled ; reg rdqs_enabled ; integer aref_count ;
//******************************************************************************************
// Registers for Delaying all inputs to the dram due to bus delay
//******************************************************************************************
reg [31 : 0] dq_in ; reg [3 : 0] dqs_in ; reg [3 : 0] dm_in ; reg [2 : 0] ba_in ; reg [15 : 0] addr_in ; reg clk_in ;
reg cke_in ;
reg cs_n_in ;
reg ras_n_in ;
reg cas_n_in ;
reg we_n_in ;
reg odt_in ;
// Timing checks
time tras_chk[(1<<BA_BITS) - 1 : 0];
time twr_chk[(1<<BA_BITS) - 1 : 0] ;
time tmrd_chk ;
time trcd_chk[(1<<BA_BITS) - 1 : 0];
time trp_chk[(1<<BA_BITS) - 1 : 0] ; time trpa_chk ; time tccd_chk ; time trc_chk[(1<<BA_BITS) - 1 : 0] ;
time trrd_chk ;
time trtw_chk ;
time tdqss_chk ;
time twtr_chk ; time tcke_chk ;
time trtp_chk[(1<<BA_BITS) - 1 : 0];
time twriteapre_chk[(1<<BA_BITS) - 1 : 0];
time treadapre_chk[(1<<BA_BITS) - 1 : 0];
time trfc_chk ;
time txs_chk ; time txp_chk ; time txards_chk ; time tanpd_chk ; time prev_dqs_rise[3 : 0] ;
time prev_dqs_fall[3 : 0] ;
time cke_event ; time cs_n_event ; time cas_n_event ; time ras_n_event ; time we_n_event ; time ba_event [2 : 0] ; time addr_event [15 : 0] ; time dqs_event [3 : 0] ; time dm_event [3 : 0] ; time dq_event [31 : 0] ; time odt_event ; time clk_rise_event ; time clk_fall_event ; //Commands Operation
`define LMR 4'h0 `define REF 4'h1 `define PRE 4'h2 `define ACT 4'h3 `define WRITE 4'h4
`define READ 4'h5 `define NOP 4'h7 wire [3:0] cmd = (~cs_n_in) ? {cs_n_in, ras_n_in, cas_n_in, we_n_in} : `NOP; reg [3:0] cmd_prev; time cmd_chk;
// ODT variables reg odt_enabled;
reg [0 : MAX_CMD_QUEUE] odt_in_pipe;
reg data_in_valid; reg odt_data;
reg outputs_enabled; assign DQ = outputs_enabled ? dq_out : {DQ_BITS{1'bz}};
assign DQS = outputs_enabled ? dqs_out : {DQS_BITS{1'bz}};
assign DQS_N = (outputs_enabled & dqs_n_enabled) ? dqs_n_out : {DQS_BITS{1'bz}};
assign DM_RDQS = (outputs_enabled & rdqs_enabled) ? dqs_out : {DQS_BITS{1'bz}}; assign RDQS_N = (outputs_enabled & rdqs_enabled & dqs_n_enabled) ? dqs_n_out : {DQS_BITS{1'bz}};
initial begin
reset_task;`ifdef FULL_MEM
`else
mem_used = 0 ;
if (MEM_BITS > BA_BITS+ROW_BITS+COL_BITS-3) $display ("%m WARNING: You have allocated more memory space than necessary.");
`endif
if (DM_BITS < 0 || DM_BITS > 4) $display ("%m ERROR: DM_BITS parameter must be between 0 and 4");
if (DQS_BITS < 0 || DQS_BITS > 4) $display ("%m ERROR: DQS_BITS parameter must be between 0 and 4");
if (DQ_BITS !== 4 && DQ_BITS !== 8 && DQ_BITS !== 16 && DQ_BITS !== 32) $display ("%m ERROR: DQ_BITS parameter must be 4, 8, 16, or 32");
if (ADDR_BITS < 0 || ADDR_BITS > 16) $display ("%m ERROR: ADDR_BITS parameter must be between 0 and 16");
if (BA_BITS < 0 || BA_BITS > 3) $display ("%m ERROR: BA_BITS parameter must be between 0 and 3");
$timeformat (-12, 1, " ps", 1) ;
end
//**************************************************
// Delaying all inputs to the dram due to bus delay
//**************************************************
always @(DQ or DQS or DM_RDQS or BA or ADDR or CLK or CKE or CS_N or RAS_N or CAS_N or WE_N or ODT) begin
dq_in <= #bus_delay {{32-DQ_BITS{1'b0}}, DQ};
dqs_in <= #bus_delay {{4-DQS_BITS{1'b0}}, DQS};
dm_in <= #bus_delay {{4-DM_BITS{1'b0}}, DM_RDQS};
ba_in <= #bus_delay {{3-BA_BITS{1'b0}}, BA};
addr_in <= #bus_delay {{16-ADDR_BITS{1'b0}}, ADDR};
clk_in <= #bus_delay CLK;
cke_in <= #bus_delay CKE;
cs_n_in <= #bus_delay CS_N;
ras_n_in <= #bus_delay RAS_N;
cas_n_in <= #bus_delay CAS_N;
we_n_in <= #bus_delay WE_N;
odt_in <= #bus_delay ODT;
end
// report ODT status always @(odt_data) begin if (odt_data) begin if (debug) $display ("%m: at time %t : On-Die Termination for Data is ON", $time); end else begin if (debug) $display ("%m: at time %t : On-Die Termination for Data is OFF", $time); end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -