updated wiki url
[debian/gnuradio] / usrp2 / fpga / models / M24LC02B.v
1 // *******************************************************************************************************\r
2 // **                                                                                                   **\r
3 // **   M24LC02B.v - 24LC02B 2K-BIT I2C SERIAL EEPROM (VCC = +2.5V TO +5.5V)                            **\r
4 // **                                                                                                   **\r
5 // *******************************************************************************************************\r
6 // **                                                                                                   **\r
7 // **                              COPYRIGHT (c) 2003 YOUNG ENGINEERING                                 **\r
8 // **                                      ALL RIGHTS RESERVED                                          **\r
9 // **                                                                                                   **\r
10 // **   THIS PROGRAM IS CONFIDENTIAL AND  A  TRADE SECRET  OF  YOUNG  ENGINEERING.  THE RECEIPT OR      **\r
11 // **   POSSESSION  OF THIS PROGRAM  DOES NOT  CONVEY  ANY  RIGHTS TO  REPRODUCE  OR  DISCLOSE ITS      **\r
12 // **   CONTENTS,  OR TO MANUFACTURE, USE, OR SELL  ANYTHING  THAT IT MAY DESCRIBE, IN WHOLE OR IN      **\r
13 // **   PART, WITHOUT THE SPECIFIC WRITTEN CONSENT OF YOUNG ENGINEERING.                                **\r
14 // **                                                                                                   **\r
15 // *******************************************************************************************************\r
16 // **   Revision       : 1.1                                                                            **\r
17 // **   Modified Date  : 07/19/2004                                                                     **\r
18 // **   Revision History:                                                                               **\r
19 // **                                                                                                   **\r
20 // **   02/01/2003:  Initial design                                                                     **\r
21 // **   07/19/2004:  Fixed the timing checks and the open-drain modeling for SDA.                       **\r
22 // **                                                                                                   **\r
23 // *******************************************************************************************************\r
24 // **                                       TABLE OF CONTENTS                                           **\r
25 // *******************************************************************************************************\r
26 // **---------------------------------------------------------------------------------------------------**\r
27 // **   DECLARATIONS                                                                                    **\r
28 // **---------------------------------------------------------------------------------------------------**\r
29 // **---------------------------------------------------------------------------------------------------**\r
30 // **   INITIALIZATION                                                                                  **\r
31 // **---------------------------------------------------------------------------------------------------**\r
32 // **---------------------------------------------------------------------------------------------------**\r
33 // **   CORE LOGIC                                                                                      **\r
34 // **---------------------------------------------------------------------------------------------------**\r
35 // **   1.01:  START Bit Detection                                                                      **\r
36 // **   1.02:  STOP Bit Detection                                                                       **\r
37 // **   1.03:  Input Shift Register                                                                     **\r
38 // **   1.04:  Input Bit Counter                                                                        **\r
39 // **   1.05:  Control Byte Register                                                                    **\r
40 // **   1.06:  Byte Address Register                                                                    **\r
41 // **   1.07:  Write Data Buffer                                                                        **\r
42 // **   1.08:  Acknowledge Generator                                                                    **\r
43 // **   1.09:  Acknowledge Detect                                                                       **\r
44 // **   1.10:  Write Cycle Timer                                                                        **\r
45 // **   1.11:  Write Cycle Processor                                                                    **\r
46 // **   1.12:  Read Data Multiplexor                                                                    **\r
47 // **   1.13:  Read Data Processor                                                                      **\r
48 // **   1.14:  SDA Data I/O Buffer                                                                      **\r
49 // **                                                                                                   **\r
50 // **---------------------------------------------------------------------------------------------------**\r
51 // **   DEBUG LOGIC                                                                                     **\r
52 // **---------------------------------------------------------------------------------------------------**\r
53 // **   2.01:  Memory Data Bytes                                                                        **\r
54 // **   2.02:  Write Data Buffer                                                                        **\r
55 // **                                                                                                   **\r
56 // **---------------------------------------------------------------------------------------------------**\r
57 // **   TIMING CHECKS                                                                                   **\r
58 // **---------------------------------------------------------------------------------------------------**\r
59 // **                                                                                                   **\r
60 // *******************************************************************************************************\r
61 \r
62 \r
63 `timescale 1ns/10ps\r
64 \r
65 module M24LC02B (A0, A1, A2, WP, SDA, SCL, RESET);\r
66 \r
67    input                A0;                             // unconnected pin\r
68    input                A1;                             // unconnected pin\r
69    input                A2;                             // unconnected pin\r
70 \r
71    input                WP;                             // write protect pin\r
72 \r
73    inout                SDA;                            // serial data I/O\r
74    input                SCL;                            // serial data clock\r
75 \r
76    input                RESET;                          // system reset\r
77 \r
78 \r
79 // *******************************************************************************************************\r
80 // **   DECLARATIONS                                                                                    **\r
81 // *******************************************************************************************************\r
82 \r
83    reg                  SDA_DO;                         // serial data - output\r
84    reg                  SDA_OE;                         // serial data - output enable\r
85 \r
86    wire                 SDA_DriveEnable;                // serial data output enable\r
87    reg                  SDA_DriveEnableDlyd;            // serial data output enable - delayed\r
88 \r
89    reg  [03:00]         BitCounter;                     // serial bit counter\r
90 \r
91    reg                  START_Rcvd;                     // START bit received flag\r
92    reg                  STOP_Rcvd;                      // STOP bit received flag\r
93    reg                  CTRL_Rcvd;                      // control byte received flag\r
94    reg                  ADDR_Rcvd;                      // byte address received flag\r
95    reg                  MACK_Rcvd;                      // master acknowledge received flag\r
96 \r
97    reg                  WrCycle;                        // memory write cycle\r
98    reg                  RdCycle;                        // memory read cycle\r
99 \r
100    reg  [07:00]         ShiftRegister;                  // input data shift register\r
101 \r
102    reg  [07:00]         ControlByte;                    // control byte register\r
103    wire                 RdWrBit;                        // read/write control bit\r
104 \r
105    reg  [07:00]         StartAddress;                   // memory access starting address\r
106    reg  [02:00]         PageAddress;                    // memory page address\r
107 \r
108    reg  [07:00]         WrDataByte [0:7];               // memory write data buffer\r
109    wire [07:00]         RdDataByte;                     // memory read data\r
110 \r
111    reg  [15:00]         WrCounter;                      // write buffer counter\r
112 \r
113    reg  [02:00]         WrPointer;                      // write buffer pointer\r
114    reg  [07:00]         RdPointer;                      // read address pointer\r
115 \r
116    reg                  WriteActive;                    // memory write cycle active\r
117 \r
118    reg  [07:00]         MemoryBlock [0:255];            // EEPROM data memory array\r
119 \r
120    integer              LoopIndex;                      // iterative loop index\r
121 \r
122    integer              tAA;                            // timing parameter\r
123    integer              tWC;                            // timing parameter\r
124 \r
125 \r
126 // *******************************************************************************************************\r
127 // **   INITIALIZATION                                                                                  **\r
128 // *******************************************************************************************************\r
129 \r
130    initial tAA = 900;                                   // SCL to SDA output delay\r
131    initial tWC = 5000000;                               // memory write cycle time\r
132 \r
133    initial begin\r
134       SDA_DO = 0;\r
135       SDA_OE = 0;\r
136    end\r
137 \r
138    initial begin\r
139       START_Rcvd = 0;\r
140       STOP_Rcvd  = 0;\r
141       CTRL_Rcvd  = 0;\r
142       ADDR_Rcvd  = 0;\r
143       MACK_Rcvd  = 0;\r
144    end\r
145 \r
146    initial begin\r
147       BitCounter  = 0;\r
148       ControlByte = 0;\r
149    end\r
150 \r
151    initial begin\r
152       WrCycle = 0;\r
153       RdCycle = 0;\r
154 \r
155       WriteActive = 0;\r
156    end\r
157 \r
158 \r
159 // *******************************************************************************************************\r
160 // **   CORE LOGIC                                                                                      **\r
161 // *******************************************************************************************************\r
162 // -------------------------------------------------------------------------------------------------------\r
163 //      1.01:  START Bit Detection\r
164 // -------------------------------------------------------------------------------------------------------\r
165 \r
166    always @(negedge SDA) begin\r
167       if (SCL == 1) begin\r
168          START_Rcvd <= 1;\r
169          STOP_Rcvd  <= 0;\r
170          CTRL_Rcvd  <= 0;\r
171          ADDR_Rcvd  <= 0;\r
172          MACK_Rcvd  <= 0;\r
173 \r
174          WrCycle <= #1 0;\r
175          RdCycle <= #1 0;\r
176 \r
177          BitCounter <= 0;\r
178       end\r
179    end\r
180 \r
181 // -------------------------------------------------------------------------------------------------------\r
182 //      1.02:  STOP Bit Detection\r
183 // -------------------------------------------------------------------------------------------------------\r
184 \r
185    always @(posedge SDA) begin\r
186       if (SCL == 1) begin\r
187          START_Rcvd <= 0;\r
188          STOP_Rcvd  <= 1;\r
189          CTRL_Rcvd  <= 0;\r
190          ADDR_Rcvd  <= 0;\r
191          MACK_Rcvd  <= 0;\r
192 \r
193          WrCycle <= #1 0;\r
194          RdCycle <= #1 0;\r
195 \r
196          BitCounter <= 10;\r
197       end\r
198    end\r
199 \r
200 // -------------------------------------------------------------------------------------------------------\r
201 //      1.03:  Input Shift Register\r
202 // -------------------------------------------------------------------------------------------------------\r
203 \r
204    always @(posedge SCL) begin\r
205       ShiftRegister[00] <= SDA;\r
206       ShiftRegister[01] <= ShiftRegister[00];\r
207       ShiftRegister[02] <= ShiftRegister[01];\r
208       ShiftRegister[03] <= ShiftRegister[02];\r
209       ShiftRegister[04] <= ShiftRegister[03];\r
210       ShiftRegister[05] <= ShiftRegister[04];\r
211       ShiftRegister[06] <= ShiftRegister[05];\r
212       ShiftRegister[07] <= ShiftRegister[06];\r
213    end\r
214 \r
215 // -------------------------------------------------------------------------------------------------------\r
216 //      1.04:  Input Bit Counter\r
217 // -------------------------------------------------------------------------------------------------------\r
218 \r
219    always @(posedge SCL) begin\r
220       if (BitCounter < 10) BitCounter <= BitCounter + 1;\r
221    end\r
222 \r
223 // -------------------------------------------------------------------------------------------------------\r
224 //      1.05:  Control Byte Register\r
225 // -------------------------------------------------------------------------------------------------------\r
226 \r
227    always @(negedge SCL) begin\r
228       if (START_Rcvd & (BitCounter == 8)) begin\r
229          if (!WriteActive & (ShiftRegister[07:04] == 4'b1010)) begin\r
230             if (ShiftRegister[00] == 0) WrCycle <= 1;\r
231             if (ShiftRegister[00] == 1) RdCycle <= 1;\r
232 \r
233             ControlByte <= ShiftRegister[07:00];\r
234 \r
235             CTRL_Rcvd <= 1;\r
236          end\r
237 \r
238          START_Rcvd <= 0;\r
239       end\r
240    end\r
241 \r
242    assign RdWrBit     = ControlByte[00];\r
243 \r
244 // -------------------------------------------------------------------------------------------------------\r
245 //      1.06:  Byte Address Register\r
246 // -------------------------------------------------------------------------------------------------------\r
247 \r
248    always @(negedge SCL) begin\r
249       if (CTRL_Rcvd & (BitCounter == 8)) begin\r
250          if (RdWrBit == 0) begin\r
251             StartAddress <= ShiftRegister[07:00];\r
252             RdPointer    <= ShiftRegister[07:00];\r
253 \r
254             ADDR_Rcvd <= 1;\r
255          end\r
256 \r
257          WrCounter <= 0;\r
258          WrPointer <= 0;\r
259 \r
260          CTRL_Rcvd <= 0;\r
261       end\r
262    end\r
263 \r
264 // -------------------------------------------------------------------------------------------------------\r
265 //      1.07:  Write Data Buffer\r
266 // -------------------------------------------------------------------------------------------------------\r
267 \r
268    always @(negedge SCL) begin\r
269       if (ADDR_Rcvd & (BitCounter == 8)) begin\r
270          if ((WP == 0) & (RdWrBit == 0)) begin\r
271             WrDataByte[WrPointer] <= ShiftRegister[07:00];\r
272 \r
273             WrCounter <= WrCounter + 1;\r
274             WrPointer <= WrPointer + 1;\r
275          end\r
276       end\r
277    end\r
278 \r
279 // -------------------------------------------------------------------------------------------------------\r
280 //      1.08:  Acknowledge Generator\r
281 // -------------------------------------------------------------------------------------------------------\r
282 \r
283    always @(negedge SCL) begin\r
284       if (!WriteActive) begin\r
285          if (BitCounter == 8) begin\r
286             if (WrCycle | (START_Rcvd & (ShiftRegister[07:04] == 4'b1010))) begin\r
287                SDA_DO <= 0;\r
288                SDA_OE <= 1;\r
289             end \r
290          end\r
291          if (BitCounter == 9) begin\r
292             BitCounter <= 0;\r
293 \r
294             if (!RdCycle) begin\r
295                SDA_DO <= 0;\r
296                SDA_OE <= 0;\r
297             end\r
298          end\r
299       end\r
300    end \r
301 \r
302 // -------------------------------------------------------------------------------------------------------\r
303 //      1.09:  Acknowledge Detect\r
304 // -------------------------------------------------------------------------------------------------------\r
305 \r
306    always @(posedge SCL) begin\r
307       if (RdCycle & (BitCounter == 8)) begin\r
308          if ((SDA == 0) & (SDA_OE == 0)) MACK_Rcvd <= 1;\r
309       end\r
310    end\r
311 \r
312    always @(negedge SCL) MACK_Rcvd <= 0;\r
313 \r
314 // -------------------------------------------------------------------------------------------------------\r
315 //      1.10:  Write Cycle Timer\r
316 // -------------------------------------------------------------------------------------------------------\r
317 \r
318    always @(posedge STOP_Rcvd) begin\r
319       if (WrCycle & (WP == 0) & (WrCounter > 0)) begin\r
320          WriteActive = 1;\r
321          #(tWC);\r
322          WriteActive = 0;\r
323       end\r
324    end\r
325 \r
326    always @(posedge STOP_Rcvd) begin\r
327       #(1.0);\r
328       STOP_Rcvd = 0;\r
329    end\r
330 \r
331 // -------------------------------------------------------------------------------------------------------\r
332 //      1.11:  Write Cycle Processor\r
333 // -------------------------------------------------------------------------------------------------------\r
334 \r
335    always @(posedge WriteActive) begin\r
336       for (LoopIndex = 0; LoopIndex < WrCounter; LoopIndex = LoopIndex + 1) begin\r
337          PageAddress = StartAddress[02:00] + LoopIndex;\r
338 \r
339          MemoryBlock[{StartAddress[07:03],PageAddress[02:00]}] = WrDataByte[LoopIndex[02:00]];\r
340       end\r
341    end\r
342 \r
343 // -------------------------------------------------------------------------------------------------------\r
344 //      1.12:  Read Data Multiplexor\r
345 // -------------------------------------------------------------------------------------------------------\r
346 \r
347    always @(negedge SCL) begin\r
348       if (BitCounter == 8) begin\r
349          if (WrCycle & ADDR_Rcvd) begin\r
350             RdPointer <= StartAddress + WrPointer + 1;\r
351          end\r
352          if (RdCycle) begin\r
353             RdPointer <= RdPointer + 1;\r
354          end\r
355       end\r
356    end\r
357 \r
358    assign RdDataByte = MemoryBlock[RdPointer[07:00]];\r
359 \r
360 // -------------------------------------------------------------------------------------------------------\r
361 //      1.13:  Read Data Processor\r
362 // -------------------------------------------------------------------------------------------------------\r
363 \r
364    always @(negedge SCL) begin\r
365       if (RdCycle) begin\r
366          if (BitCounter == 8) begin\r
367             SDA_DO <= 0;\r
368             SDA_OE <= 0;\r
369          end\r
370          else if (BitCounter == 9) begin\r
371             SDA_DO <= RdDataByte[07];\r
372 \r
373             if (MACK_Rcvd) SDA_OE <= 1;\r
374          end\r
375          else begin\r
376             SDA_DO <= RdDataByte[7-BitCounter];\r
377          end\r
378       end\r
379    end\r
380 \r
381 // -------------------------------------------------------------------------------------------------------\r
382 //      1.14:  SDA Data I/O Buffer\r
383 // -------------------------------------------------------------------------------------------------------\r
384 \r
385    bufif1 (SDA, 1'b0, SDA_DriveEnableDlyd);\r
386 \r
387    assign SDA_DriveEnable = !SDA_DO & SDA_OE;\r
388    always @(SDA_DriveEnable) SDA_DriveEnableDlyd <= #(tAA) SDA_DriveEnable;\r
389 \r
390 \r
391 // *******************************************************************************************************\r
392 // **   DEBUG LOGIC                                                                                     **\r
393 // *******************************************************************************************************\r
394 // -------------------------------------------------------------------------------------------------------\r
395 //      2.01:  Memory Data Bytes\r
396 // -------------------------------------------------------------------------------------------------------\r
397 \r
398    wire [07:00] MemoryByte00 = MemoryBlock[00];\r
399    wire [07:00] MemoryByte01 = MemoryBlock[01];\r
400    wire [07:00] MemoryByte02 = MemoryBlock[02];\r
401    wire [07:00] MemoryByte03 = MemoryBlock[03];\r
402    wire [07:00] MemoryByte04 = MemoryBlock[04];\r
403    wire [07:00] MemoryByte05 = MemoryBlock[05];\r
404    wire [07:00] MemoryByte06 = MemoryBlock[06];\r
405    wire [07:00] MemoryByte07 = MemoryBlock[07];\r
406 \r
407    wire [07:00] MemoryByte08 = MemoryBlock[08];\r
408    wire [07:00] MemoryByte09 = MemoryBlock[09];\r
409    wire [07:00] MemoryByte0A = MemoryBlock[10];\r
410    wire [07:00] MemoryByte0B = MemoryBlock[11];\r
411    wire [07:00] MemoryByte0C = MemoryBlock[12];\r
412    wire [07:00] MemoryByte0D = MemoryBlock[13];\r
413    wire [07:00] MemoryByte0E = MemoryBlock[14];\r
414    wire [07:00] MemoryByte0F = MemoryBlock[15];\r
415 \r
416 // -------------------------------------------------------------------------------------------------------\r
417 //      2.02:  Write Data Buffer\r
418 // -------------------------------------------------------------------------------------------------------\r
419 \r
420    wire [07:00] WriteData_0 = WrDataByte[00];\r
421    wire [07:00] WriteData_1 = WrDataByte[01];\r
422    wire [07:00] WriteData_2 = WrDataByte[02];\r
423    wire [07:00] WriteData_3 = WrDataByte[03];\r
424    wire [07:00] WriteData_4 = WrDataByte[04];\r
425    wire [07:00] WriteData_5 = WrDataByte[05];\r
426    wire [07:00] WriteData_6 = WrDataByte[06];\r
427    wire [07:00] WriteData_7 = WrDataByte[07];\r
428 \r
429 \r
430 // *******************************************************************************************************\r
431 // **   TIMING CHECKS                                                                                   **\r
432 // *******************************************************************************************************\r
433 \r
434    wire TimingCheckEnable = (RESET == 0) & (SDA_OE == 0);\r
435 \r
436    specify\r
437       specparam\r
438          tHI = 600,                                     // SCL pulse width - high\r
439          tLO = 1300,                                    // SCL pulse width - low\r
440          tSU_STA = 600,                                 // SCL to SDA setup time\r
441          tHD_STA = 600,                                 // SCL to SDA hold time\r
442          tSU_DAT = 100,                                 // SDA to SCL setup time\r
443          tSU_STO = 600;                                 // SCL to SDA setup time\r
444 \r
445       $width (posedge SCL, tHI);\r
446       $width (negedge SCL, tLO);\r
447 \r
448       $setup (SCL, negedge SDA &&& TimingCheckEnable, tSU_STA);\r
449       $setup (SDA, posedge SCL &&& TimingCheckEnable, tSU_DAT);\r
450       $setup (SCL, posedge SDA &&& TimingCheckEnable, tSU_STO);\r
451 \r
452       $hold  (negedge SDA &&& TimingCheckEnable, SCL, tHD_STA);\r
453    endspecify\r
454 \r
455 endmodule\r