Line 1... |
Line 1... |
|
//************************************************************************
|
|
//************************************************************************
|
|
//** This model is the property of Cypress Semiconductor Corp and is **
|
|
//** protected by the US copyright laws, any unauthorized copying and **
|
|
//** distribution is prohibited. Cypress reserves the right to change **
|
|
//** any of the functional specifications without any prior notice. **
|
|
//** Cypress is not liable for any damages which may result from the **
|
|
//** use of this functional model. **
|
|
//** **
|
|
//** File Name : CY7C1354B **
|
|
//** **
|
|
//** Revision : 1.1 - 01/30/2004 **
|
|
//** **
|
|
//** The timings are to be selected by the user depending upon the **
|
|
//** frequency of operation from the datasheet. **
|
|
//** **
|
|
//** Model : CY7C1354B - 256K x 36 NoBL Pipelined SRAM **
|
|
//** Queries : MPD Applications **
|
|
//** e-mail: mpd_apps@cypress.com **
|
|
//************************************************************************
|
|
//************************************************************************
|
|
|
|
`timescale 1ns / 10ps
|
|
|
|
// NOTE : Any setup/hold errors will force input signal to x state
|
|
// or if results indeterminant (write addr) core is reset x
|
|
|
|
// define fixed values
|
|
|
|
`define wordsize (36 -1) //
|
|
`define no_words (262144 -1) // 256K x 36 RAM
|
|
|
|
module cy7c1354 ( d, clk, a, bws, we_b, adv_lb, ce1b, ce2, ce3b, oeb, cenb, mode);
|
|
|
|
inout [`wordsize:0] d;
|
|
input clk, // clock input (R)
|
|
we_b, // byte write enable(L)
|
|
adv_lb, // burst(H)/load(L) address
|
|
ce1b, // chip enable(L)
|
|
ce2, // chip enable(H)
|
|
ce3b, // chip enable(L)
|
|
oeb, // async output enable(L)(read)
|
|
cenb, // clock enable(L)
|
|
mode; // interleave(H)/linear(L) burst
|
|
input [3:0] bws; // byte write select(L)
|
|
input [18:0] a; // address bus
|
|
|
|
// *** NOTE DEVICE OPERATES #0.01 AFTER CLOCK ***
|
|
// *** THEREFORE DELAYS HAVE TO TAKE THIS INTO ACCOUNT ***
|
|
|
|
//**********************************************************************
|
|
// This model is configured for 166 MHz Operation (CY7C1354-166).
|
|
//**********************************************************************
|
|
`define teohz #3.5
|
|
`define teolz #0
|
|
`define tchz #3.5
|
|
`define tclz #1.5
|
|
|
|
`define tco #3.5
|
|
`define tdoh #1.5
|
|
|
|
`define tas 1.5
|
|
`define tah 0.5
|
|
|
|
/**********************************************************************
|
|
// Timings for 225MHz
|
|
//**********************************************************************
|
|
`define teohz #2.8
|
|
`define teolz #0
|
|
`define tchz #2.8
|
|
`define tclz #1.5
|
|
|
|
`define tco #2.8
|
|
`define tdoh #1.5
|
|
|
|
`define tas 1.5
|
|
`define tah 0.5
|
|
|
|
//***********************************************************************
|
|
// Timings for 200MHz
|
|
//**********************************************************************
|
|
`define teohz #3.2
|
|
`define teolz #0
|
|
`define tchz #3.2
|
|
`define tclz #1.5
|
|
|
|
`define tco #3.2
|
|
`define tdoh #1.5
|
|
|
|
`define tas 1.5
|
|
`define tah 0.5
|
|
***********************************************************************/
|
|
|
|
reg notifier; // error support reg's
|
|
reg noti1_0;
|
|
reg noti1_1;
|
|
reg noti1_2;
|
|
reg noti1_3;
|
|
reg noti1_4;
|
|
reg noti1_5;
|
|
reg noti1_6;
|
|
reg noti2;
|
|
|
|
|
|
wire chipen; // combined chip enable (high for an active chip)
|
|
|
|
reg chipen_d; // _d = delayed
|
|
reg chipen_o; // _o = operational = delayed sig or _d sig
|
|
|
|
wire writestate; // holds 1 if any of writebus is low
|
|
reg writestate_d;
|
|
reg writestate_o;
|
|
|
|
wire loadcyc; // holds 1 for load cycles (setup and hold checks)
|
|
wire writecyc; // holds 1 for write cycles (setup and hold checks)
|
|
wire [3:0] bws; // holds the bws values
|
|
|
|
wire [3:0] writebusb; // holds the "internal" bws bus based on we_b
|
|
reg [3:0] writebusb_d;
|
|
reg [3:0] writebusb_o;
|
|
|
|
wire [2:0] operation; // holds chipen, adv_ld and writestate
|
|
reg [2:0] operation_d;
|
|
reg [2:0] operation_o;
|
|
|
|
wire [17:0] a; // address input bus
|
|
reg [17:0] a_d;
|
|
reg [17:0] a_o;
|
|
|
|
reg [`wordsize:0] do; // data output reg
|
|
reg [`wordsize:0] di; // data input bus
|
|
reg [`wordsize:0] dd; // data delayed bus
|
|
|
|
wire tristate; // tristate output (on a bytewise basis) when asserted
|
|
reg cetri; // register set by chip disable which sets the tristate
|
|
reg oetri; // register set by oe which sets the tristate
|
|
reg enable; // register to make the ram enabled when equal to 1
|
|
reg [17:0] addreg; // register to hold the input address
|
|
reg [`wordsize:0] pipereg; // register for the output data
|
|
|
|
reg [`wordsize:0] mem [0:`no_words]; // RAM array
|
|
|
|
reg [`wordsize:0] writeword; // temporary holding register for the write data
|
|
reg burstinit; // register to hold a[0] for burst type
|
|
reg [18:0] i; // temporary register used to write to all mem locs.
|
|
reg writetri; // tristate
|
|
reg lw, bw; // pipelined write functions
|
|
reg we_bl;
|
|
|
|
|
|
wire [`wordsize:0] d = !tristate ? do[`wordsize:0] : 36'bz ; // data bus
|
|
|
|
assign chipen = (adv_lb == 1 ) ? chipen_d :
|
|
~ce1b & ce2 & ~ce3b ;
|
|
|
|
assign writestate = ~& writebusb;
|
|
|
|
assign operation = {chipen, adv_lb, writestate};
|
|
|
|
assign writebusb[3:0] = ( we_b ==0 & adv_lb ==0) ? bws[3:0]:
|
|
( we_b ==1 & adv_lb ==0) ? 4'b1111 :
|
|
( we_bl ==0 & adv_lb ==1) ? bws[3:0]:
|
|
( we_bl ==1 & adv_lb ==1) ? 4'b1111 :
|
|
4'bxxxx ;
|
|
|
|
assign loadcyc = chipen & !cenb;
|
|
|
|
assign writecyc = writestate_d & enable & ~cenb & chipen; // check
|
|
|
|
assign tristate = cetri | writetri | oetri;
|
|
|
|
pullup (mode);
|
|
|
|
// formers for notices/errors etc
|
|
//
|
|
//$display("NOTICE : xxx :");
|
|
//$display("WARNING : xxx :");
|
|
//$display("ERROR *** : xxx :");
|
|
|
|
|
|
// initialize the output to be tri-state, ram to be disabled
|
|
|
|
initial
|
|
begin
|
|
// signals
|
|
|
|
writetri = 0;
|
|
cetri = 1;
|
|
enable = 0;
|
|
lw = 0;
|
|
bw = 0;
|
|
|
|
// error signals
|
|
|
|
notifier = 0;
|
|
noti1_0 = 0;
|
|
noti1_1 = 0;
|
|
noti1_2 = 0;
|
|
noti1_3 = 0;
|
|
noti1_4 = 0;
|
|
noti1_5 = 0;
|
|
noti1_6 = 0;
|
|
noti2 = 0;
|
|
|
|
end
|
|
|
|
|
|
|
|
// asynchronous OE
|
|
|
|
always @(oeb)
|
|
begin
|
|
if (oeb == 1)
|
|
oetri <= `teohz 1;
|
|
else
|
|
oetri <= `teolz 0;
|
|
end
|
|
|
|
// *** SETUP / HOLD VIOLATIONS ***
|
|
|
|
always @(noti2)
|
|
begin
|
|
$display("NOTICE : 020 : Data bus corruption");
|
|
force d =36'bx;
|
|
#1;
|
|
release d;
|
|
end
|
|
|
|
always @(noti1_0)
|
|
begin
|
|
$display("NOTICE : 010 : Byte write corruption");
|
|
force bws = 4'bx;
|
|
#1;
|
|
release bws;
|
|
end
|
|
|
|
always @(noti1_1)
|
|
begin
|
|
$display("NOTICE : 011 : Byte enable corruption");
|
|
force we_b = 1'bx;
|
|
#1;
|
|
release we_b;
|
|
end
|
|
|
|
always @(noti1_2)
|
|
begin
|
|
$display("NOTICE : 012 : CE1B corruption");
|
|
force ce1b =1'bx;
|
|
#1;
|
|
release ce1b;
|
|
end
|
|
|
|
always @(noti1_3)
|
|
begin
|
|
$display("NOTICE : 013 : CE2 corruption");
|
|
force ce2 =1'bx;
|
|
#1;
|
|
release ce2;
|
|
end
|
|
|
|
always @(noti1_4)
|
|
begin
|
|
$display("NOTICE : 014 : CE3B corruption");
|
|
force ce3b =1'bx;
|
|
#1;
|
|
release ce3b;
|
|
end
|
|
|
|
always @(noti1_5)
|
|
begin
|
|
$display("NOTICE : 015 : CENB corruption");
|
|
force cenb =1'bx;
|
|
#1;
|
|
release cenb;
|
|
end
|
|
|
|
always @(noti1_6)
|
|
begin
|
|
$display("NOTICE : 016 : ADV_LB corruption");
|
|
force adv_lb = 1'bx;
|
|
#1;
|
|
release adv_lb;
|
|
end
|
|
|
|
// synchronous functions from clk edge
|
|
|
|
always @(posedge clk)
|
|
if (!cenb)
|
|
begin
|
|
#0.01;
|
|
// latch conditions on adv_lb
|
|
|
|
if (adv_lb)
|
|
we_bl <= we_bl;
|
|
else
|
|
we_bl <= we_b;
|
|
|
|
chipen_d <= chipen;
|
|
|
|
|
|
chipen_o <= chipen;
|
|
writestate_o <= writestate;
|
|
writestate_d <= writestate_o;
|
|
writebusb_o <= writebusb;
|
|
writebusb_d <= writebusb_o;
|
|
operation_o <= operation;
|
|
a_o <= a;
|
|
a_d <= a_o;
|
|
di = d;
|
|
|
|
// execute previously pipelined fns
|
|
|
|
if (lw) begin
|
|
loadwrite;
|
|
lw =0;
|
|
end
|
|
|
|
if (bw) begin
|
|
burstwrite;
|
|
bw =0;
|
|
end
|
|
|
|
// decode input/piplined state
|
|
|
|
casex (operation_o)
|
|
3'b0?? : turnoff;
|
|
3'b101 : setlw;
|
|
3'b111 : setbw;
|
|
3'b100 : loadread;
|
|
3'b110 : burstread;
|
|
default : unknown; // output unknown values and display an error message
|
|
endcase
|
|
|
|
do <= `tco pipereg;
|
|
|
|
end
|
|
|
|
// *** task section ***
|
|
|
|
task read;
|
|
begin
|
|
if (enable) cetri <= `tclz 0;
|
|
do <= `tdoh 36'hx;
|
|
writetri <= `tchz 0;
|
|
pipereg = mem[addreg];
|
|
end
|
|
endtask
|
|
|
|
task write;
|
|
begin
|
|
if (enable) cetri <= `tclz 0;
|
|
writeword = mem[addreg]; // set up a word to hold the data for the current location
|
|
/* overwrite the current word for the bytes being written to */
|
|
if (!writebusb_d[3]) writeword[35:27] = di[35:27];
|
|
if (!writebusb_d[2]) writeword[26:18] = di[26:18];
|
|
if (!writebusb_d[1]) writeword[17:9] = di[17:9];
|
|
if (!writebusb_d[0]) writeword[8:0] = di[8:0];
|
|
writeword = writeword & writeword; //convert z to x states
|
|
mem[addreg] = writeword; // store the new word into the memory location
|
|
//writetri <= `tchz 1; // tristate the outputs
|
|
end
|
|
endtask
|
|
|
|
task setlw;
|
|
begin
|
|
lw =1;
|
|
writetri <= `tchz 1; // tristate the outputs
|
|
end
|
|
endtask
|
|
|
|
task setbw;
|
|
begin
|
|
bw =1;
|
|
writetri <= `tchz 1; // tristate the outputs
|
|
end
|
|
endtask
|
|
|
|
task loadread;
|
|
begin
|
|
burstinit = a_o[0];
|
|
addreg = a_o;
|
|
enable = 1;
|
|
read;
|
|
end
|
|
endtask
|
|
|
|
task loadwrite;
|
|
begin
|
|
burstinit = a_d[0];
|
|
addreg = a_d;
|
|
enable = 1;
|
|
write;
|
|
end
|
|
endtask
|
|
|
|
task burstread;
|
|
begin
|
|
burst;
|
|
read;
|
|
end
|
|
endtask
|
|
|
|
task burstwrite;
|
|
begin
|
|
burst;
|
|
write;
|
|
end
|
|
endtask
|
|
|
|
task unknown;
|
|
begin
|
|
do = 36'bx;
|
|
// $display ("Unknown function: Operation = %b\n", operation);
|
|
end
|
|
endtask
|
|
|
|
task turnoff;
|
|
begin
|
|
enable = 0;
|
|
cetri <= `tchz 1;
|
|
pipereg = 36'h0;
|
|
end
|
|
endtask
|
|
|
|
task burst;
|
|
begin
|
|
if (burstinit == 0 || mode == 0)
|
|
begin
|
|
case (addreg[1:0])
|
|
2'b00: addreg[1:0] = 2'b01;
|
|
2'b01: addreg[1:0] = 2'b10;
|
|
2'b10: addreg[1:0] = 2'b11;
|
|
2'b11: addreg[1:0] = 2'b00;
|
|
default: addreg[1:0] = 2'bxx;
|
|
endcase
|
|
end
|
|
else
|
|
begin
|
|
case (addreg[1:0])
|
|
2'b00: addreg[1:0] = 2'b11;
|
|
2'b01: addreg[1:0] = 2'b00;
|
|
2'b10: addreg[1:0] = 2'b01;
|
|
2'b11: addreg[1:0] = 2'b10;
|
|
default: addreg[1:0] = 2'bxx;
|
|
endcase
|
|
end
|
|
end
|
|
endtask
|
|
|
|
// IO checks
|
|
|
|
specify
|
|
// specify the setup and hold checks
|
|
|
|
// notifier will wipe memory as result is indeterminent
|
|
|
|
$setuphold(posedge clk &&& loadcyc, a, `tas, `tah, notifier);
|
|
|
|
// noti1 should make ip = 'bx;
|
|
|
|
$setuphold(posedge clk, bws, `tas, `tah, noti1_0);
|
|
|
|
$setuphold(posedge clk, we_b, `tas, `tah, noti1_1);
|
|
$setuphold(posedge clk, ce1b, `tas, `tah, noti1_2);
|
|
$setuphold(posedge clk, ce2, `tas, `tah, noti1_3);
|
|
$setuphold(posedge clk, ce3b, `tas, `tah, noti1_4);
|
|
|
|
// noti2 should make d = 36'hxxxxxxxxx;
|
|
|
|
$setuphold(posedge clk &&& writecyc, d, `tas, `tah, noti2);
|
|
//$setuphold(posedge clk &&& WriteTimingCheck , d, `tas, `tah, noti2);
|
|
|
|
// add extra tests here.
|
|
|
|
$setuphold(posedge clk, cenb, `tas, `tah, noti1_5);
|
|
$setuphold(posedge clk, adv_lb, `tas, `tah, noti1_6);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|