OpenCores
URL https://opencores.org/ocsvn/1g_ethernet_dpi/1g_ethernet_dpi/trunk

Subversion Repositories 1g_ethernet_dpi

[/] [1g_ethernet_dpi/] [trunk/] [hw/] [src/] [rtl/] [tri_mode_emac/] [src/] [fifo/] [tri_mode_ethernet_mac_0_rx_client_fifo.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 kuzmi4
//------------------------------------------------------------------------------
2
// Title      : Receiver FIFO with AxiStream interfaces
3
// Version    : 1.3
4
// Project    : Tri-Mode Ethernet MAC
5
//------------------------------------------------------------------------------
6
// File       : tri_mode_ethernet_mac_0_rx_client_fifo.v
7
// Author     : Xilinx Inc.
8
// -----------------------------------------------------------------------------
9
// (c) Copyright 2004-2013 Xilinx, Inc. All rights reserved.
10
//
11
// This file contains confidential and proprietary information
12
// of Xilinx, Inc. and is protected under U.S. and
13
// international copyright and other intellectual property
14
// laws.
15
//
16
// DISCLAIMER
17
// This disclaimer is not a license and does not grant any
18
// rights to the materials distributed herewith. Except as
19
// otherwise provided in a valid license issued to you by
20
// Xilinx, and to the maximum extent permitted by applicable
21
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
22
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
23
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
24
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
25
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
26
// (2) Xilinx shall not be liable (whether in contract or tort,
27
// including negligence, or under any other theory of
28
// liability) for any loss or damage of any kind or nature
29
// related to, arising under or in connection with these
30
// materials, including for any direct, or any indirect,
31
// special, incidental, or consequential loss or damage
32
// (including loss of data, profits, goodwill, or any type of
33
// loss or damage suffered as a result of any action brought
34
// by a third party) even if such damage or loss was
35
// reasonably foreseeable or Xilinx had been advised of the
36
// possibility of the same.
37
//
38
// CRITICAL APPLICATIONS
39
// Xilinx products are not designed or intended to be fail-
40
// safe, or for use in any application requiring fail-safe
41
// performance, such as life-support or safety devices or
42
// systems, Class III medical devices, nuclear facilities,
43
// applications related to the deployment of airbags, or any
44
// other applications that could lead to death, personal
45
// injury, or severe property or environmental damage
46
// (individually and collectively, "Critical
47
// Applications"). Customer assumes the sole risk and
48
// liability of any use of Xilinx products in Critical
49
// Applications, subject only to applicable laws and
50
// regulations governing limitations on product liability.
51
//
52
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
53
// PART OF THIS FILE AT ALL TIMES. 
54
// -----------------------------------------------------------------------------
55
// Description: This is the receiver side FIFO for the design example
56
//              of the Tri-Mode Ethernet MAC core. AxiStream interfaces are used.
57
//
58
//              The FIFO is built around an Inferred Dual Port RAM, 
59
//              giving a total memory capacity of 4096 bytes.
60
//
61
//              Frame data received from the MAC receiver is written into the
62
//              FIFO on the rx_mac_aclk. An end-of-frame marker is written to
63
//              the BRAM parity bit on the last byte of data stored for a frame.
64
//              This acts as frame deliniation.
65
//
66
//              The rx_axis_mac_tvalid, rx_axis_mac_tlast, and rx_axis_mac_tuser signals
67
//              qualify the frame. A frame which ends with rx_axis_mac_tuser asserted
68
//              indicates a bad frame and will cause the FIFO write address
69
//              pointer to be reset to the base address of that frame. In this
70
//              way the bad frame will be overwritten with the next received
71
//              frame and is therefore dropped from the FIFO.
72
//
73
//              Frames will also be dropped from the FIFO if an overflow occurs.
74
//              If there is not enough memory capacity in the FIFO to store the
75
//              whole of an incoming frame, the write address pointer will be
76
//              reset and the overflow signal asserted.
77
//
78
//              When there is at least one complete frame in the FIFO,
79
//              the 8-bit AxiStream read interface's rx_axis_fifo_tvalid signal will
80
//              be enabled allowing data to be read from the FIFO.
81
//
82
//              The FIFO has been designed to operate with different clocks
83
//              on the write and read sides. The read clock (user side) should
84
//              always operate at an equal or faster frequency than the write
85
//              clock (MAC side).
86
//
87
//              The FIFO is designed to work with a minimum frame length of 8
88
//              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 signaling (encoded by
96
//                rx_axis_mac_tvalid, rx_axis_mac_tlast, rx_axis_mac_tuser), is at least 64
97
//                clock cycles
98
//              * Write AxiStream clock is 125MHz downto 1.25MHz
99
//              * Read AxiStream clock equal to or faster than write clock,
100
//                and downto 20MHz
101
//
102
//------------------------------------------------------------------------------
103
 
104
`timescale 1ps / 1ps
105
 
106
//------------------------------------------------------------------------------
107
// The module declaration for the Receiver FIFO
108
//------------------------------------------------------------------------------
109
 
110
(* DowngradeIPIdentifiedWarnings = "yes" *)
111
module tri_mode_ethernet_mac_0_rx_client_fifo
112
  (
113
    // User-side (read-side) AxiStream interface
114
    input            rx_fifo_aclk,
115
    input            rx_fifo_resetn,
116
    output reg [7:0] rx_axis_fifo_tdata = 8'd0,
117
    output reg       rx_axis_fifo_tvalid,
118
    output           rx_axis_fifo_tlast,
119
    input            rx_axis_fifo_tready,
120
 
121
    // MAC-side (write-side) AxiStream interface
122
    input            rx_mac_aclk,
123
    input            rx_mac_resetn,
124
    input [7:0]      rx_axis_mac_tdata,
125
    input            rx_axis_mac_tvalid,
126
    input            rx_axis_mac_tlast,
127
    input            rx_axis_mac_tuser,
128
 
129
    // FIFO status and overflow indication,
130
    // synchronous to write-side (rx_mac_aclk) interface
131
    output [3:0]     fifo_status,
132
    output           fifo_overflow
133
  );
134
 
135
 
136
  //----------------------------------------------------------------------------
137
  // Define internal signals
138
  //----------------------------------------------------------------------------
139
 
140
  // Binary encoded read state machine states
141
  parameter WAIT_s      = 3'b000;
142
  parameter QUEUE1_s    = 3'b001;
143
  parameter QUEUE2_s    = 3'b010;
144
  parameter QUEUE3_s    = 3'b011;
145
  parameter QUEUE_SOF_s = 3'b100;
146
  parameter SOF_s       = 3'b101;
147
  parameter DATA_s      = 3'b110;
148
  parameter EOF_s       = 3'b111;
149
 
150
 
151
  reg [2:0]   rd_state;
152
 
153
  reg [2:0]   rd_nxt_state;
154
 
155
  // Binary encoded write state machine states
156
  parameter IDLE_s   = 3'b000;
157
  parameter FRAME_s  = 3'b001;
158
  parameter GF_s     = 3'b010;
159
  parameter BF_s     = 3'b011;
160
  parameter OVFLOW_s = 3'b100;
161
 
162
 
163
  reg  [2:0]  wr_state;
164
 
165
  reg  [2:0]  wr_nxt_state;
166
 
167
  wire        wr_en;
168
  reg  [11:0] wr_addr;
169
  wire        wr_addr_inc;
170
  wire        wr_start_addr_load;
171
  wire        wr_addr_reload;
172
  reg  [11:0] wr_start_addr;
173
  wire [8:0]  wr_eof_data_bram;
174
  reg  [7:0]  wr_data_bram;
175
  reg  [7:0]  wr_data_pipe[0:1];
176
  reg         wr_dv_pipe[0:2];
177
  reg         wr_gfbf_pipe[0:1];
178
  reg         wr_gf;
179
  reg         wr_bf;
180
  reg         wr_eof_bram_pipe[0:1];
181
  reg         wr_eof_bram;
182
  reg         frame_in_fifo;
183
 
184
  reg  [11:0] rd_addr;
185
  wire        rd_addr_inc;
186
  reg         rd_addr_reload;
187
  wire [8:0]  rd_eof_data_bram;
188
  wire [7:0]  rd_data_bram;
189
  reg  [7:0]  rd_data_pipe = 8'd0;
190
  reg  [7:0]  rd_data_delay = 8'd0;
191
  reg  [1:0]  rd_valid_pipe;
192
  wire [0:0]  rd_eof_bram;
193
  reg         rd_en;
194
  reg         rd_pull_frame;
195
  reg         rd_eof;
196
 
197
  (* INIT = "0" *)
198
  reg         wr_store_frame_tog = 1'b0;
199
  wire        rd_store_frame_sync;
200
 
201
  (* INIT = "0" *)
202
  reg         rd_store_frame_delay = 1'b0;
203
  reg         rd_store_frame;
204
  reg  [8:0]  rd_frames;
205
  reg         wr_fifo_full;
206
 
207
  reg  [1:0]  old_rd_addr;
208
  reg         update_addr_tog;
209
  wire        update_addr_tog_sync;
210
  reg         update_addr_tog_sync_reg;
211
 
212
  reg  [11:6] wr_rd_addr;
213
  wire [12:0] wr_addr_diff_in;
214
  reg  [11:0] wr_addr_diff;
215
 
216
  reg  [3:0]  wr_fifo_status;
217
  reg         rx_axis_fifo_tlast_int;
218
 
219
  wire        rx_fifo_reset;
220
  wire        rx_mac_reset;
221
 
222
  // invert reset sense as architecture is optimised for active high resets
223
  assign rx_fifo_reset = !rx_fifo_resetn;
224
  assign rx_mac_reset  = !rx_mac_resetn;
225
 
226
 
227
  //----------------------------------------------------------------------------
228
  // Begin FIFO architecture
229
  //----------------------------------------------------------------------------
230
 
231
 
232
  //----------------------------------------------------------------------------
233
  // Read state machines and control
234
  //----------------------------------------------------------------------------
235
 
236
  // Read state machine.
237
  // States are WAIT, QUEUE1, QUEUE2, QUEUE3, QUEUE_SOF, SOF, DATA, EOF.
238
  // Clock state to next state.
239
  always @(posedge rx_fifo_aclk)
240
  begin
241
     if (rx_fifo_reset == 1'b1) begin
242
        rd_state <= WAIT_s;
243
     end
244
     else begin
245
        rd_state <= rd_nxt_state;
246
     end
247
  end
248
 
249
  assign rx_axis_fifo_tlast = rx_axis_fifo_tlast_int;
250
 
251
  // Decode next state, combinatorial.
252
  always @(rd_state, frame_in_fifo, rd_eof, rx_axis_fifo_tready, rx_axis_fifo_tlast_int,
253
           rd_valid_pipe)
254
  begin
255
     case (rd_state)
256
        WAIT_s : begin
257
           // Wait until there is a full frame in the FIFO, then
258
           // start to load the pipeline.
259
           if (frame_in_fifo == 1'b1 && rx_axis_fifo_tlast_int == 1'b0) begin
260
              rd_nxt_state <= QUEUE1_s;
261
           end
262
           else begin
263
              rd_nxt_state <= WAIT_s;
264
           end
265
        end
266
 
267
        // Load the output pipeline, which takes three clock cycles.
268
        QUEUE1_s : begin
269
           rd_nxt_state <= QUEUE2_s;
270
        end
271
 
272
        QUEUE2_s : begin
273
           rd_nxt_state <= QUEUE3_s;
274
        end
275
 
276
        QUEUE3_s : begin
277
           rd_nxt_state <= QUEUE_SOF_s;
278
        end
279
 
280
        QUEUE_SOF_s : begin
281
           // The pipeline is full and the frame output starts now.
282
           rd_nxt_state <= DATA_s;
283
        end
284
 
285
        SOF_s : begin
286
           // A new frame begins immediately following end of last frame.
287
           if (rx_axis_fifo_tready == 1'b1) begin
288
              rd_nxt_state <= DATA_s;
289
           end
290
           else begin
291
              rd_nxt_state <= SOF_s;
292
           end
293
        end
294
 
295
        DATA_s : begin
296
           // Read data from the FIFO. When the EOF marker is detected from
297
           // the BRAM output, move to EOF state.
298
           if (rx_axis_fifo_tready == 1'b1 && rd_eof == 1'b1) begin
299
              rd_nxt_state <= EOF_s;
300
           end
301
           else begin
302
              rd_nxt_state <= DATA_s;
303
           end
304
        end
305
 
306
        EOF_s : begin
307
           // Hold in this state until tready is asserted and the EOF
308
           // marker (tlast) is accepted on interface.
309
           // If there is another frame in the FIFO, then it will already be
310
           // queued into the pipeline so move straight to SOF state.
311
           if (rx_axis_fifo_tready == 1'b1) begin
312
              if (rd_valid_pipe[1] == 1'b1) begin
313
                 rd_nxt_state <= SOF_s;
314
              end
315
              else begin
316
                 rd_nxt_state <= WAIT_s;
317
              end
318
           end
319
           else begin
320
              rd_nxt_state <= EOF_s;
321
           end
322
         end
323
 
324
         default : begin
325
           rd_nxt_state <= WAIT_s;
326
         end
327
 
328
     endcase
329
  end
330
 
331
  // Detect if frame_in_fifo was high 3 reads ago.
332
  // This is used to ensure we only treat data in the pipeline as valid if
333
  // frame_in_fifo goes high at or before the EOF marker of the current frame.
334
  // It may be that there is valid data (i.e a partial frame has been written)
335
  // but until the end of that frame we do not know if it is a good frame.
336
  always @(posedge rx_fifo_aclk)
337
  begin
338
     if (rx_axis_fifo_tready == 1'b1) begin
339
        rd_valid_pipe <= {rd_valid_pipe[0], frame_in_fifo};
340
     end
341
  end
342
 
343
  // Decode tlast signal from EOF marker.
344
  always @(posedge rx_fifo_aclk)
345
  begin
346
     if (rx_fifo_reset == 1'b1) begin
347
        rx_axis_fifo_tlast_int <= 1'b0;
348
     end
349
     else if (rx_axis_fifo_tready == 1'b1) begin
350
        // Assert tlast signal when the EOF marker has been detected, and
351
        // continue to drive it until it has been accepted on the interface.
352
        case (rd_state)
353
           EOF_s :
354
              rx_axis_fifo_tlast_int <= 1'b1;
355
           default :
356
              rx_axis_fifo_tlast_int <= 1'b0;
357
        endcase
358
     end
359
  end
360
 
361
  // Decode the tvalid output based on state.
362
  always @(posedge rx_fifo_aclk)
363
  begin
364
     if (rx_fifo_reset == 1'b1) begin
365
        rx_axis_fifo_tvalid <= 1'b0;
366
     end
367
     else begin
368
        case (rd_state)
369
           QUEUE_SOF_s :
370
              rx_axis_fifo_tvalid <= 1'b1;
371
           SOF_s :
372
              rx_axis_fifo_tvalid <= 1'b1;
373
           DATA_s :
374
              rx_axis_fifo_tvalid <= 1'b1;
375
           EOF_s :
376
              rx_axis_fifo_tvalid <= 1'b1;
377
           default :
378
              if (rx_axis_fifo_tready == 1'b1) begin
379
                 rx_axis_fifo_tvalid <= 1'b0;
380
              end
381
         endcase
382
     end
383
  end
384
 
385
  // Decode internal control signals.
386
  // rd_en is used to enable the BRAM read and load the output pipeline.
387
  always @(rd_state, rx_axis_fifo_tready)
388
  begin
389
     case (rd_state)
390
         WAIT_s :
391
            rd_en <= 1'b0;
392
         QUEUE1_s :
393
            rd_en <= 1'b1;
394
         QUEUE2_s :
395
            rd_en <= 1'b1;
396
         QUEUE3_s :
397
            rd_en <= 1'b1;
398
         QUEUE_SOF_s :
399
            rd_en <= 1'b1;
400
         default :
401
            rd_en <= rx_axis_fifo_tready;
402
     endcase
403
  end
404
 
405
  // When the BRAM is being read, enable the read address to be incremented.
406
  assign rd_addr_inc = rd_en;
407
 
408
  // When the current frame is done, and if there is no frame in the FIFO, then
409
  // the FIFO must wait until a new frame is written in. This requires the read
410
  // address to be moved back to where the new frame will be written. The
411
  // pipeline is then reloaded using the QUEUE states.
412
  always @(posedge rx_fifo_aclk)
413
  begin
414
     if (rx_fifo_reset == 1'b1) begin
415
        rd_addr_reload <= 1'b0;
416
     end
417
     else begin
418
        if (rd_state == EOF_s && rd_nxt_state == WAIT_s)
419
           rd_addr_reload <= 1'b1;
420
        else
421
           rd_addr_reload <= 1'b0;
422
     end
423
  end
424
 
425
  // Data is available if there is at leat one frame stored in the FIFO.
426
  always @(posedge rx_fifo_aclk)
427
  begin
428
     if (rx_fifo_reset == 1'b1) begin
429
        frame_in_fifo <= 1'b0;
430
     end
431
     else begin
432
        if (rd_frames != 9'b0) begin
433
           frame_in_fifo <= 1'b1;
434
        end
435
        else begin
436
           frame_in_fifo <= 1'b0;
437
        end
438
     end
439
  end
440
 
441
  // When a frame has been stored we need to synchronize that event to the
442
  // read clock domain for frame count store.
443
  tri_mode_ethernet_mac_0_sync_block resync_wr_store_frame_tog
444
  (
445
    .clk       (rx_fifo_aclk),
446
    .data_in   (wr_store_frame_tog),
447
    .data_out  (rd_store_frame_sync)
448
  );
449
 
450
  always @(posedge rx_fifo_aclk)
451
  begin
452
     rd_store_frame_delay <= rd_store_frame_sync;
453
  end
454
 
455
  // Edge detect of the resynchronized frame count. This creates a pulse
456
  // when a new frame has been stored.
457
  always @(posedge rx_fifo_aclk)
458
  begin
459
     if (rx_fifo_reset == 1'b1) begin
460
        rd_store_frame       <= 1'b0;
461
     end
462
     else begin
463
        // Edge detector
464
        if ((rd_store_frame_delay ^ rd_store_frame_sync) == 1'b1) begin
465
           rd_store_frame    <= 1'b1;
466
        end
467
        else begin
468
           rd_store_frame    <= 1'b0;
469
        end
470
     end
471
  end
472
 
473
  // This creates a pulse when a new frame has begun to be output.
474
  always @(posedge rx_fifo_aclk)
475
  begin
476
     if (rx_fifo_reset == 1'b1) begin
477
        rd_pull_frame <= 1'b0;
478
     end
479
     else begin
480
        if (rd_state == SOF_s && rd_nxt_state != SOF_s) begin
481
           rd_pull_frame <= 1'b1;
482
        end
483
        else if (rd_state == QUEUE_SOF_s && rd_nxt_state != QUEUE_SOF_s) begin
484
           rd_pull_frame <= 1'b1;
485
        end
486
        else begin
487
           rd_pull_frame <= 1'b0;
488
        end
489
     end
490
  end
491
 
492
  // Up/down counter to monitor the number of frames stored within
493
  // the FIFO. Note:
494
  //    * increments at the end of a frame write cycle
495
  //    * decrements at the beginning of a frame read cycle
496
  always @(posedge rx_fifo_aclk)
497
  begin
498
     if (rx_fifo_reset == 1'b1) begin
499
        rd_frames <= 9'b0;
500
     end
501
     else begin
502
        // A frame is written to the FIFO in this cycle, and no frame is being
503
        // read out on the same cycle.
504
        if (rd_store_frame == 1'b1 && rd_pull_frame == 1'b0) begin
505
           rd_frames <= rd_frames + 9'b1;
506
        end
507
        // A frame is being read out on this cycle and no frame is being
508
        // written on the same cycle.
509
        else if (rd_store_frame == 1'b0 && rd_pull_frame == 1'b1) begin
510
           rd_frames <= rd_frames - 9'b1;
511
        end
512
     end
513
  end
514
 
515
 
516
  //----------------------------------------------------------------------------
517
  // Write state machines and control
518
  //----------------------------------------------------------------------------
519
 
520
  // Write state machine.
521
  // States are IDLE, FRAME, GF, BF, OVFLOW.
522
  // Clock state to next state.
523
  always @(posedge rx_mac_aclk)
524
  begin
525
     if (rx_mac_reset == 1'b1) begin
526
        wr_state <= IDLE_s;
527
     end
528
     else begin
529
        wr_state <= wr_nxt_state;
530
     end
531
  end
532
 
533
  // Decode next state, combinatorial.
534
  always @(wr_state, wr_dv_pipe[1], wr_gf, wr_bf, wr_fifo_full)
535
  begin
536
     case (wr_state)
537
        IDLE_s : begin
538
           // There is data in the incoming pipeline when dv_pipe[1] goes high.
539
           if (wr_dv_pipe[1] == 1'b1) begin
540
              wr_nxt_state <= FRAME_s;
541
           end
542
           else begin
543
              wr_nxt_state <= IDLE_s;
544
           end
545
        end
546
 
547
        FRAME_s : begin
548
           // If FIFO is full then go to overflow state.
549
           // If the good or bad flag is detected, then the end of the frame
550
           // has been reached and the gf or bf state is visited before idle.
551
           // Otherwise remain in frame state while data is written to FIFO.
552
           if (wr_fifo_full == 1'b1) begin
553
              wr_nxt_state <= OVFLOW_s;
554
           end
555
           else if (wr_gf == 1'b1) begin
556
              wr_nxt_state <= GF_s;
557
           end
558
           else if (wr_bf == 1'b1) begin
559
              wr_nxt_state <= BF_s;
560
           end
561
           else begin
562
              wr_nxt_state <= FRAME_s;
563
           end
564
        end
565
 
566
        GF_s : begin
567
           // Return to idle and wait for next frame.
568
           wr_nxt_state <= IDLE_s;
569
        end
570
 
571
        BF_s : begin
572
           // Return to idle and wait for next frame.
573
           wr_nxt_state <= IDLE_s;
574
        end
575
 
576
        OVFLOW_s : begin
577
           // Wait until the good or bad flag received.
578
           if (wr_gf == 1'b1 || wr_bf == 1'b1) begin
579
              wr_nxt_state <= IDLE_s;
580
           end
581
           else begin
582
              wr_nxt_state <= OVFLOW_s;
583
           end
584
        end
585
 
586
        default : begin
587
           wr_nxt_state <= IDLE_s;
588
        end
589
 
590
     endcase
591
  end
592
 
593
  // Decode control signals, combinatorial.
594
  // wr_en is used to enable the BRAM write and loading of the input pipeline.
595
  assign wr_en = (wr_state == FRAME_s) ? wr_dv_pipe[2] : 1'b0;
596
 
597
  // Increment the write address when we are receiving valid frame data.
598
  assign wr_addr_inc = (wr_state == FRAME_s) ? wr_dv_pipe[2] : 1'b0;
599
 
600
  // If the FIFO overflows or a frame is to be dropped, we need to move the
601
  // write address back to the start of the frame.  This allows the data to be
602
  // overwritten.
603
  assign wr_addr_reload = (wr_state == BF_s || wr_state == OVFLOW_s)
604
                          ? 1'b1 : 1'b0;
605
 
606
  // The start address is saved when in the idle state.
607
  assign wr_start_addr_load = (wr_state == IDLE_s) ? 1'b1 : 1'b0;
608
 
609
  // We need to know when a frame is stored, in order to increment the count of
610
  // frames stored in the FIFO.
611
  always @(posedge rx_mac_aclk)
612
  begin
613
     if (wr_state == GF_s) begin
614
        wr_store_frame_tog <= !wr_store_frame_tog;
615
     end
616
  end
617
 
618
 
619
  //----------------------------------------------------------------------------
620
  // Address counters
621
  //----------------------------------------------------------------------------
622
 
623
  // Write address is incremented when data is being written into the FIFO.
624
  always @(posedge rx_mac_aclk)
625
  begin
626
     if (rx_mac_reset == 1'b1) begin
627
        wr_addr <= 12'b0;
628
     end
629
     else begin
630
        if (wr_addr_reload == 1'b1) begin
631
           wr_addr <= wr_start_addr;
632
        end
633
        else if (wr_addr_inc == 1'b1) begin
634
           wr_addr <= wr_addr + 12'b1;
635
        end
636
     end
637
  end
638
 
639
  // Store the start address.
640
  always @(posedge rx_mac_aclk)
641
  begin
642
     if (rx_mac_reset == 1'b1) begin
643
        wr_start_addr <= 12'b0;
644
     end
645
     else begin
646
        if (wr_start_addr_load == 1'b1) begin
647
           wr_start_addr <= wr_addr;
648
        end
649
     end
650
  end
651
 
652
  // Read address is incremented when data is being read from the FIFO.
653
  always @(posedge rx_fifo_aclk)
654
  begin
655
     if (rx_fifo_reset == 1'b1) begin
656
        rd_addr <= 12'd0;
657
     end
658
     else begin
659
        if (rd_addr_reload == 1'b1) begin
660
           rd_addr <= rd_addr - 12'd3;
661
        end
662
        else if (rd_addr_inc == 1'b1) begin
663
           rd_addr <= rd_addr + 12'd1;
664
        end
665
     end
666
  end
667
 
668
 
669
  //----------------------------------------------------------------------------
670
  // Data pipelines
671
  //----------------------------------------------------------------------------
672
 
673
  // Register data inputs to BRAM.
674
  // No resets to allow for SRL16 target.
675
  always @(posedge rx_mac_aclk)
676
  begin
677
     wr_data_pipe[0] <= rx_axis_mac_tdata;
678
     wr_data_pipe[1] <= wr_data_pipe[0];
679
     wr_data_bram    <= wr_data_pipe[1];
680
  end
681
 
682
  // The valid input enables BRAM write and is a condition for other signals.
683
  always @(posedge rx_mac_aclk)
684
  begin
685
     wr_dv_pipe[0] <= rx_axis_mac_tvalid;
686
     wr_dv_pipe[1] <= wr_dv_pipe[0];
687
     wr_dv_pipe[2] <= wr_dv_pipe[1];
688
  end
689
 
690
  // End of frame flag set when tlast and tvalid are asserted together.
691
  always @(posedge rx_mac_aclk)
692
  begin
693
     wr_eof_bram_pipe[0] <= rx_axis_mac_tlast;
694
     wr_eof_bram_pipe[1] <= wr_eof_bram_pipe[0];
695
     wr_eof_bram <= wr_eof_bram_pipe[1] & wr_dv_pipe[1];
696
  end
697
 
698
  // Upon arrival of EOF flag, the frame is good good if tuser signal
699
  // is low, and bad if tuser signal is high.
700
  always @(posedge rx_mac_aclk)
701
  begin
702
     wr_gfbf_pipe[0] <= rx_axis_mac_tuser;
703
     wr_gfbf_pipe[1] <= wr_gfbf_pipe[0];
704
     wr_gf <= !wr_gfbf_pipe[1] & wr_eof_bram_pipe[1] & wr_dv_pipe[1];
705
     wr_bf <=  wr_gfbf_pipe[1] & wr_eof_bram_pipe[1] & wr_dv_pipe[1];
706
  end
707
 
708
  // Register data outputs from BRAM.
709
  // No resets to allow for SRL16 target.
710
  always @(posedge rx_fifo_aclk)
711
  begin
712
     if (rd_en == 1'b1) begin
713
          rd_data_delay <= rd_data_bram;
714
          rd_data_pipe  <= rd_data_delay;
715
          rx_axis_fifo_tdata <= rd_data_pipe;
716
     end
717
  end
718
 
719
  always @(posedge rx_fifo_aclk)
720
  begin
721
     if (rd_en == 1'b1) begin
722
          rd_eof <= rd_eof_bram[0];
723
     end
724
  end
725
 
726
  //----------------------------------------------------------------------------
727
  // Overflow functionality
728
  //----------------------------------------------------------------------------
729
 
730
  // to minimise the number of read address updates the bottom 6 bits of the
731
  // read address are not passed across and the write domain will only sample
732
  // them when bits 5 and 4 of the read address transition from 01 to 10.
733
  // Since this is for full detection this just means that if the read stops
734
  // the write will hit full up to 64 locations early
735
 
736
  // need to use two bits and look for an increment transition as reload can cause
737
  // a decrement on this boundary (decrement is only by 3 so above bit 2 should be safe)
738
  always @(posedge rx_fifo_aclk)
739
  begin
740
     if (rx_fifo_reset == 1'b1) begin
741
        old_rd_addr <= 2'b00;
742
        update_addr_tog <= 1'b0;
743
     end
744
     else begin
745
        old_rd_addr <= rd_addr[5:4];
746
        if (rd_addr[5:4] == 2'b10 & old_rd_addr == 2'b01) begin
747
           update_addr_tog <= !update_addr_tog;
748
        end
749
     end
750
  end
751
 
752
 
753
  tri_mode_ethernet_mac_0_sync_block sync_rd_addr_tog
754
  (
755
    .clk      (rx_mac_aclk),
756
    .data_in  (update_addr_tog),
757
    .data_out (update_addr_tog_sync)
758
  );
759
 
760
  // Convert the synchronized read address pointer gray code back to binary.
761
  always @(posedge rx_mac_aclk)
762
  begin
763
     if (rx_mac_reset == 1'b1) begin
764
        update_addr_tog_sync_reg <= 1'b0;
765
        wr_rd_addr               <= 6'd0;
766
     end
767
     else begin
768
        update_addr_tog_sync_reg <= update_addr_tog_sync;
769
        if (update_addr_tog_sync_reg ^ update_addr_tog_sync) begin
770
           wr_rd_addr <= rd_addr[11:6];
771
        end
772
     end
773
  end
774
 
775
  assign wr_addr_diff_in = {1'b0, wr_rd_addr, 6'd0} - {1'b0,wr_addr};
776
 
777
  // Obtain the difference between write and read pointers.
778
  always @(posedge rx_mac_aclk)
779
  begin
780
     if (rx_mac_reset == 1'b1) begin
781
        wr_addr_diff <= 12'b0;
782
     end
783
     else begin
784
        wr_addr_diff <= wr_addr_diff_in[11:0];
785
     end
786
  end
787
 
788
  // Detect when the FIFO is full.
789
  // The FIFO is considered to be full if the write address pointer is
790
  // within 0 to 3 of the read address pointer.
791
  always @(posedge rx_mac_aclk)
792
  begin
793
     if (rx_mac_reset == 1'b1) begin
794
        wr_fifo_full <= 1'b0;
795
     end
796
     else begin
797
        if (wr_addr_diff[11:4] == 8'b0 && wr_addr_diff[3:2] != 2'b0) begin
798
           wr_fifo_full <= 1'b1;
799
        end
800
        else begin
801
           wr_fifo_full <= 1'b0;
802
        end
803
     end
804
  end
805
 
806
  // Decode the overflow indicator output.
807
  assign fifo_overflow = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
808
 
809
 
810
  //----------------------------------------------------------------------------
811
  // FIFO status signals
812
  //----------------------------------------------------------------------------
813
 
814
  // The FIFO status is four bits which represents the occupancy of the FIFO
815
  // in sixteenths. To generate this signal we therefore only need to compare
816
  // the 4 most significant bits of the write address pointer with the 4 most
817
  // significant bits of the read address pointer.
818
 
819
  always @(posedge rx_mac_aclk)
820
  begin
821
     if (rx_mac_reset == 1'b1) begin
822
         wr_fifo_status <= 4'b0;
823
     end
824
     else begin
825
        if (wr_addr_diff == 12'b0) begin
826
           wr_fifo_status <= 4'b0;
827
        end
828
        else begin
829
           wr_fifo_status[3] <= !wr_addr_diff[11];
830
           wr_fifo_status[2] <= !wr_addr_diff[10];
831
           wr_fifo_status[1] <= !wr_addr_diff[9];
832
           wr_fifo_status[0] <= !wr_addr_diff[8];
833
        end
834
     end
835
  end
836
 
837
  assign fifo_status = wr_fifo_status;
838
 
839
 
840
  //----------------------------------------------------------------------------
841
  // Instantiate FIFO block memory
842
  //----------------------------------------------------------------------------
843
 
844
  assign wr_eof_data_bram[8]   = wr_eof_bram;
845
  assign wr_eof_data_bram[7:0] = wr_data_bram;
846
 
847
  assign rd_eof_bram[0] = rd_eof_data_bram[8];
848
  assign rd_data_bram   = rd_eof_data_bram[7:0];
849
 
850
tri_mode_ethernet_mac_0_bram_tdp #
851
(
852
     .DATA_WIDTH  (9),
853
     .ADDR_WIDTH  (12)
854
  )
855
  rx_ramgen_i (
856
     .b_dout  (rd_eof_data_bram),
857
     .a_addr  (wr_addr[11:0]),
858
     .b_addr  (rd_addr[11:0]),
859
     .a_clk   (rx_mac_aclk),
860
     .b_clk   (rx_fifo_aclk),
861
     .a_din   (wr_eof_data_bram),
862
     .b_en    (rd_en),
863
     .a_rst   (rx_mac_reset),
864
     .b_rst   (rx_fifo_reset),
865
     .a_wr    (wr_en)
866
  );
867
 
868
endmodule

powered by: WebSVN 2.1.0

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