// simultaneously.
integer rasb_high_cycle
; // record cycle# @ posedge of rasb_l
integer rasb_low_cycle
; // record cycle# @ negedge of rasb_l
integer rasb_prev_low_cycle
; // needed for checking tRC
integer rast_low_cycle
; // record cycle# @ negedge of rast_l
integer rast_prev_low_cycle
; // needed for checking tRC
integer rast_high_cycle
; // record cycle# @ posedge of rast_l
integer address_active_cycle
; // cycle when address goes from x to active
integer address_prev_active_cycle
; // previous address
integer data_change_cycle
; // cycle when data goes from z to active
integer num_of_cas_cyc
; // required to differentiate between single read/write and paged mode rw
integer prev_num_of_cas_cyc
;
reg rasb_has_been_asserted
; // indicates that rasb_l is low
reg rast_has_been_asserted
; // indicates rast_l is low
reg cas_has_been_asserted
; // indicates cas assertion
reg first_cas_low_after_ras_low
; // == 1, indicates first cas low has happened
reg first_time_rasb_asserted
;
reg first_time_rast_asserted
;
reg ras_init
; // Used for first tRC check YS
wire [63:0] data_out = data_valid ? rd_data : 64'bz;
wire [1:0] parity_out = data_valid ? {rd_parity[8], rd_parity[0]} : 2'bz;
/***********************************************************************************************************************************************
initialize
************************************************************************************************************************************************/
initial
begin
size8 = 8; // 8 bytes of data(64 bits)
size1 = 1; // 1 byte parity
start_write = 1'b0; // clear flag
start_read = 1'b0;
ras_init = 1'b0;
row_addrs = 32'b0;
colm_addrs = 32'b0;
rd_data = 64'bz; // reg to store data from M64
rd_parity = 64'bz; // reg to store parity from M64
write_done = 1'b0;
data_turn_off = 1'b0;
/* YSUN
case (Msystem.speed_select)
`SPEED70:
begin
ticks_per_ns = 1.4;
end
`SPEED85:
begin
ticks_per_ns = 1.7;
end
`SPEED100:
begin
ticks_per_ns = 2.0;
end
`SPEED125:
begin
ticks_per_ns = 2.5;
end
`SPEED150:
begin
ticks_per_ns = 3.0;
end
`SPEED175:
begin
ticks_per_ns = 3.5;
end
`SPEED200:
begin
ticks_per_ns = 4.0;
end
endcase // case for Msystem.speed_select
$display ("ticks_per_ns ==", ticks_per_ns);
YSUN */
oe_high_cycle = 32'b0;
oe_low_cycle = 32'b0;
we_high_cycle = 32'b0;
we_low_cycle = 32'b0;
cas_high_cycle = 32'b0;
data_change_cycle = 32'b0;
cas_low_cycle = 32'b0;
cas_prev_low_cycle = 32'b0;
cas_prev_high_cycle = 32'b0;
rasb_high_cycle = 32'b0;
rasb_low_cycle = 32'b0;
rasb_prev_low_cycle = 32'b0;
// needed for tREZ monitors
// 01=rasb, 10=rast
rast_low_cycle = 32'b0;
rast_prev_low_cycle = 32'b0;
rast_high_cycle = 32'b0;
address_active_cycle = 32'b0;
address_prev_active_cycle = 32'b0;
num_of_cas_cyc = 32'b0;
prev_num_of_cas_cyc = 32'b0;
rasb_has_been_asserted = 1'b0;
rast_has_been_asserted = 1'b0;
cas_has_been_asserted = 1'b0;
first_time_rasb_asserted = 1'b0;
first_time_rast_asserted = 1'b0;
first_cas_low_after_ras_low = 1'b0;
tRAD_max_rasb_chk_done = 1'b0;
tRAD_min_rasb_chk_done = 1'b0;
tRAD_max_rast_chk_done = 1'b0;
tRAD_min_rast_chk_done = 1'b0;
tRCD_chkd = 1'b0;
tRAC_chkd = 1'b1;
tRAH_chkd = 1'b0;
tCSH_chkd = 1'b0;
tRP_chkd = 1'b0;
twrh_chk = 1'b0;
row_address = 1'b0;
row_addr = 32'b0;
first_col_addr = 32'b0;
tOEA_met = 1'b0; // YS
oea_met = 1'b0; // YS
oez_met = 1'b0; // YS
oez_min_met = 1'b0; // YS
oez_max_met = 1'b0; // YS
rand = 32'b0; // YS
tCPA_met = 1'b0;
cpa_met = 1'b0;
tAA_met = 1'b0;
tAA_done = 1'b0;
tAA_start = 1'b0;
tCAC_met = 1'b0;
cac_met = 1'b0;
tRAC_met = 1'b0;
rac_met = 1'b0;
data_valid = 1'b0;
type_op = 3'b0;
whichRASprevAsserted = 2'b0; // tells you which ras was last asserted
// required for tREZ monitors, 01 = rasb, 10 = rast
end
/***********************************************************************************************************************************************
NO DRAM ACCESS IF RAS AND CAS ARE NOT ASSERTED
************************************************************************************************************************************************/
always @(posedge &{rasb_l, rast_l, cas_l})
begin
first_access = 0;
end
//##################################################################################################################
// record posedge of cas_l and perform all checks and events that should happen @ posedge of cas_l
//##################################################################################################################
always @(posedge cas_l)
begin
cas_prev_high_cycle = cas_high_cycle;
cas_high_cycle = $stime; // record time at every posedge of cas_l
cas_has_been_asserted <= 1'b0;
twrh_chk = 1'b0;
//********************************************************************************
// Ensure tCPA is met for a read
//********************************************************************************
if(we_l & (rasb_has_been_asserted || rast_has_been_asserted))
begin
cpa_met = 1'b0;
cpa_met <= #((ticks_per_ns * `tCPA)) 1; // set tCPA_met after tCPA ns.
end
//*******************************************************************************
// For read check tOCH YS 08/27/96
//*******************************************************************************
if (we_l & (rasb_has_been_asserted || rast_has_been_asserted))
begin
if ((cas_high_cycle - oe_low_cycle) < (`tOCH * ticks_per_ns))
begin
$display("Error: DRAM at %t tOCH (OE to CAS hold time) violated!!", $stime);
$display("(cas_high_cycle - oe_low_cycle) == %g", (cas_high_cycle - oe_low_cycle));
end
end
//********************************************************************************
// For both read and write check tCAS, tHPC, tCSH
//********************************************************************************
if((rasb_has_been_asserted || rast_has_been_asserted) & first_cas_low_after_ras_low)
begin
if((cas_high_cycle - cas_low_cycle) < (`tCAS_MIN * ticks_per_ns))
begin
$display("Error: DRAM at %t tCAS min (CAS pulse width timing) violated!!", $stime);
end
if((cas_high_cycle - cas_low_cycle) > (`tCAS_MAX * ticks_per_ns))
begin
$display("Error: DRAM at %t tCAS max (CAS pulse width timing) exceded", $stime);
end
end
//********************************************************************************
// For tCSH if rasb has been asserted and first_time_rast is asserted and if the type of operation
// happens to be a read or write only.
//********************************************************************************
if(rasb_has_been_asserted & first_time_rasb_asserted & ((type_op != 3'b100)) &
~tCSH_chkd)
begin
tCSH_chkd = 1'b1;
if((cas_high_cycle - rasb_low_cycle) < (`tCSH * ticks_per_ns))
begin
$display("Error: DRAM at %t tCSH (CAS hold time with reference to RAS(rasb_l)) violated!!", $stime);
end
end
if(rasb_has_been_asserted & first_time_rasb_asserted & ((type_op != 3'b100))) begin
if((cas_high_cycle - cas_prev_high_cycle) < (`tHPC * ticks_per_ns))
begin
$display("Error: DRAM at %t tHPC (edo page mode read/write cycle time) violated", $stime);
end
end
if(rast_has_been_asserted & first_time_rast_asserted & ((type_op != 3'b100)) &
~tCSH_chkd)
begin
tCSH_chkd = 1'b1;
if(~tCSH_chkd) begin
if((cas_high_cycle - rast_low_cycle) < (`tCSH * ticks_per_ns))
begin
$display("Error: DRAM at %t tCSH (CAS hold time with reference to RAS(rast_l)) violated !!", $stime);
end
end
end
if(rast_has_been_asserted & first_time_rast_asserted & ((type_op != 3'b100)))
begin
if((cas_high_cycle - cas_prev_high_cycle) < (`tHPC * ticks_per_ns))
begin
$display("Error: DRAM at %t tHPC (edo page mode read/write cycle time) violated", $stime);
end
end
//********************************************************************************
// For write only check tCWL
//********************************************************************************
if(first_cas_low_after_ras_low & rasb_has_been_asserted & first_time_rasb_asserted & (type_op === 3'b001))
begin
if((cas_high_cycle - we_low_cycle) < (`tCWL * ticks_per_ns))
begin
$display("Error: DRAM at %t tCWL(write command to CAS lead time) violated", $stime);
end
end
if(rast_has_been_asserted & first_cas_low_after_ras_low & first_time_rast_asserted & (type_op === 3'b001))
begin
if((cas_high_cycle - we_low_cycle) < (`tCWL * ticks_per_ns))
begin
$display("Error: DRAM at %t tCWL(write command to CAS lead time, btw rast is low) violated", $stime);
end
end
//********************************************************************************
// For CBR refresh check tCHR(cas hold time)
//********************************************************************************
if(rasb_has_been_asserted & first_time_rasb_asserted & (type_op === 3'b100))
begin
if((cas_high_cycle - rasb_low_cycle) < (`tCHR * ticks_per_ns))
begin
$display("Error: DRAM at %t tCHR(cas hold time(w.r.t rasb_l), CBR refresh) violated", $stime);
end
end
if(rast_has_been_asserted & first_time_rast_asserted & (type_op === 3'b100))
begin
if((cas_high_cycle - rast_low_cycle) < (`tCHR * ticks_per_ns))
begin
$display("Error: DRAM at %t tCHR(cas hold time(w.r.t rast_l), CBR refresh) violated", $stime);
end
end
end
//##################################################################################################################
// record negedge of cas_l and perform all checks and events that should happen @ negedge of cas_l
//##################################################################################################################
always @(negedge cas_l)
begin
if(cas_prev_low_cycle == 32'b0) begin // Only for the first CAS low
cas_prev_low_cycle = $stime;
end
else begin
cas_prev_low_cycle = cas_low_cycle;
end
cas_low_cycle = $stime; // record time at every negedge of cas_l
cas_has_been_asserted = 1'b1;
if(rasb_has_been_asserted || rast_has_been_asserted)
begin
first_cas_low_after_ras_low <= 1'b1;
end
num_of_cas_cyc = num_of_cas_cyc + 1; // required to differentiate between
// single read/write and page mode read/write
//********************************************************************************
// Ensure tCAC is met for both read and write
//********************************************************************************
if((rasb_has_been_asserted || rast_has_been_asserted)
& (first_time_rasb_asserted || first_time_rast_asserted))
begin
cac_met = 1'b0;
cac_met <= #((ticks_per_ns * `tCAC)) 1; // tCAC_met is set after tCAC nanoseconds
end
//********************************************************************************
// tRPC
//********************************************************************************
if(type_op == 3'b100) begin
if((cas_low_cycle - rasb_high_cycle) < (`tRPC * ticks_per_ns))
begin
$display("Error: DRAM at %t, tRPC violated!!", $stime);
end
end
if(type_op == 3'b100) begin
if((cas_low_cycle - rast_high_cycle) < (`tRPC * ticks_per_ns))
begin
$display("Error: DRAM at %t, tRPC violated!!", $stime);
end
end
//********************************************************************************
// For read and write check tASC(column address setup time
//********************************************************************************
if(rasb_has_been_asserted & first_time_rasb_asserted)
begin
if((cas_low_cycle - address_active_cycle) < (`tASC * ticks_per_ns))
begin
$display("Error: DRAM at %t tASC (Column address setup time) violated!!", $stime);
end
end
if(rast_has_been_asserted & first_time_rast_asserted)
begin
if((cas_low_cycle - address_active_cycle) < (`tASC * ticks_per_ns))
begin
$display("Error: DRAM at %t tASC (Column address setup time) violated!!", $stime);
end
end
//********************************************************************************
// Skip checking for tRAD if row address == first_col_addr,
//********************************************************************************
// In simulation there is no transition on the address bus when row address
// is equal to the first column address. In this case prior to setting these
// flags the model would count against the second column address and complain
// that we were violating tRAD.
if(rasb_has_been_asserted & first_time_rasb_asserted)
begin
tRAD_min_rasb_chk_done = 1'b1;
tRAD_max_rasb_chk_done = 1'b1;
end
if(rast_has_been_asserted & first_time_rast_asserted)
begin
tRAD_min_rast_chk_done = 1'b1;
tRAD_max_rast_chk_done = 1'b1;
end
//********************************************************************************
// tWCS
//********************************************************************************
if(rasb_has_been_asserted | rast_has_been_asserted) begin
if(((cas_low_cycle - we_high_cycle)) < (`tWCS * ticks_per_ns))
begin
$display("Error: DRAM at %t, tWCS violated", $stime);
end
end
if(rasb_has_been_asserted | rast_has_been_asserted) begin
if(((cas_low_cycle - we_low_cycle)) < (`tWCS * ticks_per_ns))
begin
$display("Error: DRAM at %t, tWCS violated", $stime);
end
end
//********************************************************************************
// Check tCP(cas precharge time)
//********************************************************************************
if(rasb_has_been_asserted || rast_has_been_asserted)
begin
if((cas_low_cycle - cas_high_cycle) < (`tCP * ticks_per_ns))
begin
$display("Error: DRAM at %t tCP (CAS precharge time) violated!!", $stime);
end
end
//********************************************************************************
// Check tRCS for read only
//********************************************************************************
if(we_l & rasb_has_been_asserted & first_time_rasb_asserted
& (type_op == 3'b010))
begin
if((cas_low_cycle - we_low_cycle) < (`tRCS * ticks_per_ns))
begin
$display("Error: DRAM at %t tRCS (read command setup time) violated!!", $stime);
end
end
if(we_l & rast_has_been_asserted & first_time_rast_asserted &
(type_op == 3'b010))
begin
if((cas_low_cycle - we_low_cycle) < (`tRCS * ticks_per_ns))
begin
$display("Error: DRAM at %t tRCS (read command setup time) violated!!", $stime);
end
end
//********************************************************************************
// For both read and write check tRCD
//********************************************************************************
if(rasb_has_been_asserted & first_time_rasb_asserted & ~tRCD_chkd)
begin
tRCD_chkd = 1'b1;
if((cas_low_cycle - rasb_low_cycle) < (`tRCD_MIN * ticks_per_ns))
begin
$display("Error: DRAM at %t tRCD min (RAS(rast_l) to CAS delay time) violated!!", $stime);
end
if((cas_low_cycle - rasb_low_cycle) > (`tRCD_MAX * ticks_per_ns))
begin
// $display("Error: DRAM at %t tRCD max violated", $stime);
end
end
if(rast_has_been_asserted & first_time_rast_asserted & ~tRCD_chkd)
begin
tRCD_chkd = 1'b1;
if((cas_low_cycle - rast_low_cycle) < (`tRCD_MIN * ticks_per_ns))
begin
$display("Error: DRAM at %t tRCD min (RAS(rasb_l) to CAS delay time) violated!!", $stime);
end
end
if(rast_has_been_asserted & first_time_rast_asserted & ~tRCD_chkd)
begin
if((cas_low_cycle - rast_low_cycle) > (`tRCD_MAX * ticks_per_ns))
begin
// $display("Error: DRAM at %t tRCD max violated", $stime);
end
end
//********************************************************************************
// For write only check tDS(data setup time
//********************************************************************************
if(rasb_has_been_asserted & ~we_l & first_time_rasb_asserted)
begin
if((cas_low_cycle - data_change_cycle) < (`tDS * ticks_per_ns))
begin
$display("Error: DRAM at %t tDS(data-in setup time w.r.t rasb_l) violated", $stime);
end
end
if(rast_has_been_asserted & ~we_l & first_time_rast_asserted)
begin
if((cas_low_cycle - data_change_cycle) < (`tDS * ticks_per_ns))
begin
$display("Error: DRAM at %t tDS(data-in setup time w.r.t rast_l) violated", $stime);
end
end
end
//##################################################################################################################
// Ensure tAA is met for reads
//##################################################################################################################
always @(simm_address) begin
if(~first_access) begin // hack for the case when on the first access
// row and first column address are same and
// tAA_met does not get set for the first data
if(row_addr == first_col_addr) begin // When the second col address is driven to dram
// check to see if row and first column address were the
// same, if yes set the tAA_met flag, else deassert it.
tAA_met <= #((ticks_per_ns * `tRAC)) 1; // drive data out when tRAC is met
end
else begin
tAA_met = 0;
end
end
else begin
// tAA_met = 0;
end
if(^simm_address !== 1'bx) begin
tAA_met <= #(ticks_per_ns * `tAA) 1;
end
tAA_done = 0;
end
//##################################################################################################################
// tCAC_met
//##################################################################################################################
always @(posedge cac_met) begin
if(type_op == 3'b010) begin // set only if read operation
tCAC_met = 1'b1; // will be set for reads only and cleared after the
// read
end
end
always @(posedge rac_met) begin
if(type_op == 3'b010) begin // set only if read operation
tRAC_met = 1'b1;
end
end
// for write-read cases, since type_op = 001, tRAC_met will
// not be asserted though rac_met is 1
always @(type_op == 3'b010) begin
if(rac_met) begin
tRAC_met = 1'b1;
end
end
always @(posedge cac_met) begin
if(rac_met) begin
if(row_addr == first_col_addr) begin
tAA_met = 1'b1;
end
end
end
always @(posedge cpa_met) begin
if(type_op == 3'b010) begin // set only if read operation
tCPA_met = 1'b1;
end
end
always @(posedge oea_met) begin // YS
if(type_op == 3'b010) begin
tOEA_met = 1'b1;
end
end
//##################################################################################################################
// record when address changes and perform all checks and events that should happen when address changes
//##################################################################################################################
always @(simm_address)
begin
if(^simm_address !== 1'bx)
begin
if(address_prev_active_cycle == 32'b0) begin
address_prev_active_cycle = $stime;
end
else begin
address_prev_active_cycle = address_active_cycle;
end
address_active_cycle = $stime; // record time whenever address changes and is not equal to x
end
//********************************************************************************
// Record column address if it is first access
//********************************************************************************
if(~first_access & (rasb_has_been_asserted | rast_has_been_asserted)) begin
first_col_addr[10:0] = simm_address[10:0];
curr_simm_addr[10:0] = simm_address[10:0];
end
//********************************************************************************
// Setting row address flag
//********************************************************************************
if(rasb_has_been_asserted || rast_has_been_asserted)
begin
row_address = 1'b0; // not a row address
end
//********************************************************************************
// Check tRAH for both read and write
//********************************************************************************
if(rasb_has_been_asserted & ~cas_has_been_asserted & first_time_rasb_asserted & ~tRAH_chkd)
begin
tRAH_chkd = 1'b1;
if((address_active_cycle - rasb_low_cycle) < (`tRAH * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRAH (Row address hold time)!!", $stime);
end
end
if(rast_has_been_asserted & ~cas_has_been_asserted & first_time_rast_asserted & ~tRAH_chkd)
begin
tRAH_chkd = 1'b1;
if((address_active_cycle - rast_low_cycle) < (`tRAH * ticks_per_ns))
begin
$display("Error: DRAM at %t rast_l violates tRAH (Row address hold time)!!", $stime);
end
end
//********************************************************************************
// Check tCAH and tAR wrt rasb_l and rast_l for both read/write
//********************************************************************************
if(cas_has_been_asserted & rasb_has_been_asserted & first_time_rasb_asserted)
begin
if((address_active_cycle - cas_low_cycle) < (`tCAH * ticks_per_ns))
begin
$display("Error: DRAM at %t tCAH (Column address hold time) violated!!", $stime);
end
end
if(cas_has_been_asserted & rast_has_been_asserted & first_time_rast_asserted)
begin
if((address_active_cycle - cas_low_cycle) < (`tCAH * ticks_per_ns))
begin
$display("Error: DRAM at %t tCAH (Column address hold time) violated!!", $stime);
end
end
//********************************************************************************
// Check tRAD max and min for read/write
//********************************************************************************
if(rasb_has_been_asserted & ~cas_has_been_asserted & first_time_rasb_asserted & ~row_address)
begin
if(((address_active_cycle - rasb_low_cycle) < (`tRAD_MIN * ticks_per_ns)) & (~tRAD_min_rasb_chk_done) &
(first_col_addr != row_addr))
begin
$display("Error: DRAM at %t tRAD min (RAS(rasb_l) to Column address delay time) violated", $stime);
end
if(((address_active_cycle - rasb_low_cycle) > (`tRAD_MAX * ticks_per_ns)) & (~tRAD_max_rasb_chk_done) &
(first_col_addr != row_addr))
begin
// $display("Error: DRAM at %t tRAD max (RAS(rasb_l) to Column address delay time) violated", $stime);
end
tRAD_min_rasb_chk_done = 1'b1;
tRAD_max_rasb_chk_done = 1'b1;
end
if(rast_has_been_asserted & ~cas_has_been_asserted & first_time_rast_asserted & ~row_address & (first_col_addr != row_addr))
begin
if(((address_active_cycle - rast_low_cycle) < (`tRAD_MIN * ticks_per_ns)) & (~tRAD_min_rast_chk_done)
& (first_col_addr != row_addr))
begin
$display("Error: DRAM at %t tRAD min (RAS(rast_l) to Column address delay time) violated", $stime);
end
if(((address_active_cycle - rast_low_cycle) > (`tRAD_MAX * ticks_per_ns)) & (~tRAD_max_rast_chk_done)
& (first_col_addr != row_addr))
begin
// $display("Error: DRAM at %t tRAD max (RAS(rast_l) to Column address delay time) violated", $stime);
end
tRAD_min_rast_chk_done = 1'b1;
tRAD_max_rast_chk_done = 1'b1;
end
end
//##################################################################################################################
// record negedge of rasb_l and perform all checks and events that should happen @ negedge of rasb_l
//##################################################################################################################
always @(negedge rasb_l)
begin
rasb_prev_low_cycle = rasb_low_cycle; // needed for tRC
rasb_low_cycle = $stime;
row_addr[10:0] = simm_address[10:0];
first_col_addr[10:0] = simm_address[10:0]; // initializing first_col_addr
// in one of the diags on the first access
// to memory row_addr = first_col_addr
// but since it was not initialized 'first_col_addr'
// had 'x''s which caused grief.
first_time_rasb_asserted = 1'b1;
rasb_has_been_asserted = 1'b1;
tRAD_max_rasb_chk_done = 1'b0;
tRAD_min_rasb_chk_done = 1'b0;
tRCD_chkd = 1'b0;
tRAC_chkd = 1'b0;
tRAH_chkd = 1'b0;
tCSH_chkd = 1'b0;
first_access = 1'b0;
if(cas_has_been_asserted) begin
type_op = 3'b100;
end
if((~cas_has_been_asserted)) begin
type_op = 3'b0;
end
whichRASprevAsserted = 2'b01;
if(^simm_address !== 1'bx)
begin
row_address = 1'b1;
end
prev_num_of_cas_cyc = num_of_cas_cyc;
num_of_cas_cyc = 1'b0;
//********************************************************************************
// Ensure tRAC is met
//********************************************************************************
if(rasb_has_been_asserted & we_l & ~first_cas_low_after_ras_low & first_time_rasb_asserted)
begin
row_addrs[10:0] = simm_address[10:0];
cac_met = 0; // will get set even for writes, hence clearing
// when RAS gets asserted for next mem op.
cpa_met = 0; // will get set even for writes, hence clearin
// when RAS gets asserted for next mem op.
tRAC_met = 0;
rac_met = 0;
rac_met <= #((ticks_per_ns * `tRAC)) 1'b1; // set tRAC_met flag after tRAC
// hack for simulation only, required in cases when
// row_address of the current read is the same as last column address of the
// previous read. In this case there is no transition on the address bus for
// this read until the second column address
if(row_addr == first_col_addr) begin
tAA_met <= #((ticks_per_ns * `tRAC)) 1;
end
end
//********************************************************************************
// For both read and write check tCRP, tASR, tWRO and tRP w.r.t rasb_l
//********************************************************************************
if(~cas_has_been_asserted & we_l)
begin
if((rasb_low_cycle - cas_high_cycle) < (`tCRP * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tCRP (CAS to RAS precharge time)!!", $stime);
end
if((rasb_low_cycle - address_active_cycle) < (`tASR * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tASR (Row address setup time)!!", $stime);
end
if((rasb_low_cycle - we_high_cycle) < (`tWRP * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tWRP (Write enable setup time)!!", $stime);
end
end
if(~cas_has_been_asserted & we_l)
begin
if((rasb_low_cycle - cas_low_cycle) < (`tCRP * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tCRP (CAS to RAS precharge time)!!", $stime);
end
end
if(first_time_rasb_asserted & ~tRP_chkd)
begin
tRP = (rasb_low_cycle - rasb_high_cycle);
tRP_chkd = 1'b1;
if((rasb_low_cycle - rasb_high_cycle) < (`tRP * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRP(ras precharge time", $stime);
end
end
//********************************************************************************
// For single read or single write case check tRC
//********************************************************************************
if(first_time_rasb_asserted & (prev_num_of_cas_cyc === 1'b1))
begin
if ((tRAS > `tRAS_MIN * ticks_per_ns) & (tRP > `tRP * ticks_per_ns))
begin
if((tRAS + tRP) < (`tRC * ticks_per_ns))
begin
$display("Error: DRAM at %t tRC(random read or write cycle time, rasb_l) violated", $stime);
end
end
end
//********************************************************************************
// For CBR refresh check tCSR
//********************************************************************************
if(cas_has_been_asserted & we_l & (type_op === 3'b100))
begin
if((rasb_low_cycle - cas_low_cycle) < (`tCSR * ticks_per_ns))
begin
$display("Error: DRAM at %t tCSR(cas setup time(w.r.t rasb_l), CBR refresh) violated", $stime);
$display(" (rasb_low_cycle - cas_low_cycle) == ", (rasb_low_cycle - cas_low_cycle));
end
end
ras_init <= #1 1'b1;
end
//##################################################################################################################
// record posedge of rasb_l and perform all checks and events that should happen @ posedge of rasb_l
//##################################################################################################################
always @(posedge rasb_l)
begin
first_cas_low_after_ras_low = 1'b0;
rasb_high_cycle = $stime;
if(type_op !== 3'b010)
begin
data_turn_off = 1'b0;
end
else
begin
data_turn_off = 1'b1; // for tREZ monitor
end
rasb_has_been_asserted = 1'b0;
tRP_chkd = 1'b0;
//********************************************************************************
// Turn off rd_data and rd_parity
//********************************************************************************
if((type_op === 3'b010)) // read operation and data is not equal to Z
begin
data_valid <= #((ticks_per_ns * `tREZ_MIN)) 1'b0; // for the last data drive z's on rd_data once tREZ_MIN
rd_data <= #((ticks_per_ns * `tREZ_MIN)) 64'bx;
rd_parity <= #((ticks_per_ns * `tREZ_MIN)) 64'bx;
end
//********************************************************************************
// For paged mode read/write, check tRSH and tRASP
//********************************************************************************
if(first_time_rasb_asserted & (num_of_cas_cyc !== 1'b1))
begin
if((rasb_high_cycle - rasb_low_cycle) < (`tRASP_MIN * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRASP min (ras pulse width)", $stime);
end
if((rasb_high_cycle - rasb_low_cycle) > (`tRASP_MAX * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l exceedes tRASP max (ras pulse width)", $stime);
end
if((rasb_high_cycle - cas_low_cycle) < (`tRSH * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRSH(ras hold time)", $stime);
end
end
if(first_time_rasb_asserted & (num_of_cas_cyc !== 1'b1) & (type_op != 3'b100))
begin
if((rasb_high_cycle - cas_prev_high_cycle) < (`tRHCP * ticks_per_ns))
begin
$display("Error: DRAM at %t tRHCP (RAS hold time from CAS precharge) violated", $stime);
end
end
//********************************************************************************
// For single read/write check tRSH and tRAS
//********************************************************************************
if(first_time_rasb_asserted & ((num_of_cas_cyc === 1'b1) | (type_op == 3'b100)))
begin
tRAS = (rasb_high_cycle - rasb_low_cycle);
if((rasb_high_cycle - rasb_low_cycle) < (`tRAS_MIN * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRAS min (ras pulse width)", $stime);
end
if((rasb_high_cycle - rasb_low_cycle) > (`tRAS_MAX * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l exceedes tRAS max (ras pulse width)", $stime);
end
end
if(first_time_rasb_asserted & ((num_of_cas_cyc === 1'b1))) begin
if((rasb_high_cycle - cas_low_cycle) < (`tRSH * ticks_per_ns))
begin
$display("Error: DRAM at %t rasb_l violates tRSH(ras hold time)", $stime);
end
end
//********************************************************************************
// For write only check tRAL and tRWL
//********************************************************************************
if(rasb_has_been_asserted & cas_has_been_asserted & first_time_rasb_asserted)
begin
if((rasb_high_cycle - address_active_cycle) < (`tRAL * ticks_per_ns))
begin
$display("Error: DRAM at %t tRAL(Column address to RAS(rasb_l) lead time) violated", $stime);
end
end
if(first_time_rasb_asserted)
begin
if(((rasb_high_cycle - we_low_cycle) < (`tRWL * ticks_per_ns)) && ((rasb_high_cycle - we_low_cycle) != 0))
begin
$display("Error: DRAM at %t tRWL(write command to RAS(rasb_l) lead time) violated", $stime);
$display("rasb_high_cycle %g - we_low_cycle %g = %g ", rasb_high_cycle, we_low_cycle, (rasb_high_cycle - we_low_cycle));
$display("(`tRWL * ticks_per_ns) = %g ", (`tRWL * ticks_per_ns));
end
end
end
//##################################################################################################################
// record negedge of rast_l and perform all checks and events that should happen @ negedge of rast_l
//##################################################################################################################
always @(negedge rast_l)
begin
rast_prev_low_cycle = rast_low_cycle;
rast_low_cycle = $stime;
first_time_rast_asserted = 1'b1;
row_addr[10:0] = simm_address[10:0];
first_col_addr[10:0] = simm_address[10:0];
rast_has_been_asserted = 1'b1;
tRAD_max_rast_chk_done = 1'b0; // flags to indicate that one time check of tRAD is done
tRAD_min_rast_chk_done = 1'b0;
tRCD_chkd = 1'b0;
tRAC_chkd = 1'b0;
tRAH_chkd = 1'b0;
tCSH_chkd = 1'b0;
first_access = 1'b0;
if(cas_has_been_asserted) begin
type_op = 3'b100;
end
if((~cas_has_been_asserted)) begin
type_op = 3'b0;
end
whichRASprevAsserted = 2'b10;
if(^simm_address !== 1'bx)
begin
row_address = 1'b1;
end
prev_num_of_cas_cyc = num_of_cas_cyc;
num_of_cas_cyc = 1'b0;
//********************************************************************************
// Ensure tRAC is met for read operation
//********************************************************************************
if(rast_has_been_asserted & we_l & ~first_cas_low_after_ras_low & first_time_rast_asserted)
begin
row_addrs[10:0] = simm_address[10:0];
cac_met = 0; // will get set even for writes, hence clearing
// when RAS gets asserted for next mem op.
cpa_met = 0; // will get set even for writes, hence clearin
// when RAS gets asserted for next mem op.
tRAC_met = 0;
rac_met = 0;
rac_met <= #((ticks_per_ns * `tRAC)) 1'b1; // set tRAC_met flag after tRAC ns
// hack for simulation only, required in cases when
// row_address of the current read is the same as last column address of the
// previous read. In this case there is no transition on the address bus for
// this read until the second column address
if(row_addr == first_col_addr) begin
tAA_met <= #((ticks_per_ns * `tRAC)) 1;
end
end
//********************************************************************************
// Setting type_op for CBR refresh
//********************************************************************************
if(cas_has_been_asserted & we_l)
begin
type_op = 3'b100;
end
//********************************************************************************
// For both read and write check tCRP, tASR, tWRP and tRP
//********************************************************************************
if(~cas_has_been_asserted & we_l)
begin
if((rast_low_cycle - cas_high_cycle) < (`tCRP * ticks_per_ns))
begin
$display("Error: DRAM at %t rast_l violates tCRP (CAS to RAS precharge time)!!", $stime);
end
if((rast_low_cycle - address_active_cycle) < (`tASR * ticks_per_ns))
begin
$display("Error: DRAM at %t rast_l violates tASR (Row address setup time)!!", $stime);
end
if((rast_low_cycle - we_high_cycle) < (`tWRP * ticks_per_ns))
This page: |
Created: | Thu Aug 19 12:01:41 1999 |
| From: |
../../../sparc_v8/system/rtl/dram.v
|