URL
https://opencores.org/ocsvn/sdr_ctrl/sdr_ctrl/trunk
Subversion Repositories sdr_ctrl
Compare Revisions
- This comparison shows the changes necessary to convert path
/sdr_ctrl
- from Rev 6 to Rev 7
- ↔ Reverse comparison
Rev 6 → Rev 7
/trunk/verif/model/mt48lc2m32b2.v
0,0 → 1,1096
/************************************************************************** |
* |
* File Name: MT48LC2M32B2.V |
* Version: 2.1 |
* Date: June 6th, 2002 |
* Model: BUS Functional |
* Simulator: Model Technology |
* |
* Dependencies: None |
* |
* Email: modelsupport@micron.com |
* Company: Micron Technology, Inc. |
* Model: MT48LC2M32B2 (512K x 32 x 4 Banks) |
* |
* Description: Micron 64Mb SDRAM Verilog model |
* |
* Limitation: - Doesn't check for 4096 cycle refresh |
* |
* Note: - Set simulator resolution to "ps" accuracy |
* - Set Debug = 0 to disable $display messages |
* |
* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY |
* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY |
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR |
* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. |
* |
|
* All rights researved |
* |
* Rev Author Date Changes |
* --- -------------------------- --------------------------------------- |
* 2.1 SH 06/06/2002 - Typo in bank multiplex |
* Micron Technology Inc. |
* |
* 2.0 SH 04/30/2002 - Second release |
* Micron Technology Inc. |
* |
**************************************************************************/ |
|
`timescale 1ns / 1ps |
|
module mt48lc2m32b2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm); |
|
parameter addr_bits = 11; |
parameter data_bits = 32; |
parameter col_bits = 8; |
parameter mem_sizes = 524287; |
|
inout [data_bits - 1 : 0] Dq; |
input [addr_bits - 1 : 0] Addr; |
input [1 : 0] Ba; |
input Clk; |
input Cke; |
input Cs_n; |
input Ras_n; |
input Cas_n; |
input We_n; |
input [3 : 0] Dqm; |
|
reg [data_bits - 1 : 0] Bank0 [0 : mem_sizes]; |
reg [data_bits - 1 : 0] Bank1 [0 : mem_sizes]; |
reg [data_bits - 1 : 0] Bank2 [0 : mem_sizes]; |
reg [data_bits - 1 : 0] Bank3 [0 : mem_sizes]; |
|
reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline |
reg [col_bits - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline |
reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline |
reg [3 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline |
reg [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr; |
|
reg [addr_bits - 1 : 0] Mode_reg; |
reg [data_bits - 1 : 0] Dq_reg, Dq_dqm; |
reg [col_bits - 1 : 0] Col_temp, Burst_counter; |
|
reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate |
reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge |
|
reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command |
reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks) |
reg Auto_precharge [0 : 3]; // RW Auto Precharge (Bank) |
reg Read_precharge [0 : 3]; // R Auto Precharge |
reg Write_precharge [0 : 3]; // W Auto Precharge |
reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge |
reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge |
reg [1 : 0] RW_interrupt_bank; // RW Interrupt Bank |
integer RW_interrupt_counter [0 : 3]; // RW Interrupt Counter |
integer Count_precharge [0 : 3]; // RW Auto Precharge Counter |
|
reg Data_in_enable; |
reg Data_out_enable; |
|
reg [1 : 0] Bank, Prev_bank; |
reg [addr_bits - 1 : 0] Row; |
reg [col_bits - 1 : 0] Col, Col_brst; |
|
// Internal system clock |
reg CkeZ, Sys_clk; |
|
// Commands Decode |
wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n; |
wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n; |
wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n; |
wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n; |
wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n; |
wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n; |
wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n; |
|
// Burst Length Decode |
wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0]; |
wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0]; |
wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0]; |
wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0]; |
wire Burst_length_f = Mode_reg[2] & Mode_reg[1] & Mode_reg[0]; |
|
// CAS Latency Decode |
wire Cas_latency_1 = ~Mode_reg[6] & ~Mode_reg[5] & Mode_reg[4]; |
wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4]; |
wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4]; |
|
// Write Burst Mode |
wire Write_burst_mode = Mode_reg[9]; |
|
wire Debug = 1'b1; // Debug messages : 1 = On |
wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ |
|
assign Dq = Dq_reg; // DQ buffer |
|
// Commands Operation |
`define ACT 0 |
`define NOP 1 |
`define READ 2 |
`define WRITE 3 |
`define PRECH 4 |
`define A_REF 5 |
`define BST 6 |
`define LMR 7 |
|
// Timing Parameters for -6 CL3 |
parameter tAC = 5.5; |
parameter tHZ = 5.5; |
parameter tOH = 2.5; |
parameter tMRD = 2.0; // 2 Clk Cycles |
parameter tRAS = 42.0; |
parameter tRC = 60.0; |
parameter tRCD = 18.0; |
parameter tRFC = 60.0; |
parameter tRP = 18.0; |
parameter tRRD = 12.0; |
parameter tWRa = 6.0; // A2 Version - Auto precharge mode (1 Clk + 7 ns) |
parameter tWRm = 12.0; // A2 Version - Manual precharge mode (14 ns) |
|
// Timing Check variable |
time MRD_chk; |
time WR_chkm [0 : 3]; |
time RFC_chk, RRD_chk; |
time RC_chk0, RC_chk1, RC_chk2, RC_chk3; |
time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3; |
time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3; |
time RP_chk0, RP_chk1, RP_chk2, RP_chk3; |
|
initial begin |
Dq_reg = {data_bits{1'bz}}; |
Data_in_enable = 0; Data_out_enable = 0; |
Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1; |
Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0; |
WR_chkm[0] = 0; WR_chkm[1] = 0; WR_chkm[2] = 0; WR_chkm[3] = 0; |
RW_interrupt_read[0] = 0; RW_interrupt_read[1] = 0; RW_interrupt_read[2] = 0; RW_interrupt_read[3] = 0; |
RW_interrupt_write[0] = 0; RW_interrupt_write[1] = 0; RW_interrupt_write[2] = 0; RW_interrupt_write[3] = 0; |
MRD_chk = 0; RFC_chk = 0; RRD_chk = 0; |
RAS_chk0 = 0; RAS_chk1 = 0; RAS_chk2 = 0; RAS_chk3 = 0; |
RCD_chk0 = 0; RCD_chk1 = 0; RCD_chk2 = 0; RCD_chk3 = 0; |
RC_chk0 = 0; RC_chk1 = 0; RC_chk2 = 0; RC_chk3 = 0; |
RP_chk0 = 0; RP_chk1 = 0; RP_chk2 = 0; RP_chk3 = 0; |
$timeformat (-9, 1, " ns", 12); |
end |
|
// System clock generator |
always begin |
@ (posedge Clk) begin |
Sys_clk = CkeZ; |
CkeZ = Cke; |
end |
@ (negedge Clk) begin |
Sys_clk = 1'b0; |
end |
end |
|
always @ (posedge Sys_clk) begin |
// Internal Commamd Pipelined |
Command[0] = Command[1]; |
Command[1] = Command[2]; |
Command[2] = Command[3]; |
Command[3] = `NOP; |
|
Col_addr[0] = Col_addr[1]; |
Col_addr[1] = Col_addr[2]; |
Col_addr[2] = Col_addr[3]; |
Col_addr[3] = {col_bits{1'b0}}; |
|
Bank_addr[0] = Bank_addr[1]; |
Bank_addr[1] = Bank_addr[2]; |
Bank_addr[2] = Bank_addr[3]; |
Bank_addr[3] = 2'b0; |
|
Bank_precharge[0] = Bank_precharge[1]; |
Bank_precharge[1] = Bank_precharge[2]; |
Bank_precharge[2] = Bank_precharge[3]; |
Bank_precharge[3] = 2'b0; |
|
A10_precharge[0] = A10_precharge[1]; |
A10_precharge[1] = A10_precharge[2]; |
A10_precharge[2] = A10_precharge[3]; |
A10_precharge[3] = 1'b0; |
|
// Dqm pipeline for Read |
Dqm_reg0 = Dqm_reg1; |
Dqm_reg1 = Dqm; |
|
// Read or Write with Auto Precharge Counter |
if (Auto_precharge[0] === 1'b1) begin |
Count_precharge[0] = Count_precharge[0] + 1; |
end |
if (Auto_precharge[1] === 1'b1) begin |
Count_precharge[1] = Count_precharge[1] + 1; |
end |
if (Auto_precharge[2] === 1'b1) begin |
Count_precharge[2] = Count_precharge[2] + 1; |
end |
if (Auto_precharge[3] === 1'b1) begin |
Count_precharge[3] = Count_precharge[3] + 1; |
end |
|
// Read or Write Interrupt Counter |
if (RW_interrupt_write[0] === 1'b1) begin |
RW_interrupt_counter[0] = RW_interrupt_counter[0] + 1; |
end |
if (RW_interrupt_write[1] === 1'b1) begin |
RW_interrupt_counter[1] = RW_interrupt_counter[1] + 1; |
end |
if (RW_interrupt_write[2] === 1'b1) begin |
RW_interrupt_counter[2] = RW_interrupt_counter[2] + 1; |
end |
if (RW_interrupt_write[3] === 1'b1) begin |
RW_interrupt_counter[3] = RW_interrupt_counter[3] + 1; |
end |
|
// tMRD Counter |
MRD_chk = MRD_chk + 1; |
|
// Auto Refresh |
if (Aref_enable === 1'b1) begin |
if (Debug) begin |
$display ("%m : at time %t AREF : Auto Refresh", $time); |
end |
|
// Auto Refresh to Auto Refresh |
if ($time - RFC_chk < tRFC) begin |
$display ("%m : at time %t ERROR: tRFC violation during Auto Refresh", $time); |
end |
|
// Precharge to Auto Refresh |
if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || |
($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin |
$display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $time); |
end |
|
// Precharge to Refresh |
if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin |
$display ("%m : at time %t ERROR: All banks must be Precharge before Auto Refresh", $time); |
end |
|
// Load Mode Register to Auto Refresh |
if (MRD_chk < tMRD) begin |
$display ("%m : at time %t ERROR: tMRD violation during Auto Refresh", $time); |
end |
|
// Record Current tRFC time |
RFC_chk = $time; |
end |
|
// Load Mode Register |
if (Mode_reg_enable === 1'b1) begin |
// Register Mode |
Mode_reg = Addr; |
|
// Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode |
if (Debug) begin |
$display ("%m : at time %t LMR : Load Mode Register", $time); |
// CAS Latency |
case (Addr[6 : 4]) |
3'b001 : $display ("%m : CAS Latency = 1"); |
3'b010 : $display ("%m : CAS Latency = 2"); |
3'b011 : $display ("%m : CAS Latency = 3"); |
default : $display ("%m : CAS Latency = Reserved"); |
endcase |
|
// Burst Length |
case (Addr[2 : 0]) |
3'b000 : $display ("%m : Burst Length = 1"); |
3'b001 : $display ("%m : Burst Length = 2"); |
3'b010 : $display ("%m : Burst Length = 4"); |
3'b011 : $display ("%m : Burst Length = 8"); |
3'b111 : $display ("%m : Burst Length = Full"); |
default : $display ("%m : Burst Length = Reserved"); |
endcase |
|
// Burst Type |
if (Addr[3] === 1'b0) begin |
$display ("%m : Burst Type = Sequential"); |
end else if (Addr[3] === 1'b1) begin |
$display ("%m : Burst Type = Interleaved"); |
end else begin |
$display ("%m : Burst Type = Reserved"); |
end |
|
// Write Burst Mode |
if (Addr[9] === 1'b0) begin |
$display ("%m : Write Burst Mode = Programmed Burst Length"); |
end else if (Addr[9] === 1'b1) begin |
$display ("%m : Write Burst Mode = Single Location Access"); |
end else begin |
$display ("%m : Write Burst Mode = Reserved"); |
end |
end |
|
// Precharge to Load Mode Register |
if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0) begin |
$display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $time); |
end |
|
// Precharge to Load Mode Register |
if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || |
($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin |
$display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $time); |
end |
|
// Auto Refresh to Load Mode Register |
if ($time - RFC_chk < tRFC) begin |
$display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $time); |
end |
|
// Load Mode Register to Load Mode Register |
if (MRD_chk < tMRD) begin |
$display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $time); |
end |
|
// Reset MRD Counter |
MRD_chk = 0; |
end |
|
// Active Block (Latch Bank Address and Row Address) |
if (Active_enable === 1'b1) begin |
// Activate an open bank can corrupt data |
if ((Ba === 2'b00 && Act_b0 === 1'b1) || (Ba === 2'b01 && Act_b1 === 1'b1) || |
(Ba === 2'b10 && Act_b2 === 1'b1) || (Ba === 2'b11 && Act_b3 === 1'b1)) begin |
$display ("%m : at time %t ERROR: Bank already activated -- data can be corrupted", $time); |
end |
|
// Activate Bank 0 |
if (Ba === 2'b00 && Pc_b0 === 1'b1) begin |
// Debug Message |
if (Debug) begin |
$display ("%m : at time %t ACT : Bank = 0 Row = %d", $time, Addr); |
end |
|
// ACTIVE to ACTIVE command period |
if ($time - RC_chk0 < tRC) begin |
$display ("%m : at time %t ERROR: tRC violation during Activate bank 0", $time); |
end |
|
// Precharge to Activate Bank 0 |
if ($time - RP_chk0 < tRP) begin |
$display ("%m : at time %t ERROR: tRP violation during Activate bank 0", $time); |
end |
|
// Record variables |
Act_b0 = 1'b1; |
Pc_b0 = 1'b0; |
B0_row_addr = Addr [addr_bits - 1 : 0]; |
RAS_chk0 = $time; |
RC_chk0 = $time; |
RCD_chk0 = $time; |
end |
|
if (Ba == 2'b01 && Pc_b1 == 1'b1) begin |
// Debug Message |
if (Debug) begin |
$display ("%m : at time %t ACT : Bank = 1 Row = %d", $time, Addr); |
end |
|
// ACTIVE to ACTIVE command period |
if ($time - RC_chk1 < tRC) begin |
$display ("%m : at time %t ERROR: tRC violation during Activate bank 1", $time); |
end |
|
// Precharge to Activate Bank 1 |
if ($time - RP_chk1 < tRP) begin |
$display ("%m : at time %t ERROR: tRP violation during Activate bank 1", $time); |
end |
|
// Record variables |
Act_b1 = 1'b1; |
Pc_b1 = 1'b0; |
B1_row_addr = Addr [addr_bits - 1 : 0]; |
RAS_chk1 = $time; |
RC_chk1 = $time; |
RCD_chk1 = $time; |
end |
|
if (Ba == 2'b10 && Pc_b2 == 1'b1) begin |
// Debug Message |
if (Debug) begin |
$display ("%m : at time %t ACT : Bank = 2 Row = %d", $time, Addr); |
end |
|
// ACTIVE to ACTIVE command period |
if ($time - RC_chk2 < tRC) begin |
$display ("%m : at time %t ERROR: tRC violation during Activate bank 2", $time); |
end |
|
// Precharge to Activate Bank 2 |
if ($time - RP_chk2 < tRP) begin |
$display ("%m : at time %t ERROR: tRP violation during Activate bank 2", $time); |
end |
|
// Record variables |
Act_b2 = 1'b1; |
Pc_b2 = 1'b0; |
B2_row_addr = Addr [addr_bits - 1 : 0]; |
RAS_chk2 = $time; |
RC_chk2 = $time; |
RCD_chk2 = $time; |
end |
|
if (Ba == 2'b11 && Pc_b3 == 1'b1) begin |
// Debug Message |
if (Debug) begin |
$display ("%m : at time %t ACT : Bank = 3 Row = %d", $time, Addr); |
end |
|
// ACTIVE to ACTIVE command period |
if ($time - RC_chk3 < tRC) begin |
$display ("%m : at time %t ERROR: tRC violation during Activate bank 3", $time); |
end |
|
// Precharge to Activate Bank 3 |
if ($time - RP_chk3 < tRP) begin |
$display ("%m : at time %t ERROR: tRP violation during Activate bank 3", $time); |
end |
|
// Record variables |
Act_b3 = 1'b1; |
Pc_b3 = 1'b0; |
B3_row_addr = Addr [addr_bits - 1 : 0]; |
RAS_chk3 = $time; |
RC_chk3 = $time; |
RCD_chk3 = $time; |
end |
|
// Active Bank A to Active Bank B |
if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin |
$display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba); |
end |
|
// Auto Refresh to Activate |
if ($time - RFC_chk < tRFC) begin |
$display ("%m : at time %t ERROR: tRFC violation during Activate bank = %d", $time, Ba); |
end |
|
// Load Mode Register to Active |
if (MRD_chk < tMRD ) begin |
$display ("%m : at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba); |
end |
|
// Record variables for checking violation |
RRD_chk = $time; |
Prev_bank = Ba; |
end |
|
// Precharge Block |
if (Prech_enable == 1'b1) begin |
// Load Mode Register to Precharge |
if ($time - MRD_chk < tMRD) begin |
$display ("%m : at time %t ERROR: tMRD violaiton during Precharge", $time); |
end |
|
// Precharge Bank 0 |
if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin |
Act_b0 = 1'b0; |
Pc_b0 = 1'b1; |
RP_chk0 = $time; |
|
// Activate to Precharge |
if ($time - RAS_chk0 < tRAS) begin |
$display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); |
end |
|
// tWR violation check for write |
if ($time - WR_chkm[0] < tWRm) begin |
$display ("%m : at time %t ERROR: tWR violation during Precharge", $time); |
end |
end |
|
// Precharge Bank 1 |
if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin |
Act_b1 = 1'b0; |
Pc_b1 = 1'b1; |
RP_chk1 = $time; |
|
// Activate to Precharge |
if ($time - RAS_chk1 < tRAS) begin |
$display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); |
end |
|
// tWR violation check for write |
if ($time - WR_chkm[1] < tWRm) begin |
$display ("%m : at time %t ERROR: tWR violation during Precharge", $time); |
end |
end |
|
// Precharge Bank 2 |
if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin |
Act_b2 = 1'b0; |
Pc_b2 = 1'b1; |
RP_chk2 = $time; |
|
// Activate to Precharge |
if ($time - RAS_chk2 < tRAS) begin |
$display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); |
end |
|
// tWR violation check for write |
if ($time - WR_chkm[2] < tWRm) begin |
$display ("%m : at time %t ERROR: tWR violation during Precharge", $time); |
end |
end |
|
// Precharge Bank 3 |
if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin |
Act_b3 = 1'b0; |
Pc_b3 = 1'b1; |
RP_chk3 = $time; |
|
// Activate to Precharge |
if ($time - RAS_chk3 < tRAS) begin |
$display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); |
end |
|
// tWR violation check for write |
if ($time - WR_chkm[3] < tWRm) begin |
$display ("%m : at time %t ERROR: tWR violation during Precharge", $time); |
end |
end |
|
// Terminate a Write Immediately (if same bank or all banks) |
if (Data_in_enable === 1'b1 && (Bank === Ba || Addr[10] === 1'b1)) begin |
Data_in_enable = 1'b0; |
end |
|
// Precharge Command Pipeline for Read |
if (Cas_latency_3 === 1'b1) begin |
Command[2] = `PRECH; |
Bank_precharge[2] = Ba; |
A10_precharge[2] = Addr[10]; |
end else if (Cas_latency_2 === 1'b1) begin |
Command[1] = `PRECH; |
Bank_precharge[1] = Ba; |
A10_precharge[1] = Addr[10]; |
end else if (Cas_latency_1 === 1'b1) begin |
Command[0] = `PRECH; |
Bank_precharge[0] = Ba; |
A10_precharge[0] = Addr[10]; |
end |
end |
|
// Burst terminate |
if (Burst_term === 1'b1) begin |
// Terminate a Write Immediately |
if (Data_in_enable == 1'b1) begin |
Data_in_enable = 1'b0; |
end |
|
// Terminate a Read Depend on CAS Latency |
if (Cas_latency_3 === 1'b1) begin |
Command[2] = `BST; |
end else if (Cas_latency_2 == 1'b1) begin |
Command[1] = `BST; |
end else if (Cas_latency_1 == 1'b1) begin |
Command[0] = `BST; |
end |
|
// Display debug message |
if (Debug) begin |
$display ("%m : at time %t BST : Burst Terminate",$time); |
end |
end |
|
// Read, Write, Column Latch |
if (Read_enable === 1'b1) begin |
// Check to see if bank is open (ACT) |
if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) || |
(Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin |
$display("%m : at time %t ERROR: Bank is not Activated for Read", $time); |
end |
|
// Activate to Read or Write |
if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) || |
(Ba == 2'b01) && ($time - RCD_chk1 < tRCD) || |
(Ba == 2'b10) && ($time - RCD_chk2 < tRCD) || |
(Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin |
$display("%m : at time %t ERROR: tRCD violation during Read", $time); |
end |
|
// CAS Latency pipeline |
if (Cas_latency_3 == 1'b1) begin |
Command[2] = `READ; |
Col_addr[2] = Addr; |
Bank_addr[2] = Ba; |
end else if (Cas_latency_2 == 1'b1) begin |
Command[1] = `READ; |
Col_addr[1] = Addr; |
Bank_addr[1] = Ba; |
end else if (Cas_latency_1 == 1'b1) begin |
Command[0] = `READ; |
Col_addr[0] = Addr; |
Bank_addr[0] = Ba; |
end |
|
// Read interrupt Write (terminate Write immediately) |
if (Data_in_enable == 1'b1) begin |
Data_in_enable = 1'b0; |
|
// Interrupting a Write with Autoprecharge |
if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin |
RW_interrupt_write[RW_interrupt_bank] = 1'b1; |
RW_interrupt_counter[RW_interrupt_bank] = 0; |
|
// Display debug message |
if (Debug) begin |
$display ("%m : at time %t NOTE : Read interrupt Write with Autoprecharge", $time); |
end |
end |
end |
|
// Read with Auto Precharge |
if (Addr[10] == 1'b1) begin |
Auto_precharge[Ba] = 1'b1; |
Count_precharge[Ba] = 0; |
RW_interrupt_bank = Ba; |
Read_precharge[Ba] = 1'b1; |
end |
end |
|
// Write Command |
if (Write_enable == 1'b1) begin |
// Activate to Write |
if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) || |
(Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin |
$display("%m : at time %t ERROR: Bank is not Activated for Write", $time); |
end |
|
// Activate to Read or Write |
if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) || |
(Ba == 2'b01) && ($time - RCD_chk1 < tRCD) || |
(Ba == 2'b10) && ($time - RCD_chk2 < tRCD) || |
(Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin |
$display("%m : at time %t ERROR: tRCD violation during Read", $time); |
end |
|
// Latch Write command, Bank, and Column |
Command[0] = `WRITE; |
Col_addr[0] = Addr; |
Bank_addr[0] = Ba; |
|
// Write interrupt Write (terminate Write immediately) |
if (Data_in_enable == 1'b1) begin |
Data_in_enable = 1'b0; |
|
// Interrupting a Write with Autoprecharge |
if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin |
RW_interrupt_write[RW_interrupt_bank] = 1'b1; |
|
// Display debug message |
if (Debug) begin |
$display ("%m : at time %t NOTE : Read Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank); |
end |
end |
end |
|
// Write interrupt Read (terminate Read immediately) |
if (Data_out_enable == 1'b1) begin |
Data_out_enable = 1'b0; |
|
// Interrupting a Read with Autoprecharge |
if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Read_precharge[RW_interrupt_bank] == 1'b1) begin |
RW_interrupt_read[RW_interrupt_bank] = 1'b1; |
|
// Display debug message |
if (Debug) begin |
$display ("%m : at time %t NOTE : Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank); |
end |
end |
end |
|
// Write with Auto Precharge |
if (Addr[10] == 1'b1) begin |
Auto_precharge[Ba] = 1'b1; |
Count_precharge[Ba] = 0; |
RW_interrupt_bank = Ba; |
Write_precharge[Ba] = 1'b1; |
end |
end |
|
/* |
Write with Auto Precharge Calculation |
The device start internal precharge when: |
1. Meet minimum tRAS requirement |
and 2. tWR cycle(s) after last valid data |
or 3. Interrupt by a Read or Write (with or without Auto Precharge) |
|
Note: Model is starting the internal precharge 1 cycle after they meet all the |
requirement but tRP will be compensate for the time after the 1 cycle. |
*/ |
if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin |
if ((($time - RAS_chk0 >= tRAS) && // Case 1 |
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 2 |
(Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) || |
(RW_interrupt_write[0] == 1'b1 && RW_interrupt_counter[0] >= 1)) begin // Case 3 |
Auto_precharge[0] = 1'b0; |
Write_precharge[0] = 1'b0; |
RW_interrupt_write[0] = 1'b0; |
Pc_b0 = 1'b1; |
Act_b0 = 1'b0; |
RP_chk0 = $time + tWRa; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time); |
end |
end |
end |
if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin |
if ((($time - RAS_chk1 >= tRAS) && // Case 1 |
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) || // Case 2 |
(Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) || |
(RW_interrupt_write[1] == 1'b1 && RW_interrupt_counter[1] >= 1)) begin // Case 3 |
Auto_precharge[1] = 1'b0; |
Write_precharge[1] = 1'b0; |
RW_interrupt_write[1] = 1'b0; |
Pc_b1 = 1'b1; |
Act_b1 = 1'b0; |
RP_chk1 = $time + tWRa; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time); |
end |
end |
end |
if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin |
if ((($time - RAS_chk2 >= tRAS) && // Case 1 |
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) || // Case 2 |
(Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) || |
(RW_interrupt_write[2] == 1'b1 && RW_interrupt_counter[2] >= 1)) begin // Case 3 |
Auto_precharge[2] = 1'b0; |
Write_precharge[2] = 1'b0; |
RW_interrupt_write[2] = 1'b0; |
Pc_b2 = 1'b1; |
Act_b2 = 1'b0; |
RP_chk2 = $time + tWRa; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time); |
end |
end |
end |
if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin |
if ((($time - RAS_chk3 >= tRAS) && // Case 1 |
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) || // Case 2 |
(Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) || |
(RW_interrupt_write[3] == 1'b1 && RW_interrupt_counter[3] >= 1)) begin // Case 3 |
Auto_precharge[3] = 1'b0; |
Write_precharge[3] = 1'b0; |
RW_interrupt_write[3] = 1'b0; |
Pc_b3 = 1'b1; |
Act_b3 = 1'b0; |
RP_chk3 = $time + tWRa; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time); |
end |
end |
end |
|
// Read with Auto Precharge Calculation |
// The device start internal precharge: |
// 1. Meet minimum tRAS requirement |
// and 2. CAS Latency - 1 cycles before last burst |
// or 3. Interrupt by a Read or Write (with or without AutoPrecharge) |
if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin |
if ((($time - RAS_chk0 >= tRAS) && // Case 1 |
((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 2 |
(Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) || |
(RW_interrupt_read[0] == 1'b1)) begin // Case 3 |
Pc_b0 = 1'b1; |
Act_b0 = 1'b0; |
RP_chk0 = $time; |
Auto_precharge[0] = 1'b0; |
Read_precharge[0] = 1'b0; |
RW_interrupt_read[0] = 1'b0; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time); |
end |
end |
end |
if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin |
if ((($time - RAS_chk1 >= tRAS) && |
((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) || |
(Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) || |
(RW_interrupt_read[1] == 1'b1)) begin |
Pc_b1 = 1'b1; |
Act_b1 = 1'b0; |
RP_chk1 = $time; |
Auto_precharge[1] = 1'b0; |
Read_precharge[1] = 1'b0; |
RW_interrupt_read[1] = 1'b0; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time); |
end |
end |
end |
if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin |
if ((($time - RAS_chk2 >= tRAS) && |
((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) || |
(Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) || |
(RW_interrupt_read[2] == 1'b1)) begin |
Pc_b2 = 1'b1; |
Act_b2 = 1'b0; |
RP_chk2 = $time; |
Auto_precharge[2] = 1'b0; |
Read_precharge[2] = 1'b0; |
RW_interrupt_read[2] = 1'b0; |
if (Debug) begin |
$display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time); |
end |
end |
end |
if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin |
if ((($time - RAS_chk3 >= tRAS) && |
((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) || |
(Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) || |
(Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) || |
(Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) || |
(RW_interrupt_read[3] == 1'b1)) begin |
Pc_b3 = 1'b1; |
Act_b3 = 1'b0; |
RP_chk3 = $time; |
Auto_precharge[3] = 1'b0; |
Read_precharge[3] = 1'b0; |
RW_interrupt_read[3] = 1'b0; |
if (Debug) begin |
$display("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time); |
end |
end |
end |
|
// Internal Precharge or Bst |
if (Command[0] == `PRECH) begin // Precharge terminate a read with same bank or all banks |
if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin |
if (Data_out_enable == 1'b1) begin |
Data_out_enable = 1'b0; |
end |
end |
end else if (Command[0] == `BST) begin // BST terminate a read to current bank |
if (Data_out_enable == 1'b1) begin |
Data_out_enable = 1'b0; |
end |
end |
|
if (Data_out_enable == 1'b0) begin |
Dq_reg <= #tOH {data_bits{1'bz}}; |
end |
|
// Detect Read or Write command |
if (Command[0] == `READ) begin |
Bank = Bank_addr[0]; |
Col = Col_addr[0]; |
Col_brst = Col_addr[0]; |
case (Bank_addr[0]) |
2'b00 : Row = B0_row_addr; |
2'b01 : Row = B1_row_addr; |
2'b10 : Row = B2_row_addr; |
2'b11 : Row = B3_row_addr; |
endcase |
Burst_counter = 0; |
Data_in_enable = 1'b0; |
Data_out_enable = 1'b1; |
end else if (Command[0] == `WRITE) begin |
Bank = Bank_addr[0]; |
Col = Col_addr[0]; |
Col_brst = Col_addr[0]; |
case (Bank_addr[0]) |
2'b00 : Row = B0_row_addr; |
2'b01 : Row = B1_row_addr; |
2'b10 : Row = B2_row_addr; |
2'b11 : Row = B3_row_addr; |
endcase |
Burst_counter = 0; |
Data_in_enable = 1'b1; |
Data_out_enable = 1'b0; |
end |
|
// DQ buffer (Driver/Receiver) |
if (Data_in_enable == 1'b1) begin // Writing Data to Memory |
// Array buffer |
case (Bank) |
2'b00 : Dq_dqm = Bank0 [{Row, Col}]; |
2'b01 : Dq_dqm = Bank1 [{Row, Col}]; |
2'b10 : Dq_dqm = Bank2 [{Row, Col}]; |
2'b11 : Dq_dqm = Bank3 [{Row, Col}]; |
endcase |
|
// Dqm operation |
if (Dqm[0] == 1'b0) begin |
Dq_dqm [ 7 : 0] = Dq [ 7 : 0]; |
end |
if (Dqm[1] == 1'b0) begin |
Dq_dqm [15 : 8] = Dq [15 : 8]; |
end |
if (Dqm[2] == 1'b0) begin |
Dq_dqm [23 : 16] = Dq [23 : 16]; |
end |
if (Dqm[3] == 1'b0) begin |
Dq_dqm [31 : 24] = Dq [31 : 24]; |
end |
|
// Write to memory |
case (Bank) |
2'b00 : Bank0 [{Row, Col}] = Dq_dqm; |
2'b01 : Bank1 [{Row, Col}] = Dq_dqm; |
2'b10 : Bank2 [{Row, Col}] = Dq_dqm; |
2'b11 : Bank3 [{Row, Col}] = Dq_dqm; |
endcase |
|
// Display debug message |
if (Dqm !== 4'b1111) begin |
// Record tWR for manual precharge |
WR_chkm [Bank] = $time; |
|
if (Debug) begin |
$display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %h", $time, Bank, Row, Col, Dq_dqm); |
end |
end else begin |
if (Debug) begin |
$display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col); |
end |
end |
|
// Advance burst counter subroutine |
#tHZ Burst_decode; |
|
end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory |
// Array buffer |
case (Bank) |
2'b00 : Dq_dqm = Bank0[{Row, Col}]; |
2'b01 : Dq_dqm = Bank1[{Row, Col}]; |
2'b10 : Dq_dqm = Bank2[{Row, Col}]; |
2'b11 : Dq_dqm = Bank3[{Row, Col}]; |
endcase |
|
// Dqm operation |
if (Dqm_reg0 [0] == 1'b1) begin |
Dq_dqm [ 7 : 0] = 8'bz; |
end |
if (Dqm_reg0 [1] == 1'b1) begin |
Dq_dqm [15 : 8] = 8'bz; |
end |
if (Dqm_reg0 [2] == 1'b1) begin |
Dq_dqm [23 : 16] = 8'bz; |
end |
if (Dqm_reg0 [3] == 1'b1) begin |
Dq_dqm [31 : 24] = 8'bz; |
end |
|
// Display debug message |
if (Dqm_reg0 !== 4'b1111) begin |
Dq_reg = #tAC Dq_dqm; |
if (Debug) begin |
$display("%m : at time %t READ : Bank = %d Row = %d, Col = %d, Data = %h", $time, Bank, Row, Col, Dq_reg); |
end |
end else begin |
Dq_reg = #tHZ {data_bits{1'bz}}; |
if (Debug) begin |
$display("%m : at time %t READ : Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col); |
end |
end |
|
// Advance burst counter subroutine |
Burst_decode; |
end |
end |
|
// Burst counter decode |
task Burst_decode; |
begin |
// Advance Burst Counter |
Burst_counter = Burst_counter + 1; |
|
// Burst Type |
if (Mode_reg[3] == 1'b0) begin // Sequential Burst |
Col_temp = Col + 1; |
end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst |
Col_temp[2] = Burst_counter[2] ^ Col_brst[2]; |
Col_temp[1] = Burst_counter[1] ^ Col_brst[1]; |
Col_temp[0] = Burst_counter[0] ^ Col_brst[0]; |
end |
|
// Burst Length |
if (Burst_length_2) begin // Burst Length = 2 |
Col [0] = Col_temp [0]; |
end else if (Burst_length_4) begin // Burst Length = 4 |
Col [1 : 0] = Col_temp [1 : 0]; |
end else if (Burst_length_8) begin // Burst Length = 8 |
Col [2 : 0] = Col_temp [2 : 0]; |
end else begin // Burst Length = FULL |
Col = Col_temp; |
end |
|
// Burst Read Single Write |
if (Write_burst_mode == 1'b1) begin |
Data_in_enable = 1'b0; |
end |
|
// Data Counter |
if (Burst_length_1 == 1'b1) begin |
if (Burst_counter >= 1) begin |
Data_in_enable = 1'b0; |
Data_out_enable = 1'b0; |
end |
end else if (Burst_length_2 == 1'b1) begin |
if (Burst_counter >= 2) begin |
Data_in_enable = 1'b0; |
Data_out_enable = 1'b0; |
end |
end else if (Burst_length_4 == 1'b1) begin |
if (Burst_counter >= 4) begin |
Data_in_enable = 1'b0; |
Data_out_enable = 1'b0; |
end |
end else if (Burst_length_8 == 1'b1) begin |
if (Burst_counter >= 8) begin |
Data_in_enable = 1'b0; |
Data_out_enable = 1'b0; |
end |
end |
end |
endtask |
|
// Timing Parameters for -6 CL3 |
specify |
specparam |
tAH = 1.0, // Addr, Ba Hold Time |
tAS = 1.5, // Addr, Ba Setup Time |
tCH = 2.5, // Clock High-Level Width |
tCL = 2.5, // Clock Low-Level Width |
tCK = 6.0, // Clock Cycle Time |
tDH = 1.0, // Data-in Hold Time |
tDS = 1.5, // Data-in Setup Time |
tCKH = 1.0, // CKE Hold Time |
tCKS = 1.5, // CKE Setup Time |
tCMH = 1.0, // CS#, RAS#, CAS#, WE#, DQM# Hold Time |
tCMS = 1.5; // CS#, RAS#, CAS#, WE#, DQM# Setup Time |
$width (posedge Clk, tCH); |
$width (negedge Clk, tCL); |
$period (negedge Clk, tCK); |
$period (posedge Clk, tCK); |
$setuphold(posedge Clk, Cke, tCKS, tCKH); |
$setuphold(posedge Clk, Cs_n, tCMS, tCMH); |
$setuphold(posedge Clk, Cas_n, tCMS, tCMH); |
$setuphold(posedge Clk, Ras_n, tCMS, tCMH); |
$setuphold(posedge Clk, We_n, tCMS, tCMH); |
$setuphold(posedge Clk, Addr, tAS, tAH); |
$setuphold(posedge Clk, Ba, tAS, tAH); |
$setuphold(posedge Clk, Dqm, tCMS, tCMH); |
$setuphold(posedge Dq_chk, Dq, tDS, tDH); |
endspecify |
|
endmodule |
trunk/verif/model/mt48lc2m32b2.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/verif/model/mt48lc4m16.v
===================================================================
--- trunk/verif/model/mt48lc4m16.v (nonexistent)
+++ trunk/verif/model/mt48lc4m16.v (revision 7)
@@ -0,0 +1,1624 @@
+//////////////////////////////////////////////////////////////////////////////
+// File name : mt48lc4m16.v
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2008 Free Model Foundry; http://www.freemodelfoundry.com
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// MODIFICATION HISTORY:
+//
+// version: | author: | mod date: | changes made:
+// V1.0 S.Janevski 08 Feb 27 Initial release
+// V1.1 S.Janevski 08 Mar 26 Assertions of wrong DQM settings during powerup removed
+//////////////////////////////////////////////////////////////////////////////
+// PART DESCRIPTION:
+//
+// Library: RAM
+// Technology: LVTTL
+// Part: mt48lc4m16
+//
+// Description: 1M x 16 x 4Banks SDRAM
+//
+//////////////////////////////////////////////////////////////////////////////
+// Known Bugs:
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// MODULE DECLARATION //
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns/100 ps
+
+module mt48lc4m16
+ (
+ A11 ,
+ A10 ,
+ A9 ,
+ A8 ,
+ A7 ,
+ A6 ,
+ A5 ,
+ A4 ,
+ A3 ,
+ A2 ,
+ A1 ,
+ A0 ,
+
+ DQ15 ,
+ DQ14 ,
+ DQ13 ,
+ DQ12 ,
+ DQ11 ,
+ DQ10 ,
+ DQ9 ,
+ DQ8 ,
+ DQ7 ,
+ DQ6 ,
+ DQ5 ,
+ DQ4 ,
+ DQ3 ,
+ DQ2 ,
+ DQ1 ,
+ DQ0 ,
+
+ BA0 ,
+ BA1 ,
+ DQMH ,
+ DQML ,
+ CLK ,
+ CKE ,
+ WENeg ,
+ RASNeg ,
+ CSNeg ,
+ CASNeg );
+
+ ////////////////////////////////////////////////////////////////////////
+ // Port / Part Pin Declarations
+ ////////////////////////////////////////////////////////////////////////
+ input A11 ;
+ input A10 ;
+ input A9 ;
+ input A8 ;
+ input A7 ;
+ input A6 ;
+ input A5 ;
+ input A4 ;
+ input A3 ;
+ input A2 ;
+ input A1 ;
+ input A0 ;
+
+ inout DQ15 ;
+ inout DQ14 ;
+ inout DQ13 ;
+ inout DQ12 ;
+ inout DQ11 ;
+ inout DQ10 ;
+ inout DQ9 ;
+ inout DQ8 ;
+ inout DQ7 ;
+ inout DQ6 ;
+ inout DQ5 ;
+ inout DQ4 ;
+ inout DQ3 ;
+ inout DQ2 ;
+ inout DQ1 ;
+ inout DQ0 ;
+
+ input BA0 ;
+ input BA1 ;
+ input DQMH ;
+ input DQML ;
+ input CLK ;
+ input CKE ;
+ input WENeg ;
+ input RASNeg ;
+ input CSNeg ;
+ input CASNeg ;
+
+ // interconnect path delay signals
+ wire A11_ipd ;
+ wire A10_ipd ;
+ wire A9_ipd ;
+ wire A8_ipd ;
+ wire A7_ipd ;
+ wire A6_ipd ;
+ wire A5_ipd ;
+ wire A4_ipd ;
+ wire A3_ipd ;
+ wire A2_ipd ;
+ wire A1_ipd ;
+ wire A0_ipd ;
+
+ wire [11 : 0] A;
+ assign A = {A11_ipd,
+ A10_ipd,
+ A9_ipd,
+ A8_ipd,
+ A7_ipd,
+ A6_ipd,
+ A5_ipd,
+ A4_ipd,
+ A3_ipd,
+ A2_ipd,
+ A1_ipd,
+ A0_ipd };
+
+ wire DQ15_ipd ;
+ wire DQ14_ipd ;
+ wire DQ13_ipd ;
+ wire DQ12_ipd ;
+ wire DQ11_ipd ;
+ wire DQ10_ipd ;
+ wire DQ9_ipd ;
+ wire DQ8_ipd ;
+ wire DQ7_ipd ;
+ wire DQ6_ipd ;
+ wire DQ5_ipd ;
+ wire DQ4_ipd ;
+ wire DQ3_ipd ;
+ wire DQ2_ipd ;
+ wire DQ1_ipd ;
+ wire DQ0_ipd ;
+
+ wire [15 : 0 ] DQIn;
+ assign DQIn = { DQ15_ipd,
+ DQ14_ipd,
+ DQ13_ipd,
+ DQ12_ipd,
+ DQ11_ipd,
+ DQ10_ipd,
+ DQ9_ipd,
+ DQ8_ipd,
+ DQ7_ipd,
+ DQ6_ipd,
+ DQ5_ipd,
+ DQ4_ipd,
+ DQ3_ipd,
+ DQ2_ipd,
+ DQ1_ipd,
+ DQ0_ipd };
+
+ wire [15 : 0] DQOut;
+ assign DQOut = { DQ15,
+ DQ14,
+ DQ13,
+ DQ12,
+ DQ11,
+ DQ10,
+ DQ9,
+ DQ8,
+ DQ7,
+ DQ6,
+ DQ5,
+ DQ4,
+ DQ3,
+ DQ2,
+ DQ1,
+ DQ0 };
+
+ wire BA0_ipd ;
+ wire BA1_ipd ;
+ wire DQM1_ipd ;
+ wire DQM0_ipd ;
+ wire CLK_ipd ;
+ wire CKE_ipd ;
+ wire WENeg_ipd ;
+ wire RASNeg_ipd ;
+ wire CSNeg_ipd ;
+ wire CASNeg_ipd ;
+
+ integer bank;
+ integer bank_tmp;
+
+ // internal delays
+ reg rct_in ;
+ reg rct_out;
+ reg [3:0] rcdt_in ;
+ reg [3:0] rcdt_out;
+ reg pre_in ;
+ reg pre_out ;
+ reg refreshed_in ;
+ reg refreshed_out ;
+ reg rcar_out ;
+ reg rcar_in ;
+ reg [3:0] ras_in = 1'b0;
+ reg [3:0] ras_out = 1'b0;
+
+ reg [15 : 0] DQ_zd = 16'bz;
+ assign {DQ15_zd,
+ DQ14_zd,
+ DQ13_zd,
+ DQ12_zd,
+ DQ11_zd,
+ DQ10_zd,
+ DQ9_zd,
+ DQ8_zd,
+ DQ7_zd,
+ DQ6_zd,
+ DQ5_zd,
+ DQ4_zd,
+ DQ3_zd,
+ DQ2_zd,
+ DQ1_zd,
+ DQ0_zd } = DQ_zd;
+
+ parameter UserPreload = 1'b1;
+ parameter mem_file_name = "none"; //"mt48lc4m16.mem";
+ parameter TimingModel = "DefaultTimingModel";
+ parameter PartID = "mt48lc4m16";
+ parameter hi_bank = 3;
+ parameter depth = 25'h100000;
+
+ reg PoweredUp = 1'b0;
+ reg CKEreg = 1'b0;
+ reg CAS_Lat ;
+ reg CAS_Lat2;
+ reg [15:0] DataDrive = 16'bz ;
+
+ // Memory array declaration
+ integer Mem [0:(hi_bank+1)*depth*2-1];
+
+ // Type definition for state machine
+ parameter pwron = 5'd0;
+ parameter precharge = 5'd1;
+ parameter idle = 5'd2;
+ parameter mode_set = 5'd3;
+ parameter self_refresh = 5'd4;
+ parameter auto_refresh = 5'd5;
+ parameter pwrdwn = 5'd6;
+ parameter bank_act = 5'd7;
+ parameter bank_act_pwrdwn = 5'd8;
+ parameter write = 5'd9;
+ parameter write_suspend = 5'd10;
+ parameter read = 5'd11;
+ parameter read_suspend = 5'd12;
+ parameter write_auto_pre = 5'd13;
+ parameter read_auto_pre = 5'd14;
+
+ reg [4:0] statebank [hi_bank:0];
+
+ // Type definition for commands
+ parameter desl = 4'd0;
+ parameter nop = 4'd1;
+ parameter bst = 4'd2;
+ parameter rd = 4'd3;
+ parameter writ = 4'd4;
+ parameter act = 4'd5;
+ parameter pre = 4'd6;
+ parameter mrs = 4'd7;
+ parameter ref = 4'd8;
+
+ reg [3:0] command = desl;
+
+ // burst type
+ parameter sequential = 1'b0;
+ parameter interleave = 1'b1;
+ reg Burst ;
+
+ // write burst mode
+ parameter programmed = 1'b0;
+ parameter single = 1'b1;
+ reg WB ;
+
+ //burst sequences
+ integer intab [0:63];
+
+ reg [19:0] MemAddr [hi_bank:0];
+ integer BurstCnt [hi_bank:0];
+ integer StartAddr [hi_bank:0];
+ integer BurstInc [hi_bank:0];
+ integer BaseLoc [hi_bank:0];
+
+ integer Loc;
+ integer BurstLen;
+ integer Burst_Bits;
+
+ reg written = 1'b0;
+ reg chip_en = 1'b0;
+
+ integer cur_bank;
+ reg [11:0] ModeReg ;
+ integer Ref_Cnt = 0;
+
+ time Next_Ref = 0;
+ reg [8*8:1] BankString ;
+
+ reg Viol = 1'b0;
+ reg [15:0] DataDriveOut = 16'bz;
+ reg [15:0] DataDrive1 = 16'bz;
+ reg [15:0] DataDrive2 = 16'bz;
+ reg [15:0] DataDrive3 = 16'bz;
+
+ reg DQM0_reg0 ;
+ reg DQM0_reg1 ;
+ reg DQM0_reg2 ;
+ reg DQM1_reg0 ;
+ reg DQM1_reg1 ;
+ reg DQM1_reg2 ;
+
+ // tdevice values: values for internal delays
+ time tdevice_TRASmin = 0;
+ time tdevice_TRASmax = 0;
+ time tdevice_TRC = 0;
+ time tdevice_TRCAR = 0;
+ time tdevice_TRCD = 0;
+ time tdevice_TRP = 0;
+
+ ///////////////////////////////////////////////////////////////////////////
+ //Interconnect Path Delay Section
+ ///////////////////////////////////////////////////////////////////////////
+ buf (A11_ipd, A11);
+ buf (A10_ipd, A10);
+ buf (A9_ipd , A9 );
+ buf (A8_ipd , A8 );
+ buf (A7_ipd , A7 );
+ buf (A6_ipd , A6 );
+ buf (A5_ipd , A5 );
+ buf (A4_ipd , A4 );
+ buf (A3_ipd , A3 );
+ buf (A2_ipd , A2 );
+ buf (A1_ipd , A1 );
+ buf (A0_ipd , A0 );
+
+ buf (DQ15_ipd , DQ15 );
+ buf (DQ14_ipd , DQ14 );
+ buf (DQ13_ipd , DQ13 );
+ buf (DQ12_ipd , DQ12 );
+ buf (DQ11_ipd , DQ11 );
+ buf (DQ10_ipd , DQ10 );
+ buf (DQ9_ipd , DQ9 );
+ buf (DQ8_ipd , DQ8 );
+ buf (DQ7_ipd , DQ7 );
+ buf (DQ6_ipd , DQ6 );
+ buf (DQ5_ipd , DQ5 );
+ buf (DQ4_ipd , DQ4 );
+ buf (DQ3_ipd , DQ3 );
+ buf (DQ2_ipd , DQ2 );
+ buf (DQ1_ipd , DQ1 );
+ buf (DQ0_ipd , DQ0 );
+
+ buf (CASNeg_ipd, CASNeg);
+ buf (RASNeg_ipd, RASNeg);
+ buf (BA0_ipd , BA0 );
+ buf (BA1_ipd , BA1 );
+ buf (DQM0_ipd , DQML );
+ buf (DQM1_ipd , DQMH );
+ buf (CLK_ipd , CLK );
+ buf (CKE_ipd , CKE );
+ buf (WENeg_ipd , WENeg );
+ buf (CSNeg_ipd , CSNeg );
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Propagation delay Section
+ ///////////////////////////////////////////////////////////////////////////
+ nmos (DQ15 , DQ15_zd , 1);
+ nmos (DQ14 , DQ14_zd , 1);
+ nmos (DQ13 , DQ13_zd , 1);
+ nmos (DQ12 , DQ12_zd , 1);
+ nmos (DQ11 , DQ11_zd , 1);
+ nmos (DQ10 , DQ10_zd , 1);
+ nmos (DQ9 , DQ9_zd , 1);
+ nmos (DQ8 , DQ8_zd , 1);
+ nmos (DQ7 , DQ7_zd , 1);
+ nmos (DQ6 , DQ6_zd , 1);
+ nmos (DQ5 , DQ5_zd , 1);
+ nmos (DQ4 , DQ4_zd , 1);
+ nmos (DQ3 , DQ3_zd , 1);
+ nmos (DQ2 , DQ2_zd , 1);
+ nmos (DQ1 , DQ1_zd , 1);
+ nmos (DQ0 , DQ0_zd , 1);
+
+ wire deg;
+ wire chip_act;
+ assign chip_act = chip_en;
+
+ wire chip_act_deg;
+ assign chip_act_deg = chip_act && deg;
+
+ wire cas_latency2;
+ wire cas_latency3;
+
+ assign cas_latency2 = ~CAS_Lat && CAS_Lat2;
+ assign cas_latency3 = CAS_Lat && CAS_Lat2;
+
+ specify
+ // tipd delays: interconnect path delays, mapped to input port delays.
+ // In Verilog it is not necessary to declare any tipd delay variables,
+ // they can be taken from SDF file
+ // With all the other delays real delays would be taken from SDF file
+
+ // tpd delays
+ specparam tpd_CLK_DQ0 = 1;
+ specparam tpd_CLK_DQ1 = 1;
+
+ // tpw values: pulse widths
+ specparam tpw_CLK_posedge = 1;
+ specparam tpw_CLK_negedge = 1;
+
+ // tsetup values: setup times
+ specparam tsetup_DQ0_CLK = 1; // tDS
+
+ // thold values: hold times
+ specparam thold_DQ0_CLK = 1; // tDH
+
+ // tperiod_min: minimum clock period = 1/max freq
+ specparam tperiod_CLK_cl1_eq_1_posedge = 1;
+ specparam tperiod_CLK_cl2_eq_1_posedge = 1;
+
+ // tdevice values: values for internal delays
+ specparam tdevice_REF = 15625 ;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Input Port Delays don't require Verilog description
+ ///////////////////////////////////////////////////////////////////////
+ // Path delays //
+ ///////////////////////////////////////////////////////////////////////
+
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ0;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ0;
+
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ1;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ1;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Timing Check Section
+ ////////////////////////////////////////////////////////////////////////
+ $setup (BA0 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (BA1 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQML, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQMH, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CKE , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (WENeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CSNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (RASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+
+ $setup (DQ0 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ1 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ2 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ3 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ4 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ5 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ6 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ7 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ8 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ9 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ10 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ11 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ12 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ13 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ14 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ15 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+
+ $setup (A0, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A1, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A2, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A3, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A4, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A5, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A6, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A7, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A8, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A9, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A10, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A11, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act, BA0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, BA1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQML, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQMH, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CKE , thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CASNeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, RASNeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, WENeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CSNeg, thold_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act, A0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A2, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A3, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A4, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A5, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A6, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A7, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A8, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A9, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A10, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A11, thold_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act_deg, DQ0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ2, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ3, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ4, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ5, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ6, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ7, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ8, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ9, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ10, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ11, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ12, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ13, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ14, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ15, thold_DQ0_CLK, Viol);
+
+ $width (posedge CLK &&& chip_act, tpw_CLK_posedge);
+ $width (negedge CLK &&& chip_act, tpw_CLK_negedge);
+
+ $period (posedge CLK &&& cas_latency2, tperiod_CLK_cl1_eq_1_posedge);
+ $period (posedge CLK &&& cas_latency3, tperiod_CLK_cl2_eq_1_posedge);
+
+ endspecify
+
+ task generate_out ;
+ output [15:0] DataDrive;
+ input Bank;
+ integer Bank;
+ integer location;
+ begin
+ location = Bank * depth * 2 + Loc;
+
+ DataDrive[7:0] = 8'bx;
+ if (Mem[location] > -1)
+ DataDrive[7:0] = Mem[location];
+
+ DataDrive[15:8] = 8'bx;
+ if (Mem[location+1] > -1)
+ DataDrive[15:8] = Mem[location+1];
+
+ end
+ endtask
+
+ task MemWrite;
+ input Bank;
+ integer Bank;
+ integer location;
+ begin
+ location = Bank * depth * 2 + Loc;
+
+ if (~DQM0_ipd)
+ begin
+ Mem[location] = -1;
+ if (~Viol)
+ Mem[location] = DQIn[7:0];
+ end
+
+ if (~DQM1_ipd)
+ begin
+ Mem[location+1] = -1;
+ if (~Viol)
+ Mem[location+1] = DQIn[15:8];
+ end
+
+ end
+ endtask
+
+ task BurstIncProc;
+ input Bank;
+ integer Bank;
+ begin
+ BurstInc[Bank] = 0;
+ if (Burst_Bits == 1)
+ BurstInc[Bank] = A[0:0];
+ if (Burst_Bits == 2)
+ BurstInc[Bank] = A[1:0];
+ if (Burst_Bits == 3)
+ BurstInc[Bank] = A[2:0];
+ if (Burst_Bits == 7)
+ BurstInc[Bank] = A[6:0];
+ end
+ endtask
+
+ task NextStateAuto;
+ input Bank;
+ input state;
+ integer Bank;
+ reg [4:0] state;
+ begin
+ if (~A[10])
+ statebank[Bank] = state;
+ else if (A[10])
+ if (state == write)
+ statebank[Bank] = write_auto_pre;
+ else
+ statebank[Bank] = read_auto_pre;
+ end
+ endtask
+
+ //////////////////////////////////////////////////////////////////////////
+ // Main Behavior Block //
+ //////////////////////////////////////////////////////////////////////////
+
+ // chech when data is generated from model to avoid setup/hold check in
+ // those occasion
+ reg deq;
+ always @(DQIn, DQOut)
+ begin
+ if (DQIn==DQOut)
+ deq=1'b1;
+ else
+ deq=1'b0;
+ end
+ assign deg=deq;
+
+ // initialize burst sequences
+ initial
+ begin
+ intab[0] = 0;
+ intab[1] = 1;
+ intab[2] = 2;
+ intab[3] = 3;
+ intab[4] = 4;
+ intab[5] = 5;
+ intab[6] = 6;
+ intab[7] = 7;
+ intab[8] = 1;
+ intab[9] = 0;
+ intab[10] = 3;
+ intab[11] = 2;
+ intab[12] = 5;
+ intab[13] = 4;
+ intab[14] = 7;
+ intab[15] = 6;
+ intab[16] = 2;
+ intab[17] = 3;
+ intab[18] = 0;
+ intab[19] = 1;
+ intab[20] = 6;
+ intab[21] = 7;
+ intab[22] = 4;
+ intab[23] = 5;
+ intab[24] = 3;
+ intab[25] = 2;
+ intab[26] = 1;
+ intab[27] = 0;
+ intab[28] = 7;
+ intab[29] = 6;
+ intab[30] = 5;
+ intab[31] = 4;
+ intab[32] = 4;
+ intab[33] = 5;
+ intab[34] = 6;
+ intab[35] = 7;
+ intab[36] = 0;
+ intab[37] = 1;
+ intab[38] = 2;
+ intab[39] = 3;
+ intab[40] = 5;
+ intab[41] = 4;
+ intab[42] = 7;
+ intab[43] = 6;
+ intab[44] = 1;
+ intab[45] = 0;
+ intab[46] = 3;
+ intab[47] = 2;
+ intab[48] = 6;
+ intab[49] = 7;
+ intab[50] = 4;
+ intab[51] = 5;
+ intab[52] = 2;
+ intab[53] = 3;
+ intab[54] = 0;
+ intab[55] = 1;
+ intab[56] = 7;
+ intab[57] = 6;
+ intab[58] = 5;
+ intab[59] = 4;
+ intab[60] = 3;
+ intab[61] = 2;
+ intab[62] = 1;
+ intab[63] = 0;
+ end
+
+ // initialize memory and load preload files if any
+ initial
+ begin: InitMemory
+ integer i;
+ for (i=0; i<=((hi_bank+1)*depth*2 - 1); i=i+1)
+ begin
+ Mem[i] = -1;
+ end
+ // Memory preload file
+ // mt48lc4m16.mem file
+ // @bbbbbb - stands for address within memory,
+ // dd - is word to be written at Mem(bbbbbb++)
+ // (bbbbbb is incremented at every load)
+ if (UserPreload && !(mem_file_name == "none"))
+ $readmemh(mem_file_name,Mem);
+ end
+
+ //Power Up time 100 us;
+ initial
+ begin
+ PoweredUp = 1'b0;
+ statebank[0] = pwron;
+ statebank[1] = pwron;
+ statebank[2] = pwron;
+ statebank[3] = pwron;
+ #100000 PoweredUp = 1'b1;
+ end
+
+ always @(posedge ras_in[0])
+ begin:TRASrise0
+ ras_out[0] <= #tdevice_TRASmin ras_in[0];
+ end
+
+ always @(negedge ras_in[0])
+ begin:TRASfall0
+ ras_out[0] <= #tdevice_TRASmax ras_in[0];
+ end
+
+ always @(posedge ras_in[1])
+ begin:TRASrise1
+ ras_out[1] <= #tdevice_TRASmin ras_in[1];
+ end
+
+ always @(negedge ras_in[1])
+ begin:TRASfall1
+ ras_out[1] <= #tdevice_TRASmax ras_in[1];
+ end
+
+ always @(posedge ras_in[2])
+ begin:TRASrise2
+ ras_out[2] <= #tdevice_TRASmin ras_in[2];
+ end
+ always @(negedge ras_in[2])
+ begin:TRASfall2
+ ras_out[2] <= #tdevice_TRASmax ras_in[2];
+ end
+
+ always @(posedge ras_in[3])
+ begin:TRASrise3
+ ras_out[3] <= #tdevice_TRASmin ras_in[3];
+ end
+
+ always @(negedge ras_in[3])
+ begin:TRASfall3
+ ras_out[3] <= #tdevice_TRASmax ras_in[3];
+ end
+
+ always @(posedge rcdt_in[0])
+ begin:TRCDrise0
+ rcdt_out[0] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[0])
+ begin:TRCDfall0
+ rcdt_out[0] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[1])
+ begin:TRCDrise1
+ rcdt_out[1] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[1])
+ begin:TRCDfall1
+ rcdt_out[1] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[2])
+ begin:TRCDrise2
+ rcdt_out[2] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[2])
+ begin:TRCDfall2
+ rcdt_out[2] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[3])
+ begin:TRCDrise3
+ rcdt_out[3] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[3])
+ begin:TRCDfall3
+ rcdt_out[3] <= #tdevice_TRCD 1'b0;
+ end
+
+ /////////////////////////////////////////////////////////////////////////
+ // Functional Section
+ /////////////////////////////////////////////////////////////////////////
+ always @(posedge CLK)
+ begin
+ if ($time > Next_Ref && PoweredUp && Ref_Cnt > 0)
+ begin
+ Ref_Cnt = Ref_Cnt - 1;
+ Next_Ref = $time + tdevice_REF;
+ end
+ if (CKEreg)
+ begin
+ if (~CSNeg_ipd)
+ chip_en = 1;
+ else
+ chip_en = 0;
+ end
+
+ if (CKEreg && ~CSNeg_ipd)
+ begin
+ if (WENeg_ipd == 1'bx)
+ $display(" Unusable value for WENeg ");
+ if (RASNeg_ipd == 1'bx)
+ $display(" Unusable value for RASNeg ");
+ if (CASNeg_ipd == 1'bx)
+ $display(" Unusable value for CASNeg ");
+
+ // Command Decode
+ if (RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
+ command = nop;
+ else if (~RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
+ command = act;
+ else if (RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
+ command = rd;
+ else if (RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
+ command = writ;
+ else if (RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
+ command = bst;
+ else if (~RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
+ command = pre;
+ else if (~RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
+ command = ref;
+ else if (~RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
+ command = mrs;
+
+ // PowerUp Check
+ if (~(PoweredUp) && command != nop)
+ begin
+ $display (" Incorrect power up. Command issued before ");
+ $display (" power up complete. ");
+ end
+
+ // Bank Decode
+ if (~BA0_ipd && ~BA1_ipd)
+ cur_bank = 0;
+ else if (BA0_ipd && ~BA1_ipd)
+ cur_bank = 1;
+ else if (~BA0_ipd && BA1_ipd)
+ cur_bank = 2;
+ else if (BA0_ipd && BA1_ipd)
+ cur_bank = 3;
+ else
+ begin
+ $display ("Could not decode bank selection - results");
+ $display ("may be incorrect.");
+ end
+ end
+
+ // The Big State Machine
+ if (CKEreg)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+
+ if (CSNeg_ipd)
+ command = nop;
+
+ // DQM pipeline
+ DQM0_reg2 = DQM0_reg1;
+ DQM0_reg1 = DQM0_reg0;
+ DQM0_reg0 = DQM0_ipd;
+ DQM1_reg2 = DQM1_reg1;
+ DQM1_reg1 = DQM1_reg0;
+ DQM1_reg0 = DQM1_ipd;
+
+ // by default data drive is Z, might get over written in one
+ // of the passes below
+ DataDrive = 16'bz;
+
+ for (bank = 0; bank <= hi_bank; bank = bank + 1)
+ begin
+ case (statebank[bank])
+ pwron :
+ begin
+ if (~PoweredUp)
+ begin
+ if (command != nop)
+ $display ("Only NOPs allowed during power up.");
+ DataDrive = 16'bz;
+ end
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ end
+
+ precharge :
+ begin
+ if (cur_bank == bank)
+ // It is only an error if this bank is selected
+ if (command != nop && command != pre)
+ begin
+ $display ("Illegal command received ");
+ $display ("during precharge.",$time);
+ end
+ end
+
+ idle :
+ begin
+ if (command == nop || command == bst || command == pre
+ || cur_bank != bank)
+ begin
+ end
+ else if (command == mrs)
+ begin
+ if (statebank[0] == idle && statebank[1] == idle &&
+ statebank[2] == idle && statebank[3] == idle)
+ begin
+ ModeReg = A;
+ statebank[bank] = mode_set;
+ end
+ end
+ else if (command == ref)
+ begin
+ if (statebank[0] == idle && statebank[1] == idle &&
+ statebank[2] == idle && statebank[3] == idle)
+ if (CKE)
+ begin
+ statebank[bank] = auto_refresh;
+ statebank[bank] <= #tdevice_TRCAR idle;
+ end
+ else
+ begin
+ statebank[0] = self_refresh;
+ statebank[1] = self_refresh;
+ statebank[2] = self_refresh;
+ statebank[3] = self_refresh;
+ end
+ end
+ else if (command == act)
+ begin
+ statebank[bank] = bank_act;
+ ras_in[bank] = 1'b1;
+ ras_in [bank] <= #70 1'b0;
+ rct_in = 1'b1;
+ rct_in <= #1 1'b0;
+ rcdt_in[bank] = 1'b1;
+ rcdt_in[bank] <= #1 1'b0;
+ MemAddr[bank][19:8] = A; // latch row addr
+ end
+ else
+ $display ("Illegal command received in idle state.",$time);
+ end
+
+ mode_set :
+ begin
+ if (ModeReg[7] != 0 || ModeReg[8] != 0)
+ $display ("Illegal operating mode set.");
+ if (command != nop)
+ begin
+ $display ("Illegal command received during mode");
+ $display ("set.",$time);
+ end
+
+ // read burst length
+ if (ModeReg[2:0] == 3'b000)
+ begin
+ BurstLen = 1;
+ Burst_Bits = 0;
+ end
+ else if (ModeReg[2:0] == 3'b001)
+ begin
+ BurstLen = 2;
+ Burst_Bits = 1;
+ end
+ else if (ModeReg[2:0] == 3'b010)
+ begin
+ BurstLen = 4;
+ Burst_Bits = 2;
+ end
+ else if (ModeReg[2:0] == 3'b011)
+ begin
+ BurstLen = 8;
+ Burst_Bits = 3;
+ end
+ else if (ModeReg[2:0] == 3'b111)
+ begin
+ BurstLen = 256;
+ Burst_Bits = 7;
+ end
+ else
+ $display ("Invalid burst length specified.");
+
+ // read burst type
+ if (~ModeReg[3])
+ Burst = sequential;
+ else if (ModeReg[3])
+ Burst = interleave;
+ else
+ $display ("Invalid burst type specified.");
+
+ // read CAS latency
+ if (ModeReg[6:4] == 3'b010)
+ begin
+ CAS_Lat = 1'b0;
+ CAS_Lat2 = 1'b1;
+ end
+ else if (ModeReg[6:4] == 3'b011)
+ begin
+ CAS_Lat = 1'b1;
+ CAS_Lat2 = 1'b1;
+ end
+ else
+ $display ("CAS Latency set incorrecty");
+
+ // write burst mode
+ if (~ModeReg[9])
+ WB = programmed;
+ else if (ModeReg[9])
+ WB = single;
+ else
+ $display ("Invalid burst type specified.");
+
+ statebank[bank] = idle;
+ end
+
+ auto_refresh :
+ begin
+ if (Ref_Cnt < 8192)
+ Ref_Cnt = Ref_Cnt + 1;
+ if (command != nop)
+ begin
+ $display ("Illegal command received during");
+ $display ("auto_refresh.",$time);
+ end
+ end
+
+ bank_act :
+ begin
+ if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("precharge command does not meet tRAS");
+ $display ("time", $time);
+ end
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else if (command == nop || command == bst
+ || cur_bank != bank)
+ begin
+ end
+ else if (command == rd)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("read command received too soon");
+ $display ("after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during read command.");
+ $display ("Next state unknown.");
+ end
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ BurstIncProc(bank);
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive,bank);
+ BurstCnt[bank] = 1;
+ NextStateAuto(bank, read);
+ bank_tmp = bank;
+ end
+ else if (command == writ)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("write command received too soon");
+ $display ("after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during write command.");
+ $display ("Next state unknown.");
+ end
+ MemAddr[bank][7:0] = 8'b0; // clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank, write);
+ written = 1'b1;
+ end
+ else if (cur_bank == bank || command == mrs)
+ begin
+ $display ("Illegal command received in");
+ $display ("active state",$time);
+ end
+ end
+
+ write :
+ begin
+ if (command == bst)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ end
+ else if (command == rd)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank, read);
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == writ)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ if (A[10])
+ statebank[bank] = write_auto_pre;
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("precharge command does not meet tRAS time",$time);
+ end
+ if (~DQM0_ipd)
+ begin
+ $display ("DQM0 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ if (~DQM1_ipd)
+ begin
+ $display ("DQM1 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else if (command == nop || cur_bank != bank)
+ if (BurstCnt[bank] == BurstLen || WB == single)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ else if (cur_bank == bank)
+ $display ("Illegal command received in write state",$time);
+ end
+
+ read :
+ begin
+ if (command == bst)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ end
+ else if (command == rd)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank, read);
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == writ)
+ if (cur_bank == bank)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("write command received too soon after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during write command.");
+ $display ("Next state unknown.");
+ end
+
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank,write);
+ end
+ else
+ statebank[bank] = bank_act;
+
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("Precharge command does not meet tRAS time",$time);
+ end
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+
+ else if (command == nop || cur_bank != bank)
+ begin
+ if (BurstCnt[bank] == BurstLen)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ end
+ else if (cur_bank == bank)
+ $display ("Illegal command received in read state",$time);
+ end
+
+ write_auto_pre :
+ begin
+ if (command == nop || cur_bank != bank)
+ if (BurstCnt[bank] == BurstLen || WB == single)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ else
+ $display ("Illegal command received in write state.",$time);
+ end
+
+ read_auto_pre :
+ begin
+ if (command == nop || (cur_bank != bank && command != rd
+ && command != writ))
+ if (BurstCnt[bank] == BurstLen)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ else if ((command == rd || command == writ) && cur_bank
+ != bank)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else
+ $display ("Illegal command received in read state",$time);
+ end
+ endcase
+ end
+
+ // Check Refresh Status
+ if (written && (Ref_Cnt == 0))
+ $display ("memory not refreshed (by ref_cnt)", $time);
+
+ DataDrive3 = DataDrive2;
+ DataDrive2 = DataDrive1;
+ DataDrive1 = DataDrive;
+
+ end
+
+ // Latency adjustments and DQM read masking
+ if (~DQM0_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[7:0] = DataDrive3[7:0];
+ else
+ DataDriveOut[7:0] = DataDrive2[7:0];
+ else
+ DataDriveOut[7:0] = 8'bz;
+
+ if (~DQM1_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[15:8] = DataDrive3[15:8];
+ else
+ DataDriveOut[15:8] = DataDrive2[15:8];
+ else
+ DataDriveOut[15:8] = 8'bz;
+
+ // The Powering-up State Machine
+ if (~CKEreg && CKE_ipd)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+ if (CSNeg_ipd)
+ command = nop;
+
+ case (statebank[cur_bank])
+ write_suspend :
+ begin
+ statebank[cur_bank] = write;
+ end
+
+ read_suspend :
+ begin
+ statebank[cur_bank] = read;
+ end
+
+ self_refresh :
+ begin
+ statebank[0] <= #tdevice_TRP idle;
+ statebank[1] <= #tdevice_TRP idle;
+ statebank[2] <= #tdevice_TRP idle;
+ statebank[3] <= #tdevice_TRP idle;
+ Ref_Cnt = 8192;
+ if (command != nop)
+ begin
+ $display ("Illegal command received during self");
+ $display ("refresh",$time);
+ end
+ end
+
+ pwrdwn :
+ begin
+ statebank[0] = idle;
+ statebank[1] = idle;
+ statebank[2] = idle;
+ statebank[3] = idle;
+ end
+
+ bank_act_pwrdwn :
+ begin
+ statebank[cur_bank] = bank_act;
+ end
+ endcase
+ end
+
+ // The Powering-down State Machine
+ if (CKEreg && ~CKE_ipd)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+ if (CSNeg_ipd)
+ command = nop;
+
+ case (statebank[cur_bank])
+ idle :
+ begin
+ if (command == nop)
+ begin
+ statebank[0] = pwrdwn;
+ statebank[1] = pwrdwn;
+ statebank[2] = pwrdwn;
+ statebank[3] = pwrdwn;
+ end
+ end
+
+ write :
+ begin
+ statebank[cur_bank] = write_suspend;
+ end
+
+ read :
+ begin
+ statebank[cur_bank] = read_suspend;
+ end
+
+ bank_act :
+ begin
+ statebank[cur_bank] = bank_act_pwrdwn;
+ end
+ endcase
+ end
+
+ CKEreg = CKE_ipd;
+ end
+
+ always @(DataDriveOut)
+ begin
+ DQ_zd = DataDriveOut;
+ end
+
+ reg TRASMIN_In, TRASMAX_In, TRC_In , TRCAR_In;
+ reg TRCD_In , TRP_In , TWR_In;
+ wire TRASMIN_Out,TRASMAX_Out,TRC_Out,TRCAR_Out, TRCD_Out, TRP_Out, TWR_Out;
+
+ BUFFER BUF_TRASMIN (TRASMIN_Out , TRASMIN_In);
+ BUFFER BUF_TRASMAX (TRASMAX_Out , TRASMAX_In);
+ BUFFER BUF_TRC (TRC_Out , TRC_In);
+ BUFFER BUF_TRCAR (TRCAR_Out, TRCAR_In);
+ BUFFER BUF_TRCD (TRCD_Out , TRCD_In);
+ BUFFER BUF_TRP (TRP_Out , TRP_In);
+
+ initial
+ begin
+ TRASMIN_In = 1;
+ TRASMAX_In = 1;
+ TRC_In = 1;
+ TRCAR_In = 1;
+ TRCD_In = 1'b1;
+ TRP_In = 1;
+ TWR_In = 1;
+ end
+
+ always @(posedge TRC_Out)
+ begin
+ tdevice_TRC = $time;
+ end
+
+ always @(posedge TRASMIN_Out)
+ begin
+ tdevice_TRASmin = $time;
+ end
+
+ always @(posedge TRASMAX_Out)
+ begin
+ tdevice_TRASmax = $time;
+ end
+
+ always @(posedge TRCAR_Out)
+ begin
+ tdevice_TRCAR = $time;
+ end
+
+ always @(posedge TRCD_Out)
+ begin
+ tdevice_TRCD = $time;
+ end
+
+ always @(posedge TRP_Out)
+ begin
+ tdevice_TRP = $time;
+ end
+
+endmodule
+
+module BUFFER (OUT,IN);
+ input IN;
+ output OUT;
+ buf (OUT, IN);
+endmodule
trunk/verif/model/mt48lc4m16.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/verif/model/mt48lc4m32b2.v
===================================================================
--- trunk/verif/model/mt48lc4m32b2.v (nonexistent)
+++ trunk/verif/model/mt48lc4m32b2.v (revision 7)
@@ -0,0 +1,1976 @@
+//////////////////////////////////////////////////////////////////////////////
+// File name : mt48lc4m32b2.v
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2006 Free Model Foundry; http://www.freemodelfoundry.com
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// MODIFICATION HISTORY:
+//
+// version: | author: | mod date: | changes made:
+// V1.0 I.Milutinovic 06 Apr 18 Initial release
+//
+//////////////////////////////////////////////////////////////////////////////
+// PART DESCRIPTION:
+//
+// Library: RAM
+// Technology: LVTTL
+// Part: MT48LC4M32B2
+//
+// Description: 1M x 32 x 4Banks SDRAM
+//
+//////////////////////////////////////////////////////////////////////////////
+// Known Bugs:
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// MODULE DECLARATION //
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns/100 ps
+
+module mt48lc4m32b2
+ (
+ A11 ,
+ A10 ,
+ A9 ,
+ A8 ,
+ A7 ,
+ A6 ,
+ A5 ,
+ A4 ,
+ A3 ,
+ A2 ,
+ A1 ,
+ A0 ,
+
+ DQ31 ,
+ DQ30 ,
+ DQ29 ,
+ DQ28 ,
+ DQ27 ,
+ DQ26 ,
+ DQ25 ,
+ DQ24 ,
+ DQ23 ,
+ DQ22 ,
+ DQ21 ,
+ DQ20 ,
+ DQ19 ,
+ DQ18 ,
+ DQ17 ,
+ DQ16 ,
+ DQ15 ,
+ DQ14 ,
+ DQ13 ,
+ DQ12 ,
+ DQ11 ,
+ DQ10 ,
+ DQ9 ,
+ DQ8 ,
+ DQ7 ,
+ DQ6 ,
+ DQ5 ,
+ DQ4 ,
+ DQ3 ,
+ DQ2 ,
+ DQ1 ,
+ DQ0 ,
+
+ BA0 ,
+ BA1 ,
+ DQM3 ,
+ DQM2 ,
+ DQM1 ,
+ DQM0 ,
+ CLK ,
+ CKE ,
+ WENeg ,
+ RASNeg ,
+ CSNeg ,
+ CASNeg );
+
+ ////////////////////////////////////////////////////////////////////////
+ // Port / Part Pin Declarations
+ ////////////////////////////////////////////////////////////////////////
+ input A11 ;
+ input A10 ;
+ input A9 ;
+ input A8 ;
+ input A7 ;
+ input A6 ;
+ input A5 ;
+ input A4 ;
+ input A3 ;
+ input A2 ;
+ input A1 ;
+ input A0 ;
+
+ inout DQ31 ;
+ inout DQ30 ;
+ inout DQ29 ;
+ inout DQ28 ;
+ inout DQ27 ;
+ inout DQ26 ;
+ inout DQ25 ;
+ inout DQ24 ;
+ inout DQ23 ;
+ inout DQ22 ;
+ inout DQ21 ;
+ inout DQ20 ;
+ inout DQ19 ;
+ inout DQ18 ;
+ inout DQ17 ;
+ inout DQ16 ;
+ inout DQ15 ;
+ inout DQ14 ;
+ inout DQ13 ;
+ inout DQ12 ;
+ inout DQ11 ;
+ inout DQ10 ;
+ inout DQ9 ;
+ inout DQ8 ;
+ inout DQ7 ;
+ inout DQ6 ;
+ inout DQ5 ;
+ inout DQ4 ;
+ inout DQ3 ;
+ inout DQ2 ;
+ inout DQ1 ;
+ inout DQ0 ;
+
+ input BA0 ;
+ input BA1 ;
+ input DQM3 ;
+ input DQM2 ;
+ input DQM1 ;
+ input DQM0 ;
+ input CLK ;
+ input CKE ;
+ input WENeg ;
+ input RASNeg ;
+ input CSNeg ;
+ input CASNeg ;
+
+ // interconnect path delay signals
+ wire A11_ipd ;
+ wire A10_ipd ;
+ wire A9_ipd ;
+ wire A8_ipd ;
+ wire A7_ipd ;
+ wire A6_ipd ;
+ wire A5_ipd ;
+ wire A4_ipd ;
+ wire A3_ipd ;
+ wire A2_ipd ;
+ wire A1_ipd ;
+ wire A0_ipd ;
+
+ wire [11 : 0] A;
+ assign A = {A11_ipd,
+ A10_ipd,
+ A9_ipd,
+ A8_ipd,
+ A7_ipd,
+ A6_ipd,
+ A5_ipd,
+ A4_ipd,
+ A3_ipd,
+ A2_ipd,
+ A1_ipd,
+ A0_ipd };
+
+ wire DQ31_ipd ;
+ wire DQ30_ipd ;
+ wire DQ29_ipd ;
+ wire DQ28_ipd ;
+ wire DQ27_ipd ;
+ wire DQ26_ipd ;
+ wire DQ25_ipd ;
+ wire DQ24_ipd ;
+ wire DQ23_ipd ;
+ wire DQ22_ipd ;
+ wire DQ21_ipd ;
+ wire DQ20_ipd ;
+ wire DQ19_ipd ;
+ wire DQ18_ipd ;
+ wire DQ17_ipd ;
+ wire DQ16_ipd ;
+ wire DQ15_ipd ;
+ wire DQ14_ipd ;
+ wire DQ13_ipd ;
+ wire DQ12_ipd ;
+ wire DQ11_ipd ;
+ wire DQ10_ipd ;
+ wire DQ9_ipd ;
+ wire DQ8_ipd ;
+ wire DQ7_ipd ;
+ wire DQ6_ipd ;
+ wire DQ5_ipd ;
+ wire DQ4_ipd ;
+ wire DQ3_ipd ;
+ wire DQ2_ipd ;
+ wire DQ1_ipd ;
+ wire DQ0_ipd ;
+
+ wire [31 : 0 ] DQIn;
+ assign DQIn = { DQ31_ipd,
+ DQ30_ipd,
+ DQ29_ipd,
+ DQ28_ipd,
+ DQ27_ipd,
+ DQ26_ipd,
+ DQ25_ipd,
+ DQ24_ipd,
+ DQ23_ipd,
+ DQ22_ipd,
+ DQ21_ipd,
+ DQ20_ipd,
+ DQ19_ipd,
+ DQ18_ipd,
+ DQ17_ipd,
+ DQ16_ipd,
+ DQ15_ipd,
+ DQ14_ipd,
+ DQ13_ipd,
+ DQ12_ipd,
+ DQ11_ipd,
+ DQ10_ipd,
+ DQ9_ipd,
+ DQ8_ipd,
+ DQ7_ipd,
+ DQ6_ipd,
+ DQ5_ipd,
+ DQ4_ipd,
+ DQ3_ipd,
+ DQ2_ipd,
+ DQ1_ipd,
+ DQ0_ipd };
+
+ wire [31 : 0] DQOut;
+ assign DQOut = { DQ31,
+ DQ30,
+ DQ29,
+ DQ28,
+ DQ27,
+ DQ26,
+ DQ25,
+ DQ24,
+ DQ23,
+ DQ22,
+ DQ21,
+ DQ20,
+ DQ19,
+ DQ18,
+ DQ17,
+ DQ16,
+ DQ15,
+ DQ14,
+ DQ13,
+ DQ12,
+ DQ11,
+ DQ10,
+ DQ9,
+ DQ8,
+ DQ7,
+ DQ6,
+ DQ5,
+ DQ4,
+ DQ3,
+ DQ2,
+ DQ1,
+ DQ0 };
+
+ wire BA0_ipd ;
+ wire BA1_ipd ;
+ wire DQM3_ipd ;
+ wire DQM2_ipd ;
+ wire DQM1_ipd ;
+ wire DQM0_ipd ;
+ wire CLK_ipd ;
+ wire CKE_ipd ;
+ wire WENeg_ipd ;
+ wire RASNeg_ipd ;
+ wire CSNeg_ipd ;
+ wire CASNeg_ipd ;
+
+ integer bank;
+ integer bank_tmp;
+
+ // internal delays
+ reg rct_in ;
+ reg rct_out;
+ reg [3:0] rcdt_in ;
+ reg [3:0] rcdt_out;
+ reg pre_in ;
+ reg pre_out ;
+ reg refreshed_in ;
+ reg refreshed_out ;
+ reg rcar_out ;
+ reg rcar_in ;
+ reg wrt_in ;
+ reg wrt_out ;
+ reg [3:0] ras_in = 1'b0;
+ reg [3:0] ras_out = 1'b0;
+
+ reg [31 : 0] DQ_zd = 32'bz;
+ assign {DQ31_zd,
+ DQ30_zd,
+ DQ29_zd,
+ DQ28_zd,
+ DQ27_zd,
+ DQ26_zd,
+ DQ25_zd,
+ DQ24_zd,
+ DQ23_zd,
+ DQ22_zd,
+ DQ21_zd,
+ DQ20_zd,
+ DQ19_zd,
+ DQ18_zd,
+ DQ17_zd,
+ DQ16_zd,
+ DQ15_zd,
+ DQ14_zd,
+ DQ13_zd,
+ DQ12_zd,
+ DQ11_zd,
+ DQ10_zd,
+ DQ9_zd,
+ DQ8_zd,
+ DQ7_zd,
+ DQ6_zd,
+ DQ5_zd,
+ DQ4_zd,
+ DQ3_zd,
+ DQ2_zd,
+ DQ1_zd,
+ DQ0_zd } = DQ_zd;
+
+ parameter UserPreload = 1'b1;
+ parameter mem_file_name = "none"; //"mt48lc4m32b2.mem";
+ parameter TimingModel = "DefaultTimingModel";
+ parameter PartID = "mt48lc4m32b2";
+ parameter hi_bank = 3;
+ parameter depth = 25'h100000;
+
+ reg PoweredUp = 1'b0;
+ reg CKEreg = 1'b0;
+ reg CAS_Lat ;
+ reg CAS_Lat2;
+ reg [31:0] DataDrive = 32'bz ;
+
+ // Memory array declaration
+ integer Mem [0:(hi_bank+1)*depth*4-1];
+
+ // Type definition for state machine
+ parameter pwron = 5'd0;
+ parameter precharge = 5'd1;
+ parameter idle = 5'd2;
+ parameter mode_set = 5'd3;
+ parameter self_refresh = 5'd4;
+ parameter auto_refresh = 5'd5;
+ parameter pwrdwn = 5'd6;
+ parameter bank_act = 5'd7;
+ parameter bank_act_pwrdwn = 5'd8;
+ parameter write = 5'd9;
+ parameter write_suspend = 5'd10;
+ parameter read = 5'd11;
+ parameter read_suspend = 5'd12;
+ parameter write_auto_pre = 5'd13;
+ parameter read_auto_pre = 5'd14;
+
+ reg [4:0] statebank [hi_bank:0];
+
+ // Type definition for commands
+ parameter desl = 4'd0;
+ parameter nop = 4'd1;
+ parameter bst = 4'd2;
+ parameter rd = 4'd3;
+ parameter writ = 4'd4;
+ parameter act = 4'd5;
+ parameter pre = 4'd6;
+ parameter mrs = 4'd7;
+ parameter ref = 4'd8;
+
+ reg [3:0] command = desl;
+
+ // burst type
+ parameter sequential = 1'b0;
+ parameter interleave = 1'b1;
+ reg Burst ;
+
+ // write burst mode
+ parameter programmed = 1'b0;
+ parameter single = 1'b1;
+ reg WB ;
+
+ //burst sequences
+ integer intab [0:63];
+
+ reg [19:0] MemAddr [hi_bank:0];
+ integer BurstCnt [hi_bank:0];
+ integer StartAddr [hi_bank:0];
+ integer BurstInc [hi_bank:0];
+ integer BaseLoc [hi_bank:0];
+
+ integer Loc;
+ integer BurstLen;
+ integer Burst_Bits;
+
+ reg written = 1'b0;
+ reg chip_en = 1'b0;
+
+ integer cur_bank;
+ reg [11:0] ModeReg ;
+ integer Ref_Cnt = 0;
+
+ time Next_Ref = 0;
+ reg [8*8:1] BankString ;
+
+ reg Viol = 1'b0;
+ reg [31:0] DataDriveOut = 32'bz;
+ reg [31:0] DataDrive1 = 32'bz;
+ reg [31:0] DataDrive2 = 32'bz;
+ reg [31:0] DataDrive3 = 32'bz;
+
+ reg DQM0_reg0 ;
+ reg DQM0_reg1 ;
+ reg DQM0_reg2 ;
+ reg DQM1_reg0 ;
+ reg DQM1_reg1 ;
+ reg DQM1_reg2 ;
+ reg DQM2_reg0 ;
+ reg DQM2_reg1 ;
+ reg DQM2_reg2 ;
+ reg DQM3_reg0 ;
+ reg DQM3_reg1 ;
+ reg DQM3_reg2 ;
+
+ // tdevice values: values for internal delays
+ time tdevice_TRC = 0;
+ time tdevice_TRCAR = 0;
+ time tdevice_TRCD = 0;
+ time tdevice_TRP = 0;
+ time tdevice_TWR = 0;
+
+ ///////////////////////////////////////////////////////////////////////////
+ //Interconnect Path Delay Section
+ ///////////////////////////////////////////////////////////////////////////
+ buf (A11_ipd, A11);
+ buf (A10_ipd, A10);
+ buf (A9_ipd , A9 );
+ buf (A8_ipd , A8 );
+ buf (A7_ipd , A7 );
+ buf (A6_ipd , A6 );
+ buf (A5_ipd , A5 );
+ buf (A4_ipd , A4 );
+ buf (A3_ipd , A3 );
+ buf (A2_ipd , A2 );
+ buf (A1_ipd , A1 );
+ buf (A0_ipd , A0 );
+
+ buf (DQ31_ipd , DQ31 );
+ buf (DQ30_ipd , DQ30 );
+ buf (DQ29_ipd , DQ29 );
+ buf (DQ28_ipd , DQ28 );
+ buf (DQ27_ipd , DQ27 );
+ buf (DQ26_ipd , DQ26 );
+ buf (DQ25_ipd , DQ25 );
+ buf (DQ24_ipd , DQ24 );
+ buf (DQ23_ipd , DQ23 );
+ buf (DQ22_ipd , DQ22 );
+ buf (DQ21_ipd , DQ21 );
+ buf (DQ20_ipd , DQ20 );
+ buf (DQ19_ipd , DQ19 );
+ buf (DQ18_ipd , DQ18 );
+ buf (DQ17_ipd , DQ17 );
+ buf (DQ16_ipd , DQ16 );
+ buf (DQ15_ipd , DQ15 );
+ buf (DQ14_ipd , DQ14 );
+ buf (DQ13_ipd , DQ13 );
+ buf (DQ12_ipd , DQ12 );
+ buf (DQ11_ipd , DQ11 );
+ buf (DQ10_ipd , DQ10 );
+ buf (DQ9_ipd , DQ9 );
+ buf (DQ8_ipd , DQ8 );
+ buf (DQ7_ipd , DQ7 );
+ buf (DQ6_ipd , DQ6 );
+ buf (DQ5_ipd , DQ5 );
+ buf (DQ4_ipd , DQ4 );
+ buf (DQ3_ipd , DQ3 );
+ buf (DQ2_ipd , DQ2 );
+ buf (DQ1_ipd , DQ1 );
+ buf (DQ0_ipd , DQ0 );
+
+ buf (CASNeg_ipd, CASNeg);
+ buf (RASNeg_ipd, RASNeg);
+ buf (BA0_ipd , BA0 );
+ buf (BA1_ipd , BA1 );
+ buf (DQM0_ipd , DQM0 );
+ buf (DQM1_ipd , DQM1 );
+ buf (DQM2_ipd , DQM2 );
+ buf (DQM3_ipd , DQM3 );
+ buf (CLK_ipd , CLK );
+ buf (CKE_ipd , CKE );
+ buf (WENeg_ipd , WENeg );
+ buf (CSNeg_ipd , CSNeg );
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Propagation delay Section
+ ///////////////////////////////////////////////////////////////////////////
+ nmos (DQ31 , DQ31_zd , 1);
+ nmos (DQ30 , DQ30_zd , 1);
+ nmos (DQ29 , DQ29_zd , 1);
+ nmos (DQ28 , DQ28_zd , 1);
+ nmos (DQ27 , DQ27_zd , 1);
+ nmos (DQ26 , DQ26_zd , 1);
+ nmos (DQ25 , DQ25_zd , 1);
+ nmos (DQ24 , DQ24_zd , 1);
+ nmos (DQ23 , DQ23_zd , 1);
+ nmos (DQ22 , DQ22_zd , 1);
+ nmos (DQ21 , DQ21_zd , 1);
+ nmos (DQ20 , DQ20_zd , 1);
+ nmos (DQ19 , DQ19_zd , 1);
+ nmos (DQ18 , DQ18_zd , 1);
+ nmos (DQ17 , DQ17_zd , 1);
+ nmos (DQ16 , DQ16_zd , 1);
+ nmos (DQ15 , DQ15_zd , 1);
+ nmos (DQ14 , DQ14_zd , 1);
+ nmos (DQ13 , DQ13_zd , 1);
+ nmos (DQ12 , DQ12_zd , 1);
+ nmos (DQ11 , DQ11_zd , 1);
+ nmos (DQ10 , DQ10_zd , 1);
+ nmos (DQ9 , DQ9_zd , 1);
+ nmos (DQ8 , DQ8_zd , 1);
+ nmos (DQ7 , DQ7_zd , 1);
+ nmos (DQ6 , DQ6_zd , 1);
+ nmos (DQ5 , DQ5_zd , 1);
+ nmos (DQ4 , DQ4_zd , 1);
+ nmos (DQ3 , DQ3_zd , 1);
+ nmos (DQ2 , DQ2_zd , 1);
+ nmos (DQ1 , DQ1_zd , 1);
+ nmos (DQ0 , DQ0_zd , 1);
+
+ wire deg;
+ wire chip_act;
+ assign chip_act = chip_en;
+
+ wire chip_act_deg;
+ assign chip_act_deg = chip_act && deg;
+
+ wire cas_latency1;
+ wire cas_latency2;
+ wire cas_latency3;
+
+ assign cas_latency1 = CAS_Lat && ~CAS_Lat2;
+ assign cas_latency2 = ~CAS_Lat && CAS_Lat2;
+ assign cas_latency3 = CAS_Lat && CAS_Lat2;
+
+ specify
+ // tipd delays: interconnect path delays, mapped to input port delays.
+ // In Verilog it is not necessary to declare any tipd delay variables,
+ // they can be taken from SDF file
+ // With all the other delays real delays would be taken from SDF file
+
+ // tpd delays
+ specparam tpd_CLK_DQ1 = 1;
+ specparam tpd_CLK_DQ2 = 1;
+ specparam tpd_CLK_DQ3 = 1;
+
+ // tpw values: pulse widths
+ specparam tpw_CLK_posedge = 1;
+ specparam tpw_CLK_negedge = 1;
+
+ // tsetup values: setup times
+ specparam tsetup_DQ0_CLK = 1; // tDS
+
+ // thold values: hold times
+ specparam thold_DQ0_CLK = 1; // tDH
+
+ // tperiod_min: minimum clock period = 1/max freq
+ specparam tperiod_CLK_cl0_eq_1_posedge = 1; //tCK
+ specparam tperiod_CLK_cl1_eq_1_posedge = 1;
+ specparam tperiod_CLK_cl2_eq_1_posedge = 1;
+
+ // tdevice values: values for internal delays
+ specparam tdevice_REF = 15625 ;
+ specparam tdevice_TRASmin = 42;
+ specparam tdevice_TRASmax = 120000;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Input Port Delays don't require Verilog description
+ ///////////////////////////////////////////////////////////////////////
+ // Path delays //
+ ///////////////////////////////////////////////////////////////////////
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ16) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ17) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ18) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ19) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ20) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ21) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ22) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ23) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ24) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ25) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ26) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ27) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ28) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ29) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ30) = tpd_CLK_DQ1;
+ if (CAS_Lat && ~CAS_Lat2) (CLK *> DQ31) = tpd_CLK_DQ1;
+
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ16) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ17) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ18) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ19) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ20) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ21) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ22) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ23) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ24) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ25) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ26) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ27) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ28) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ29) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ30) = tpd_CLK_DQ2;
+ if (~CAS_Lat && CAS_Lat2) (CLK *> DQ31) = tpd_CLK_DQ2;
+
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ16) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ17) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ18) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ19) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ20) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ21) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ22) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ23) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ24) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ25) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ26) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ27) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ28) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ29) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ30) = tpd_CLK_DQ3;
+ if (CAS_Lat && CAS_Lat2) (CLK *> DQ31) = tpd_CLK_DQ3;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Timing Check Section
+ ////////////////////////////////////////////////////////////////////////
+ $setup (BA0 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (BA1 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQM0, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQM1, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQM2, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (DQM3, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CKE , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (WENeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CSNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (CASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (RASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+
+ $setup (DQ0 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ1 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ2 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ3 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ4 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ5 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ6 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ7 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ8 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ9 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ10 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ11 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ12 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ13 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ14 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ15 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ16 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ17 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ18 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ19 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ20 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ21 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ22 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ23 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ24 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ25 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ26 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ27 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ28 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ29 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ30 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+ $setup (DQ31 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
+
+ $setup (A0, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A1, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A2, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A3, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A4, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A5, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A6, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A7, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A8, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A9, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A10, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+ $setup (A11, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act, BA0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, BA1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQM0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQM1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQM2, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, DQM3, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CKE , thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CASNeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, RASNeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, WENeg, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, CSNeg, thold_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act, A0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A2, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A3, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A4, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A5, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A6, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A7, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A8, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A9, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A10, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act, A11, thold_DQ0_CLK, Viol);
+
+ $hold (posedge CLK &&& chip_act_deg, DQ0, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ1, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ2, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ3, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ4, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ5, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ6, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ7, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ8, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ9, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ10, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ11, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ12, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ13, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ14, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ15, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ16, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ17, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ18, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ19, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ20, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ21, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ22, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ23, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ24, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ25, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ26, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ27, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ28, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ29, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ30, thold_DQ0_CLK, Viol);
+ $hold (posedge CLK &&& chip_act_deg, DQ31, thold_DQ0_CLK, Viol);
+
+ $width (posedge CLK &&& chip_act, tpw_CLK_posedge);
+ $width (negedge CLK &&& chip_act, tpw_CLK_negedge);
+
+ $period (posedge CLK &&& cas_latency1, tperiod_CLK_cl0_eq_1_posedge);
+ $period (posedge CLK &&& cas_latency2, tperiod_CLK_cl1_eq_1_posedge);
+ $period (posedge CLK &&& cas_latency3, tperiod_CLK_cl2_eq_1_posedge);
+
+ endspecify
+
+ task generate_out ;
+ output [31:0] DataDrive;
+ input Bank;
+ integer Bank;
+ integer location;
+ begin
+ location = Bank * depth * 4 + Loc;
+
+ DataDrive[7:0] = 8'bx;
+ if (Mem[location] > -1)
+ DataDrive[7:0] = Mem[location];
+
+ DataDrive[15:8] = 8'bx;
+ if (Mem[location+1] > -1)
+ DataDrive[15:8] = Mem[location+1];
+
+ DataDrive[23:16] = 8'bx;
+ if (Mem[location+2] > -1)
+ DataDrive[23:16] = Mem[location+2];
+
+ DataDrive[31:24] = 8'bx;
+ if (Mem[location+3] > -1)
+ DataDrive[31:24] = Mem[location+3];
+ end
+ endtask
+
+ task MemWrite;
+ input Bank;
+ integer Bank;
+ integer location;
+ begin
+ location = Bank * depth * 4 + Loc;
+
+ if (~DQM0_ipd)
+ begin
+ Mem[location] = -1;
+ if (~Viol)
+ Mem[location] = DQIn[7:0];
+ end
+
+ if (~DQM1_ipd)
+ begin
+ Mem[location+1] = -1;
+ if (~Viol)
+ Mem[location+1] = DQIn[15:8];
+ end
+
+ if (~DQM2_ipd)
+ begin
+ Mem[location+2] = -1;
+ if (~Viol)
+ Mem[location+2] = DQIn[23:16];
+ end
+
+ if (~DQM3_ipd)
+ begin
+ Mem[location+3] = -1;
+ if (~Viol)
+ Mem[location+3] = DQIn[31:24];
+ end
+ end
+ endtask
+
+ task BurstIncProc;
+ input Bank;
+ integer Bank;
+ begin
+ BurstInc[Bank] = 0;
+ if (Burst_Bits == 1)
+ BurstInc[Bank] = A[0:0];
+ if (Burst_Bits == 2)
+ BurstInc[Bank] = A[1:0];
+ if (Burst_Bits == 3)
+ BurstInc[Bank] = A[2:0];
+ if (Burst_Bits == 7)
+ BurstInc[Bank] = A[6:0];
+ end
+ endtask
+
+ task NextStateAuto;
+ input Bank;
+ input state;
+ integer Bank;
+ reg [4:0] state;
+ begin
+ if (~A[10])
+ statebank[Bank] = state;
+ else if (A[10])
+ if (state == write)
+ statebank[Bank] = write_auto_pre;
+ else
+ statebank[Bank] = read_auto_pre;
+ end
+ endtask
+
+ //////////////////////////////////////////////////////////////////////////
+ // Main Behavior Block //
+ //////////////////////////////////////////////////////////////////////////
+
+ // chech when data is generated from model to avoid setup/hold check in
+ // those occasion
+ reg deq;
+ always @(DQIn, DQOut)
+ begin
+ if (DQIn==DQOut)
+ deq=1'b1;
+ else
+ deq=1'b0;
+ end
+ assign deg=deq;
+
+ // initialize burst sequences
+ initial
+ begin
+ intab[0] = 0;
+ intab[1] = 1;
+ intab[2] = 2;
+ intab[3] = 3;
+ intab[4] = 4;
+ intab[5] = 5;
+ intab[6] = 6;
+ intab[7] = 7;
+ intab[8] = 1;
+ intab[9] = 0;
+ intab[10] = 3;
+ intab[11] = 2;
+ intab[12] = 5;
+ intab[13] = 4;
+ intab[14] = 7;
+ intab[15] = 6;
+ intab[16] = 2;
+ intab[17] = 3;
+ intab[18] = 0;
+ intab[19] = 1;
+ intab[20] = 6;
+ intab[21] = 7;
+ intab[22] = 4;
+ intab[23] = 5;
+ intab[24] = 3;
+ intab[25] = 2;
+ intab[26] = 1;
+ intab[27] = 0;
+ intab[28] = 7;
+ intab[29] = 6;
+ intab[30] = 5;
+ intab[31] = 4;
+ intab[32] = 4;
+ intab[33] = 5;
+ intab[34] = 6;
+ intab[35] = 7;
+ intab[36] = 0;
+ intab[37] = 1;
+ intab[38] = 2;
+ intab[39] = 3;
+ intab[40] = 5;
+ intab[41] = 4;
+ intab[42] = 7;
+ intab[43] = 6;
+ intab[44] = 1;
+ intab[45] = 0;
+ intab[46] = 3;
+ intab[47] = 2;
+ intab[48] = 6;
+ intab[49] = 7;
+ intab[50] = 4;
+ intab[51] = 5;
+ intab[52] = 2;
+ intab[53] = 3;
+ intab[54] = 0;
+ intab[55] = 1;
+ intab[56] = 7;
+ intab[57] = 6;
+ intab[58] = 5;
+ intab[59] = 4;
+ intab[60] = 3;
+ intab[61] = 2;
+ intab[62] = 1;
+ intab[63] = 0;
+ end
+
+ // initialize memory and load preload files if any
+ initial
+ begin: InitMemory
+ integer i;
+ for (i=0; i<=((hi_bank+1)*depth*4 - 1); i=i+1)
+ begin
+ Mem[i] = -1;
+ end
+ // Memory preload file
+ // mt48lc4m32b2.mem file
+ // @bbbbbb - stands for address within memory,
+ // dd - is word to be written at Mem(bbbbbb++)
+ // (bbbbbb is incremented at every load)
+ if (UserPreload && !(mem_file_name == "none"))
+ $readmemh(mem_file_name,Mem);
+ end
+
+ //Power Up time 100 us;
+ initial
+ begin
+ PoweredUp = 1'b0;
+ statebank[0] = pwron;
+ statebank[1] = pwron;
+ statebank[2] = pwron;
+ statebank[3] = pwron;
+ #100000 PoweredUp = 1'b1;
+ end
+
+ always @(posedge wrt_in)
+ begin:TWRrise
+ #tdevice_TWR wrt_out = wrt_in;
+ end
+
+ always @(negedge wrt_in)
+ begin:TWRfall
+ #1 wrt_out = wrt_in;
+ end
+
+ always @(posedge ras_in[0])
+ begin:TRASrise0
+ ras_out[0] <= #tdevice_TRASmin ras_in[0];
+ end
+
+ always @(negedge ras_in[0])
+ begin:TRASfall0
+ ras_out[0] <= #tdevice_TRASmax ras_in[0];
+ end
+
+ always @(posedge ras_in[1])
+ begin:TRASrise1
+ ras_out[1] <= #tdevice_TRASmin ras_in[1];
+ end
+
+ always @(negedge ras_in[1])
+ begin:TRASfall1
+ ras_out[1] <= #tdevice_TRASmax ras_in[1];
+ end
+
+ always @(posedge ras_in[2])
+ begin:TRASrise2
+ ras_out[2] <= #tdevice_TRASmin ras_in[2];
+ end
+ always @(negedge ras_in[2])
+ begin:TRASfall2
+ ras_out[2] <= #tdevice_TRASmax ras_in[2];
+ end
+
+ always @(posedge ras_in[3])
+ begin:TRASrise3
+ ras_out[3] <= #tdevice_TRASmin ras_in[3];
+ end
+
+ always @(negedge ras_in[3])
+ begin:TRASfall3
+ ras_out[3] <= #tdevice_TRASmax ras_in[3];
+ end
+
+ always @(posedge rcdt_in[0])
+ begin:TRCDrise0
+ rcdt_out[0] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[0])
+ begin:TRCDfall0
+ rcdt_out[0] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[1])
+ begin:TRCDrise1
+ rcdt_out[1] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[1])
+ begin:TRCDfall1
+ rcdt_out[1] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[2])
+ begin:TRCDrise2
+ rcdt_out[2] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[2])
+ begin:TRCDfall2
+ rcdt_out[2] <= #tdevice_TRCD 1'b0;
+ end
+
+ always @(posedge rcdt_in[3])
+ begin:TRCDrise3
+ rcdt_out[3] <= #5 1'b1;
+ end
+ always @(negedge rcdt_in[3])
+ begin:TRCDfall3
+ rcdt_out[3] <= #tdevice_TRCD 1'b0;
+ end
+
+ /////////////////////////////////////////////////////////////////////////
+ // Functional Section
+ /////////////////////////////////////////////////////////////////////////
+ always @(posedge CLK)
+ begin
+ if ($time > Next_Ref && PoweredUp && Ref_Cnt > 0)
+ begin
+ Ref_Cnt = Ref_Cnt - 1;
+ Next_Ref = $time + tdevice_REF;
+ end
+ if (CKEreg)
+ begin
+ if (~CSNeg_ipd)
+ chip_en = 1;
+ else
+ chip_en = 0;
+ end
+
+ if (CKEreg && ~CSNeg_ipd)
+ begin
+ if (DQM0_ipd == 1'bx)
+ $display(" Unusable value for DQM0 ");
+ if (DQM1_ipd == 1'bx)
+ $display(" Unusable value for DQM1 ");
+ if (DQM2_ipd == 1'bx)
+ $display(" Unusable value for DQM2 ");
+ if (DQM3_ipd == 1'bx)
+ $display(" Unusable value for DQM3 ");
+ if (WENeg_ipd == 1'bx)
+ $display(" Unusable value for WENeg ");
+ if (RASNeg_ipd == 1'bx)
+ $display(" Unusable value for RASNeg ");
+ if (CASNeg_ipd == 1'bx)
+ $display(" Unusable value for CASNeg ");
+
+ // Command Decode
+ if (RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
+ command = nop;
+ else if (~RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
+ command = act;
+ else if (RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
+ command = rd;
+ else if (RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
+ command = writ;
+ else if (RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
+ command = bst;
+ else if (~RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
+ command = pre;
+ else if (~RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
+ command = ref;
+ else if (~RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
+ command = mrs;
+
+ // PowerUp Check
+ if (~(PoweredUp) && command != nop)
+ begin
+ $display (" Incorrect power up. Command issued before ");
+ $display (" power up complete. ");
+ end
+
+ // Bank Decode
+ if (~BA0_ipd && ~BA1_ipd)
+ cur_bank = 0;
+ else if (BA0_ipd && ~BA1_ipd)
+ cur_bank = 1;
+ else if (~BA0_ipd && BA1_ipd)
+ cur_bank = 2;
+ else if (BA0_ipd && BA1_ipd)
+ cur_bank = 3;
+ else
+ begin
+ $display ("Could not decode bank selection - results");
+ $display ("may be incorrect.");
+ end
+ end
+
+ // The Big State Machine
+ if (CKEreg)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+
+ if (CSNeg_ipd)
+ command = nop;
+
+ // DQM pipeline
+ DQM0_reg2 = DQM0_reg1;
+ DQM0_reg1 = DQM0_reg0;
+ DQM0_reg0 = DQM0_ipd;
+ DQM1_reg2 = DQM1_reg1;
+ DQM1_reg1 = DQM1_reg0;
+ DQM1_reg0 = DQM1_ipd;
+ DQM2_reg2 = DQM2_reg1;
+ DQM2_reg1 = DQM2_reg0;
+ DQM2_reg0 = DQM2_ipd;
+ DQM3_reg2 = DQM3_reg1;
+ DQM3_reg1 = DQM3_reg0;
+ DQM3_reg0 = DQM3_ipd;
+
+ // by default data drive is Z, might get over written in one
+ // of the passes below
+ DataDrive = 32'bz;
+
+ for (bank = 0; bank <= hi_bank; bank = bank + 1)
+ begin
+ case (statebank[bank])
+ pwron :
+ begin
+ if (~DQM0_ipd)
+ begin
+ $display ("DQM0 must be held high during");
+ $display ("initialization.");
+ end
+ if (~DQM1_ipd)
+ begin
+ $display ("DQM1 must be held high during");
+ $display ("initialization.");
+ end
+ if (~DQM2_ipd)
+ begin
+ $display ("DQM2 must be held high during");
+ $display ("initialization.");
+ end
+ if (~DQM3_ipd)
+ begin
+ $display ("DQM3 must be held high during");
+ $display ("initialization.");
+ end
+
+ if (~PoweredUp)
+ begin
+ if (command != nop)
+ $display ("Only NOPs allowed during power up.");
+ DataDrive = 32'bz;
+ end
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ end
+
+ precharge :
+ begin
+ if (cur_bank == bank)
+ // It is only an error if this bank is selected
+ if (command != nop && command != pre)
+ begin
+ $display ("Illegal command received ");
+ $display ("during precharge.",$time);
+ end
+ end
+
+ idle :
+ begin
+ if (command == nop || command == bst || command == pre
+ || cur_bank != bank)
+ begin
+ end
+ else if (command == mrs)
+ begin
+ if (statebank[0] == idle && statebank[1] == idle &&
+ statebank[2] == idle && statebank[3] == idle)
+ begin
+ ModeReg = A;
+ statebank[bank] = mode_set;
+ end
+ end
+ else if (command == ref)
+ begin
+ if (statebank[0] == idle && statebank[1] == idle &&
+ statebank[2] == idle && statebank[3] == idle)
+ if (CKE)
+ begin
+ statebank[bank] = auto_refresh;
+ statebank[bank] <= #tdevice_TRCAR idle;
+ end
+ else
+ begin
+ statebank[0] = self_refresh;
+ statebank[1] = self_refresh;
+ statebank[2] = self_refresh;
+ statebank[3] = self_refresh;
+ end
+ end
+ else if (command == act)
+ begin
+ statebank[bank] = bank_act;
+ ras_in[bank] = 1'b1;
+ ras_in [bank] <= #70 1'b0;
+ rct_in = 1'b1;
+ rct_in <= #1 1'b0;
+ rcdt_in[bank] = 1'b1;
+ rcdt_in[bank] <= #1 1'b0;
+ MemAddr[bank][19:8] = A; // latch row addr
+ end
+ else
+ $display ("Illegal command received in idle state.",$time);
+ end
+
+ mode_set :
+ begin
+ if (ModeReg[7] != 0 || ModeReg[8] != 0)
+ $display ("Illegal operating mode set.");
+ if (command != nop)
+ begin
+ $display ("Illegal command received during mode");
+ $display ("set.",$time);
+ end
+
+ // read burst length
+ if (ModeReg[2:0] == 3'b000)
+ begin
+ BurstLen = 1;
+ Burst_Bits = 0;
+ end
+ else if (ModeReg[2:0] == 3'b001)
+ begin
+ BurstLen = 2;
+ Burst_Bits = 1;
+ end
+ else if (ModeReg[2:0] == 3'b010)
+ begin
+ BurstLen = 4;
+ Burst_Bits = 2;
+ end
+ else if (ModeReg[2:0] == 3'b011)
+ begin
+ BurstLen = 8;
+ Burst_Bits = 3;
+ end
+ else if (ModeReg[2:0] == 3'b111)
+ begin
+ BurstLen = 256;
+ Burst_Bits = 7;
+ end
+ else
+ $display ("Invalid burst length specified.");
+
+ // read burst type
+ if (~ModeReg[3])
+ Burst = sequential;
+ else if (ModeReg[3])
+ Burst = interleave;
+ else
+ $display ("Invalid burst type specified.");
+
+ // read CAS latency
+ if (ModeReg[6:4] == 3'b001)
+ begin
+ CAS_Lat = 1'b1;
+ CAS_Lat2 = 1'b0;
+ end
+ else if (ModeReg[6:4] == 3'b010)
+ begin
+ CAS_Lat = 1'b0;
+ CAS_Lat2 = 1'b1;
+ end
+ else if (ModeReg[6:4] == 3'b011)
+ begin
+ CAS_Lat = 1'b1;
+ CAS_Lat2 = 1'b1;
+ end
+ else
+ $display ("CAS Latency set incorrecty");
+
+ // write burst mode
+ if (~ModeReg[9])
+ WB = programmed;
+ else if (ModeReg[9])
+ WB = single;
+ else
+ $display ("Invalid burst type specified.");
+
+ statebank[bank] = idle;
+ end
+
+ auto_refresh :
+ begin
+ if (Ref_Cnt < 4096)
+ Ref_Cnt = Ref_Cnt + 1;
+ if (command != nop)
+ begin
+ $display ("Illegal command received during");
+ $display ("auto_refresh.",$time);
+ end
+ end
+
+ bank_act :
+ begin
+ if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("precharge command does not meet tRAS");
+ $display ("time", $time);
+ end
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else if (command == nop || command == bst
+ || cur_bank != bank)
+ begin
+ end
+ else if (command == rd)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("read command received too soon");
+ $display ("after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during read command.");
+ $display ("Next state unknown.");
+ end
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ BurstIncProc(bank);
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive,bank);
+ BurstCnt[bank] = 1;
+ NextStateAuto(bank, read);
+ bank_tmp = bank;
+ end
+ else if (command == writ)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("write command received too soon");
+ $display ("after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during write command.");
+ $display ("Next state unknown.");
+ end
+ MemAddr[bank][7:0] = 8'b0; // clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ wrt_in = 1'b1;
+ NextStateAuto(bank, write);
+ written = 1'b1;
+ end
+ else if (cur_bank == bank || command == mrs)
+ begin
+ $display ("Illegal command received in");
+ $display ("active state",$time);
+ end
+ end
+
+ write :
+ begin
+ if (command == bst)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ end
+ else if (command == rd)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank, read);
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == writ)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ wrt_in = 1'b1;
+ if (A[10])
+ statebank[bank] = write_auto_pre;
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("precharge command does not meet tRAS time",$time);
+ end
+ if (~DQM0_ipd)
+ begin
+ $display ("DQM0 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ if (~DQM1_ipd)
+ begin
+ $display ("DQM1 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ if (~DQM2_ipd)
+ begin
+ $display ("DQM2 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ if (~DQM2_ipd)
+ begin
+ $display ("DQM2 should be held high, data is");
+ $display ("lost.",$time);
+ end
+ wrt_in = 1'b0;
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else if (command == nop || cur_bank != bank)
+ if (BurstCnt[bank] == BurstLen || WB == single)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ wrt_in = 1'b1;
+ end
+ else if (cur_bank == bank)
+ $display ("Illegal command received in write state",$time);
+ end
+
+ read :
+ begin
+ if (command == bst)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ end
+ else if (command == rd)
+ if (cur_bank == bank)
+ begin
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = 1'b1;
+ NextStateAuto(bank, read);
+ end
+ else
+ statebank[bank] = bank_act;
+ else if (command == writ)
+ if (cur_bank == bank)
+ begin
+ if (rcdt_out[bank])
+ begin
+ $display ("write command received too soon after active",$time);
+ end
+ if (A[10] == 1'bx)
+ begin
+ $display ("A(10) = X during write command.");
+ $display ("Next state unknown.");
+ end
+
+ MemAddr[bank][7:0] = 8'b0;// clr old addr
+ BurstIncProc(bank);
+ // latch col addr
+ if (Burst_Bits == 0)
+ MemAddr[bank][7:0] = A[7:0];
+ if (Burst_Bits == 1)
+ MemAddr[bank][7:1] = A[7:1];
+ if (Burst_Bits == 2)
+ MemAddr[bank][7:2] = A[7:2];
+ if (Burst_Bits == 3)
+ MemAddr[bank][7:3] = A[7:3];
+ if (Burst_Bits == 7)
+ MemAddr[bank][7:7] = A[7:7];
+ StartAddr[bank] = BurstInc[bank] % 8;
+ BaseLoc[bank] = MemAddr[bank];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = 1'b1;
+ wrt_in = 1'b1;
+ NextStateAuto(bank,write);
+ end
+ else
+ statebank[bank] = bank_act;
+
+ else if (command == pre && (cur_bank == bank || A[10]))
+ begin
+ if (~ras_out[bank])
+ begin
+ $display ("Precharge command does not meet tRAS time",$time);
+ end
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+
+ else if (command == nop || cur_bank != bank)
+ begin
+ if (BurstCnt[bank] == BurstLen)
+ begin
+ statebank[bank] = bank_act;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ end
+ else if (cur_bank == bank)
+ $display ("Illegal command received in read state",$time);
+ end
+
+ write_auto_pre :
+ begin
+ if (command == nop || cur_bank != bank)
+ if (BurstCnt[bank] == BurstLen || WB == single)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ MemWrite(bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ wrt_in = 1'b1;
+ end
+ else
+ $display ("Illegal command received in write state.",$time);
+ end
+
+ read_auto_pre :
+ begin
+ if (command == nop || (cur_bank != bank && command != rd
+ && command != writ))
+ if (BurstCnt[bank] == BurstLen)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ BurstCnt[bank] = 1'b0;
+ ras_in[bank] = 1'b1;
+ end
+ else
+ begin
+ if (Burst == sequential)
+ BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
+ else
+ BurstInc[bank] =
+ intab[StartAddr[bank]*8 + BurstCnt[bank]];
+ Loc = 4*(BaseLoc[bank] + BurstInc[bank]);
+ generate_out(DataDrive, bank);
+ BurstCnt[bank] = BurstCnt[bank] + 1;
+ end
+ else if ((command == rd || command == writ) && cur_bank
+ != bank)
+ begin
+ statebank[bank] = precharge;
+ statebank[bank] <= #tdevice_TRP idle;
+ end
+ else
+ $display ("Illegal command received in read state",$time);
+ end
+ endcase
+ end
+
+ // Check Refresh Status
+ if (written && (Ref_Cnt == 0))
+ $display ("memory not refreshed (by ref_cnt)", $time);
+
+ DataDrive3 = DataDrive2;
+ DataDrive2 = DataDrive1;
+ DataDrive1 = DataDrive;
+
+ end
+
+ // Latency adjustments and DQM read masking
+ if (~DQM0_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[7:0] = DataDrive3[7:0];
+ else if (~CAS_Lat && CAS_Lat2)
+ DataDriveOut[7:0] = DataDrive2[7:0];
+ else
+ DataDriveOut[7:0] = DataDrive1[7:0];
+ else
+ DataDriveOut[7:0] = 8'bz;
+
+ if (~DQM1_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[15:8] = DataDrive3[15:8];
+ else if (~CAS_Lat && CAS_Lat2)
+ DataDriveOut[15:8] = DataDrive2[15:8];
+ else
+ DataDriveOut[15:8] = DataDrive1[15:8];
+ else
+ DataDriveOut[15:8] = 8'bz;
+
+ if (~DQM2_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[23:16] = DataDrive3[23:16];
+ else if (~CAS_Lat && CAS_Lat2)
+ DataDriveOut[23:16] = DataDrive2[23:16];
+ else
+ DataDriveOut[23:16] = DataDrive1[23:16];
+ else
+ DataDriveOut[23:16] = 8'bz;
+
+ if (~DQM3_reg1)
+ if (CAS_Lat && CAS_Lat2)
+ DataDriveOut[31:24] = DataDrive3[31:24];
+ else if (~CAS_Lat && CAS_Lat2)
+ DataDriveOut[31:24] = DataDrive2[31:24];
+ else
+ DataDriveOut[31:24] = DataDrive1[31:24];
+ else
+ DataDriveOut[31:24] = 8'bz;
+
+ // The Powering-up State Machine
+ if (~CKEreg && CKE_ipd)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+ if (CSNeg_ipd)
+ command = nop;
+
+ case (statebank[cur_bank])
+ write_suspend :
+ begin
+ statebank[cur_bank] = write;
+ end
+
+ read_suspend :
+ begin
+ statebank[cur_bank] = read;
+ end
+
+ self_refresh :
+ begin
+ statebank[0] <= #tdevice_TRP idle;
+ statebank[1] <= #tdevice_TRP idle;
+ statebank[2] <= #tdevice_TRP idle;
+ statebank[3] <= #tdevice_TRP idle;
+ Ref_Cnt = 4096;
+ if (command != nop)
+ begin
+ $display ("Illegal command received during self");
+ $display ("refresh",$time);
+ end
+ end
+
+ pwrdwn :
+ begin
+ statebank[0] = idle;
+ statebank[1] = idle;
+ statebank[2] = idle;
+ statebank[3] = idle;
+ end
+
+ bank_act_pwrdwn :
+ begin
+ statebank[cur_bank] = bank_act;
+ end
+ endcase
+ end
+
+ // The Powering-down State Machine
+ if (CKEreg && ~CKE_ipd)
+ begin
+ if (CSNeg_ipd == 1'bx)
+ $display ("Unusable value for CSNeg");
+ if (CSNeg_ipd)
+ command = nop;
+
+ case (statebank[cur_bank])
+ idle :
+ begin
+ if (command == nop)
+ begin
+ statebank[0] = pwrdwn;
+ statebank[1] = pwrdwn;
+ statebank[2] = pwrdwn;
+ statebank[3] = pwrdwn;
+ end
+ end
+
+ write :
+ begin
+ statebank[cur_bank] = write_suspend;
+ end
+
+ read :
+ begin
+ statebank[cur_bank] = read_suspend;
+ end
+
+ bank_act :
+ begin
+ statebank[cur_bank] = bank_act_pwrdwn;
+ end
+ endcase
+ end
+
+ CKEreg = CKE_ipd;
+ end
+
+ always @(DataDriveOut)
+ begin
+ DQ_zd = DataDriveOut;
+ end
+
+ reg TRC_In , TRCAR_In;
+ reg TRCD_In , TRP_In , TWR_In;
+ wire TRC_Out, TRCAR_Out, TRCD_Out, TRP_Out, TWR_Out;
+
+ BUFFER BUF_TRC (TRC_Out , TRC_In);
+ BUFFER BUF_TRCAR (TRCAR_Out, TRCAR_In);
+ BUFFER BUF_TRCD (TRCD_Out , TRCD_In);
+ BUFFER BUF_TRP (TRP_Out , TRP_In);
+ BUFFER BUF_TWR (TWR_Out , TWR_In);
+
+ initial
+ begin
+ TRC_In = 1;
+ TRCAR_In = 1;
+ TRCD_In = 1'b1;
+ TRP_In = 1;
+ TWR_In = 1;
+ end
+
+ always @(posedge TRC_Out)
+ begin
+ tdevice_TRC = $time;
+ end
+
+ always @(posedge TRCAR_Out)
+ begin
+ tdevice_TRCAR = $time;
+ end
+
+ always @(posedge TRCD_Out)
+ begin
+ tdevice_TRCD = $time;
+ end
+
+ always @(posedge TRP_Out)
+ begin
+ tdevice_TRP = $time;
+ end
+
+ always @(posedge TWR_Out)
+ begin
+ tdevice_TWR = $time;
+ end
+
+endmodule
+
+module BUFFER (OUT,IN);
+ input IN;
+ output OUT;
+ buf (OUT, IN);
+endmodule
trunk/verif/model/mt48lc4m32b2.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/verif/model/IS42VM16400K.V
===================================================================
--- trunk/verif/model/IS42VM16400K.V (nonexistent)
+++ trunk/verif/model/IS42VM16400K.V (revision 7)
@@ -0,0 +1,1728 @@
+/************************************************************************
+*
+* Copyright(c) ISSI Inc., 2010
+*
+* == 64M Low power SDRAM behavioral Model by ESC ==
+*
+* Address : 1940 Zanker Road San Jose,CA95112-4216,U.S.A.
+* Tel : +1-408-969-6600, Fax : +1-408-969-7800
+*
+* Revision : Rev0.0 (2010.10.4)
+*
+* Running Options
+* +S50 : Set AC timing parameter for -50(200MHz )
+* +S60 : Set AC timing parameter for -60(166MHz )
+* +S75 : Set AC timing parameter for -75(133MHz )
+* +VERBOSE : Display internal operation status
+*
+************************************************************************/
+
+`timescale 1ns / 1ps
+
+ module IS42VM16400K (dq, addr, ba, clk, cke, csb, rasb, casb, web, dqm);
+
+ parameter no_of_bank = 2;
+ parameter no_of_addr = 12;
+ parameter no_of_data = 16;
+ parameter no_of_col = 8;
+ parameter no_of_dqm = 2;
+ parameter mem_sizes = 1048575;
+
+
+ // Timing Parameters for -50 PC200
+ `ifdef S50
+ parameter tAC3 = 5.0;
+ parameter tHZ3 = 5.0;
+ parameter tAC2 = 8.0;
+ parameter tHZ2 = 8.0;
+ parameter tOH = 2.0;
+ parameter tMRD = 2.0;
+ parameter tRAS = 40.0;
+ parameter tRC = 55.0;
+ parameter tRCD = 18.0;
+ parameter tRFC = 60.0;
+ parameter tXSR = 60.0;
+ parameter tRP = 15.0;
+ parameter tRRD = 10.0;
+ parameter tDPLa = 5.0;
+ parameter tDPLm = 12.0;
+ parameter tDPDX = 100000.0;
+ `endif
+
+
+ // Timing Parameters for -60 PC166
+ `ifdef S60
+ parameter tAC3 = 5.5;
+ parameter tHZ3 = 5.5;
+ parameter tAC2 = 8.0;
+ parameter tHZ2 = 8.0;
+ parameter tOH = 2.5;
+ parameter tMRD = 2.0;
+ parameter tRAS = 42.0;
+ parameter tRC = 60.0;
+ parameter tRCD = 18.0;
+ parameter tRFC = 66.0;
+ parameter tXSR = 66.0;
+ parameter tRP = 18.0;
+ parameter tRRD = 12.0;
+ parameter tDPLa = 6.0;
+ parameter tDPLm = 12.0;
+ parameter tDPDX = 100000.0;
+ `endif
+
+ // Timing Parameters for -75 PC133
+ `ifdef S75
+ parameter tAC3 = 6.0;
+ parameter tHZ3 = 6.0;
+ parameter tAC2 = 8.0;
+ parameter tHZ2 = 8.0;
+ parameter tOH = 2.5;
+ parameter tMRD = 2.0;
+ parameter tRAS = 45.0;
+ parameter tRC = 67.5;
+ parameter tRCD = 22.5;
+ parameter tRFC = 67.5;
+ parameter tXSR = 67.5;
+ parameter tRP = 22.5;
+ parameter tRRD = 15.0;
+ parameter tDPLa = 7.5;
+ parameter tDPLm = 15.0;
+ parameter tDPDX = 100000.0;
+ `endif
+
+
+ inout [no_of_data - 1 : 0] dq;
+ input [no_of_addr - 1 : 0] addr;
+ input [no_of_bank - 1 : 0] ba;
+ input clk;
+ input cke;
+ input csb;
+ input rasb;
+ input casb;
+ input web;
+ input [no_of_dqm - 1 : 0] dqm;
+
+`protect
+
+ reg [no_of_data - 1 : 0] bank0 [0 : mem_sizes];
+ reg [no_of_data - 1 : 0] bank1 [0 : mem_sizes];
+ reg [no_of_data - 1 : 0] bank2 [0 : mem_sizes];
+ reg [no_of_data - 1 : 0] bank3 [0 : mem_sizes];
+
+ reg [no_of_bank - 1 : 0] bank_addr [0 : 3]; // bank address Pipeline
+ reg [no_of_col - 1 : 0] Col_addr [0 : 3]; // Column address Pipeline
+ reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline
+ reg [no_of_dqm - 1 : 0] dqm_reg0, dqm_reg1; // DQM Operation Pipeline
+ reg [no_of_dqm - 1 : 0] dqm_save [0 : 3]; // DQM Operation Pipeline
+ reg [no_of_addr - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
+
+ reg [no_of_addr - 1 : 0] Mode_reg;
+ reg [no_of_addr - 1 : 0] EMode_reg;
+ reg [no_of_data - 1 : 0] dq_reg, dq_dqm;
+ reg [no_of_col - 1 : 0] Col_temp, Burst_counter;
+
+ reg Act_b0, Act_b1, Act_b2, Act_b3; // bank Activate
+ reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // bank Precharge
+
+ reg [1 : 0] bank_precharge [0 : 3]; // Precharge Command
+ reg A10_precharge [0 : 3]; // addr[10] = 1 (All banks)
+ reg Auto_precharge [0 : 3]; // RW Auto Precharge (bank)
+ reg Read_precharge [0 : 3]; // R Auto Precharge
+ reg Write_precharge [0 : 3]; // W Auto Precharge
+ reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge
+ reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge
+ reg [1 : 0] RW_interrupt_bank; // RW Interrupt bank
+ integer RW_interrupt_counter [0 : 3]; // RW Interrupt Counter
+ integer Count_precharge [0 : 3]; // RW Auto Precharge Counter
+
+ reg Data_in_enable;
+ reg Data_out_enable;
+
+ reg [no_of_bank - 1 : 0] bank, Prev_bank;
+ reg [no_of_addr - 1 : 0] Row;
+ reg [no_of_col - 1 : 0] Col, Col_brst;
+
+ reg [19:0] ccc;
+ reg [3:0] bit;
+ reg [2:0] CL;
+ reg [8:0] BL;
+ reg RIW_violate;
+ reg Dout_Drive_Flag;
+ reg Pre_Dout_Drive_Flag;
+ reg [10:0] Count_at_Read;
+ reg Read_cmd_received;
+ reg Read_cmd_received_cke;
+ reg Write_cmd_received_cke;
+ reg state_act_pwrdn,state_pre_pwrdn,state_dpdn,state_self;
+ reg dpdn_check_start;
+ reg [10:0] Read_cmd_count;
+ reg [10:0] Read_cmd_count_cke;
+ reg [10:0] Write_cmd_count_cke;
+ reg [3:0] cmp_count;
+ // Internal system clock
+ reg ckeZ, Sys_clk;
+
+ // Commands Decode
+ wire Active_enable = ~csb & ~rasb & casb & web ;
+ wire Aref_enable = ~csb & ~rasb & ~casb & web & cke;
+ wire Sref_enable = ~csb & ~rasb & ~casb & web & ~cke;
+ wire Burst_term = ~csb & rasb & casb & ~web & cke;
+ wire Deep_pwrdn = ~csb & rasb & casb & ~web & ~cke;
+ wire Mode_reg_enable = ~csb & ~rasb & ~casb & ~web & ~ba[1] & ~ba[0];
+ wire EMode_reg_enable = ~csb & ~rasb & ~casb & ~web & ba[1] & ~ba[0];
+ wire Prech_enable = ~csb & ~rasb & casb & ~web ;
+ wire Read_enable = ~csb & rasb & ~casb & web ;
+ wire Write_enable = ~csb & rasb & ~casb & ~web ;
+
+ // Burst Length Decode
+ wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
+ wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0];
+ wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0];
+ wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
+ wire Burst_length_f = Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
+
+ // CAS Latency Decode
+ wire Cas_latency_1 = ~Mode_reg[6] & ~Mode_reg[5] & Mode_reg[4];
+ wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4];
+ wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4];
+
+ // Write Burst Mode
+ wire Write_burst_mode = Mode_reg[9];
+
+`ifdef VERBOSE
+ wire Debug = 1'b1; // Debug messages : 1 = On
+`else
+ wire Debug = 1'b0; // Debug messages : 1 = On
+`endif
+
+ wire dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ
+
+ // CKE function
+ wire clk_suspend_write= (Act_b0 | Act_b1 | Act_b2 | Act_b3) & Write_cmd_received_cke;
+ wire clk_suspend_read = (Act_b0 | Act_b1 | Act_b2 | Act_b3) & Read_cmd_received_cke;
+ wire act_pwrdn = (Act_b0 | Act_b1 | Act_b2 | Act_b3) & (~Read_cmd_received_cke & ~Write_cmd_received_cke);
+ wire pch_pwrdn = (Pc_b0 & Pc_b1 & Pc_b2 & Pc_b3) & (~Read_cmd_received_cke | ~Write_cmd_received_cke);
+
+ assign dq = dq_reg; // DQ buffer
+
+ // Commands Operation
+ `define ACT 0
+ `define NOP 1
+ `define READ 2
+ `define WRITE 3
+ `define PRECH 4
+ `define A_REF 5
+ `define BST 6
+ `define LMR 7
+
+ // Timing Check variable
+ real MRD_chk;
+ real WR_chkm0, WR_chkm1, WR_chkm2, WR_chkm3;
+ real RFC_chk, RRD_chk;
+ real RC_chk0, RC_chk1, RC_chk2, RC_chk3 ;
+ real RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 ;
+ real RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 ;
+ real RP_chk0, RP_chk1, RP_chk2, RP_chk3 ;
+ real SELF_chk, DPDN_chk ;
+
+ initial begin
+ mem_init;
+ dq_reg = {no_of_data{1'bz}};
+ Data_in_enable = 0; Data_out_enable = 0;
+ Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1;
+ Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0;
+ WR_chkm0 = 0; WR_chkm1 = 0; WR_chkm2 = 0; WR_chkm3 = 0;
+ RW_interrupt_read[0] = 0; RW_interrupt_read[1] = 0; RW_interrupt_read[2] = 0; RW_interrupt_read[3] = 0;
+ RW_interrupt_write[0] = 0; RW_interrupt_write[1] = 0; RW_interrupt_write[2] = 0; RW_interrupt_write[3] = 0;
+ MRD_chk = 0; RFC_chk = 0; RRD_chk = 0;
+ RAS_chk0 = 0; RAS_chk1 = 0; RAS_chk2 = 0; RAS_chk3 = 0;
+ RCD_chk0 = 0; RCD_chk1 = 0; RCD_chk2 = 0; RCD_chk3 = 0;
+ RC_chk0 = 0; RC_chk1 = 0; RC_chk2 = 0; RC_chk3 = 0;
+ RP_chk0 = 0; RP_chk1 = 0; RP_chk2 = 0; RP_chk3 = 0;
+ SELF_chk = 0; DPDN_chk = 0;
+ Read_cmd_received=0;
+ Read_cmd_count=0;
+ Read_cmd_received_cke=0;
+ Read_cmd_count_cke=0;
+ Write_cmd_received_cke=0;
+ Write_cmd_count_cke=0;
+ state_act_pwrdn=0;
+ state_pre_pwrdn=0;
+ state_dpdn=0;
+ state_self=0;
+ dpdn_check_start=0;
+ EMode_reg=0;
+ Mode_reg=0;
+ Count_at_Read=0;
+
+ $timeformat (-9, 2, " ns", 12);
+ end
+
+ // System clock generator
+ always begin
+ @ (posedge clk) begin
+ Sys_clk = ckeZ;
+ ckeZ = cke;
+ end
+ @ (negedge clk) begin
+ Sys_clk = 1'b0;
+ end
+ end
+
+ always @ (posedge clk) begin
+ // CKE Exit
+ if (cke === 1'b1) begin
+ if (state_self === 1'b1) begin
+ state_self = 1'b0;
+ SELF_chk=$realtime;
+ if (Debug) $display ("Time = %t : OPERATION = SREFX : Self Refresh exit", $realtime);
+ end else if (state_dpdn == 1'b1) begin
+ state_dpdn = 1'b0;
+ DPDN_chk=$realtime;
+ if (Debug) $display ("Time = %t : OPERATION = DPDNX : Deep Powerdown exit", $realtime);
+ end else if (state_act_pwrdn == 1'b1) begin
+ state_act_pwrdn = 1'b0;
+ if (Debug) $display ("Time = %t : OPERATION = APDNX : Active Power down exit", $realtime);
+ end else if (state_pre_pwrdn == 1'b1) begin
+ state_pre_pwrdn = 1'b0;
+ if (Debug) $display ("Time = %t : OPERATION = PPDNX : Precharge Power down exit", $realtime);
+ end
+ end
+ end
+
+
+ always @ (Dout_Drive_Flag) begin
+
+ if(Cas_latency_2 ==1) begin
+
+ Pre_Dout_Drive_Flag <= #tHZ2 Dout_Drive_Flag;
+
+ end else if(Cas_latency_3 ==1) begin
+
+ Pre_Dout_Drive_Flag <= #tHZ3 Dout_Drive_Flag;
+
+ end
+
+ end
+
+
+
+
+ always @ (posedge Sys_clk) begin
+ // Internal Commamd Pipelined
+ Command[0] = Command[1];
+ Command[1] = Command[2];
+ Command[2] = Command[3];
+ Command[3] = `NOP;
+
+ Col_addr[0] = Col_addr[1];
+ Col_addr[1] = Col_addr[2];
+ Col_addr[2] = Col_addr[3];
+ Col_addr[3] = {no_of_col{1'b0}};
+
+ bank_addr[0] = bank_addr[1];
+ bank_addr[1] = bank_addr[2];
+ bank_addr[2] = bank_addr[3];
+ bank_addr[3] = 2'b00;
+
+ bank_precharge[0] = bank_precharge[1];
+ bank_precharge[1] = bank_precharge[2];
+ bank_precharge[2] = bank_precharge[3];
+ bank_precharge[3] = 2'b00;
+
+ A10_precharge[0] = A10_precharge[1];
+ A10_precharge[1] = A10_precharge[2];
+ A10_precharge[2] = A10_precharge[3];
+ A10_precharge[3] = 1'b0;
+
+ // dqm pipeline for Read
+ dqm_reg0 = dqm_reg1;
+ dqm_reg1 = dqm;
+
+ dqm_save[3]=dqm_save[2];
+ dqm_save[2]=dqm_save[1];
+ dqm_save[1]=dqm_save[0];
+ dqm_save[0]=dqm;
+
+
+ if (Read_cmd_received == 1'b1) begin
+ Read_cmd_count = Read_cmd_count + 1;
+ end
+ else begin
+ Read_cmd_count = 4'b0;
+ end
+ //if (Read_cmd_count == (BL+CL+1)) begin
+ if (Read_cmd_count == Count_at_Read+(BL+CL+1)) begin
+ Read_cmd_received = 1'b0;
+ end
+
+ // Count for CKE
+ if (Read_cmd_received_cke == 1'b1) begin
+ Read_cmd_count_cke = Read_cmd_count_cke + 1;
+ end
+ else begin
+ Read_cmd_count_cke = 4'b0;
+ end
+ if (Read_cmd_count_cke == (BL+CL-1)) begin
+ Read_cmd_received_cke = 1'b0;
+ end
+
+ // Count for CKE
+ if (Write_cmd_received_cke == 1'b1) begin
+ Write_cmd_count_cke = Write_cmd_count_cke + 1;
+ end
+ else begin
+ Write_cmd_count_cke = 4'b0;
+ end
+ if (Write_cmd_count_cke == BL) begin
+ Write_cmd_received_cke = 1'b0;
+ end
+
+
+
+ // Read or Write with Auto Precharge Counter
+ if (Auto_precharge[0] === 1'b1) begin
+ Count_precharge[0] = Count_precharge[0] + 1;
+ end
+ if (Auto_precharge[1] === 1'b1) begin
+ Count_precharge[1] = Count_precharge[1] + 1;
+ end
+ if (Auto_precharge[2] === 1'b1) begin
+ Count_precharge[2] = Count_precharge[2] + 1;
+ end
+ if (Auto_precharge[3] === 1'b1) begin
+ Count_precharge[3] = Count_precharge[3] + 1;
+ end
+
+ // Read or Write Interrupt Counter
+ if (RW_interrupt_write[0] === 1'b1) begin
+ RW_interrupt_counter[0] = RW_interrupt_counter[0] + 1;
+ end
+ if (RW_interrupt_write[1] === 1'b1) begin
+ RW_interrupt_counter[1] = RW_interrupt_counter[1] + 1;
+ end
+ if (RW_interrupt_write[2] === 1'b1) begin
+ RW_interrupt_counter[2] = RW_interrupt_counter[2] + 1;
+ end
+ if (RW_interrupt_write[3] === 1'b1) begin
+ RW_interrupt_counter[3] = RW_interrupt_counter[3] + 1;
+ end
+
+ // tMRD Counter
+ MRD_chk = MRD_chk + 1;
+
+ // Auto Refresh
+ if (Aref_enable === 1'b1) begin
+ if (Debug) begin
+ //$display ("%m : at time %t AREF : Auto Refresh", $realtime);
+ $display ("Time = %t : OPERATION = AREF : Auto Refresh", $realtime);
+ end
+
+ // DPDXN to Auto Refresh
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to AREF)", $realtime);
+ end
+
+ // Self exit to Auto Refresh
+ if ($realtime - SELF_chk < tXSR) begin
+ $display ("Time = %t : ERROR : tXSR violation(SREFX to AREF)", $realtime);
+ end
+
+ // Auto Refresh to Auto Refresh
+ if ($realtime - RFC_chk < tRFC) begin
+ //$display ("%m : at time %t ERROR: tRFC violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tRFC violation(AREF to AREF)", $realtime);
+ end
+
+ // Precharge to Auto Refresh
+ if (($realtime - RP_chk0 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE0 to AREF)", $realtime);
+ end
+ if (($realtime - RP_chk1 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE1 to AREF)", $realtime);
+ end
+ if (($realtime - RP_chk2 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE2 to AREF)", $realtime);
+ end
+ if (($realtime - RP_chk3 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE3 to AREF)", $realtime);
+ end
+
+
+ // Precharge to Refresh
+ if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
+ //$display ("%m : at time %t ERROR: All banks must be Precharge before Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : All banks must be Precharged before AREF", $realtime);
+ end
+
+ // Load Mode Register to Auto Refresh
+ if (MRD_chk < tMRD) begin
+ //$display ("%m : at time %t ERROR: tMRD violation during Auto Refresh", $realtime);
+ $display ("Time = %t : ERROR : tMRD violation(MRS to AREF)", $realtime);
+ end
+
+ // Record Current tRFC time
+ RFC_chk = $realtime;
+ end
+
+ // Load Mode Register
+ if (Mode_reg_enable === 1'b1) begin
+ // Register Mode
+ Mode_reg = addr;
+
+ // Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
+ if (Debug) begin
+ //$display ("%m : at time %t LMR : Load Mode Register", $realtime);
+ $display ("Time = %t : OPERATION = MRS : Load Mode Register", $realtime);
+ // CAS Latency
+ case (addr[6 : 4])
+ 3'b010 : $display (" CAS Latency = 2");
+ 3'b011 : $display (" CAS Latency = 3");
+ default : $display (" CAS Latency = Reserved");
+ endcase
+ case (addr[6 : 4])
+ 3'b010 : CL=2;
+ 3'b011 : CL=3;
+ default : CL=3;
+ endcase
+
+ // Burst Length
+ case (addr[2 : 0])
+ 3'b000 : $display (" Burst Length = 1");
+ 3'b001 : $display (" Burst Length = 2");
+ 3'b010 : $display (" Burst Length = 4");
+ 3'b011 : $display (" Burst Length = 8");
+ 3'b111 : $display (" Burst Length = Full");
+ default : $display (" Burst Length = Reserved");
+ endcase
+
+ case (addr[2 : 0])
+ 3'b000 : BL=1;
+ 3'b001 : BL=2;
+ 3'b010 : BL=4;
+ 3'b011 : BL=8;
+ 3'b111 : BL=512;
+ default : BL=4;
+ endcase
+
+
+ // Burst Type
+ if (addr[3] === 1'b0) begin
+ $display (" Burst Type = Sequential");
+ end else if (addr[3] === 1'b1) begin
+ $display (" Burst Type = Interleaved");
+ end else begin
+ $display (" Burst Type = Reserved");
+ end
+
+ // Write Burst Mode
+ if (addr[9] === 1'b0) begin
+ $display (" Write Burst Mode = Programmed Burst Length");
+ end else if (addr[9] === 1'b1) begin
+ $display (" Write Burst Mode = Single Location Access");
+ end else begin
+ $display (" Write Burst Mode = Reserved");
+ end
+ end
+
+ // Precharge to Load Mode Register
+ if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0 ) begin
+ //$display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : all banks must be Precharge before Load Mode Register", $realtime);
+ end
+
+ // Precharge to Load Mode Register
+ if (($realtime - RP_chk0 < tRP) || ($realtime - RP_chk1 < tRP) ||
+ ($realtime - RP_chk2 < tRP) || ($realtime - RP_chk3 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE to MRS)", $realtime);
+ end
+
+ // Auto Refresh to Load Mode Register
+ if ($realtime - RFC_chk < tRFC) begin
+ //$display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tRFC violation(AREF to MRS)", $realtime);
+ end
+
+ // Load Mode Register to Load Mode Register
+ if (MRD_chk < tMRD) begin
+ //$display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tMRD violation(MRS to MRS)", $realtime);
+ end
+
+ // Reset MRD Counter
+ MRD_chk = 0;
+ end
+
+ // Load Extended Mode Register
+ if (EMode_reg_enable === 1'b1) begin
+ // Register Mode
+ EMode_reg = addr;
+
+ // Decode Driver Strength, Maximum Case Temp, Self Refresh Coverage
+ if (Debug) begin
+ //$display ("%m : at time %t LMR : Load Mode Register", $realtime);
+ $display ("Time = %t : OPERATION = EMRS : Load Extended Mode Register", $realtime);
+ // Driver Strength
+ case (addr[6 : 5])
+ 2'b00 : $display (" Driver Strength = Full");
+ 2'b01 : $display (" Driver Strength = 1/2");
+ 2'b10 : $display (" Driver Strength = 1/4");
+ 2'b11 : $display (" Driver Strength = 1/8");
+ default : $display (" Driver Strength = Reserved");
+ endcase
+
+ // Self Refresh Coverage
+ case (addr[2 : 0])
+ 3'b000 : $display (" Self Refresh Coverage = All Banks");
+ 3'b001 : $display (" Self Refresh Coverage = TWO Bank");
+ 3'b010 : $display (" Self Refresh Coverage = One Bank");
+ 3'b101 : $display (" Self Refresh Coverage = Half of one Banks");
+ 3'b110 : $display (" Self Refresh Coverage = Quater of one Banks");
+ default : $display (" Self Refresh Coverage = Reserved");
+ endcase
+
+ end
+
+ // Precharge to Load Mode Register
+ if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0) begin
+ //$display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : all banks must be Precharge before Load Mode Register", $realtime);
+ end
+
+ // Precharge to Load Mode Register
+ if (($realtime - RP_chk0 < tRP) || ($realtime - RP_chk1 < tRP) ||
+ ($realtime - RP_chk2 < tRP) || ($realtime - RP_chk3 < tRP)) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE to EMRS)", $realtime);
+ end
+
+ // Auto Refresh to Load Mode Register
+ if ($realtime - RFC_chk < tRFC) begin
+ //$display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tRFC violation(AREF to EMRS)", $realtime);
+ end
+
+ // Load Mode Register to Load Mode Register
+ if (MRD_chk < tMRD) begin
+ //$display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $realtime);
+ $display ("Time = %t : ERROR : tMRD violation(MRS to EMRS)", $realtime);
+ end
+
+ // Reset MRD Counter
+ MRD_chk = 0;
+ end
+
+ // Active Block (Latch bank address and Row address)
+ if (Active_enable === 1'b1) begin
+ // Activate an open bank can corrupt data
+ if ((ba === 2'b00 && Act_b0 === 1'b1) || (ba === 2'b01 && Act_b1 === 1'b1) ||
+ (ba === 2'b10 && Act_b2 === 1'b1) || (ba === 2'b11 && Act_b3 === 1'b1)) begin
+ //$display ("%m : at time %t ERROR: bank already activated -- data can be corrupted", $realtime);
+ $display ("Time = %t : ERROR : bank already activated -- data could be corrupted", $realtime);
+ // $display ("Time = %t : Bank = %d, Act_b0 = %d, Act_b2 = %d", $realtime, ba, Act_b0, Act_b2);
+ end
+
+ // Activate bank 0
+ if (ba === 2'b00 && Pc_b0 === 1'b1) begin
+ // Debug Message
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 0 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = ACT : bank = 0 Row = 'h%h", $realtime, addr);
+ end
+
+ // Self exit to ACTIVE
+ if ($realtime - SELF_chk < tXSR) begin
+ $display ("Time = %t : ERROR : tXSR violation(SREFX to ACT0)", $realtime);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to ACT0)", $realtime);
+ end
+
+ // ACTIVE to ACTIVE command period
+ if ($realtime - RC_chk0 < tRC) begin
+ //$display ("%m : at time %t ERROR: tRC violation during Activate bank 0", $realtime);
+ $display ("Time = %t : ERROR : tRC violation (ACT0 to ACT0) ", $realtime);
+ end
+
+ // Precharge to Activate bank 0
+ if ($realtime - RP_chk0 < tRP) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Activate bank 0", $realtime);
+ $display ("Time = %t : ERROR : tRP violation (PRECHARGE0 to PRECHARGE0) ", $realtime);
+ end
+
+ // Record variables
+ Act_b0 = 1'b1;
+ Pc_b0 = 1'b0;
+ B0_row_addr = addr [no_of_addr - 1 : 0];
+ RAS_chk0 = $realtime;
+ RC_chk0 = $realtime;
+ RCD_chk0 = $realtime;
+ end
+
+ // Activate bank 1
+ if (ba === 2'b01 && Pc_b1 === 1'b1) begin
+ // Debug Message
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 1 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = ACT : bank = 1 Row = 'h%h", $realtime, addr);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to ACT1)", $realtime);
+ end
+
+ // Self exit to ACTIVE
+ if ($realtime - SELF_chk < tXSR) begin
+ $display ("Time = %t : ERROR : tXSR violation(SREFX to ACT1)", $realtime);
+ end
+
+ // ACTIVE to ACTIVE command period
+ if ($realtime - RC_chk1 < tRC) begin
+ //$display ("%m : at time %t ERROR: tRC violation during Activate bank 1", $realtime);
+ $display ("Time = %t : ERROR : tRC violation (ACT1 to ACT1) ", $realtime);
+ end
+
+ // Precharge to Activate bank 1
+ if ($realtime - RP_chk1 < tRP) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Activate bank 1", $realtime);
+ $display ("Time = %t : ERROR : tRP violation (PRECHARGE1 to PRECHARGE1) ", $realtime);
+ end
+
+ // Record variables
+ Act_b1 = 1'b1;
+ Pc_b1 = 1'b0;
+ B1_row_addr = addr [no_of_addr - 1 : 0];
+ RAS_chk1 = $realtime;
+ RC_chk1 = $realtime;
+ RCD_chk1 = $realtime;
+ end
+
+ // Activate bank 2
+ if (ba === 2'b10 && Pc_b2 === 1'b1) begin
+ // Debug Message
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 2 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = ACT : bank = 2 Row = 'h%h", $realtime, addr);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to ACT2)", $realtime);
+ end
+
+ // Self exit to ACTIVE
+ if ($realtime - SELF_chk < tXSR) begin
+ $display ("Time = %t : ERROR : tXSR violation(SREFX to ACT2)", $realtime);
+ end
+
+ // ACTIVE to ACTIVE command period
+ if ($realtime - RC_chk2 < tRC) begin
+ //$display ("%m : at time %t ERROR: tRC violation during Activate bank 2", $realtime);
+ $display ("Time = %t : ERROR : tRC violation (ACT2 to ACT2) ", $realtime);
+ end
+
+ // Precharge to Activate bank 2
+ if ($realtime - RP_chk2 < tRP) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Activate bank 2", $realtime);
+ $display ("Time = %t : ERROR : tRP violation (PRECHARGE2 to PRECHARGE2) ", $realtime);
+ end
+
+ // Record variables
+ Act_b2 = 1'b1;
+ Pc_b2 = 1'b0;
+ B2_row_addr = addr [no_of_addr - 1 : 0];
+ RAS_chk2 = $realtime;
+ RC_chk2 = $realtime;
+ RCD_chk2 = $realtime;
+ end
+
+ // Activate bank 3
+ if (ba === 2'b11 && Pc_b3 === 1'b1) begin
+ // Debug Message
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 3 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = ACT : bank = 3 Row = 'h%h", $realtime, addr);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to ACT3)", $realtime);
+ end
+
+ // Self exit to ACTIVE
+ if ($realtime - SELF_chk < tXSR) begin
+ $display ("Time = %t : ERROR : tXSR violation(SREFX to ACT3)", $realtime);
+ end
+
+ // ACTIVE to ACTIVE command period
+ if ($realtime - RC_chk3 < tRC) begin
+ //$display ("%m : at time %t ERROR: tRC violation during Activate bank 3", $realtime);
+ $display ("Time = %t : ERROR : tRC violation (ACT1 to ACT3) ", $realtime);
+ end
+
+ // Precharge to Activate bank 3
+ if ($realtime - RP_chk3 < tRP) begin
+ //$display ("%m : at time %t ERROR: tRP violation during Activate bank 3", $realtime);
+ $display ("Time = %t : ERROR : tRP violation (PRECHARGE3 to PRECHARGE3) ", $realtime);
+ end
+
+ // Record variables
+ Act_b3 = 1'b1;
+ Pc_b3 = 1'b0;
+ B3_row_addr = addr [no_of_addr - 1 : 0];
+ RAS_chk3 = $realtime;
+ RC_chk3 = $realtime;
+ RCD_chk3 = $realtime;
+ end
+
+ // Active other bank to Active bank A
+ if ((Prev_bank != ba) && ($realtime - RRD_chk < tRRD) && (ba === 2'b00)) begin
+ //$display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tRRD violation(ACT Others to ACT0) ", $realtime);
+ end
+
+ // Active other bank to Active bank B
+ if ((Prev_bank != ba) && ($realtime - RRD_chk < tRRD) && (ba === 2'b01)) begin
+ //$display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tRRD violation(ACT Others to ACT1) ", $realtime);
+ end
+
+ // Active other bank to Active bank C
+ if ((Prev_bank != ba) && ($realtime - RRD_chk < tRRD) && (ba === 2'b10)) begin
+ //$display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tRRD violation(ACT Others to ACT2) ", $realtime);
+ end
+
+ // Active other bank to Active bank D
+ if ((Prev_bank != ba) && ($realtime - RRD_chk < tRRD) && (ba === 2'b11)) begin
+ //$display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tRRD violation(ACT Others to ACT3) ", $realtime);
+ end
+
+ // Auto Refresh to Activate
+ if ($realtime - RFC_chk < tRFC) begin
+ //$display ("%m : at time %t ERROR: tRFC violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tRFC violation(AREF to ACT)", $realtime);
+ end
+
+ // Load Mode Register to Active
+ if (MRD_chk < tMRD ) begin
+ //$display ("%m : at time %t ERROR: tMRD violation during Activate bank = %d", $realtime, ba);
+ $display ("Time = %t : ERROR : tMRD violation(MRS to ACT)", $realtime);
+ end
+
+ // Record variables for checking violation
+ RRD_chk = $realtime;
+ Prev_bank = ba;
+ end
+
+ // Precharge Block
+ if (Prech_enable == 1'b1) begin
+ // Load Mode Register to Precharge
+ if ($realtime - MRD_chk < tMRD) begin
+ //$display ("%m : at time %t ERROR: tMRD violaiton during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tMRD violation(MRS to PRECHARGE)", $realtime);
+ end
+
+ //Precharge bank 0
+
+ if ((addr[10] === 1'b1 || (addr[10] === 1'b0 && ba === 2'b00)) && Act_b0 === 1'b1) begin
+ Act_b0 = 1'b0;
+ Pc_b0 = 1'b1;
+ RP_chk0 = $realtime;
+
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 0 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = PCHG : bank = 0 ", $realtime);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to PRECHARGE0)", $realtime);
+ end
+
+ // Activate to Precharge
+ if ($realtime - RAS_chk0 < tRAS) begin
+ //$display ("%m : at time %t ERROR: tRAS violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tRAS violation(ACT0 to PRECHARGE0)", $realtime);
+ end
+
+ // tWR violation check for write
+ if ($realtime - WR_chkm0 < tDPLm) begin
+ //$display ("%m : at time %t ERROR: tWR violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tDPL violation(LAST DATA to PRECHARGE0)", $realtime);
+ end
+ end
+
+ // Precharge bank 1
+
+ if ((addr[10] === 1'b1 || (addr[10] === 1'b0 && ba === 2'b01)) && Act_b1 === 1'b1) begin
+ Act_b1 = 1'b0;
+ Pc_b1 = 1'b1;
+ RP_chk1 = $realtime;
+
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 1 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = PCHG : bank = 1 ", $realtime);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to PRECHARGE1)", $realtime);
+ end
+
+ // Activate to Precharge
+ if ($realtime - RAS_chk1 < tRAS) begin
+ //$display ("%m : at time %t ERROR: tRAS violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tRAS violation(ACT1 to PRECHARGE1)", $realtime);
+ end
+
+ // tWR violation check for write
+ if ($realtime - WR_chkm1 < tDPLm) begin
+ //$display ("%m : at time %t ERROR: tWR violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tDPL violation(LAST DATA to PRECHARGE1)", $realtime);
+ end
+ end
+
+ // Precharge bank 2
+
+ if ((addr[10] === 1'b1 || (addr[10] === 1'b0 && ba === 2'b10)) && Act_b2 === 1'b1) begin
+ Act_b2 = 1'b0;
+ Pc_b2 = 1'b1;
+ RP_chk2 = $realtime;
+
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 2 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = PCHG : bank = 2 ", $realtime);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to PRECHARGE2)", $realtime);
+ end
+
+ // Activate to Precharge
+ if ($realtime - RAS_chk2 < tRAS) begin
+ //$display ("%m : at time %t ERROR: tRAS violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tRAS violation(ACT2 to PRECHARGE2)", $realtime);
+ end
+
+ // tWR violation check for write
+ if ($realtime - WR_chkm2 < tDPLm) begin
+ //$display ("%m : at time %t ERROR: tWR violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tDPL violation(LAST DATA to PRECHARGE2)", $realtime);
+ end
+ end
+
+ // Precharge bank 3
+
+ if ((addr[10] === 1'b1 || (addr[10] === 1'b0 && ba === 2'b11)) && Act_b3 === 1'b1) begin
+ Act_b3 = 1'b0;
+ Pc_b3 = 1'b1;
+ RP_chk3 = $realtime;
+
+ if (Debug) begin
+ //$display ("%m : at time %t ACT : bank = 3 Row = %d", $realtime, addr);
+ $display ("Time = %t : OPERATION = PCHG : bank = 3 ", $realtime);
+ end
+
+ // DPDXN to Precharge
+ if (($realtime - DPDN_chk < tDPDX) && (dpdn_check_start)) begin
+ $display ("Time = %t : ERROR : Pwrup violation(DPDX to PRECHARGE3)", $realtime);
+ end
+
+ // Activate to Precharge
+ if ($realtime - RAS_chk3 < tRAS) begin
+ //$display ("%m : at time %t ERROR: tRAS violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tRAS violation(ACT3 to PRECHARGE3)", $realtime);
+ end
+
+ // tWR violation check for write
+ if ($realtime - WR_chkm3 < tDPLm) begin
+ //$display ("%m : at time %t ERROR: tWR violation during Precharge", $realtime);
+ $display ("Time = %t : ERROR : tDPL violation(LAST DATA to PRECHARGE3)", $realtime);
+ end
+ end
+
+
+ // Terminate a Write Immediately (if same bank or all banks)
+ if (Data_in_enable === 1'b1 && (bank === ba || addr[10] === 1'b1)) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Precharge Command Pipeline for Read
+ if (Cas_latency_3 === 1'b1) begin
+ Command[2] = `PRECH;
+ bank_precharge[2] = ba;
+ A10_precharge[2] = addr[10];
+ end else if (Cas_latency_2 === 1'b1) begin
+ Command[1] = `PRECH;
+ bank_precharge[1] = ba;
+ A10_precharge[1] = addr[10];
+ end
+ end
+
+ // Burst terminate
+ if (Burst_term === 1'b1) begin
+ // Terminate a Write Immediately
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Terminate a Read Depend on CAS Latency
+ if (Cas_latency_3 === 1'b1) begin
+ Command[2] = `BST;
+ end else if (Cas_latency_2 == 1'b1) begin
+ Command[1] = `BST;
+ end
+
+ // Display debug message
+ if (Debug) begin
+ //$display ("%m : at time %t BST : Burst Terminate",$realtime);
+ $display ("Time = %t : OPERATION = BST : Burst Stop", $realtime);
+ end
+ end
+
+ // Read, Write, Column Latch
+ if (Read_enable === 1'b1) begin
+
+ Read_cmd_received = 1'b1;
+ Read_cmd_received_cke = 1'b1;
+ //Read_cmd_count = 0;
+ Count_at_Read = Read_cmd_count;
+ Read_cmd_count_cke = 0;
+ Write_cmd_received_cke = 1'b0;
+
+ // Check to see if bank is open (ACT)
+ if ((ba == 2'b00 && Pc_b0 == 1'b1) || (ba == 2'b01 && Pc_b1 == 1'b1) ||
+ (ba == 2'b10 && Pc_b2 == 1'b1) || (ba == 2'b11 && Pc_b3 == 1'b1)) begin
+ //$display("%m : at time %t ERROR: bank is not Activated for Read", $realtime);
+ $display ("Time = %t : ERROR : bank is not Activated for Read", $realtime);
+ end
+
+ // Activate to Read or Write
+ if ((ba == 2'b00) && ($realtime - RCD_chk0 < tRCD) ||
+ (ba == 2'b01) && ($realtime - RCD_chk1 < tRCD) ||
+ (ba == 2'b10) && ($realtime - RCD_chk2 < tRCD) ||
+ (ba == 2'b11) && ($realtime - RCD_chk3 < tRCD)) begin
+ //$display("%m : at time %t ERROR: tRCD violation during Read", $realtime);
+ $display ("Time = %t : ERROR : tRCD violation(ACT to READ)", $realtime);
+ end
+
+ // CAS Latency pipeline
+ if (Cas_latency_3 == 1'b1) begin
+ Command[2] = `READ;
+ Col_addr[2] = addr;
+ bank_addr[2] = ba;
+ end else if (Cas_latency_2 == 1'b1) begin
+ Command[1] = `READ;
+ Col_addr[1] = addr;
+ bank_addr[1] = ba;
+ end
+
+ // Read interrupt Write (terminate Write immediately)
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+
+ // Interrupting a Write with Autoprecharge
+ if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
+ RW_interrupt_write[RW_interrupt_bank] = 1'b1;
+ RW_interrupt_counter[RW_interrupt_bank] = 0;
+
+ // Display debug message
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Read interrupt Write with Autoprecharge", $realtime);
+ $display ("Time = %t : OPERATION = Read interrupt Write with Autoprecharge", $realtime);
+ end
+ end
+ end
+
+ // Read with Auto Precharge
+ if (addr[10] == 1'b1) begin
+ Auto_precharge[ba] = 1'b1;
+ Count_precharge[ba] = 0;
+ RW_interrupt_bank = ba;
+ Read_precharge[ba] = 1'b1;
+ end
+ end
+
+ // Write Command
+ if (Write_enable == 1'b1) begin
+
+ RIW_violate=1'b0;
+ if ((Pre_Dout_Drive_Flag == 1'b1) || (Dout_Drive_Flag == 1'b1)) begin
+ $display ("Time = %t : ERROR : Read and Write Data collision", $realtime);
+ end
+ else if ((Data_out_enable == 1'b1) && (&(dqm_save[1]) != 1'b1)) begin
+ $display ("Time = %t : ERROR : Read and Write Data collision", $realtime);
+ end
+
+
+ Write_cmd_received_cke=1'b1;
+ Read_cmd_received=1'b0;
+ Read_cmd_received_cke=1'b0;
+ Write_cmd_count_cke=1'b0;
+
+ // Activate to Write
+ if ((ba == 2'b00 && Pc_b0 == 1'b1) || (ba == 2'b01 && Pc_b1 == 1'b1) ||
+ (ba == 2'b10 && Pc_b2 == 1'b1) || (ba == 2'b11 && Pc_b3 == 1'b1)) begin
+ //$display("%m : at time %t ERROR: bank is not Activated for Write", $realtime);
+ $display ("Time = %t : ERROR : bank is not Activated for Write", $realtime);
+ end
+
+ if ((ba == 2'b00) && ($realtime - RCD_chk0 < tRCD)) begin
+ $display ("Time = %t : ERROR = %t, %t: tRCD violation(ACT0 to WRITE)", $realtime, RCD_chk0,$realtime-RCD_chk0);
+ end
+ if ((ba == 2'b01) && ($realtime - RCD_chk1 < tRCD)) begin
+ $display ("Time = %t : ERROR = %t, %t: tRCD violation(ACT1 to WRITE)", $realtime, RCD_chk1,$realtime-RCD_chk1);
+ end
+ if ((ba == 2'b10) && ($realtime - RCD_chk2 < tRCD)) begin
+ $display ("Time = %t : ERROR = %t, %t: tRCD violation(ACT2 to WRITE)", $realtime, RCD_chk2,$realtime-RCD_chk2);
+ end
+ if ((ba == 2'b11) && ($realtime - RCD_chk3 < tRCD)) begin
+ $display ("Time = %t : ERROR = %t, %t: tRCD violation(ACT3 to WRITE)", $realtime, RCD_chk3,$realtime-RCD_chk3);
+ end
+
+
+ // Latch Write command, bank, and Column
+ Command[0] = `WRITE;
+ Command[1] = `NOP;
+ Col_addr[0] = addr;
+ bank_addr[0] = ba;
+
+ // Write interrupt Write (terminate Write immediately)
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+
+ // Interrupting a Write with Autoprecharge
+ if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
+ RW_interrupt_write[RW_interrupt_bank] = 1'b1;
+
+ // Display debug message
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Read bank %d interrupt Write bank %d with Autoprecharge", $realtime, ba, RW_interrupt_bank);
+ $display ("Time = %t : OPERATION = Write bank %d interrupt Write bank %d with Autoprecharge", $realtime, ba, RW_interrupt_bank);
+
+ end
+ end
+ end
+
+ // Write interrupt Read (terminate Read immediately)
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+
+ // Interrupting a Read with Autoprecharge
+ if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Read_precharge[RW_interrupt_bank] == 1'b1) begin
+ RW_interrupt_read[RW_interrupt_bank] = 1'b1;
+
+ // Display debug message
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Write bank %d interrupt Read bank %d with Autoprecharge", $realtime, ba, RW_interrupt_bank);
+ $display ("Time = %t : OPERATION = Write bank %d interrupt Read bank %d with Autoprecharge", $realtime, ba, RW_interrupt_bank);
+ end
+ end
+ end
+
+ // Write with Auto Precharge
+ if (addr[10] == 1'b1) begin
+ Auto_precharge[ba] = 1'b1;
+ Count_precharge[ba] = 0;
+ RW_interrupt_bank = ba;
+ Write_precharge[ba] = 1'b1;
+ end
+ end
+
+ /*
+ Write with Auto Precharge Calculation
+ The device start internal precharge when:
+ 1. Meet minimum tRAS requirement
+ and 2. tWR cycle(s) after last valid data
+ or 3. Interrupt by a Read or Write (with or without Auto Precharge)
+
+ Note: Model is starting the internal precharge 1 cycle after they meet all the
+ requirement but tRP will be compensate for the time after the 1 cycle.
+ */
+ if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
+ if ((($realtime - RAS_chk0 >= tRAS) && // Case 1
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 2
+ (Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) ||
+ (RW_interrupt_write[0] == 1'b1 && RW_interrupt_counter[0] >= 1)) begin // Case 3
+ Auto_precharge[0] = 1'b0;
+ Write_precharge[0] = 1'b0;
+ RW_interrupt_write[0] = 1'b0;
+ Pc_b0 = 1'b1;
+ Act_b0 = 1'b0;
+ RP_chk0 = $realtime + tDPLa;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 0", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 0", $realtime+tDPLa);
+ end
+ end
+ end
+ if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
+ if ((($realtime - RAS_chk1 >= tRAS) && // Case 1
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) || // Case 2
+ (Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) ||
+ (RW_interrupt_write[1] == 1'b1 && RW_interrupt_counter[1] >= 1)) begin // Case 3
+ Auto_precharge[1] = 1'b0;
+ Write_precharge[1] = 1'b0;
+ RW_interrupt_write[1] = 1'b0;
+ Pc_b1 = 1'b1;
+ Act_b1 = 1'b0;
+ RP_chk1 = $realtime + tDPLa;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 1", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 1", $realtime+tDPLa);
+ end
+ end
+ end
+ if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
+ if ((($realtime - RAS_chk2 >= tRAS) && // Case 1
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) || // Case 2
+ (Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) ||
+ (RW_interrupt_write[2] == 1'b1 && RW_interrupt_counter[2] >= 1)) begin // Case 3
+ Auto_precharge[2] = 1'b0;
+ Write_precharge[2] = 1'b0;
+ RW_interrupt_write[2] = 1'b0;
+ Pc_b2 = 1'b1;
+ Act_b2 = 1'b0;
+ RP_chk2 = $realtime + tDPLa;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 2", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 2", $realtime+tDPLa);
+ end
+ end
+ end
+ if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
+ if ((($realtime - RAS_chk3 >= tRAS) && // Case 1
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) || // Case 2
+ (Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) ||
+ (RW_interrupt_write[3] == 1'b1 && RW_interrupt_counter[3] >= 1)) begin // Case 3
+ Auto_precharge[3] = 1'b0;
+ Write_precharge[3] = 1'b0;
+ RW_interrupt_write[3] = 1'b0;
+ Pc_b3 = 1'b1;
+ Act_b3 = 1'b0;
+ RP_chk3 = $realtime + tDPLa;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 3", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 3", $realtime+tDPLa);
+ end
+ end
+ end
+
+ // Read with Auto Precharge Calculation
+ // The device start internal precharge:
+ // 1. Meet minimum tRAS requirement
+ // and 2. CAS Latency - 1 cycles before last burst
+ // or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
+ if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
+ if ((($realtime - RAS_chk0 >= tRAS) && // Case 1
+ ((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 2
+ (Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
+ (RW_interrupt_read[0] == 1'b1)) begin // Case 3
+ Pc_b0 = 1'b1;
+ Act_b0 = 1'b0;
+ RP_chk0 = $realtime;
+ Auto_precharge[0] = 1'b0;
+ Read_precharge[0] = 1'b0;
+ RW_interrupt_read[0] = 1'b0;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 0", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 0", $realtime);
+ end
+ end
+ end
+ if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
+ if ((($realtime - RAS_chk1 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
+ (RW_interrupt_read[1] == 1'b1)) begin
+ Pc_b1 = 1'b1;
+ Act_b1 = 1'b0;
+ RP_chk1 = $realtime;
+ Auto_precharge[1] = 1'b0;
+ Read_precharge[1] = 1'b0;
+ RW_interrupt_read[1] = 1'b0;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 1", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 1", $realtime);
+ end
+ end
+ end
+ if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
+ if ((($realtime - RAS_chk2 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
+ (RW_interrupt_read[2] == 1'b1)) begin
+ Pc_b2 = 1'b1;
+ Act_b2 = 1'b0;
+ RP_chk2 = $realtime;
+ Auto_precharge[2] = 1'b0;
+ Read_precharge[2] = 1'b0;
+ RW_interrupt_read[2] = 1'b0;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 2", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 2", $realtime);
+ end
+ end
+ end
+ if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
+ if ((($realtime - RAS_chk3 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
+ (RW_interrupt_read[3] == 1'b1)) begin
+ Pc_b3 = 1'b1;
+ Act_b3 = 1'b0;
+ RP_chk3 = $realtime;
+ Auto_precharge[3] = 1'b0;
+ Read_precharge[3] = 1'b0;
+ RW_interrupt_read[3] = 1'b0;
+ if (Debug) begin
+ //$display ("%m : at time %t NOTE : Start Internal Auto Precharge for bank 3", $realtime);
+ $display ("Time = %t : OPERATION = Start Internal Auto Precharge for bank 3", $realtime);
+ end
+ end
+ end
+
+ // CKE Function
+ if (cke === 1'b0) begin
+ if (Sref_enable === 1'b1) begin
+ state_self = 1'b1;
+ if (Debug) begin
+ $display ("Time = %t : OPERATION = SREF : Self Refresh", $realtime);
+ if (EMode_reg[2:0]==3'b000) $display (" Refresh Full Bank");
+
+ if (EMode_reg[2:0]==3'b001) begin
+ $display (" Refresh Only TWO Bank");
+ abbank_init;
+ end
+
+ if (EMode_reg[2:0]==3'b010) begin
+ $display (" Refresh Only One Bank(BANK A)");
+ bbank_init;
+ end
+ if (EMode_reg[2:0]==3'b101) begin
+ $display (" Refresh Only half of one Bank(BANK A, A10=0)");
+ half_init;
+ end
+ if (EMode_reg[2:0]==3'b110) begin
+ $display (" Refresh Only Quarter of one Bank(BANK A, A10=0)");
+ quat_init;
+ end
+ end
+
+ // Precharge to Auto Refresh
+ if (($realtime - RP_chk0 < tRP) || ($realtime - RP_chk1 < tRP) ||
+ ($realtime - RP_chk2 < tRP) || ($realtime - RP_chk3 < tRP))
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE to SREF)", $realtime);
+
+ // Precharge to Refresh
+ if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0)
+ $display ("Time = %t : ERROR : All banks must be Precharged before SREF", $realtime);
+
+ // Load Mode Register to Self Refresh
+ if (MRD_chk < tMRD)
+ $display ("Time = %t : ERROR : tMRD violation(MRS to SREF)", $realtime);
+
+ end else if (Deep_pwrdn == 1'b1) begin
+ state_dpdn = 1'b1;
+ dpdn_check_start = 1'b1;
+ Act_b0 = 0; Act_b1 = 0; Act_b2 = 0; Act_b3 = 0;
+ Pc_b0 = 1; Pc_b1 = 1; Pc_b2 = 1; Pc_b3 = 1;
+ mem_init;
+ if (Debug) $display ("Time = %t : OPERATION = DPDN : Deep Powerdown", $realtime);
+
+ // Precharge to Auto Refresh
+ if (($realtime - RP_chk0 < tRP) || ($realtime - RP_chk1 < tRP) ||
+ ($realtime - RP_chk2 < tRP) || ($realtime - RP_chk3 < tRP))
+ $display ("Time = %t : ERROR : tRP violation(PRECHARGE to DPDN)", $realtime);
+
+ // Precharge to Refresh
+ if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0)
+ $display ("Time = %t : ERROR : All banks must be Precharged before DPDN", $realtime);
+
+ end else if (act_pwrdn == 1'b1) begin
+ state_act_pwrdn = 1'b1;
+ if (Debug) $display ("Time = %t : OPERATION = APDN : Active Power down", $realtime);
+ end else if (pch_pwrdn == 1'b1) begin
+ state_pre_pwrdn = 1'b1;
+ if (Debug) $display ("Time = %t : OPERATION = PPDN : Precharge Power down", $realtime);
+ end else if (clk_suspend_write == 1'b1) begin
+ if (Debug) $display ("Time = %t : OPERATION = CKSW : Clock Suspend during Write", $realtime);
+ end else if (clk_suspend_read == 1'b1) begin
+ if (Debug) $display ("Time = %t : OPERATION = CKSR : Clock Suspend during Read", $realtime);
+ end
+ end
+
+ // Internal Precharge or Bst
+ if (Command[0] == `PRECH) begin // Precharge terminate a read with same bank or all banks
+ if (bank_precharge[0] == bank || A10_precharge[0] == 1'b1) begin
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+ end
+ end
+ end else if (Command[0] == `BST) begin // BST terminate a read to current bank
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+ end
+ end
+
+ if (Data_out_enable == 1'b0) begin
+ dq_reg <= #tOH {no_of_data{1'bz}};
+ Dout_Drive_Flag <= #tOH 1'b0;
+ end
+
+ // Detect Read or Write command
+ if (Command[0] == `READ) begin
+ bank = bank_addr[0];
+ Col = Col_addr[0];
+ Col_brst = Col_addr[0];
+ case (bank_addr[0])
+ 2'b00 : Row = B0_row_addr;
+ 2'b01 : Row = B1_row_addr;
+ 2'b10 : Row = B2_row_addr;
+ 2'b11 : Row = B3_row_addr;
+
+ endcase
+ Burst_counter = 0;
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b1;
+ end else if (Command[0] == `WRITE) begin
+ bank = bank_addr[0];
+ Col = Col_addr[0];
+ Col_brst = Col_addr[0];
+ case (bank_addr[0])
+ 2'b00 : Row = B0_row_addr;
+ 2'b01 : Row = B1_row_addr;
+ 2'b10 : Row = B2_row_addr;
+ 2'b11 : Row = B3_row_addr;
+ endcase
+ Burst_counter = 0;
+ Data_in_enable = 1'b1;
+ Data_out_enable = 1'b0;
+ end
+
+ // DQ buffer (Driver/Receiver)
+ if (Data_in_enable == 1'b1) begin // Writing Data to Memory
+ // Array buffer
+ case (bank)
+ 2'b00 : dq_dqm = bank0 [{Row, Col}];
+ 2'b01 : dq_dqm = bank1 [{Row, Col}];
+ 2'b10 : dq_dqm = bank2 [{Row, Col}];
+ 2'b11 : dq_dqm = bank3 [{Row, Col}];
+ endcase
+
+ // dqm operation
+ if (dqm[0] == 1'b0) begin
+ dq_dqm [ 7 : 0] = dq [ 7 : 0 ] & dq [ 7 : 0 ];
+ end
+ if (dqm[1] == 1'b0) begin
+ dq_dqm [15 : 8] = dq [15 : 8] & dq [15 : 8];
+ end
+
+
+
+ // Write to memory
+ case (bank)
+ 2'b00 : bank0 [{Row, Col}] = dq_dqm;
+ 2'b01 : bank1 [{Row, Col}] = dq_dqm;
+ 2'b10 : bank2 [{Row, Col}] = dq_dqm;
+ 2'b11 : bank3 [{Row, Col}] = dq_dqm;
+ endcase
+
+ // Display debug message
+ if (dqm !== 2'b11) begin
+ // Record tWR for manual precharge
+ if (bank == 2'b00) WR_chkm0 = $realtime;
+ if (bank == 2'b01) WR_chkm1 = $realtime;
+ if (bank == 2'b10) WR_chkm2 = $realtime;
+ if (bank == 2'b11) WR_chkm3 = $realtime;
+
+ if (Debug) begin
+ //$display("%m : at time %t WRITE: bank = %d Row = %d, Col = %d, Data = %d", $realtime, bank, Row, Col, dq_dqm);
+ $display ("Time = %t : OPERATION = WRITE : bank = %d Row = 'h%h, Col = 'h%h, Data = 'h%h", $realtime, bank, Row, Col, dq_dqm);
+ end
+ end else begin
+ if (Debug) begin
+ //$display("%m : at time %t WRITE: bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+ $display ("Time = %t : OPERATION = WRITE : bank = %d Row = 'h%h, Col = 'h%h, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+ end
+ end
+
+ // Advance burst counter subroutine
+
+ if(Cas_latency_2 == 1) begin
+
+ #tHZ2 Burst_decode;
+
+ end else if(Cas_latency_3 == 1) begin
+
+ #tHZ3 Burst_decode;
+
+ end
+
+
+ end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory
+ // Array buffer
+ case (bank)
+ 2'b00 : dq_dqm = bank0[{Row, Col}];
+ 2'b01 : dq_dqm = bank1[{Row, Col}];
+ 2'b10 : dq_dqm = bank2[{Row, Col}];
+ 2'b11 : dq_dqm = bank3[{Row, Col}];
+ endcase
+
+
+ // dqm operation
+ if (dqm_reg0 [0] == 1'b1) begin
+ dq_dqm [ 7 : 0] = 8'bz;
+ end
+ if (dqm_reg0 [1] == 1'b1) begin
+ dq_dqm [15 : 8] = 8'bz;
+ end
+
+ if(Cas_latency_2 ==1) begin
+
+ // Display debug message
+ if ( &(dqm_reg0) != 1'b1) begin
+ dq_reg = #tAC2 dq_dqm;
+ Dout_Drive_Flag = 1'b1;
+ if (Debug) begin
+ //$display("%m : at time %t READ : bank = %d Row = %d, Col = %d, Data = %d", $realtime, bank, Row, Col, dq_reg);
+ $display ("Time = %t : OPERATION = READ : bank = %d Row = 'h%h, Col = 'h%h, Data = 'h%h", $realtime, bank, Row, Col, dq_reg);
+ end
+ end else begin
+ dq_reg = #tHZ2 {no_of_data{1'bz}};
+ Dout_Drive_Flag = 1'b0;
+ if (Debug) begin
+ //$display("%m : at time %t READ : bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+ $display ("Time = %t : OPERATION = READ : bank = %d Row = 'h%h, Col = 'h%h, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+
+ end
+ end
+
+ end else if(Cas_latency_3 ==1) begin
+
+ // Display debug message
+ if ( &(dqm_reg0) != 1'b1) begin
+ dq_reg = #tAC3 dq_dqm;
+ Dout_Drive_Flag = 1'b1;
+ if (Debug) begin
+ //$display("%m : at time %t READ : bank = %d Row = %d, Col = %d, Data = %d", $realtime, bank, Row, Col, dq_reg);
+ $display ("Time = %t : OPERATION = READ : bank = %d Row = 'h%h, Col = 'h%h, Data = 'h%h", $realtime, bank, Row, Col, dq_reg);
+ end
+ end else begin
+ dq_reg = #tHZ3 {no_of_data{1'bz}};
+ Dout_Drive_Flag = 1'b0;
+ if (Debug) begin
+ //$display("%m : at time %t READ : bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+ $display ("Time = %t : OPERATION = READ : bank = %d Row = 'h%h, Col = 'h%h, Data = Hi-Z due to DQM", $realtime, bank, Row, Col);
+
+ end
+ end
+
+ end
+
+ // Advance burst counter subroutine
+ Burst_decode;
+ end
+ end
+
+ // Burst counter decode
+ task Burst_decode;
+ begin
+ // Advance Burst Counter
+ Burst_counter = Burst_counter + 1;
+
+ // Burst Type
+ if (Mode_reg[3] == 1'b0) begin // Sequential Burst
+ Col_temp = Col + 1;
+ end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst
+ Col_temp[2] = Burst_counter[2] ^ Col_brst[2];
+ Col_temp[1] = Burst_counter[1] ^ Col_brst[1];
+ Col_temp[0] = Burst_counter[0] ^ Col_brst[0];
+ end
+
+ // Burst Length
+ if (Burst_length_2) begin // Burst Length = 2
+ Col [0] = Col_temp [0];
+ end else if (Burst_length_4) begin // Burst Length = 4
+ Col [1 : 0] = Col_temp [1 : 0];
+ end else if (Burst_length_8) begin // Burst Length = 8
+ Col [2 : 0] = Col_temp [2 : 0];
+ end else begin // Burst Length = FULL
+ Col = Col_temp;
+ end
+
+ // Burst Read Single Write
+ if (Write_burst_mode == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Data Counter
+ if (Burst_length_1 == 1'b1) begin
+ if (Burst_counter >= 1) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_2 == 1'b1) begin
+ if (Burst_counter >= 2) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_4 == 1'b1) begin
+ if (Burst_counter >= 4) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_8 == 1'b1) begin
+ if (Burst_counter >= 8) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end
+ end
+ endtask
+
+ task mem_init;
+ begin
+ for (ccc=0;ccc<'b1000_0000_0000_0000_0000;ccc=ccc+1)
+ begin
+ bank0[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ bank1[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ bank2[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ bank3[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ //bank0[ccc]=16'b1111_1111_1111_1111;
+ //bank1[ccc]=16'b1111_1111_1111_1111;
+ end
+ end
+ endtask
+
+ task abbank_init;
+ begin
+ for (ccc=0;ccc<'b1000_0000_0000_0000_0000;ccc=ccc+1)
+ begin
+ bank0[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ bank1[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ end
+ end
+ endtask
+
+
+ task bbank_init;
+ begin
+ for (ccc=0;ccc<'b1000_0000_0000_0000_0000;ccc=ccc+1)
+ begin
+ bank1[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ end
+ end
+ endtask
+
+ task half_init;
+ begin
+ bbank_init;
+ for (ccc='b0100_0000_0000_0000_0000;ccc<'b1000_0000_0000_0000_0000;ccc=ccc+1)
+ begin
+ bank0[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ end
+ end
+ endtask
+
+ task quat_init;
+ begin
+ bbank_init;
+ for (ccc='b0010_0000_0000_0000_0000;ccc<'b1000_0000_0000_0000_0000;ccc=ccc+1)
+ begin
+ bank0[ccc]=32'bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx;
+ end
+ end
+ endtask
+`endprotect
+
+ // Timing Parameters
+ specify
+ specparam
+ `ifdef S50
+ tAH = 1.0, // addr, ba Hold Time
+ tAS = 1.5, // addr, ba Setup Time
+ tCH = 2.5, // Clock High-Level Width
+ tCL = 2.5, // Clock Low-Level Width
+ tCK = 5.0, // Clock Cycle Time
+ tDH = 1.0, // Data-in Hold Time
+ tDS = 1.5, // Data-in Setup Time
+ tCKH = 1.0, // CKE Hold Time
+ tCKS = 1.5, // CKE Setup Time
+ tCMH = 1.0, // CSB, RASB, CASB, WEB, DQMB Hold Time
+ tCMS = 1.5; // CSB, RASB, CASB, WEB, DQMB Setup Time
+ `endif
+
+ `ifdef S60
+ tAH = 1.0, // addr, ba Hold Time
+ tAS = 1.5, // addr, ba Setup Time
+ tCH = 2.5, // Clock High-Level Width
+ tCL = 2.5, // Clock Low-Level Width
+ tCK = 6.0, // Clock Cycle Time
+ tDH = 1.0, // Data-in Hold Time
+ tDS = 1.5, // Data-in Setup Time
+ tCKH = 1.0, // CKE Hold Time
+ tCKS = 1.5, // CKE Setup Time
+ tCMH = 1.0, // CSB, RASB, CASB, WEB, DQMB Hold Time
+ tCMS = 1.5; // CSB, RASB, CASB, WEB, DQMB Setup Time
+ `endif
+
+ `ifdef S75
+ tAH = 1.0, // addr, ba Hold Time
+ tAS = 2.0, // addr, ba Setup Time
+ tCH = 2.5, // Clock High-Level Width
+ tCL = 2.5, // Clock Low-Level Width
+ tCK = 7.5, // Clock Cycle Time
+ tDH = 1.0, // Data-in Hold Time
+ tDS = 2.0, // Data-in Setup Time
+ tCKH = 1.0, // CKE Hold Time
+ tCKS = 2.0, // CKE Setup Time
+ tCMH = 1.0, // CSB, RASB, CASB, WEB, DQMB Hold Time
+ tCMS = 2.0; // CSB, RASB, CASB, WEB, DQMB Setup Time
+ `endif
+
+
+ $width (posedge clk, tCH);
+ $width (negedge clk, tCL);
+ $period (negedge clk, tCK);
+ $period (posedge clk, tCK);
+ $setuphold(posedge clk, cke, tCKS, tCKH);
+ $setuphold(posedge clk, csb, tCMS, tCMH);
+ $setuphold(posedge clk, casb, tCMS, tCMH);
+ $setuphold(posedge clk, rasb, tCMS, tCMH);
+ $setuphold(posedge clk, web, tCMS, tCMH);
+ $setuphold(posedge clk, addr, tAS, tAH);
+ $setuphold(posedge clk, ba, tAS, tAH);
+ $setuphold(posedge clk, dqm, tCMS, tCMH);
+ $setuphold(posedge dq_chk, dq, tDS, tDH);
+ endspecify
+
+
+endmodule
trunk/verif/model/IS42VM16400K.V
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property