aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/models/CY7C1356C/cy1356.v
blob: dd3cd56e8bb9efb5baee3cc806a5d0b9caea332a (plain)
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
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
//
// Copyright 2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

`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