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

Subversion Repositories fpga-cf

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

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

powered by: WebSVN 2.1.0

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