c282501daf885abbb084e4958e70c0aa3f76b8f8
[fleet.git] / src / edu / berkeley / fleet / slipway / user_fifo.v
1 //  Copyright (c) 2005-2006, Regents of the University of California
2 //  All rights reserved.
3 //
4 //  Redistribution and use in source and binary forms, with or without modification,
5 //  are permitted provided that the following conditions are met:
6 //
7 //      - Redistributions of source code must retain the above copyright notice,
8 //          this list of conditions and the following disclaimer.
9 //      - Redistributions in binary form must reproduce the above copyright
10 //          notice, this list of conditions and the following disclaimer
11 //          in the documentation and/or other materials provided with the
12 //          distribution.
13 //      - Neither the name of the University of California, Berkeley nor the
14 //          names of its contributors may be used to endorse or promote
15 //          products derived from this software without specific prior
16 //          written permission.
17 //
18 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 //  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 //  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 //  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 //  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 //  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 //  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 //----------------------------------------------------------------------------
30 // user_fifo.v
31 //----------------------------------------------------------------------------
32
33 `timescale 1ps / 1ps
34
35 module user_fifo
36   (
37    // FIFO interface ports
38    WrFifo_Din,                  // Write FIFO data-in
39    WrFifo_WrEn,                 // Write FIFO write enable
40    WrFifo_Full,                 // Write FIFO full
41    WrFifo_WrCnt,                // Write FIFO write count
42    RdFifo_Dout,                 // Read FIFO data-out
43    RdFifo_RdEn,                 // Read FIFO read enable
44    RdFifo_Empty,                // Read FIFO empty
45    RdFifo_RdCnt,                // Read FIFO read count
46    User_Rst,                    // User reset
47    User_Clk,                    // User clock
48    Sys_Rst,                     // System clock reset
49    Sys_Clk,                     // 100MHz system clock for CCLK generation
50
51    // SelectMAP interface ports
52    D_I,                         // Data bus input
53    D_O,                         // Data bus output
54    D_T,                         // Data bus tristate enable
55    RDWR_B,                      // Read/write signal
56    CS_B,                        // Chip select
57    INIT_B,                      // Initialization/interrupt signal
58    CCLK                         // CCLK output
59    );
60
61    // FIFO interface ports
62    input [0:7]         WrFifo_Din;
63    input               WrFifo_WrEn;
64    output              WrFifo_Full;
65    output [0:7]        WrFifo_WrCnt;
66    output [0:7]        RdFifo_Dout;
67    input               RdFifo_RdEn;
68    output              RdFifo_Empty;
69    output [0:7]        RdFifo_RdCnt;
70    input               User_Rst;
71    input               User_Clk;
72    input               Sys_Rst;
73    input               Sys_Clk;
74
75    // SelectMAP protocol ports
76    input [0:7]         D_I;
77    output [0:7]        D_O;
78    output [0:7]        D_T;
79    input               RDWR_B;
80    input               CS_B;
81    output              INIT_B;
82    output              CCLK;
83
84    //   ____        __ _       _ _   _                   //
85    //  |  _ \  ___ / _(_)_ __ (_) |_(_) ___  _ __  ___   //
86    //  | | | |/ _ \ |_| | '_ \| | __| |/ _ \| '_ \/ __|  //
87    //  | |_| |  __/  _| | | | | | |_| | (_) | | | \__ \  //
88    //  |____/ \___|_| |_|_| |_|_|\__|_|\___/|_| |_|___/  //
89    //                                                    //
90
91    //----------------------------------------------------------------------------
92    // Signal definitions
93    //----------------------------------------------------------------------------
94    // Write FIFO signals
95    wire [0:7]          WrFifo_Dout;
96    wire                WrFifo_Empty;
97    wire                WrFifo_RdEn;
98    wire [0:7]          WrFifo_RdCnt;
99    wire [0:7]          WrFifo_RdCnt_int;
100    wire [0:7]          WrFifo_WrCnt_int;
101
102    // Read FIFO signals
103    wire [0:7]          RdFifo_Din;
104    wire                RdFifo_Full;
105    wire                RdFifo_WrEn;
106    wire [0:7]          RdFifo_WrCnt;
107    wire [0:7]          RdFifo_WrCnt_int;
108    wire [0:7]          RdFifo_RdCnt_int;
109
110    //----------------------------------------------------------------------------
111    // IO Registers
112    //----------------------------------------------------------------------------
113    reg                 CCLK;
114
115    reg [0:7]           D_I_reg;    // synthesis attribute iob of D_I_reg is true;
116    reg [0:7]           D_O_reg;    // synthesis attribute iob of D_O_reg is true;
117    reg                 RDWR_B_reg; // synthesis attribute iob of RDWR_B_reg is true;
118    reg                 CS_B_reg;   // synthesis attribute iob of CS_B_reg is true;
119    reg                 INIT_B_reg; // synthesis attribute iob of INIT_B_reg is true;
120
121    // Outputs
122    assign              D_O = D_O_reg;
123    assign              INIT_B = INIT_B_reg;
124
125    // Inputs
126    always @( posedge Sys_Clk )
127      begin
128         D_I_reg    <= D_I;
129         RDWR_B_reg <= RDWR_B;
130         CS_B_reg   <= CS_B;
131      end
132
133    //----------------------------------------------------------------------------
134    // Generate CCLK and associated reset
135    //----------------------------------------------------------------------------
136    reg                SYNC_done;
137    reg                SYNC_done_dly;
138    reg                CS_B_reg_dly;
139
140    always @( posedge Sys_Clk )
141      begin
142         CS_B_reg_dly <= CS_B_reg;
143      end
144
145    always @( posedge Sys_Clk )
146      begin
147         if (Sys_Rst)
148           SYNC_done <= 1'b0;
149         else if (RDWR_B_reg && ~CS_B_reg)
150           SYNC_done <= 1'b1;
151      end
152
153    always @( posedge Sys_Clk )
154      begin
155         if (Sys_Rst)
156           SYNC_done_dly <= 1'b0;
157         else
158           SYNC_done_dly <= SYNC_done;
159      end
160
161    always @( posedge Sys_Clk )
162      begin
163         if (Sys_Rst)
164           CCLK <= 1'b0;
165         else if (~CS_B_reg && CS_B_reg_dly && CCLK)
166           CCLK <= 1'b1;
167         else
168           CCLK <= ~CCLK;
169      end
170
171    //   _____ ___ _____ ___        //
172    //  |  ___|_ _|  ___/ _ \ ___   //
173    //  | |_   | || |_ | | | / __|  //
174    //  |  _|  | ||  _|| |_| \__ \  //
175    //  |_|   |___|_|   \___/|___/  //
176    //                              //
177    // Write FIFO:  The write is with respect to the user.  The user writes data to this
178    //              FIFO and the control side of SelectMAP reads the data.
179    //
180    // Read FIFO:  The read is with respect to the user.  The user reads data sent from the
181    //             control side of SelectMAP.
182    //
183
184    //----------------------------------------------------------------------------
185    // Read FIFO
186    //----------------------------------------------------------------------------
187    assign RdFifo_WrEn = SYNC_done_dly && ~RDWR_B_reg && ~CS_B_reg && ~RdFifo_Full && CCLK;
188    assign RdFifo_Din = D_I_reg;
189
190    async_fifo_8_8_128 RdFifo( .din( RdFifo_Din ),
191                   .dout( RdFifo_Dout ),
192                   .rd_clk( User_Clk ),
193                   .rd_en( RdFifo_RdEn ),
194                   .wr_clk( Sys_Clk ),
195                   .wr_en( RdFifo_WrEn ),
196                   .rst( User_Rst ),
197                   .empty( RdFifo_Empty ),
198                   .full( RdFifo_Full ),
199                   .rd_data_count( RdFifo_RdCnt_int ),
200                   .wr_data_count( RdFifo_WrCnt_int ) );
201
202    assign RdFifo_WrCnt = 8'd129 - RdFifo_WrCnt_int;
203    assign RdFifo_RdCnt = RdFifo_RdCnt_int;
204
205    //----------------------------------------------------------------------------
206    // Write FIFO
207    //----------------------------------------------------------------------------
208    assign WrFifo_RdEn = SYNC_done_dly && RDWR_B_reg && ~CS_B_reg && ~WrFifo_Empty && CCLK;
209
210    async_fifo_8_8_128 WrFifo( .din( WrFifo_Din ),
211                   .dout( WrFifo_Dout ),
212                   .rd_clk( Sys_Clk ),
213                   .rd_en( WrFifo_RdEn ),
214                   .wr_clk( User_Clk ),
215                   .wr_en( WrFifo_WrEn ),
216                   .rst( User_Rst ),
217                   .empty( WrFifo_Empty ),
218                   .full( WrFifo_Full ),
219                   .rd_data_count( WrFifo_RdCnt_int ),
220                   .wr_data_count( WrFifo_WrCnt_int ) );
221
222    assign WrFifo_WrCnt = 8'd129 - WrFifo_WrCnt_int;
223    assign WrFifo_RdCnt = WrFifo_RdCnt_int;
224
225    //   ____       _           _   __  __    _    ____    //
226    //  / ___|  ___| | ___  ___| |_|  \/  |  / \  |  _ \   //
227    //  \___ \ / _ \ |/ _ \/ __| __| |\/| | / _ \ | |_) |  //
228    //   ___) |  __/ |  __/ (__| |_| |  | |/ ___ \|  __/   //
229    //  |____/ \___|_|\___|\___|\__|_|  |_/_/   \_\_|      //
230    //                                                     //
231
232    //----------------------------------------------------------------------------
233    // SelectMAP control outputs
234    //----------------------------------------------------------------------------
235    wire [0:7] DataCnt = RDWR_B_reg ? WrFifo_RdCnt : RdFifo_WrCnt;
236
237    assign     D_T    = {8{(~RDWR_B & ~CS_B)}}; // stop driving if master is sending
238
239    always @( posedge Sys_Clk )
240      begin
241         D_O_reg    <= CS_B_reg ? DataCnt : WrFifo_Dout;
242         INIT_B_reg <= WrFifo_Empty;
243      end
244
245    //----------------------------------------------------------------------------
246
247 endmodule