Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / models / CY7C1356C / cy1356.v
1 `define sb200  \r
2 //************************************************************************\r
3 //************************************************************************\r
4 //** This model is the property of Cypress Semiconductor Corp and is    **\r
5 //** protected by the US copyright laws, any unauthorized copying and   **\r
6 //** distribution is prohibited. Cypress reserves the right to change   ** \r
7 //** any of the functional specifications without any prior notice.     ** \r
8 //** Cypress is not liable for any damages which may result from the    **\r
9 //** use of this functional model.                                      **\r
10 //**                                                                    **\r
11 //** File Name  :   CY7C1356                                            **\r
12 //**                                                                    **\r
13 //** Revision   :   1.0 - 08/03/2004                                    **\r
14 //**                                                                    **\r
15 //** The timings are to be selected by the user depending upon the      **\r
16 //** frequency of operation from the datasheet.                         **\r
17 //**                                                                    **\r
18 //** Model      :   CY7C1356C - NoBL Pipelined SRAM             **\r
19 //** Queries    :   MPD Applications                                    **\r
20 //** Website:    www.cypress.com/support              **                \r
21 //************************************************************************\r
22 //************************************************************************\r
23 \r
24 `timescale  1ns /  10ps\r
25 \r
26 //      NOTE :  Any setup/hold errors will force input signal to x state\r
27 //              or if results indeterminant (write addr) core is reset x\r
28 \r
29 // define fixed values\r
30 \r
31 `define wordsize (18 -1)                //\r
32 `define no_words (1048576  -1)          // 1M x 18 RAM\r
33 \r
34 module cy1356 ( d, clk, a, bws, we_b, adv_lb, ce1b, ce2, ce3b, oeb, cenb, mode);\r
35 \r
36 inout   [`wordsize:0]   d;\r
37 input                   clk,            // clock input (R)\r
38                         we_b,           // byte write enable(L)\r
39                         adv_lb,         // burst(H)/load(L) address\r
40                         ce1b,           // chip enable(L)\r
41                         ce2,            // chip enable(H)\r
42                         ce3b,           // chip enable(L)\r
43                         oeb,            // async output enable(L)(read)\r
44                         cenb,           // clock enable(L)\r
45                         mode;           // interleave(H)/linear(L) burst\r
46 input   [1:0]           bws;            // byte write select(L)\r
47 input   [18:0]          a;              // address bus\r
48 \r
49 //      ***     NOTE DEVICE OPERATES #0.01 AFTER CLOCK          ***\r
50 //      *** THEREFORE DELAYS HAVE TO TAKE THIS INTO ACCOUNT     ***\r
51 \r
52 \r
53 //**********************************************************************\r
54 //  Timings for 225MHz\r
55 //**********************************************************************\r
56 `ifdef sb225\r
57   `define teohz #2.8\r
58   `define teolz #0\r
59   `define tchz #2.8\r
60   `define tclz #1.25\r
61   \r
62   `define tco   #2.8\r
63   `define tdoh  #1.25\r
64   `define tas 1.4                       \r
65   `define tah 0.4               \r
66 `endif\r
67 //***********************************************************************\r
68 //  Timings for 200MHz\r
69 //**********************************************************************\r
70 `ifdef sb200\r
71   `define teohz #3.2\r
72   `define teolz #0\r
73   `define tchz #3.2\r
74   `define tclz #1.5\r
75   \r
76   `define tco   #3.2\r
77   `define tdoh  #1.5\r
78 \r
79   `define tas 1.5                       \r
80   `define tah 0.5               \r
81 `endif\r
82 //***********************************************************************\r
83 \r
84 //**********************************************************************\r
85 //  This model is configured for 166 MHz Operation (CY7C1356-166). \r
86 //**********************************************************************\r
87 `ifdef sb166\r
88   `define teohz #3.5\r
89   `define teolz #0\r
90   `define tchz #3.5\r
91   `define tclz #1.5\r
92   \r
93   `define tco   #3.5\r
94   `define tdoh  #1.5\r
95 \r
96   `define tas 1.5                       \r
97   `define tah 0.5               \r
98 `endif\r
99 \r
100 reg             notifier;       // error support reg's\r
101 reg             noti1_0;\r
102 reg             noti1_1;\r
103 reg             noti1_2;\r
104 reg             noti1_3;\r
105 reg             noti1_4;\r
106 reg             noti1_5;\r
107 reg             noti1_6;\r
108 reg             noti2;\r
109 \r
110 \r
111 wire chipen;            // combined chip enable (high for an active chip)\r
112 \r
113 reg  chipen_d;          // _d = delayed\r
114 reg  chipen_o;          // _o = operational = delayed sig or _d sig\r
115 \r
116 wire writestate;        // holds 1 if any of writebus is low\r
117 reg  writestate_d;\r
118 reg  writestate_o;\r
119 \r
120 wire loadcyc;           // holds 1 for load cycles (setup and hold checks)\r
121 wire writecyc;          // holds 1 for write cycles (setup and hold checks)\r
122 wire [1:0] bws;         // holds the bws values\r
123 \r
124 wire [1:0] writebusb;   // holds the "internal" bws bus based on we_b\r
125 reg  [1:0] writebusb_d;\r
126 reg  [1:0] writebusb_o;\r
127 \r
128 wire [2:0] operation;   // holds chipen, adv_ld and writestate\r
129 reg  [2:0] operation_d;\r
130 reg  [2:0] operation_o;\r
131 \r
132 wire [18:0] a;          // address input bus\r
133 reg  [18:0] a_d;\r
134 reg  [18:0] a_o;\r
135 \r
136 reg  [`wordsize:0] do;          // data  output reg\r
137 reg  [`wordsize:0] di;          // data   input bus\r
138 reg  [`wordsize:0] dd;          // data delayed bus\r
139 \r
140 wire tristate;          // tristate output (on a bytewise basis) when asserted\r
141 reg  cetri;             // register set by chip disable which sets the tristate \r
142 reg  oetri;             // register set by oe which sets the tristate\r
143 reg  enable;            // register to make the ram enabled when equal to 1\r
144 reg  [18:0] addreg;     // register to hold the input address\r
145 reg  [`wordsize:0] pipereg;     // register for the output data\r
146 \r
147 reg  [`wordsize:0] mem [0:`no_words];   // RAM array\r
148 \r
149 reg  [`wordsize:0] writeword;   // temporary holding register for the write data\r
150 reg  burstinit;         // register to hold a[0] for burst type\r
151 reg  [18:0] i;          // temporary register used to write to all mem locs.\r
152 reg  writetri;          // tristate\r
153 reg  lw, bw;            // pipelined write functions\r
154 reg  we_bl;\r
155 \r
156 \r
157 wire [`wordsize:0]  d =  !tristate ?  do[`wordsize:0] : 18'bz ; //  data bus\r
158 \r
159 assign chipen           = (adv_lb == 1 ) ? chipen_d :\r
160                                 ~ce1b & ce2 & ~ce3b ;\r
161 \r
162 assign writestate       = ~& writebusb;\r
163 \r
164 assign operation        = {chipen, adv_lb, writestate};\r
165 \r
166 assign writebusb[1:0]   = (  we_b  ==0 & adv_lb ==0) ? bws[1:0]:\r
167                           (  we_b  ==1 & adv_lb ==0) ? 2'b11 :\r
168                           (  we_bl ==0 & adv_lb ==1) ? bws[1:0]:\r
169                           (  we_bl ==1 & adv_lb ==1) ? 2'b11 :\r
170                                                        2'bxx ;\r
171 \r
172 assign loadcyc          = chipen & !cenb;\r
173 \r
174 assign writecyc         = writestate_d & enable & ~cenb & chipen; // check\r
175 \r
176 assign tristate         = cetri | writetri | oetri;\r
177 \r
178 pullup    (mode); \r
179 \r
180 // formers for notices/errors etc\r
181 //\r
182 //$display("NOTICE      : xxx :");\r
183 //$display("WARNING     : xxx :");\r
184 //$display("ERROR   *** : xxx :");\r
185 \r
186 \r
187 // initialize the output to be tri-state, ram to be disabled\r
188 \r
189 initial\r
190         begin\r
191 // signals\r
192 \r
193           writetri      = 0;\r
194           cetri         = 1;\r
195           enable        = 0;\r
196           lw            = 0;\r
197           bw            = 0;\r
198 \r
199 // error signals \r
200 \r
201           notifier      = 0;\r
202           noti1_0       = 0;\r
203           noti1_1       = 0;\r
204           noti1_2       = 0;\r
205           noti1_3       = 0;\r
206           noti1_4       = 0;\r
207           noti1_5       = 0;\r
208           noti1_6       = 0;\r
209           noti2         = 0;  \r
210 \r
211 end\r
212 \r
213 \r
214 \r
215 // asynchronous OE\r
216 \r
217 always @(oeb)\r
218 begin\r
219   if (oeb == 1)\r
220     oetri <= `teohz 1;\r
221   else\r
222     oetri <= `teolz 0;\r
223 end\r
224 \r
225 //      ***     SETUP / HOLD VIOLATIONS         ***\r
226 \r
227 always @(noti2)\r
228 begin\r
229 $display("NOTICE      : 020 : Data bus    corruption");\r
230     force d =18'bx;\r
231     #1;\r
232     release d;\r
233 end\r
234 \r
235 always @(noti1_0)\r
236 begin\r
237 $display("NOTICE      : 010 : Byte write  corruption");\r
238     force bws = 2'bx;\r
239     #1;\r
240     release bws;\r
241 end\r
242 \r
243 always @(noti1_1)\r
244 begin\r
245 $display("NOTICE      : 011 : Byte enable corruption");\r
246     force we_b = 1'bx;\r
247     #1;\r
248     release we_b;\r
249 end\r
250 \r
251 always @(noti1_2)\r
252 begin\r
253 $display("NOTICE      : 012 : CE1B       corruption");\r
254     force ce1b =1'bx;\r
255     #1;\r
256     release ce1b;\r
257 end\r
258 \r
259 always @(noti1_3)\r
260 begin\r
261 $display("NOTICE      : 013 : CE2       corruption");\r
262     force ce2 =1'bx;\r
263     #1;\r
264    release ce2;\r
265 end\r
266 \r
267 always @(noti1_4)\r
268 begin\r
269 $display("NOTICE      : 014 : CE3B      corruption");\r
270     force ce3b =1'bx;\r
271     #1;\r
272     release ce3b;\r
273 end\r
274 \r
275 always @(noti1_5)\r
276 begin\r
277 $display("NOTICE      : 015 : CENB      corruption");\r
278     force cenb =1'bx;\r
279     #1;\r
280     release cenb;\r
281 end\r
282 \r
283 always @(noti1_6)\r
284 begin\r
285 $display("NOTICE      : 016 : ADV_LB   corruption");\r
286     force adv_lb = 1'bx;\r
287     #1;\r
288     release adv_lb;\r
289 end\r
290 \r
291 // synchronous functions from clk edge\r
292 \r
293 always @(posedge clk)\r
294 if (!cenb)\r
295 begin\r
296 #0.01;  \r
297   // latch conditions on adv_lb\r
298 \r
299   if (adv_lb) \r
300    we_bl                <=      we_bl;\r
301   else\r
302    we_bl                <=      we_b;\r
303 \r
304   chipen_d              <=      chipen;\r
305   \r
306 \r
307       chipen_o          <=      chipen;\r
308       writestate_o      <=      writestate;\r
309       writestate_d      <=      writestate_o;  \r
310       writebusb_o       <=      writebusb;\r
311       writebusb_d       <=      writebusb_o;\r
312       operation_o       <=      operation;\r
313       a_o               <=      a;\r
314       a_d               <=      a_o;\r
315       di                 =      d;\r
316 \r
317   // execute previously pipelined fns\r
318 \r
319   if (lw) begin                 \r
320                 loadwrite;\r
321                 lw =0;\r
322           end\r
323 \r
324   if (bw) begin\r
325                 burstwrite;\r
326                 bw =0;\r
327           end\r
328 \r
329   // decode input/piplined state\r
330 \r
331     casex (operation_o)\r
332     3'b0??      : turnoff;\r
333     3'b101      : setlw;\r
334     3'b111      : setbw;\r
335     3'b100      : loadread;\r
336     3'b110      : burstread;\r
337     default : unknown; // output unknown values and display an error message\r
338   endcase\r
339 \r
340    do <= `tco  pipereg;\r
341 \r
342 end\r
343 \r
344 //                      ***     task section    ***\r
345 \r
346 task read;\r
347 begin\r
348   if (enable) cetri <= `tclz 0;\r
349   writetri <= `tchz 0;\r
350   do <= `tdoh 18'hx;\r
351   pipereg = mem[addreg];\r
352 end\r
353 endtask\r
354 \r
355 task write;\r
356 begin\r
357   if (enable) cetri <= `tclz 0;\r
358   writeword = mem[addreg];  // set up a word to hold the data for the current location\r
359   /* overwrite the current word for the bytes being written to */\r
360   if (!writebusb_d[1]) writeword[17:9]  = di[17:9];\r
361   if (!writebusb_d[0]) writeword[8:0]   = di[8:0];\r
362   writeword = writeword &  writeword; //convert z to x states\r
363   mem[addreg] = writeword; // store the new word into the memory location\r
364   //writetri <= `tchz 1;    // tristate the outputs\r
365 end\r
366 endtask\r
367 \r
368 task setlw;\r
369 begin\r
370     lw =1;\r
371     writetri <= `tchz 1;    // tristate the outputs\r
372 end\r
373 endtask\r
374 \r
375 task setbw;\r
376 begin\r
377     bw =1;\r
378     writetri <= `tchz 1;    // tristate the outputs\r
379 end\r
380 endtask\r
381 \r
382 task loadread;\r
383 begin\r
384   burstinit = a_o[0];\r
385   addreg = a_o;\r
386   enable = 1;\r
387   read;\r
388 end\r
389 endtask\r
390 \r
391 task loadwrite;\r
392 begin\r
393   burstinit = a_d[0];\r
394   addreg = a_d;\r
395   enable = 1;\r
396   write;\r
397 end\r
398 endtask\r
399 \r
400 task burstread;\r
401 begin\r
402   burst;\r
403   read;\r
404 end\r
405 endtask\r
406 \r
407 task burstwrite;\r
408 begin\r
409   burst;\r
410   write;\r
411 end\r
412 endtask\r
413 \r
414 task unknown;\r
415 begin\r
416   do = 18'bx;\r
417   // $display ("Unknown function:  Operation = %b\n", operation);\r
418 end\r
419 endtask\r
420 \r
421 task turnoff;\r
422 begin\r
423   enable = 0;\r
424   cetri <= `tchz 1;\r
425   pipereg = 18'h0;\r
426 end\r
427 endtask\r
428 \r
429 task burst;\r
430 begin\r
431   if (burstinit == 0 || mode == 0)\r
432   begin\r
433     case (addreg[1:0])\r
434       2'b00:   addreg[1:0] = 2'b01;\r
435       2'b01:   addreg[1:0] = 2'b10;\r
436       2'b10:   addreg[1:0] = 2'b11;\r
437       2'b11:   addreg[1:0] = 2'b00;\r
438       default: addreg[1:0] = 2'bxx;\r
439     endcase\r
440   end\r
441   else\r
442   begin\r
443     case (addreg[1:0])\r
444       2'b00:   addreg[1:0] = 2'b11;\r
445       2'b01:   addreg[1:0] = 2'b00;\r
446       2'b10:   addreg[1:0] = 2'b01;\r
447       2'b11:   addreg[1:0] = 2'b10;\r
448       default: addreg[1:0] = 2'bxx;\r
449     endcase\r
450   end\r
451 end\r
452 endtask\r
453 \r
454 // IO checks\r
455 \r
456 specify\r
457 // specify the setup and hold checks\r
458 \r
459 // notifier will wipe memory as result is indeterminent\r
460 \r
461 $setuphold(posedge clk &&& loadcyc, a, `tas, `tah, notifier);\r
462 \r
463 // noti1 should make ip = 'bx;\r
464 \r
465 $setuphold(posedge clk, bws,  `tas, `tah, noti1_0);\r
466 \r
467 $setuphold(posedge clk, we_b, `tas, `tah, noti1_1);\r
468 $setuphold(posedge clk, ce1b, `tas, `tah, noti1_2);\r
469 $setuphold(posedge clk,  ce2, `tas, `tah, noti1_3);\r
470 $setuphold(posedge clk, ce3b, `tas, `tah, noti1_4);\r
471 \r
472 // noti2 should make d = 18'hxxxxx;\r
473 \r
474 $setuphold(posedge clk &&& writecyc, d, `tas, `tah, noti2);\r
475 \r
476 // add extra tests here.\r
477 \r
478 $setuphold(posedge clk,   cenb, `tas, `tah, noti1_5);\r
479 $setuphold(posedge clk, adv_lb, `tas, `tah, noti1_6);\r
480 \r
481 endspecify\r
482 \r
483 endmodule\r
484 \r
485 \r