OpenCores
URL https://opencores.org/ocsvn/fpga-cf/fpga-cf/trunk

Subversion Repositories fpga-cf

[/] [fpga-cf/] [trunk/] [hdl/] [boardsupport/] [v4/] [rx_client_fifo_8.v] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 peteralieb
//-----------------------------------------------------------------------------
2
// Title      : 8-bit Client to Local-link Receiver FIFO
3
// Project    : Virtex-4 Embedded Tri-Mode Ethernet MAC Wrapper
4
// File       : rx_client_fifo_8.v
5
// Version    : 4.8
6
//-----------------------------------------------------------------------------
7
//
8
// (c) Copyright 2004-2010 Xilinx, Inc. All rights reserved.
9
//
10
// This file contains confidential and proprietary information
11
// of Xilinx, Inc. and is protected under U.S. and
12
// international copyright and other intellectual property
13
// laws.
14
//
15
// DISCLAIMER
16
// This disclaimer is not a license and does not grant any
17
// rights to the materials distributed herewith. Except as
18
// otherwise provided in a valid license issued to you by
19
// Xilinx, and to the maximum extent permitted by applicable
20
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
21
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
22
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
23
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
24
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
25
// (2) Xilinx shall not be liable (whether in contract or tort,
26
// including negligence, or under any other theory of
27
// liability) for any loss or damage of any kind or nature
28
// related to, arising under or in connection with these
29
// materials, including for any direct, or any indirect,
30
// special, incidental, or consequential loss or damage
31
// (including loss of data, profits, goodwill, or any type of
32
// loss or damage suffered as a result of any action brought
33
// by a third party) even if such damage or loss was
34
// reasonably foreseeable or Xilinx had been advised of the
35
// possibility of the same.
36
//
37
// CRITICAL APPLICATIONS
38
// Xilinx products are not designed or intended to be fail-
39
// safe, or for use in any application requiring fail-safe
40
// performance, such as life-support or safety devices or
41
// systems, Class III medical devices, nuclear facilities,
42
// applications related to the deployment of airbags, or any
43
// other applications that could lead to death, personal
44
// injury, or severe property or environmental damage
45
// (individually and collectively, "Critical
46
// Applications"). Customer assumes the sole risk and
47
// liability of any use of Xilinx products in Critical
48
// Applications, subject only to applicable laws and
49
// regulations governing limitations on product liability.
50
//
51
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
52
// PART OF THIS FILE AT ALL TIMES.
53
//
54
//-----------------------------------------------------------------------------
55
// Description: This is the receiver side local link fifo for the design example
56
//              of the Virtex-4 Ethernet MAC Wrapper core.
57
//
58
//              The FIFO is created from 2 Block RAMs of size 2048
59
//              words of 8-bits per word, giving a total frame memory capacity
60
//              of 4096 bytes.
61
//
62
//              Frame data received from the MAC receiver is written into the
63
//              FIFO on the wr_clk.  An End Of Frame marker is written to the
64
//              BRAM parity bit on the last byte of data stored for a frame.
65
//              This acts as frame deliniation.
66
//
67
//              The rx_good_frame and rx_bad_frame signals are used to
68
//              qualify the frame.  A frame for which rx_bad_frame was
69
//              asserted will cause the FIFO write address pointer to be
70
//              reset to the base address of that frame.  In this way
71
//              the bad frame will be overwritten with the next received
72
//              frame and is therefore dropped from the FIFO.
73
//
74
//              Frames will also be dropped from the FIFO if an overflow occurs. 
75
//              If there is not enough memory capacity in the FIFO to store the 
76
//              whole of an incoming frame, the write address pointer will be
77
//              reset and the overflow signal asserted.
78
//
79
//              When there is at least one complete frame in the FIFO,
80
//              the 8 bit Local-link read interface will be enabled allowing
81
//              data to be read from the fifo.
82
//
83
//              The FIFO has been designed to operate with different clocks
84
//              on the write and read sides.  The read clock (locallink clock)
85
//              should always operate at an equal or faster frequency
86
//              than the write clock (client clock).
87
//
88
//              The FIFO is designed to work with a minimum frame length of 8 bytes.
89
//
90
//              The FIFO memory size can be increased by expanding the rd_addr
91
//              and wr_addr signal widths, to address further BRAMs.
92
//
93
//              Requirements :
94
//              * Minimum frame size of 8 bytes
95
//              * Spacing between good/bad frame flags is at least 64 clock cycles
96
//              * Wr clock is 125MHz downto 1.25MHz
97
//              * Rd clock is downto 20MHz
98
//
99
//-------------------------------------------------------------------------------
100
 
101
`timescale 1ps / 1ps
102
 
103
module rx_client_fifo_8
104
     (
105
        // Local-link Interface
106
        rd_clk,
107
        rd_sreset,
108
        rd_data_out,
109
        rd_sof_n,
110
        rd_eof_n,
111
        rd_src_rdy_n,
112
        rd_dst_rdy_n,
113
        rx_fifo_status,
114
 
115
        // Client Interface
116
        wr_sreset,
117
        wr_clk,
118
        wr_enable,
119
        rx_data,
120
        rx_data_valid,
121
        rx_good_frame,
122
        rx_bad_frame,
123
        overflow
124
        );
125
 
126
 
127
  //---------------------------------------------------------------------------
128
  // Define Interface Signals
129
  //--------------------------------------------------------------------------
130
 
131
  // Local-link Interface
132
  input        rd_clk;
133
  input        rd_sreset;
134
  output [7:0] rd_data_out;
135
  output       rd_sof_n;
136
  output       rd_eof_n;
137
  output       rd_src_rdy_n;
138
  input        rd_dst_rdy_n;
139
  output [3:0] rx_fifo_status;
140
 
141
  // Client Interface
142
  input        wr_sreset;
143
  input        wr_clk;
144
  input        wr_enable;
145
  input [7:0]  rx_data;
146
  input        rx_data_valid;
147
  input        rx_good_frame;
148
  input        rx_bad_frame;
149
  output       overflow;
150
 
151
  reg          rd_sof_n;
152
  wire         rd_eof_n;
153
  reg          rd_src_rdy_n;
154
  reg [7:0]    rd_data_out;
155
 
156
 
157
  //---------------------------------------------------------------------------
158
  // Define Internal Signals
159
  //---------------------------------------------------------------------------
160
 
161
  wire        GND;
162
  wire        VCC;
163
  wire [7:0]  GND_BUS;
164
 
165
  // Encode rd_state_machine states   
166
  parameter WAIT_s = 3'b000;      parameter QUEUE1_s = 3'b001;
167
  parameter QUEUE2_s = 3'b010;    parameter QUEUE3_s = 3'b011;
168
  parameter QUEUE_SOF_s = 3'b100; parameter SOF_s = 3'b101;
169
  parameter DATA_s = 3'b110;      parameter EOF_s = 3'b111;
170
 
171
  reg [2:0]   rd_state;
172
  reg [2:0]   rd_nxt_state;
173
 
174
  // Encode wr_state_machine states 
175
  parameter IDLE_s = 3'b000; parameter FRAME_s = 3'b001;
176
  parameter END_s= 3'b010;   parameter GF_s = 3'b011;
177
  parameter BF_s = 3'b100;   parameter OVFLOW_s = 3'b101;
178
 
179
  reg  [2:0]  wr_state;
180
  reg  [2:0]  wr_nxt_state;
181
 
182
 
183
  wire        wr_en;
184
  wire        wr_en_u;
185
  wire        wr_en_l;
186
  reg  [11:0] wr_addr;
187
  wire        wr_addr_inc;
188
  wire        wr_start_addr_load;
189
  wire        wr_addr_reload;
190
  reg  [11:0] wr_start_addr;
191
  reg  [7:0]  wr_data_bram;
192
  reg  [7:0]  wr_data_pipe[0:1];
193
  reg  [0:0]  wr_eof_bram;
194
  reg         wr_dv_pipe[0:1];
195
  reg         wr_gf_pipe[0:1];
196
  reg         wr_bf_pipe[0:1];
197
  reg         frame_in_fifo;
198
 
199
  reg  [11:0] rd_addr;
200
  wire        rd_addr_inc;
201
  wire        rd_addr_reload;
202
  wire [7:0]  rd_data_bram_u;
203
  wire [7:0]  rd_data_bram_l;
204
  reg  [7:0]  rd_data_pipe_u;
205
  reg  [7:0]  rd_data_pipe_l;
206
  reg  [7:0]  rd_data_pipe;
207
  wire [0:0]  rd_eof_bram_u;
208
  wire [0:0]  rd_eof_bram_l;
209
  reg         rd_en;
210
  reg         rd_bram_u;
211
  reg         rd_bram_u_reg;
212
  wire        rd_pull_frame;
213
  reg         rd_eof;
214
 
215
  reg         wr_store_frame_tog;
216
  reg         rd_store_frame_tog;
217
  reg         rd_store_frame_sync;
218
  reg         rd_store_frame_delay;
219
  reg         rd_store_frame;
220
  reg  [8:0]  rd_frames;
221
  reg         wr_fifo_full;
222
 
223
  reg  [11:0] rd_addr_gray;
224
  reg  [11:0] wr_rd_addr_gray_sync;
225
  reg  [11:0] wr_rd_addr_gray;
226
  wire [11:0] wr_rd_addr;
227
  reg  [11:0] wr_addr_diff;
228
 
229
  reg  [3:0]  wr_fifo_status;
230
 
231
  reg         rd_eof_n_int;
232
 
233
  reg  [1:0]  rd_valid_pipe;
234
 
235
  //---------------------------------------------------------------------------
236
  // Attributes for FIFO simulation and synthesis
237
  //---------------------------------------------------------------------------
238
  // ASYNC_REG attributes added to simulate actual behaviour under
239
  // asynchronous operating conditions.
240
  // synthesis attribute ASYNC_REG of rd_store_frame_tog is "TRUE";
241
  // synthesis attribute ASYNC_REG of wr_rd_addr_gray_sync is "TRUE";
242
 
243
  // WRITE_MODE attributes added to Block RAM to mitigate port contention
244
  // synthesis attribute WRITE_MODE_A of ramgen_u is "READ_FIRST";
245
  // synthesis attribute WRITE_MODE_B of ramgen_u is "READ_FIRST";
246
  // synthesis attribute WRITE_MODE_A of ramgen_l is "READ_FIRST";
247
  // synthesis attribute WRITE_MODE_B of ramgen_l is "READ_FIRST";
248
 
249
  //---------------------------------------------------------------------------
250
  // Functions for gray code conversion
251
  //---------------------------------------------------------------------------   
252
  function [11:0] bin_to_gray;
253
  input    [11:0] bin;
254
  integer         i;
255
  begin
256
     for (i=0;i<12;i=i+1)
257
        begin
258
          if (i == 11)
259
             bin_to_gray[i] = bin[i];
260
          else
261
             bin_to_gray[i] = bin[i+1] ^ bin[i];
262
        end
263
  end
264
  endfunction
265
 
266
  function [11:0] gray_to_bin;
267
  input   [11:0] gray;
268
  integer        i;
269
  begin
270
     for (i=11;i>=0;i=i-1)
271
        begin
272
          if (i == 11)
273
            gray_to_bin[i] = gray[i];
274
          else
275
            gray_to_bin[i] = gray_to_bin[i+1] ^ gray[i];
276
        end
277
  end
278
  endfunction // gray_to_bin
279
 
280
 
281
  //---------------------------------------------------------------------------
282
  // Begin FIFO architecture
283
  //---------------------------------------------------------------------------
284
 
285
  assign GND     = 1'b0;
286
  assign VCC     = 1'b1;
287
  assign GND_BUS = 8'b0;
288
 
289
 
290
  //---------------------------------------------------------------------------
291
  // Read State machines and control
292
  //---------------------------------------------------------------------------
293
  // local link state machine
294
  // states are WAIT, QUEUE1, QUEUE2, QUEUE3, SOF, DATA, EOF
295
  // clock state to next state
296
  always @(posedge rd_clk)
297
  begin
298
     if (rd_sreset == 1'b1)
299
        rd_state <= WAIT_s;
300
     else
301
        rd_state <= rd_nxt_state;
302
  end
303
 
304
  assign rd_eof_n = rd_eof_n_int;
305
 
306
  // decode next state, combinatorial
307
  always @(rd_state or frame_in_fifo or rd_eof or rd_dst_rdy_n or
308
           rd_eof_n_int or rd_valid_pipe)
309
  begin
310
     case (rd_state)
311
        WAIT_s : begin
312
           // wait till there is a full frame in the fifo
313
           // then start to load the pipeline
314
           if (frame_in_fifo == 1'b1 && rd_eof_n_int == 1'b1)
315
              rd_nxt_state <= QUEUE1_s;
316
           else
317
              rd_nxt_state <= WAIT_s;
318
           end
319
        QUEUE1_s : begin
320
           // load the output pipeline
321
           // this takes three clocks
322
           rd_nxt_state <= QUEUE2_s;
323
           end
324
        QUEUE2_s : begin
325
           rd_nxt_state <= QUEUE3_s;
326
           end
327
        QUEUE3_s : begin
328
           rd_nxt_state <= QUEUE_SOF_s;
329
           end
330
        QUEUE_SOF_s : begin
331
           // used mark sof at end of queue
332
              rd_nxt_state <= DATA_s;  // move straight to frame.
333
           end
334
        SOF_s : begin
335
           // used to mark sof when following straight from eof
336
           if (rd_dst_rdy_n == 1'b0)
337
              rd_nxt_state <= DATA_s;
338
           else
339
              rd_nxt_state <= SOF_s;
340
           end
341
        DATA_s : begin
342
           // When the eof marker is detected from the BRAM output
343
           // move to EOF state
344
           if (rd_dst_rdy_n == 1'b0 && rd_eof == 1'b1)
345
              rd_nxt_state <= EOF_s;
346
           else
347
              rd_nxt_state <= DATA_s;
348
           end
349
        EOF_s : begin
350
           // hold in this state until dst rdy is low
351
           // and eof bit is accepted on interface
352
           // If there is a frame in the fifo, then the next frame
353
           // will already be queued into the pipe line so move straight
354
           // to sof state.
355
           if (rd_dst_rdy_n == 1'b0)
356
              if (rd_valid_pipe[1] == 1'b1)
357
                 rd_nxt_state <= SOF_s;
358
              else
359
                 rd_nxt_state <= WAIT_s;
360
           else
361
              rd_nxt_state <= EOF_s;
362
           end
363
        default : begin
364
           rd_nxt_state <= WAIT_s;
365
           end
366
        endcase
367
  end
368
 
369
  // detect if frame in fifo was high 3 reads ago
370
  // this is used to ensure we only treat data in the pipeline as valid if
371
  // frame in fifo goes high at or before the eof of the current frame
372
  // It may be that there is valid data (i.e a partial packet has been written)
373
  // but until the end of that packet we do not know if it is a good packet
374
  always @(posedge rd_clk)
375
  begin
376
     if (rd_dst_rdy_n == 1'b0)
377
        rd_valid_pipe <= {rd_valid_pipe[0], frame_in_fifo};
378
  end
379
 
380
 
381
  // decode the output signals depending on current state.
382
  // decode sof signal.
383
  always @(posedge rd_clk)
384
  begin
385
     if (rd_sreset == 1'b1)
386
        rd_sof_n <= 1'b1;
387
     else
388
        case (rd_state)
389
           QUEUE_SOF_s :
390
              // no need to wait for dst rdy to be low, as there is valid data
391
              rd_sof_n <= 1'b0;
392
           SOF_s :
393
              // needed to wait till rd_dst_rdy is low to ensure eof signal has
394
              // been accepted onto the interface before asserting sof.
395
              if (rd_dst_rdy_n == 1'b0)
396
                 rd_sof_n <= 1'b0;
397
           default :
398
              // needed to wait till rd_dst_rdy is low to ensure sof signal has
399
              // been accepted onto the interface.
400
              if (rd_dst_rdy_n == 1'b0)
401
                 rd_sof_n <= 1'b1;
402
        endcase
403
  end
404
 
405
  // decode eof signal
406
  // check init value of this reg is 1.
407
  always @(posedge rd_clk)
408
  begin
409
     if (rd_sreset == 1'b1)
410
        rd_eof_n_int <= 1'b1;
411
     else if (rd_dst_rdy_n == 1'b0)
412
        // needed to wait till rd_dst_rdy is low to ensure penultimate byte of frame has
413
        // been accepted onto the interface before asserting eof and that
414
        // eof is accepted before moving on
415
        case (rd_state)
416
           EOF_s :
417
              rd_eof_n_int <= 1'b0;
418
           default :
419
              rd_eof_n_int <= 1'b1;
420
        endcase
421
           // queue sof is not needed if init value is 1
422
  end
423
 
424
  // decode data output
425
  always @(posedge rd_clk)
426
  begin
427
     if (rd_en == 1'b1)
428
        rd_data_out <= rd_data_pipe;
429
  end
430
 
431
  // decode the output scr_rdy signal
432
  // want to remove the dependancy of src_rdy from dst rdy
433
  // check init value of this reg is 1'b1
434
  always @(posedge rd_clk)
435
  begin
436
     if (rd_sreset == 1'b1)
437
        rd_src_rdy_n <= 1'b1;
438
     else
439
        case (rd_state)
440
           QUEUE_SOF_s :
441
              rd_src_rdy_n <= 1'b0;
442
           SOF_s :
443
              rd_src_rdy_n <= 1'b0;
444
           DATA_s :
445
              rd_src_rdy_n <= 1'b0;
446
           EOF_s :
447
              rd_src_rdy_n <= 1'b0;
448
           default :
449
              if (rd_dst_rdy_n == 1'b0)
450
                 rd_src_rdy_n <= 1'b1;
451
         endcase
452
  end
453
 
454
 
455
  // decode internal control signals
456
  // rd_en is used to enable the BRAM read and load the output pipe
457
  always @(rd_state or rd_dst_rdy_n)
458
  begin
459
     case (rd_state)
460
         WAIT_s :
461
              rd_en <= 1'b0;
462
         QUEUE1_s :
463
              rd_en <= 1'b1;
464
         QUEUE2_s :
465
              rd_en <= 1'b1;
466
         QUEUE3_s :
467
              rd_en <= 1'b1;
468
         QUEUE_SOF_s :
469
              rd_en <= 1'b1;
470
         default :
471
              rd_en <= !rd_dst_rdy_n;
472
         endcase
473
  end
474
 
475
  // rd_addr_inc is used to enable the BRAM read address to increment
476
  assign rd_addr_inc = rd_en;
477
 
478
 
479
  // When the current frame is output, if there is no frame in the fifo, then
480
  // the fifo must wait until a new frame is written in.  This requires the read
481
  // address to be moved back to where the new frame will be written.  The pipe
482
  // is then reloaded using the QUEUE states
483
  assign rd_addr_reload = (rd_state == EOF_s && rd_nxt_state == WAIT_s) ? 1'b1 : 1'b0;
484
 
485
  // Data is available if there is at leat one frame stored in the FIFO.
486
  always @(posedge rd_clk)
487
  begin
488
     if (rd_sreset == 1'b1)
489
        frame_in_fifo <= 1'b0;
490
     else
491
        if (rd_frames != 9'b0)
492
           frame_in_fifo <= 1'b1;
493
        else
494
           frame_in_fifo <= 1'b0;
495
  end
496
 
497
  // when a frame has been stored need to convert to rd clock domain for frame
498
  // count store.
499
  always @(posedge rd_clk)
500
  begin
501
     if (rd_sreset == 1'b1)
502
        begin
503
           rd_store_frame_tog  <= 1'b0;
504
           rd_store_frame_sync <= 1'b0;
505
           rd_store_frame_delay <= 1'b0;
506
           rd_store_frame      <= 1'b0;
507
        end
508
     else
509
        begin
510
           rd_store_frame_tog  <= wr_store_frame_tog;
511
           rd_store_frame_sync <= rd_store_frame_tog;
512
           rd_store_frame_delay <= rd_store_frame_sync;
513
           // edge detector
514
           if ((rd_store_frame_delay ^ rd_store_frame_sync) == 1'b1)
515
              rd_store_frame    <= 1'b1;
516
           else
517
              rd_store_frame    <= 1'b0;
518
        end
519
  end
520
 
521
  assign rd_pull_frame = (rd_state == SOF_s && rd_nxt_state != SOF_s) ? 1'b1 :
522
                         (rd_state == QUEUE_SOF_s && rd_nxt_state != QUEUE_SOF_s) ? 1'b1 : 1'b0;
523
 
524
  // Up/Down counter to monitor the number of frames stored within the
525
  // the FIFO. Note:  
526
  //    * decrements at the beginning of a frame read cycle
527
  //    * increments at the end of a frame write cycle
528
  always @(posedge rd_clk)
529
  begin
530
     if (rd_sreset == 1'b1)
531
        rd_frames <= 9'b0;
532
     else
533
        // A frame is written to the fifo in this cycle, and no frame is being
534
        // read out on the same cycle
535
        if (rd_store_frame == 1'b1 && rd_pull_frame == 1'b0)
536
           rd_frames <= rd_frames + 1;
537
        // A frame is being read out on this cycle and no frame is being
538
        // written on the same cycle
539
        else if (rd_store_frame == 1'b0 && rd_pull_frame == 1'b1)
540
           rd_frames <= rd_frames - 1;
541
  end
542
 
543
 
544
  //---------------------------------------------------------------------------
545
  // Write State machines and control
546
  //---------------------------------------------------------------------------
547
  // write state machine
548
  // states are IDLE, FRAME, EOF, GF, BF, OVFLOW
549
  // clock state to next state
550
  always @(posedge wr_clk)
551
  begin
552
     if (wr_sreset == 1'b1)
553
        wr_state <= IDLE_s;
554
     else if (wr_enable == 1'b1)
555
        wr_state <= wr_nxt_state;
556
  end
557
 
558
  // decode next state, combinatorial
559
  always @(wr_state or wr_dv_pipe[1] or wr_gf_pipe[1] or wr_bf_pipe[1] or wr_eof_bram[0] or wr_fifo_full)
560
  begin
561
     case (wr_state)
562
        IDLE_s : begin
563
           // there is data in the incoming pipeline when dv_pipe(1) goes high
564
           if (wr_dv_pipe[1] == 1'b1)
565
              wr_nxt_state <= FRAME_s;
566
           else
567
              wr_nxt_state <= IDLE_s;
568
           end
569
        FRAME_s : begin
570
              // if fifo is full then go to overflow state.
571
              // if the good or bad flag is detected the end
572
              // of the frame has been reached!
573
              // this transistion occurs when the gb flag
574
              // is on the clock edge immediately following
575
              // the end of the frame.
576
              // if the eof_bram signal is detected then data valid has
577
              // fallen low and the end of frame has been detected.
578
              if (wr_fifo_full == 1'b1)
579
                 wr_nxt_state <= OVFLOW_s;
580
              else if (wr_gf_pipe[1] == 1'b1)
581
                 wr_nxt_state <= GF_s;
582
              else if (wr_bf_pipe[1] == 1'b1)
583
                 wr_nxt_state <= BF_s;
584
              else if (wr_eof_bram[0] == 1'b1)
585
                 wr_nxt_state <= END_s;
586
              else
587
                 wr_nxt_state <= FRAME_s;
588
              end
589
           END_s : begin
590
              // if frame is full then go to overflow state
591
              // else wait until the good or bad flag has been received.
592
              if (wr_gf_pipe[1] == 1'b1)
593
                 wr_nxt_state <= GF_s;
594
              else if (wr_bf_pipe[1] == 1'b1)
595
                 wr_nxt_state <= BF_s;
596
              else
597
                 wr_nxt_state <= END_s;
598
              end
599
           GF_s : begin
600
              // wait for next frame
601
              wr_nxt_state <= IDLE_s;
602
              end
603
           BF_s : begin
604
              // wait for next frame
605
              wr_nxt_state <= IDLE_s;
606
              end
607
           OVFLOW_s : begin
608
              // wait until the good or bad flag received.
609
              if (wr_gf_pipe[1] == 1'b1 || wr_bf_pipe[1] == 1'b1)
610
                 wr_nxt_state <= IDLE_s;
611
              else
612
                 wr_nxt_state <= OVFLOW_s;
613
              end
614
           default : begin
615
              wr_nxt_state <= IDLE_s;
616
              end
617
        endcase
618
  end
619
 
620
 
621
  // decode control signals
622
  // wr_en is used to enable the BRAM write and loading of the input pipeline
623
  assign wr_en = (wr_state == FRAME_s) ? 1'b1 : 1'b0;
624
 
625
  // the upper and lower signals are used to distinguish between the upper and
626
  // lower BRAM
627
  assign wr_en_l = wr_en & !wr_addr[11];
628
  assign wr_en_u = wr_en & wr_addr[11];
629
 
630
  // increment the write address when we are receiving a frame
631
  assign wr_addr_inc = (wr_state == FRAME_s) ? 1'b1 : 1'b0;
632
 
633
  // if the fifo overflows or a frame is to be dropped, we need to move the
634
  // write address back to the start of the frame.  This allows the data to be
635
  // overwritten.
636
  assign wr_addr_reload = (wr_state == BF_s || wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
637
 
638
  // the start address is saved when in the WAIT state
639
  assign wr_start_addr_load = (wr_state == IDLE_s) ? 1'b1 : 1'b0;
640
 
641
  // we need to know when a frame is stored, in order to increment the count of
642
  // frames stored in the fifo.
643
  always @(posedge wr_clk)
644
  begin  // process
645
     if (wr_sreset == 1'b1)
646
        wr_store_frame_tog <= 1'b0;
647
     else if (wr_enable == 1'b1)
648
        if (wr_state == GF_s)
649
           wr_store_frame_tog <= ! wr_store_frame_tog;
650
  end
651
 
652
 
653
  //---------------------------------------------------------------------------
654
  // Address counters
655
  //---------------------------------------------------------------------------
656
  // write address is incremented when write enable signal has been asserted
657
  always @(posedge wr_clk)
658
  begin
659
     if (wr_sreset == 1'b1)
660
        wr_addr <= 12'b0;
661
     else if (wr_enable == 1'b1)
662
        if (wr_addr_reload == 1'b1)
663
           wr_addr <= wr_start_addr;
664
        else if (wr_addr_inc == 1'b1)
665
           wr_addr <= wr_addr + 1;
666
  end
667
 
668
  // store the start address
669
  always @(posedge wr_clk)
670
  begin
671
     if (wr_sreset == 1'b1)
672
        wr_start_addr <= 12'b0;
673
     else if (wr_enable == 1'b1)
674
        if (wr_start_addr_load == 1'b1)
675
           wr_start_addr <= wr_addr;
676
  end
677
 
678
  // read address is incremented when read enable signal has been asserted
679
  always @(posedge rd_clk)
680
  begin
681
     if (rd_sreset == 1'b1)
682
        rd_addr <= 12'b0;
683
     else
684
        if (rd_addr_reload == 1'b1)
685
           rd_addr <= rd_addr - 2;
686
        else if (rd_addr_inc == 1'b1)
687
           rd_addr <= rd_addr + 1;
688
  end
689
 
690
  // which BRAM is read from is dependant on the upper bit of the address
691
  // space.  this needs to be registered to give the correct timing.
692
  always @(posedge rd_clk)
693
  begin
694
     if (rd_sreset == 1'b1)
695
        begin
696
           rd_bram_u <= 1'b0;
697
           rd_bram_u_reg <= 1'b0;
698
        end
699
     else if (rd_addr_inc == 1'b1)
700
        begin
701
           rd_bram_u <= rd_addr[11];
702
           rd_bram_u_reg <= rd_bram_u;
703
        end
704
  end
705
 
706
  //---------------------------------------------------------------------------
707
  // Data Pipelines
708
  //---------------------------------------------------------------------------
709
  // register data inputs to bram
710
  // no reset to allow srl16 target
711
  always @(posedge wr_clk)
712
  begin
713
     if (wr_enable == 1'b1)
714
        begin
715
           wr_data_pipe[0] <= rx_data;
716
           wr_data_pipe[1] <= wr_data_pipe[0];
717
           wr_data_bram    <= wr_data_pipe[1];
718
        end
719
  end
720
 
721
  // no reset to allow srl16 target
722
  always @(posedge wr_clk)
723
  begin
724
     if (wr_enable == 1'b1)
725
        begin
726
           wr_dv_pipe[0] <= rx_data_valid;
727
           wr_dv_pipe[1] <= wr_dv_pipe[0];
728
           wr_eof_bram[0] <= wr_dv_pipe[1] & !wr_dv_pipe[0];
729
        end
730
  end
731
 
732
   // no reset to allow srl16 target
733
  always @(posedge wr_clk)
734
  begin
735
     if (wr_enable == 1'b1)
736
        begin
737
           wr_gf_pipe[0] <= rx_good_frame;
738
           wr_gf_pipe[1] <= wr_gf_pipe[0];
739
           wr_bf_pipe[0] <= rx_bad_frame;
740
           wr_bf_pipe[1] <= wr_bf_pipe[0];
741
        end
742
  end
743
 
744
  // register data outputs from bram
745
  // no reset to allow srl16 target
746
  always @(posedge rd_clk)
747
  begin
748
     if (rd_en == 1'b1)
749
        begin
750
           rd_data_pipe_u <= rd_data_bram_u;
751
           rd_data_pipe_l <= rd_data_bram_l;
752
           if (rd_bram_u_reg == 1'b1)
753
              rd_data_pipe <= rd_data_pipe_u;
754
           else
755
              rd_data_pipe <= rd_data_pipe_l;
756
        end
757
  end
758
 
759
  // register data outputs from bram
760
  always @(posedge rd_clk)
761
  begin
762
     if (rd_en == 1'b1)
763
        if (rd_bram_u == 1'b1)
764
           rd_eof <= rd_eof_bram_u[0];
765
        else
766
           rd_eof <= rd_eof_bram_l[0];
767
  end
768
 
769
  //---------------------------------------------------------------------------
770
  // Overflow functionality
771
  //---------------------------------------------------------------------------
772
  // Take the Read Address Pointer and convert it into a grey code 
773
  always @(posedge rd_clk)
774
  begin
775
     if (rd_sreset == 1'b1)
776
        rd_addr_gray <= 12'b0;
777
     else
778
        rd_addr_gray <= bin_to_gray(rd_addr);
779
  end
780
 
781
  // Resync the Read Address Pointer grey code onto the write clock
782
  // NOTE: rd_addr_gray signal crosses clock domains
783
  always @(posedge wr_clk)
784
  begin
785
     if (wr_sreset == 1'b1)
786
        begin
787
           wr_rd_addr_gray_sync <= 12'b0;
788
           wr_rd_addr_gray <= 12'b0;
789
        end
790
     else if (wr_enable == 1'b1)
791
        begin
792
           wr_rd_addr_gray_sync <= rd_addr_gray;
793
           wr_rd_addr_gray <= wr_rd_addr_gray_sync;
794
        end
795
  end
796
 
797
  // Convert the resync'd Read Address Pointer grey code back to binary
798
  assign wr_rd_addr = gray_to_bin(wr_rd_addr_gray);
799
 
800
  // Obtain the difference between write and read pointers
801
  always @(posedge wr_clk)
802
  begin
803
     if (wr_sreset == 1'b1)
804
        wr_addr_diff <= 12'b0;
805
     else if (wr_enable == 1'b1)
806
        wr_addr_diff <= wr_rd_addr - wr_addr;
807
  end
808
 
809
  // Detect when the FIFO is full
810
  // The FIFO is considered to be full if the write address
811
  // pointer is within 4 to 15 of the read address pointer.
812
  always @(posedge wr_clk)
813
  begin
814
     if (wr_sreset == 1'b1)
815
        wr_fifo_full <= 1'b0;
816
     else if (wr_enable == 1'b1)
817
        if (wr_addr_diff[11:4] == 8'b0 && wr_addr_diff[3:2] != 2'b0)
818
           wr_fifo_full <= 1'b1;
819
        else
820
           wr_fifo_full <= 1'b0;
821
  end
822
 
823
  assign overflow = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
824
 
825
  //--------------------------------------------------------------------
826
  // FIFO Status Signals
827
  //--------------------------------------------------------------------
828
 
829
  // The FIFO status signal is four bits which represents the occupancy
830
  // of the FIFO in 16'ths.  To generate this signal we therefore only
831
  // need to compare the 4 most significant bits of the write address
832
  // pointer with the 4 most significant bits of the read address 
833
  // pointer.
834
 
835
  // already have fifo status on write side through wr_addr_diff.
836
  // calculate fifo status here and output on the wr clock domain.
837
 
838
 
839
  always @(posedge wr_clk)
840
  begin
841
     if (wr_sreset == 1'b1)
842
         wr_fifo_status <= 4'b0;
843
     else if (wr_enable == 1'b1)
844
        if (wr_addr_diff == 12'b0)
845
           wr_fifo_status <= 4'b0;
846
        else
847
           begin
848
              wr_fifo_status[3] <= !wr_addr_diff[11];
849
              wr_fifo_status[2] <= !wr_addr_diff[10];
850
              wr_fifo_status[1] <= !wr_addr_diff[9];
851
              wr_fifo_status[0] <= !wr_addr_diff[8];
852
           end
853
  end
854
 
855
  assign rx_fifo_status = wr_fifo_status;
856
 
857
 
858
  //---------------------------------------------------------------------------
859
  // Memory
860
  //---------------------------------------------------------------------------
861
  // Block Ram for lower address space (rx_addr(11) = 1'b0)
862
  defparam ramgen_l.WRITE_MODE_A = "READ_FIRST";
863
  defparam ramgen_l.WRITE_MODE_B = "READ_FIRST";
864
  RAMB16_S9_S9 ramgen_l (
865
      .WEA   (wr_en_l),
866
      .ENA   (VCC),
867
      .SSRA  (wr_sreset),
868
      .CLKA  (wr_clk),
869
      .ADDRA (wr_addr[10:0]),
870
      .DIA   (wr_data_bram),
871
      .DIPA  (wr_eof_bram),
872
      .DOA   (),
873
      .DOPA  (),
874
      .WEB   (GND),
875
      .ENB   (rd_en),
876
      .SSRB  (rd_sreset),
877
      .CLKB  (rd_clk),
878
      .ADDRB (rd_addr[10:0]),
879
      .DIB   (GND_BUS[7:0]),
880
      .DIPB  (GND_BUS[0:0]),
881
      .DOB   (rd_data_bram_l),
882
      .DOPB  (rd_eof_bram_l));
883
 
884
  // Block Ram for lower address space (rx_addr(11) = 1'b0)
885
  defparam ramgen_u.WRITE_MODE_A = "READ_FIRST";
886
  defparam ramgen_u.WRITE_MODE_B = "READ_FIRST";
887
  RAMB16_S9_S9 ramgen_u (
888
      .WEA   (wr_en_u),
889
      .ENA   (VCC),
890
      .SSRA  (wr_sreset),
891
      .CLKA  (wr_clk),
892
      .ADDRA (wr_addr[10:0]),
893
      .DIA   (wr_data_bram),
894
      .DIPA  (wr_eof_bram),
895
      .DOA   (),
896
      .DOPA  (),
897
      .WEB   (GND),
898
      .ENB   (rd_en),
899
      .SSRB  (rd_sreset),
900
      .CLKB  (rd_clk),
901
      .ADDRB (rd_addr[10:0]),
902
      .DIB   (GND_BUS[7:0]),
903
      .DIPB  (GND_BUS[0:0]),
904
      .DOB   (rd_data_bram_u),
905
      .DOPB  (rd_eof_bram_u));
906
 
907
 
908
 
909
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.