1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
|
`define sb200
//************************************************************************
//************************************************************************
//** 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 : CY7C1356 **
//** **
//** Revision : 1.0 - 08/03/2004 **
//** **
//** The timings are to be selected by the user depending upon the **
//** frequency of operation from the datasheet. **
//** **
//** Model : CY7C1356C - NoBL Pipelined SRAM **
//** Queries : MPD Applications **
//** Website: www.cypress.com/support **
//************************************************************************
//************************************************************************
`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 (18 -1) //
`define no_words (1048576 -1) // 1M x 18 RAM
module cy1356 ( 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 [1: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 ***
//**********************************************************************
// Timings for 225MHz
//**********************************************************************
`ifdef sb225
`define teohz #2.8
`define teolz #0
`define tchz #2.8
`define tclz #1.25
`define tco #2.8
`define tdoh #1.25
`define tas 1.4
`define tah 0.4
`endif
//***********************************************************************
// Timings for 200MHz
//**********************************************************************
`ifdef sb200
`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
`endif
//***********************************************************************
//**********************************************************************
// This model is configured for 166 MHz Operation (CY7C1356-166).
//**********************************************************************
`ifdef sb166
`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
`endif
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 [1:0] bws; // holds the bws values
wire [1:0] writebusb; // holds the "internal" bws bus based on we_b
reg [1:0] writebusb_d;
reg [1:0] writebusb_o;
wire [2:0] operation; // holds chipen, adv_ld and writestate
reg [2:0] operation_d;
reg [2:0] operation_o;
wire [18:0] a; // address input bus
reg [18:0] a_d;
reg [18: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 [18: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] : 18'bz ; // data bus
assign chipen = (adv_lb == 1 ) ? chipen_d :
~ce1b & ce2 & ~ce3b ;
assign writestate = ~& writebusb;
assign operation = {chipen, adv_lb, writestate};
assign writebusb[1:0] = ( we_b ==0 & adv_lb ==0) ? bws[1:0]:
( we_b ==1 & adv_lb ==0) ? 2'b11 :
( we_bl ==0 & adv_lb ==1) ? bws[1:0]:
( we_bl ==1 & adv_lb ==1) ? 2'b11 :
2'bxx ;
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 =18'bx;
#1;
release d;
end
always @(noti1_0)
begin
$display("NOTICE : 010 : Byte write corruption");
force bws = 2'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;
writetri <= `tchz 0;
do <= `tdoh 18'hx;
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[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 = 18'bx;
// $display ("Unknown function: Operation = %b\n", operation);
end
endtask
task turnoff;
begin
enable = 0;
cetri <= `tchz 1;
pipereg = 18'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 = 18'hxxxxx;
$setuphold(posedge clk &&& writecyc, 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
|