📄 ddr2.v
字号:
$display ("%m: at time %t ERROR: Memory overflow. Write to Address %h with Data %h will be lost.", $time, add, data);
$display ("%m: You must increase the MEM_BITS parameter or define FULL_MEM.");
if (!no_halt) $stop(0);
end else
mem_used = mem_used + 1;
ADD[mem_index] = add;
end
`endif
MEM[mem_index] = data;
end
endtask
task read_mem;
input [BA_BITS+ROW_BITS+COL_BITS-3-1 : 0] add;
output [8*DQ_BITS - 1 : 0] data;
begin
get_mem_index(add);
if (found)
data = MEM[mem_index];
else
data = {8*DQ_BITS{1'bx}};
end
endtask
// task that runs at every positive edge of clk_in
task cmd_task;
begin
if (cmd !== cmd_prev) begin cmd_chk = $time; end cmd_prev = cmd;
// DLL Reset Check if (dll_reset) begin dll_reset_clocks = dll_reset_clocks + 1; if (dll_reset_clocks >= tdllk) begin dll_locked = 1; dll_reset = 0; end end // tRFC max check if (!trfc_max_violation) begin if (trfc_chk > 0) if ($time - trfc_chk > trfc_max) begin $display ("%m: at time %t ERROR: tRFC maximum violation", $time); if (!no_halt) $stop(0); trfc_max_violation = 1; end end for (i=0; i<(1<<BA_BITS); i=i+1) begin // Indicate that the bank is precharged at the end of the tRP time if (trp_chk[i] > 0) if (trp_chk[i] + trp <= $time) begin precharged_banks[i] = 1'b1; trp_chk[i] = 0; end end // Read with Auto Precharge Calculation
// The device start internal precharge:
// 1. Additive Latency PLUS 2 cycles after Read command
// 2. Meet minimum tRAS requirement
// 3. Additive Latency PLUS tRTP cycles after Read command
for (i=0; i<(1<<BA_BITS); i=i+1) begin
if ((auto_precharge[i]) && (read_precharge[i]) && (($time - tras_chk[i]) >= tras_min)) begin
if ((($time - treadapre_chk[i]) >= (add_latency_clocks + burst_clocks - 2)*tck + trtp) && (($time - treadapre_chk[i]) >= (add_latency_clocks + 2)*tck)) begin activated_banks[i] = 1'b0;
auto_precharge[i] = 1'b0;
read_precharge[i] = 1'b0;
trp_chk[i] = tras_chk[i] + tras_min; if ((treadapre_chk[i] + (add_latency_clocks + 2)*tck) > trp_chk[i]) begin trp_chk[i] = (treadapre_chk[i] + (add_latency_clocks + 2)*tck); end if ((treadapre_chk[i] + (add_latency_clocks + burst_clocks - 2)*tck + trtp) > trp_chk[i]) begin trp_chk[i] = (treadapre_chk[i] + (add_latency_clocks + burst_clocks - 2)*tck + trtp); end if (debug) $display ("%m: at time %t APRE : Start Internal Read Auto Precharge for Bank %d", $time, i); end
end
end
// Write with Auto Precharge Calculation
// The device start internal precharge
// 1. CAS Write Latency PLUS BL/2 cycles PLUS WR after Write command
// 2. Meet minimum tRAS requirement
for (i=0; i<(1<<BA_BITS); i=i+1) begin
if ((auto_precharge[i]) && (write_precharge[i]) && (($time - tras_chk[i]) >= tras_min)) begin
if (($time - twr_chk[i]) >= (write_latency + burst_clocks + write_recovery)*tck) begin
activated_banks[i] = 1'b0;
auto_precharge[i] = 1'b0;
write_precharge[i] = 1'b0; trp_chk[i] = tras_chk[i] + tras_min; if ((twriteapre_chk[i] + (write_latency + burst_clocks + write_recovery)*tck) > trp_chk[i]) begin
trp_chk[i] = (twriteapre_chk[i] + (write_latency + burst_clocks + write_recovery)*tck);
end
if (debug) $display ("%m: at time %t APRE : Start Internal Write Auto Precharge for Bank %d", $time, i);
end
end
end
// Command Decode if (cke_in) begin case (cmd) `LMR : begin // Load Mode Register if (tmrd_chk > 0) if (tmrd_chk + tmrd*tck > $time) $display ("%m: at time %t ERROR: tMRD violation during Load Mode Register %d", $time, ba_in); if (trfc_chk > 0) if (trfc_chk + trfc_min > $time) $display ("%m: at time %t ERROR: tRFC violation during Load Mode Register %d", $time, ba_in); for (i=0; i<(1<<BA_BITS); i=i+1) begin if (trp_chk[i] > 0) if ((trp_chk[i] + trp > $time)) $display ("%m: at time %t ERROR: tRP violation during Load Mode Register %d", $time, ba_in); end if (trpa_chk > 0) if ((trpa_chk + trpa > $time)) $display ("%m: at time %t ERROR: tRPA violation during Load Mode Register %d", $time, ba_in); if (txp_chk + txp*tck > $time) $display ("%m: at time %t ERROR: tXP violation during Load Mode Register %d", $time, ba_in); if (($time > txsnr) && (txs_chk + txsnr > $time)) $display ("%m: at time %t ERROR: tXSNR violation during Load Mode Register %d", $time, ba_in); if (&precharged_banks) begin // All banks precharged? case (ba_in) 0 : begin mode_reg = addr_in & {{MODE_BITS-9{1'b1}}, 9'h0FF}; // FILL THE MODE REGISTER if (debug) $display ("%m: at time %t LMR : Load Mode Register", $time); // Burst Length if (mode_reg[2:0] == 3'b010) begin if (debug) $display ("%m: at time %t LMR : Burst Length = 4", $time); burst_clocks = 2; end else if (mode_reg[2:0] == 3'b011) begin if (debug) $display ("%m: at time %t LMR : Burst Length = 8", $time); burst_clocks = 4; end else begin $display ("%m: at time %t ERROR: BURST LENGTH SPECIFIED NOT SUPPORTED", $time); end // Burst Type if (mode_reg[3]) begin if (debug) $display ("%m: at time %t LMR : Burst Type = Interleaved", $time); burst_order = 1; end else begin if (debug) $display ("%m: at time %t LMR : Burst Type = Sequential", $time); burst_order = 0; end // CAS Latency if ((mode_reg[6:4] >= cl_min) && (mode_reg[6:4] <= cl_max)) begin if (debug) $display ("%m: at time %t LMR : CAS Latency = %d", $time, mode_reg[6:4]); cas_latency_clocks = mode_reg[6:4]; end else begin $display ("%m: at time %t ERROR: CAS LATENCY SPECIFIED NOT SUPPORTED", $time); end // Test if (mode_reg[7]) begin $display ("%m: at time %t ERROR: TEST MODE IS NOT SUPPORTED", $time); end else begin if (debug) $display ("%m: at time %t LMR : Normal Mode", $time); end // DLL Reset if (addr_in[8]) begin if (!dll_enabled) $display ("%m: at time %t ERROR: DLL must be enabled in EMR prior to DLL reset.", $time); if (debug) $display ("%m: at time %t LMR : Normal Operation/Reset DLL", $time); dll_locked = 0; dll_reset = 1; dll_reset_clocks = 0; end else begin if (debug) $display ("%m: at time %t LMR : Normal Operation", $time); end // Write Recovery if ((mode_reg[11:9] + 1 >= wr_min) && (mode_reg[11:9] + 1 <= wr_max)) begin if (debug) $display ("%m: at time %t LMR : Write Recovery = %d", $time, mode_reg[11:9] + 1); write_recovery = mode_reg[11:9] + 1; end else begin $display ("%m: at time %t ERROR: WRITE RECOVERY SPECIFIED NOT SUPPORTED", $time); end // Check to make sure write recovery was programmed greater or equal to the twr parameter if (write_recovery < twr/tck) begin $display ("%m: at time %t ERROR: WR in MR cannot be less than twr/tck", $time); end // power down mode if (mode_reg[12]) begin if (debug) $display ("%m: at time %t LMR : Power Down Mode = Fast Exit", $time); low_power = 1'b0; end else begin if (debug) $display ("%m: at time %t LMR : Power Down Mode = Slow Exit", $time); low_power = 1'b1; end end 1 : begin ext_mode_reg_1 = addr_in; // FILL THE EXTENDED MODE REGISTER if (debug) $display ("%m: at time %t EMR : Load Extended Mode Register 1", $time); // Report the status of the DLL if (!ext_mode_reg_1[0]) begin if (debug) $display ("%m: at time %t EMR : Enable DLL", $time); dll_enabled = 1; end else begin if (debug) $display ("%m: at time %t EMR : Disable DLL", $time); dll_enabled = 0; end // Report the Output Drive Strength if (ext_mode_reg_1[1]) begin if (debug) $display ("%m: at time %t EMR : Normal Drive Strength", $time); end else begin if (debug) $display ("%m: at time %t EMR : Weak Drive Strength", $time); end // Report the Rtt for ODT
if ({ext_mode_reg_1[6], ext_mode_reg_1[2]} == 2'b00) begin
if (debug) $display ("%m: at time %t EMR : ODT Rtt Disabled", $time);
odt_enabled = 0;
end else if ({ext_mode_reg_1[6], ext_mode_reg_1[2]} == 2'b01) begin if (debug) $display ("%m: at time %t EMR : ODT Rtt = 75 Ohm", $time); odt_enabled = 1; end else if ({ext_mode_reg_1[6], ext_mode_reg_1[2]} == 2'b10) begin if (debug) $display ("%m: at time %t EMR : ODT Rtt = 150 Ohm", $time); odt_enabled = 1; end else begin
$display ("%m: at time %t ERROR: ODT Rtt VALUE SPECIFIED NOT SUPPORTED", $time);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -