Bee2 branch landing: step 1
[fleet.git] / src / edu / berkeley / fleet / fpga / bee2 / user_fifo.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