e00f5e586bfc85ff7874f473703638aa212b4027
[fleet.git] / src / edu / berkeley / fleet / fpga / main.v
1 `timescale 1ps / 1ps
2
3 //  Copyright (c) 2005-2006, Regents of the University of California
4 //  All rights reserved.
5 //
6 //  Redistribution and use in source and binary forms, with or without modification,
7 //  are permitted provided that the following conditions are met:
8 //
9 //      - Redistributions of source code must retain the above copyright notice,
10 //          this list of conditions and the following disclaimer.
11 //      - Redistributions in binary form must reproduce the above copyright
12 //          notice, this list of conditions and the following disclaimer
13 //          in the documentation and/or other materials provided with the
14 //          distribution.
15 //      - Neither the name of the University of California, Berkeley nor the
16 //          names of its contributors may be used to endorse or promote
17 //          products derived from this software without specific prior
18 //          written permission.
19 //
20 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 //  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 //  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24 //  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 //  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 //  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 //  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 //----------------------------------------------------------------------------
32 // user_fifo.v
33 //----------------------------------------------------------------------------
34
35 `timescale 1ps / 1ps
36
37 module user_fifo
38   (
39    // FIFO interface ports
40    WrFifo_Din,                  // Write FIFO data-in
41    WrFifo_WrEn,                 // Write FIFO write enable
42    WrFifo_Full,                 // Write FIFO full
43    WrFifo_WrCnt,                // Write FIFO write count
44    RdFifo_Dout,                 // Read FIFO data-out
45    RdFifo_RdEn,                 // Read FIFO read enable
46    RdFifo_Empty,                // Read FIFO empty
47    RdFifo_RdCnt,                // Read FIFO read count
48    User_Rst,                    // User reset
49    User_Clk,                    // User clock
50    Sys_Rst,                     // System clock reset
51    Sys_Clk,                     // 100MHz system clock for CCLK generation
52
53    // SelectMAP interface ports
54    D_I,                         // Data bus input
55    D_O,                         // Data bus output
56    D_T,                         // Data bus tristate enable
57    RDWR_B,                      // Read/write signal
58    CS_B,                        // Chip select
59    INIT_B,                      // Initialization/interrupt signal
60    CCLK                         // CCLK output
61    );
62
63    // FIFO interface ports
64    input [0:7]         WrFifo_Din;
65    input               WrFifo_WrEn;
66    output              WrFifo_Full;
67    output [0:7]        WrFifo_WrCnt;
68    output [0:7]        RdFifo_Dout;
69    input               RdFifo_RdEn;
70    output              RdFifo_Empty;
71    output [0:7]        RdFifo_RdCnt;
72    input               User_Rst;
73    input               User_Clk;
74    input               Sys_Rst;
75    input               Sys_Clk;
76
77    // SelectMAP protocol ports
78    input [0:7]         D_I;
79    output [0:7]        D_O;
80    output [0:7]        D_T;
81    input               RDWR_B;
82    input               CS_B;
83    output              INIT_B;
84    output              CCLK;
85
86    //   ____        __ _       _ _   _                   //
87    //  |  _ \  ___ / _(_)_ __ (_) |_(_) ___  _ __  ___   //
88    //  | | | |/ _ \ |_| | '_ \| | __| |/ _ \| '_ \/ __|  //
89    //  | |_| |  __/  _| | | | | | |_| | (_) | | | \__ \  //
90    //  |____/ \___|_| |_|_| |_|_|\__|_|\___/|_| |_|___/  //
91    //                                                    //
92
93    //----------------------------------------------------------------------------
94    // Signal definitions
95    //----------------------------------------------------------------------------
96    // Write FIFO signals
97    wire [0:7]          WrFifo_Dout;
98    wire                WrFifo_Empty;
99    wire                WrFifo_RdEn;
100    wire [0:7]          WrFifo_RdCnt;
101    wire [0:7]          WrFifo_RdCnt_int;
102    wire [0:7]          WrFifo_WrCnt_int;
103
104    // Read FIFO signals
105    wire [0:7]          RdFifo_Din;
106    wire                RdFifo_Full;
107    wire                RdFifo_WrEn;
108    wire [0:7]          RdFifo_WrCnt;
109    wire [0:7]          RdFifo_WrCnt_int;
110    wire [0:7]          RdFifo_RdCnt_int;
111
112    //----------------------------------------------------------------------------
113    // IO Registers
114    //----------------------------------------------------------------------------
115    reg                 CCLK;
116
117    reg [0:7]           D_I_reg;    // synthesis attribute iob of D_I_reg is true;
118    reg [0:7]           D_O_reg;    // synthesis attribute iob of D_O_reg is true;
119    reg                 RDWR_B_reg; // synthesis attribute iob of RDWR_B_reg is true;
120    reg                 CS_B_reg;   // synthesis attribute iob of CS_B_reg is true;
121    reg                 INIT_B_reg; // synthesis attribute iob of INIT_B_reg is true;
122
123    // Outputs
124    assign              D_O = D_O_reg;
125    assign              INIT_B = INIT_B_reg;
126
127    // Inputs
128    always @( posedge Sys_Clk )
129      begin
130         D_I_reg    <= D_I;
131         RDWR_B_reg <= RDWR_B;
132         CS_B_reg   <= CS_B;
133      end
134
135    //----------------------------------------------------------------------------
136    // Generate CCLK and associated reset
137    //----------------------------------------------------------------------------
138    reg                SYNC_done;
139    reg                SYNC_done_dly;
140    reg                CS_B_reg_dly;
141
142    always @( posedge Sys_Clk )
143      begin
144         CS_B_reg_dly <= CS_B_reg;
145      end
146
147    always @( posedge Sys_Clk )
148      begin
149         if (Sys_Rst)
150           SYNC_done <= 1'b0;
151         else if (RDWR_B_reg && ~CS_B_reg)
152           SYNC_done <= 1'b1;
153      end
154
155    always @( posedge Sys_Clk )
156      begin
157         if (Sys_Rst)
158           SYNC_done_dly <= 1'b0;
159         else
160           SYNC_done_dly <= SYNC_done;
161      end
162
163    always @( posedge Sys_Clk )
164      begin
165         if (Sys_Rst)
166           CCLK <= 1'b0;
167         else if (~CS_B_reg && CS_B_reg_dly && CCLK)
168           CCLK <= 1'b1;
169         else
170           CCLK <= ~CCLK;
171      end
172
173    //   _____ ___ _____ ___        //
174    //  |  ___|_ _|  ___/ _ \ ___   //
175    //  | |_   | || |_ | | | / __|  //
176    //  |  _|  | ||  _|| |_| \__ \  //
177    //  |_|   |___|_|   \___/|___/  //
178    //                              //
179    // Write FIFO:  The write is with respect to the user.  The user writes data to this
180    //              FIFO and the control side of SelectMAP reads the data.
181    //
182    // Read FIFO:  The read is with respect to the user.  The user reads data sent from the
183    //             control side of SelectMAP.
184    //
185
186    //----------------------------------------------------------------------------
187    // Read FIFO
188    //----------------------------------------------------------------------------
189    assign RdFifo_WrEn = SYNC_done_dly && ~RDWR_B_reg && ~CS_B_reg && ~RdFifo_Full && CCLK;
190    assign RdFifo_Din = D_I_reg;
191
192    async_fifo_8_8_128 RdFifo( .din( RdFifo_Din ),
193                   .dout( RdFifo_Dout ),
194                   .rd_clk( User_Clk ),
195                   .rd_en( RdFifo_RdEn ),
196                   .wr_clk( Sys_Clk ),
197                   .wr_en( RdFifo_WrEn ),
198                   .rst( User_Rst ),
199                   .empty( RdFifo_Empty ),
200                   .full( RdFifo_Full ),
201                   .rd_data_count( RdFifo_RdCnt_int ),
202                   .wr_data_count( RdFifo_WrCnt_int ) );
203
204    assign RdFifo_WrCnt = 8'd129 - RdFifo_WrCnt_int;
205    assign RdFifo_RdCnt = RdFifo_RdCnt_int;
206
207    //----------------------------------------------------------------------------
208    // Write FIFO
209    //----------------------------------------------------------------------------
210    assign WrFifo_RdEn = SYNC_done_dly && RDWR_B_reg && ~CS_B_reg && ~WrFifo_Empty && CCLK;
211
212    async_fifo_8_8_128 WrFifo( .din( WrFifo_Din ),
213                   .dout( WrFifo_Dout ),
214                   .rd_clk( Sys_Clk ),
215                   .rd_en( WrFifo_RdEn ),
216                   .wr_clk( User_Clk ),
217                   .wr_en( WrFifo_WrEn ),
218                   .rst( User_Rst ),
219                   .empty( WrFifo_Empty ),
220                   .full( WrFifo_Full ),
221                   .rd_data_count( WrFifo_RdCnt_int ),
222                   .wr_data_count( WrFifo_WrCnt_int ) );
223
224    assign WrFifo_WrCnt = 8'd129 - WrFifo_WrCnt_int;
225    assign WrFifo_RdCnt = WrFifo_RdCnt_int;
226
227    //   ____       _           _   __  __    _    ____    //
228    //  / ___|  ___| | ___  ___| |_|  \/  |  / \  |  _ \   //
229    //  \___ \ / _ \ |/ _ \/ __| __| |\/| | / _ \ | |_) |  //
230    //   ___) |  __/ |  __/ (__| |_| |  | |/ ___ \|  __/   //
231    //  |____/ \___|_|\___|\___|\__|_|  |_/_/   \_\_|      //
232    //                                                     //
233
234    //----------------------------------------------------------------------------
235    // SelectMAP control outputs
236    //----------------------------------------------------------------------------
237    wire [0:7] DataCnt = RDWR_B_reg ? WrFifo_RdCnt : RdFifo_WrCnt;
238
239    assign     D_T    = {8{(~RDWR_B & ~CS_B)}}; // stop driving if master is sending
240
241    always @( posedge Sys_Clk )
242      begin
243         D_O_reg    <= CS_B_reg ? DataCnt : WrFifo_Dout;
244         INIT_B_reg <= WrFifo_Empty;
245      end
246
247    //----------------------------------------------------------------------------
248
249 endmodule
250
251
252 module main
253   (
254    // User clock ports
255    Clkin_p,
256    Clkin_m,
257    
258    // SelectMAP interface ports
259    D,                           // Data bus
260    RDWR_B,                      // Read/write signal
261    CS_B,                        // Chip select
262    INIT_B,                      // Initialization/interrupt signal
263    CCLK,                        // Local CCLK output
264    gpleds
265    );
266
267    // User clock/reset ports
268    input                       Clkin_p;
269    input                       Clkin_m;
270   
271    // SelectMAP protocol ports
272    inout [0:7]                 D;
273    input                       RDWR_B;
274    input                       CS_B;
275    output                      INIT_B;
276    output                      CCLK;
277    output [6:1] gpleds;
278
279
280    // Wires
281    wire                        CCLK_int;
282    
283    wire [0:31]                 LoopData;
284    wire [0:31]                 LoopDataW;
285    wire                        LoopEmpty;
286    wire                        LoopFull;
287
288    wire [0:7]                  D_I;
289    wire [0:7]                  D_O;
290    wire [0:7]                  D_T;
291
292    wire                        User_Clk;
293    wire                        User_Rst;
294
295    reg  [6:1]                  gpleds_reg;
296
297    // synthesis attribute tig of activate_r is yes; 
298    wire   activate_r;
299    // synthesis attribute tig of activate_a is yes; 
300    wire   activate_a;
301
302    wire [7:0] write_data;
303    wire       write_enable;
304    wire       write_full;
305
306    wire [7:0] read_data;
307    wire       read_empty;
308    wire [7:0] read_wire;
309
310    reg  [7:0] write_reg;
311    reg  [7:0] read_reg;
312
313    reg [7:0] read_in;
314    wire read_enable;
315    reg read_enable_reg;
316    reg write_enable_reg;
317
318    reg root_out_a_reg;
319    reg root_in_r_reg;
320    reg [7:0] root_in_d_reg;
321    wire root_in_a;
322    wire root_in_r;
323    wire root_out_a;
324    wire root_out_r;
325    wire [7:0] root_in_d;
326
327    root my_root(User_Clk, root_in_r, root_in_a, root_in_d,
328                           root_out_r, root_out_a, write_data);
329
330    assign root_out_a = root_out_a_reg;                
331    assign root_in_r  = root_in_r_reg;
332    assign read_enable = read_enable_reg;
333    assign write_enable = write_enable_reg;
334    assign root_in_d = root_in_d_reg;
335
336    // fpga -> host
337    always @(posedge User_Clk)
338    begin
339      write_enable_reg = 0;
340      if (root_out_r && !root_out_a_reg && !write_full) begin
341        write_enable_reg = 1;
342        root_out_a_reg = 1;
343      end else if (root_out_a_reg && !root_out_r) begin
344        root_out_a_reg = 0;
345      end
346      gpleds_reg[4] = write_enable_reg;
347      gpleds_reg[5] = root_out_r;
348      gpleds_reg[6] = root_out_a_reg;
349    end
350
351    // host -> fpga
352    always @(posedge User_Clk)
353    begin
354      read_enable_reg = 0;
355      if (!read_empty && !root_in_r_reg && !root_in_a) begin
356         root_in_r_reg = 1;
357         root_in_d_reg = read_data;
358         read_enable_reg = 1;
359      end else begin
360         if (root_in_a) begin
361           root_in_r_reg = 0;
362         end
363      end
364      gpleds_reg[1] = read_enable_reg;
365      gpleds_reg[2] = root_in_r_reg;
366      gpleds_reg[3] = root_in_a;
367    end
368
369    assign gpleds = gpleds_reg;
370
371    initial
372    begin
373      gpleds_reg    = 0;
374      root_in_r_reg = 0;
375      root_in_d_reg = 0;
376      root_out_a_reg = 0;
377      root_in_r_reg = 0;
378      read_enable_reg = 0;
379      read_reg = 0;
380      read_in = 255;
381    end
382
383    // IO buffers
384    OBUF obuf_cclk( .I( CCLK_int ),
385                    .O( CCLK )
386                    );
387    
388    IOBUF iobuf_d0( .I( D_O[0] ),
389                    .IO( D[0] ),
390                    .O( D_I[0] ),
391                    .T( D_T[0] )
392                    );
393    
394    IOBUF iobuf_d1( .I( D_O[1] ),
395                    .IO( D[1] ),
396                    .O( D_I[1] ),
397                    .T( D_T[1] )
398                    );
399    
400    IOBUF iobuf_d2( .I( D_O[2] ),
401                    .IO( D[2] ),
402                    .O( D_I[2] ),
403                    .T( D_T[2] )
404                    );
405    
406    IOBUF iobuf_d3( .I( D_O[3] ),
407                    .IO( D[3] ),
408                    .O( D_I[3] ),
409                    .T( D_T[3] )
410                    );
411    
412    IOBUF iobuf_d4( .I( D_O[4] ),
413                    .IO( D[4] ),
414                    .O( D_I[4] ),
415                    .T( D_T[4] )
416                    );
417    
418    IOBUF iobuf_d5( .I( D_O[5] ),
419                    .IO( D[5] ),
420                    .O( D_I[5] ),
421                    .T( D_T[5] )
422                    );
423    
424    IOBUF iobuf_d6( .I( D_O[6] ),
425                    .IO( D[6] ),
426                    .O( D_I[6] ),
427                    .T( D_T[6] )
428                    );
429    
430    IOBUF iobuf_d7( .I( D_O[7] ),
431                    .IO( D[7] ),
432                    .O( D_I[7] ),
433                    .T( D_T[7] )
434                    );
435
436    // Clock buffer and reset
437    IBUFGDS_LVDS_25 diff_usrclk_buf( .I( Clkin_p ),
438                                     .IB( Clkin_m ), 
439                                     .O( User_Clk )
440                                     );
441
442    wire [0:3] rst;
443    
444    FD rst0( .D( 1'b0 ),
445             .Q( rst[0] ),
446             .C( User_Clk )
447             );
448    defparam rst0.INIT = 1'b1;
449
450    FD rst1( .D( rst[0] ),
451             .Q( rst[1] ),
452             .C( User_Clk )
453             );
454    defparam rst1.INIT = 1'b1;
455
456    FD rst2( .D( rst[1] ),
457             .Q( rst[2] ),
458             .C( User_Clk )
459             );
460    defparam rst2.INIT = 1'b1;
461
462    FD rst3( .D( rst[2] ),
463             .Q( rst[3] ),
464             .C( User_Clk )
465             );
466    defparam rst3.INIT = 1'b1;
467
468    assign   User_Rst = |rst;
469
470
471    // FIFO module instantiation
472    user_fifo test_fifo( 
473                         .WrFifo_Din( write_data ),
474                         .WrFifo_WrEn( write_enable ),
475                         .WrFifo_Full( write_full ),
476                         .WrFifo_WrCnt(  ),
477                         .RdFifo_Dout( read_data ),
478                         .RdFifo_RdEn( read_enable ),
479                         .RdFifo_Empty( read_empty ),
480                         .RdFifo_RdCnt(  ),
481                         .User_Rst( User_Rst ),
482                         .User_Clk( User_Clk ),
483                         .Sys_Rst( User_Rst ),
484                         .Sys_Clk( User_Clk ),                        
485                         .D_I( D_I ),
486                         .D_O( D_O ),
487                         .D_T( D_T ),                         
488                         .RDWR_B( RDWR_B ),
489                         .CS_B( CS_B ),
490                         .INIT_B( INIT_B ),
491                         .CCLK( CCLK_int )
492                         );
493    
494 endmodule