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

Subversion Repositories fpga-cf

[/] [fpga-cf/] [trunk/] [hdl/] [boardsupport/] [v5/] [tx_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 Transmitter FIFO
3
// Project    : Virtex-5 Ethernet MAC Wrappers
4
//-----------------------------------------------------------------------------
5
// File       : tx_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 a transmitter side local link fifo implementation for
45
//              the design example of the Virtex-5 Ethernet MAC Wrapper
46
//              core.
47
//              
48
//              The transmit FIFO is created from 2 Block RAMs of size 2048
49
//              words of 8-bits per word, giving a total frame memory capacity
50
//              of 4096 bytes.
51
//
52
//              Valid frame data received from local link interface is written
53
//              into the Block RAM on the write clock.  The FIFO will store
54
//              frames upto 4kbytes in length.  If larger frames are written
55
//              to the FIFO the local-link interface will accept the rest of the
56
//              frame, but that frame will be dropped by the FIFO and
57
//              the overflow signal will be asserted.
58
//
59
//              The FIFO is designed to work with a minimum frame length of 14 bytes.
60
//              
61
//              When there is at least one complete frame in the FIFO,
62
//              the MAC transmitter client interface will be driven to
63
//              request frame transmission by placing the first byte of
64
//              the frame onto tx_data[7:0] and by asserting
65
//              tx_data_valid.  The MAC will later respond by asserting
66
//              tx_ack.  At this point the remaining frame data is read
67
//              out of the FIFO in a continuous burst. Data is read out
68
//              of the FIFO on the rd_clk.
69
//
70
//              If the generic FULL_DUPLEX_ONLY is set to false, the FIFO will
71
//              requeue and retransmit frames as requested by the MAC.  Once a
72
//              frame has been transmitted by the FIFO it is stored until the
73
//              possible retransmit window for that frame has expired.
74
//
75
//              The FIFO has been designed to operate with different clocks
76
//              on the write and read sides. The write clock (locallink clock)
77
//              can be an equal or faster frequency than the read clock (client clock).
78
//              The minimum write clock frequency is the read clock frequency divided
79
//              by 2.5.
80
//
81
//              The FIFO memory size can be increased by expanding the rd_addr
82
//              and wr_addr signal widths, to address further BRAMs.
83
//
84
//-----------------------------------------------------------------------------
85
 
86
`timescale 1ps / 1ps
87
 
88
 
89
module tx_client_fifo_8
90
    (
91
        // MAC Interface
92
        rd_clk,
93
        rd_sreset,
94
        rd_enable,
95
        tx_data,
96
        tx_data_valid,
97
        tx_ack,
98
        tx_collision,
99
        tx_retransmit,
100
        overflow,
101
 
102
        // Local-link Interface
103
        wr_clk,
104
        wr_sreset,
105
        wr_data,
106
        wr_sof_n,
107
        wr_eof_n,
108
        wr_src_rdy_n,
109
        wr_dst_rdy_n,
110
        wr_fifo_status
111
        );
112
 
113
  //---------------------------------------------------------------------------
114
  // Define Interface Signals
115
  //---------------------------------------------------------------------------
116
 
117
  // MAC Interface
118
  input        rd_clk;
119
  input        rd_sreset;
120
  input        rd_enable;
121
  output [7:0] tx_data;
122
  output       tx_data_valid;
123
  input        tx_ack;
124
  input        tx_collision;
125
  input        tx_retransmit;
126
  output       overflow;
127
 
128
  // Local-link Interface
129
  input        wr_clk;
130
  input        wr_sreset;
131
  input  [7:0] wr_data;
132
  input        wr_sof_n;
133
  input        wr_eof_n;
134
  input        wr_src_rdy_n;
135
  output       wr_dst_rdy_n;
136
  output [3:0] wr_fifo_status;
137
 
138
  // If FULL_DUPLEX_ONLY is 1 then all the half duplex logic in the FIFO is removed.
139
  // The default for the fifo is to include the half duplex functionality 
140
  parameter    FULL_DUPLEX_ONLY = 0;
141
 
142
  reg [7:0]    tx_data;
143
  reg          tx_data_valid;
144
  reg [3:0]    wr_fifo_status;
145
 
146
 
147
  //---------------------------------------------------------------------------
148
  // Define Internal Signals
149
  //---------------------------------------------------------------------------
150
 
151
  wire        GND;
152
  wire        VCC;
153
  wire [7:0]  GND_BUS;
154
 
155
  // Encode rd_state_machine states   
156
  parameter  IDLE_s = 4'b0000;      parameter  QUEUE1_s = 4'b0001;
157
  parameter  QUEUE2_s = 4'b0010;    parameter  QUEUE3_s = 4'b0011;
158
  parameter  QUEUE_ACK_s = 4'b0100; parameter  WAIT_ACK_s = 4'b0101;
159
  parameter  FRAME_s = 4'b0110;     parameter  DROP_s = 4'b0111;
160
  parameter  RETRANSMIT_s = 4'b1000;
161
 
162
  reg  [3:0]  rd_state;
163
  reg  [3:0]  rd_nxt_state;
164
 
165
  // Encode wr_state_machine states 
166
  parameter WAIT_s = 2'b00;  parameter DATA_s = 2'b01;
167
  parameter EOF_s = 2'b10;   parameter OVFLOW_s = 2'b11;
168
 
169
  reg  [1:0]  wr_state;
170
  reg  [1:0]  wr_nxt_state;
171
 
172
  reg  [7:0]  wr_data_bram;
173
  reg  [7:0]  wr_data_pipe[0:1];
174
  reg         wr_sof_pipe[0:1];
175
  reg         wr_eof_pipe[0:1];
176
  reg         wr_accept_pipe[0:1];
177
  reg         wr_accept_bram;
178
  reg  [0:0]  wr_eof_bram;
179
  reg  [11:0] wr_addr;
180
  wire        wr_addr_inc;
181
  wire        wr_start_addr_load;
182
  wire        wr_addr_reload;
183
  reg  [11:0] wr_start_addr;
184
  reg         wr_fifo_full;
185
  wire        wr_en;
186
  wire        wr_en_u;
187
  wire        wr_en_l;
188
  reg         wr_ovflow_dst_rdy;
189
  wire        wr_dst_rdy_int_n;
190
 
191
  reg         frame_in_fifo;
192
  reg         frame_in_fifo_sync;
193
  reg         rd_eof;
194
  reg         rd_eof_reg;
195
  reg         rd_eof_pipe;
196
  reg  [11:0] rd_addr;
197
  wire        rd_addr_inc;
198
  wire        rd_addr_reload;
199
  wire [7:0]  rd_data_bram_u;
200
  wire [7:0]  rd_data_bram_l;
201
  reg  [7:0]  rd_data_pipe_u;
202
  reg  [7:0]  rd_data_pipe_l;
203
  reg  [7:0]  rd_data_pipe;
204
  wire [0:0]  rd_eof_bram_u;
205
  wire [0:0]  rd_eof_bram_l;
206
  wire        rd_en;
207
  wire        rd_en_bram;
208
  reg         rd_bram_u;
209
  reg         rd_bram_u_reg;
210
 
211
  reg         rd_tran_frame_tog;
212
  reg         wr_tran_frame_tog;
213
  reg         wr_tran_frame_sync;
214
  reg         wr_tran_frame_delay;
215
  reg         rd_retran_frame_tog;
216
  reg         wr_retran_frame_tog;
217
  reg         wr_retran_frame_sync;
218
  reg         wr_retran_frame_delay;
219
  wire        wr_store_frame;
220
  wire        wr_eof_state;
221
  reg         wr_eof_state_reg;
222
  reg         wr_transmit_frame;
223
  reg         wr_retransmit_frame;
224
  reg  [8:0]  wr_frames;
225
  reg         wr_frame_in_fifo;
226
 
227
  reg   [3:0] rd_16_count;
228
  wire        rd_txfer_en;
229
  reg  [11:0] rd_addr_txfer;
230
  reg         rd_txfer_tog;
231
  reg         wr_txfer_tog;
232
  reg         wr_txfer_tog_sync;
233
  reg         wr_txfer_tog_delay;
234
  wire        wr_txfer_en;
235
  reg  [11:0] wr_rd_addr;
236
  reg  [11:0] wr_addr_diff;
237
 
238
  reg         rd_drop_frame;
239
  reg         rd_retransmit;
240
  reg  [11:0] rd_start_addr;
241
  wire        rd_start_addr_load;
242
  wire        rd_start_addr_reload;
243
 
244
  reg  [11:0] rd_dec_addr;
245
 
246
  wire        rd_transmit_frame;
247
  wire        rd_retransmit_frame;
248
  reg         rd_col_window_expire;
249
  reg         rd_col_window_pipe[0:1];
250
  reg         wr_col_window_pipe[0:1];
251
 
252
  wire        wr_fifo_overflow;
253
  reg  [9:0]  rd_slot_timer;
254
  reg         wr_col_window_expire;
255
  wire        rd_idle_state;
256
 
257
  reg         rd_enable_delay;
258
  reg         rd_enable_delay2;
259
 
260
  //---------------------------------------------------------------------------
261
  // Attributes for FIFO simulation and synthesis
262
  //---------------------------------------------------------------------------
263
  // ASYNC_REG attributes added to simulate actual behaviour under
264
  // asynchronous operating conditions.
265
  // synthesis attribute ASYNC_REG of wr_tran_frame_tog is "TRUE";
266
  // synthesis attribute ASYNC_REG of wr_retran_frame_tog is "TRUE";
267
  // synthesis attribute ASYNC_REG of frame_in_fifo_sync is "TRUE";
268
  // synthesis attribute ASYNC_REG of wr_rd_addr is "TRUE";
269
  // synthesis attribute ASYNC_REG of wr_txfer_tog is "TRUE";
270
  // synthesis attribute ASYNC_REG of wr_col_window_pipe[0] is "TRUE";
271
 
272
  // WRITE_MODE attributes added to Block RAM to mitigate port contention
273
  // synthesis attribute WRITE_MODE_A of ramgen_u is "READ_FIRST";
274
  // synthesis attribute WRITE_MODE_B of ramgen_u is "READ_FIRST";
275
  // synthesis attribute WRITE_MODE_A of ramgen_l is "READ_FIRST";
276
  // synthesis attribute WRITE_MODE_B of ramgen_l is "READ_FIRST";
277
 
278
 
279
 
280
  //---------------------------------------------------------------------------
281
  // Begin FIFO architecture
282
  //---------------------------------------------------------------------------
283
 
284
  assign GND = 1'b0;
285
  assign VCC = 1'b1;
286
  assign GND_BUS = 8'b0;
287
 
288
  always @(posedge rd_clk)
289
  begin
290
     rd_enable_delay <= rd_enable;
291
     rd_enable_delay2 <= rd_enable_delay;
292
  end
293
 
294
  //---------------------------------------------------------------------------
295
  // Write State machine and control
296
  //---------------------------------------------------------------------------
297
  // Write state machine
298
  // states are WAIT, DATA, EOF, OVFLOW
299
  // clock through next state of sm
300
  always @(posedge wr_clk)
301
  begin
302
     if (wr_sreset == 1'b1)
303
         wr_state <= WAIT_s;
304
     else
305
         wr_state <= wr_nxt_state;
306
  end
307
 
308
  // decode next state, combinitorial
309
  // should never be able to overflow whilst not in the data state.
310
  always @(wr_state or wr_sof_pipe[1] or wr_eof_pipe[0] or wr_eof_pipe[1] or wr_eof_bram[0] or wr_fifo_overflow)
311
  begin
312
  case (wr_state)
313
     WAIT_s : begin
314
        if (wr_sof_pipe[1] == 1'b1)
315
           wr_nxt_state <= DATA_s;
316
        else
317
           wr_nxt_state <= WAIT_s;
318
        end
319
     DATA_s : begin
320
        // wait for the end of frame to be detected
321
        if (wr_fifo_overflow == 1'b1 && wr_eof_pipe[0] == 1'b0 && wr_eof_pipe[1] == 1'b0)
322
           wr_nxt_state <= OVFLOW_s;
323
        else if (wr_eof_pipe[1] == 1'b1)
324
           wr_nxt_state <= EOF_s;
325
        else
326
           wr_nxt_state <= DATA_s;
327
        end
328
     EOF_s : begin
329
        // if the start of frame is already in the pipe, a back to back frame
330
        // transmission has occured.  move straight back to frame state
331
        if (wr_sof_pipe[1] == 1'b1)
332
 
333
 
334
           wr_nxt_state <= DATA_s;
335
        else if (wr_eof_bram[0] == 1'b1)
336
           wr_nxt_state <= WAIT_s;
337
        else
338
           wr_nxt_state <= EOF_s;
339
        end
340
     OVFLOW_s : begin
341
        // wait until the end of frame is reached before clearing the overflow
342
        if (wr_eof_bram[0] == 1'b1)
343
           wr_nxt_state <= WAIT_s;
344
        else
345
           wr_nxt_state <= OVFLOW_s;
346
        end
347
     default : begin
348
        wr_nxt_state <= WAIT_s;
349
        end
350
  endcase
351
  end
352
 
353
 
354
  // decode output signals.
355
  assign wr_en = (wr_state == OVFLOW_s) ? 1'b0 : wr_accept_bram;
356
  assign wr_en_l = wr_en & !wr_addr[11];
357
  assign wr_en_u = wr_en & wr_addr[11];
358
 
359
  assign wr_addr_inc = wr_en;
360
 
361
  assign wr_addr_reload = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
362
  assign wr_start_addr_load = (wr_state == EOF_s && wr_nxt_state == WAIT_s) ? 1'b1 :
363
                              (wr_state == EOF_s && wr_nxt_state == DATA_s) ? 1'b1 : 1'b0;
364
 
365
 
366
  // pause the local link flow when the fifo is full.
367
  assign wr_dst_rdy_int_n = (wr_state == OVFLOW_s) ? wr_ovflow_dst_rdy : wr_fifo_full;
368
  assign wr_dst_rdy_n = wr_dst_rdy_int_n;
369
 
370
  // when in overflow and have captured ovflow eof send dst rdy high again.
371
  assign overflow = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
372
 
373
  // when in overflow and have captured ovflow eof send dst rdy high again.
374
  always @(posedge wr_clk)
375
  begin
376
     if (wr_sreset == 1'b1)
377
        wr_ovflow_dst_rdy <= 1'b0;
378
     else
379
        begin
380
        if (wr_fifo_overflow == 1'b1 && wr_state == DATA_s)
381
            wr_ovflow_dst_rdy <= 1'b0;
382
        else if (wr_eof_n == 1'b0 && wr_src_rdy_n == 1'b0)
383
            wr_ovflow_dst_rdy <= 1'b1;
384
        end
385
  end
386
 
387
    // eof signals for use in overflow logic
388
  assign wr_eof_state = (wr_state == EOF_s) ? 1'b1 : 1'b0;
389
 
390
  always @(posedge wr_clk)
391
  begin
392
     if (wr_sreset == 1'b1)
393
        wr_eof_state_reg <= 1'b0;
394
     else
395
        wr_eof_state_reg <= wr_eof_state;
396
  end
397
 
398
  //---------------------------------------------------------------------------
399
  // Read state machine and control
400
  //---------------------------------------------------------------------------
401
 
402
  // clock through the read state machine
403
  always @(posedge rd_clk)
404
  begin
405
     if (rd_sreset == 1'b1)
406
        rd_state <= IDLE_s;
407
     else if (rd_enable == 1'b1)
408
        rd_state <= rd_nxt_state;
409
  end
410
 
411
  //---------------------------------------------------------------------------
412
  // Full Duplex Only State Machine
413
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_sm
414
  // decode the next state
415
  always @(rd_state or frame_in_fifo or rd_eof or tx_ack)
416
  begin
417
  case (rd_state)
418
           IDLE_s : begin
419
              // if there is a frame in the fifo start to queue the new frame
420
              // to the output
421
              if (frame_in_fifo == 1'b1)
422
                 rd_nxt_state <= QUEUE1_s;
423
              else
424
                 rd_nxt_state <= IDLE_s;
425
              end
426
           QUEUE1_s : begin
427
                 rd_nxt_state <= QUEUE2_s;
428
              end
429
           QUEUE2_s : begin
430
                 rd_nxt_state <= QUEUE3_s;
431
              end
432
           QUEUE3_s : begin
433
                 rd_nxt_state <= QUEUE_ACK_s;
434
              end
435
           QUEUE_ACK_s : begin
436
                 rd_nxt_state <= WAIT_ACK_s;
437
              end
438
           WAIT_ACK_s : begin
439
              // the output pipe line is fully loaded, so wait for ack from mac
440
              // before moving on
441
              if (tx_ack == 1'b1)
442
                 rd_nxt_state <= FRAME_s;
443
              else
444
                 rd_nxt_state <= WAIT_ACK_s;
445
              end
446
           FRAME_s : begin
447
              // when the end of frame has been reached wait another frame in
448
              // the fifo
449
              if (rd_eof == 1'b1)
450
                 rd_nxt_state <= IDLE_s;
451
              else
452
                 rd_nxt_state <= FRAME_s;
453
              end
454
           default : begin
455
                 rd_nxt_state <= IDLE_s;
456
              end
457
        endcase
458
  end
459
                                // full duplex state machine
460
 
461
end // gen_fd_sm
462
endgenerate
463
 
464
 
465
  //---------------------------------------------------------------------------
466
  // Full and Half Duplex State Machine
467
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_sm
468
  // decode the next state
469
  // should never receive a rd_drop_frame pulse outside of the Frame state
470
  always @(rd_state or frame_in_fifo or rd_eof_reg or tx_ack or rd_drop_frame or rd_retransmit)
471
  begin
472
  case (rd_state)
473
           IDLE_s : begin
474
              // if a retransmit request is detected go to retransmit state
475
              if (rd_retransmit == 1'b1)
476
                 rd_nxt_state <= RETRANSMIT_s;
477
              // if there is a frame in the fifo then queue the new frame to
478
              // the output
479
              else if (frame_in_fifo == 1'b1)
480
                 rd_nxt_state <= QUEUE1_s;
481
              else
482
                 rd_nxt_state <= IDLE_s;
483
              end
484
           QUEUE1_s : begin
485
              if (rd_retransmit == 1'b1)
486
                 rd_nxt_state <= RETRANSMIT_s;
487
              else
488
                rd_nxt_state <= QUEUE2_s;
489
              end
490
           QUEUE2_s : begin
491
              if (rd_retransmit == 1'b1)
492
                 rd_nxt_state <= RETRANSMIT_s;
493
              else
494
                 rd_nxt_state <= QUEUE3_s;
495
              end
496
           QUEUE3_s : begin
497
              if (rd_retransmit == 1'b1)
498
                 rd_nxt_state <= RETRANSMIT_s;
499
              else
500
                 rd_nxt_state <= QUEUE_ACK_s;
501
              end
502
           QUEUE_ACK_s : begin
503
              if (rd_retransmit == 1'b1)
504
                 rd_nxt_state <= RETRANSMIT_s;
505
              else
506
                 rd_nxt_state <= WAIT_ACK_s;
507
              end
508
           WAIT_ACK_s : begin
509
              // the output pipeline is now fully loaded so wait for ack from
510
              // mac before moving on.
511
              if (rd_retransmit == 1'b1)
512
                 rd_nxt_state <= RETRANSMIT_s;
513
              else if (tx_ack == 1'b1)
514
                 rd_nxt_state <= FRAME_s;
515
              else
516
                 rd_nxt_state <= WAIT_ACK_s;
517
              end
518
           FRAME_s : begin
519
              // if a collision only request, then must drop the rest of the
520
              // current frame, move to drop state
521
              if (rd_drop_frame == 1'b1)
522
                 rd_nxt_state <= DROP_s;
523
              else if (rd_retransmit == 1'b1)
524
                 rd_nxt_state <= RETRANSMIT_s;
525
              // continue transmitting frame until the end of the frame is
526
              // detected, then wait for a new frame to be sent.
527
              else if (rd_eof_reg == 1'b1)
528
                 rd_nxt_state <= IDLE_s;
529
              else
530
                 rd_nxt_state <= FRAME_s;
531
              end
532
           DROP_s : begin
533
              // wait until rest of frame has been cleared.
534
              if (rd_eof_reg == 1'b1)
535
                 rd_nxt_state <= IDLE_s;
536
              else
537
                 rd_nxt_state <= DROP_s;
538
              end
539
           RETRANSMIT_s : begin
540
              // reload the data pipe from the start of the frame
541
                 rd_nxt_state <= QUEUE1_s;
542
              end
543
           default : begin
544
                 rd_nxt_state <= IDLE_s;
545
              end
546
        endcase
547
  end
548
 
549
end // gen_hd_sm                               // half duplex state machine
550
endgenerate
551
 
552
  //---------------------------------------------------------------------------
553
  // decode output signals
554
  // decode output data
555
  always @(posedge rd_clk)
556
  begin
557
     if (rd_enable == 1'b1)
558
        begin
559
        if (rd_nxt_state == FRAME_s)
560
           tx_data <= rd_data_pipe;
561
        else
562
           begin
563
           case (rd_state)
564
              QUEUE_ACK_s :
565
                 tx_data <= rd_data_pipe;
566
              WAIT_ACK_s :
567
                 tx_data <= tx_data;
568
              FRAME_s :
569
                 tx_data <= rd_data_pipe;
570
              default :
571
                 tx_data <= 8'b0;
572
           endcase
573
           end
574
        end
575
  end
576
 
577
  // decode output data valid
578
  always @(posedge rd_clk)
579
  begin
580
     if (rd_enable == 1'b1)
581
        begin
582
        if (rd_nxt_state == FRAME_s)
583
           tx_data_valid <= ~(tx_collision && ~(tx_retransmit));
584
        else
585
           begin
586
           case (rd_state)
587
              QUEUE_ACK_s :
588
                 tx_data_valid <= 1'b1;
589
              WAIT_ACK_s :
590
                 tx_data_valid <= 1'b1;
591
              FRAME_s :
592
                 tx_data_valid <= ~(rd_nxt_state == DROP_s);
593
              default :
594
                 tx_data_valid <= 1'b0;
595
           endcase
596
           end
597
        end
598
  end
599
 
600
  //---------------------------------------------------------------------------
601
  // decode full duplex only control signals
602
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_decode
603
 
604
  assign rd_en = (rd_state == IDLE_s) ? 1'b0 :
605
                 (rd_nxt_state == FRAME_s) ? 1'b1 :
606
                 (rd_state == WAIT_ACK_s) ? 1'b0 : 1'b1;
607
 
608
  assign rd_addr_inc = rd_en;
609
 
610
  assign rd_addr_reload = (rd_state == FRAME_s && rd_nxt_state == IDLE_s) ? 1'b1 : 1'b0;
611
 
612
  // Transmit frame pulse is only 1 clock enabled pulse long.
613
  // Transmit frame pulse must never be more frequent than 64 clocks to allow toggle to cross clock domain
614
  assign rd_transmit_frame = (rd_state == WAIT_ACK_s && rd_nxt_state == FRAME_s) ? 1'b1 : 1'b0;
615
 
616
  // unused for full duplex only
617
  assign rd_start_addr_reload = 1'b0;
618
  assign rd_start_addr_load   = 1'b0;
619
  assign rd_retransmit_frame  = 1'b0;
620
 
621
end // gen_fd_decode                              // full duplex control signals
622
endgenerate
623
 
624
  //---------------------------------------------------------------------------
625
  // decode half duplex control signals
626
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_decode
627
 
628
  assign rd_en = (rd_state == IDLE_s) ? 1'b0 :
629
                 (rd_nxt_state == DROP_s && rd_eof == 1'b1) ? 1'b0 :
630
                 (rd_nxt_state == FRAME_s) ? 1'b1 :
631
                 (rd_state == RETRANSMIT_s) ? 1'b0 :
632
                 (rd_state == WAIT_ACK_s) ? 1'b0 : 1'b1;
633
 
634
  assign rd_addr_inc = rd_en;
635
 
636
  assign rd_addr_reload = (rd_state == FRAME_s && rd_nxt_state == IDLE_s) ? 1'b1 :
637
                          (rd_state == DROP_s && rd_nxt_state == IDLE_s) ? 1'b1 : 1'b0;
638
 
639
  assign rd_start_addr_reload = (rd_state == RETRANSMIT_s) ? 1'b1 : 1'b0;
640
 
641
  assign rd_start_addr_load = (rd_state == WAIT_ACK_s && rd_nxt_state == FRAME_s) ? 1'b1 :
642
                              (rd_col_window_expire == 1'b1) ? 1'b1 : 1'b0;
643
 
644
  // Transmit frame pulse must never be more frequent than 64 clocks to allow toggle to cross clock domain
645
  assign rd_transmit_frame = (rd_state == WAIT_ACK_s && rd_nxt_state == FRAME_s) ? 1'b1 : 1'b0;
646
 
647
  // Retransmit frame pulse must never be more frequent than 16 clocks to allow toggle to cross clock domain
648
  assign rd_retransmit_frame = (rd_state == RETRANSMIT_s) ? 1'b1 : 1'b0;
649
 
650
end // gen_hd_decode                           // half duplex control signals
651
endgenerate
652
 
653
  //---------------------------------------------------------------------------
654
  // Frame Count
655
  // We need to maintain a count of frames in the fifo, so that we know when a
656
  // frame is available for transmission.  The counter must be held on the
657
  // write clock domain as this is the faster clock.
658
  //---------------------------------------------------------------------------
659
 
660
  // A frame has been written to the fifo
661
  assign wr_store_frame = (wr_state == EOF_s && wr_nxt_state != EOF_s) ? 1'b1 : 1'b0;
662
 
663
  // generate a toggle to indicate when a frame has been transmitted from the fifo
664
  always @(posedge rd_clk)
665
  begin  // process
666
     if (rd_sreset == 1'b1)
667
         rd_tran_frame_tog <= 1'b0;
668
     else if (rd_enable == 1'b1)
669
        if (rd_transmit_frame == 1'b1)     // assumes EOF_s is valid for one clock
670
                                        // cycle only ever!  check
671
              rd_tran_frame_tog <= !rd_tran_frame_tog;
672
  end
673
 
674
  // move the read transmit frame signal onto the write clock domain
675
  always @(posedge wr_clk)
676
  begin
677
      if (wr_sreset == 1'b1)
678
         begin
679
            wr_tran_frame_tog  <= 1'b0;
680
            wr_tran_frame_sync <= 1'b0;
681
            wr_tran_frame_delay <= 1'b0;
682
            wr_transmit_frame   <= 1'b0;
683
         end
684
      else
685
        begin
686
           wr_tran_frame_tog  <= rd_tran_frame_tog;
687
           wr_tran_frame_sync <= wr_tran_frame_tog;
688
           wr_tran_frame_delay <= wr_tran_frame_sync;
689
           // edge detector
690
           if ((wr_tran_frame_delay ^ wr_tran_frame_sync) == 1'b1)
691
             wr_transmit_frame    <= 1'b1;
692
           else
693
             wr_transmit_frame    <= 1'b0;
694
        end
695
  end
696
 
697
  //---------------------------------------------------------------------------  
698
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_count
699
 
700
  // count the number of frames in the fifo.  the counter is incremented when a
701
  // frame is stored and decremented when a frame is transmitted.  Need to keep
702
  // the counter on the write clock as this is the fastest clock.
703
  always @(posedge wr_clk)
704
  begin
705
     if (wr_sreset == 1'b1)
706
        wr_frames <= 9'b0;
707
     else
708
        if ((wr_store_frame & !wr_transmit_frame) == 1'b1)
709
           wr_frames <= wr_frames + 1;
710
        else if ((!wr_store_frame & wr_transmit_frame) == 1'b1)
711
           wr_frames <= wr_frames - 1;
712
  end
713
 
714
end // gen_fd_count
715
endgenerate
716
 
717
  //---------------------------------------------------------------------------
718
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_count
719
 
720
  // generate a toggle to indicate when a frame has been transmitted from the fifo
721
  always @(posedge rd_clk)
722
  begin  // process
723
     if (rd_sreset == 1'b1)
724
        rd_retran_frame_tog <= 1'b0;
725
     else if (rd_enable == 1'b1)
726
        if (rd_retransmit_frame == 1'b1)     // assumes EOF_s is valid for one clock
727
                                   // cycle only ever!  check
728
           rd_retran_frame_tog <= !rd_retran_frame_tog;
729
  end
730
 
731
  // move the read transmit frame signal onto the write clock domain
732
  always @(posedge wr_clk)
733
  begin
734
     if (wr_sreset == 1'b1)
735
        begin
736
           wr_retran_frame_tog  <= 1'b0;
737
           wr_retran_frame_sync <= 1'b0;
738
           wr_retran_frame_delay <= 1'b0;
739
           wr_retransmit_frame  <= 1'b0;
740
        end
741
     else
742
        begin
743
           wr_retran_frame_tog  <= rd_retran_frame_tog;
744
           wr_retran_frame_sync <= wr_retran_frame_tog;
745
           wr_retran_frame_delay <= wr_retran_frame_sync;
746
           // edge detector
747
           if ((wr_retran_frame_delay ^ wr_retran_frame_sync) == 1'b1)
748
              wr_retransmit_frame    <= 1'b1;
749
           else
750
              wr_retransmit_frame    <= 1'b0;
751
        end
752
  end
753
 
754
  // count the number of frames in the fifo.  the counter is incremented when a
755
  // frame is stored or retransmitted and decremented when a frame is transmitted.  Need to keep
756
  // the counter on the write clock as this is the fastest clock.
757
  // Assumes transmit and retransmit cannot happen at same time
758
  always @(posedge wr_clk)
759
  begin
760
     if (wr_sreset == 1'b1)
761
        wr_frames <= 9'b0;
762
     else
763
        if ((wr_store_frame & wr_retransmit_frame) == 1'b1)
764
           wr_frames <= wr_frames + 2;
765
        else if (((wr_store_frame | wr_retransmit_frame) & !wr_transmit_frame) == 1'b1)
766
           wr_frames <= wr_frames + 1;
767
        else if (wr_transmit_frame == 1'b1 & !wr_store_frame)
768
           wr_frames <= wr_frames - 1;
769
  end
770
 
771
end // gen_hd_count
772
endgenerate
773
 
774
 
775
  //---------------------------------------------------------------------------
776
  // generate a frame in fifo signal for use in control logic
777
  always @(posedge wr_clk)
778
  begin
779
      if (wr_sreset == 1'b1)
780
         wr_frame_in_fifo <= 1'b0;
781
      else
782
         if (wr_frames != 9'b0)
783
            wr_frame_in_fifo <= 1'b1;
784
         else
785
            wr_frame_in_fifo <= 1'b0;
786
  end
787
 
788
  // register back onto read domain for use in the read logic
789
  always @(posedge rd_clk)
790
  begin
791
     if (rd_sreset == 1'b1)
792
        begin
793
           frame_in_fifo_sync <= 1'b0;
794
           frame_in_fifo <= 1'b0;
795
        end
796
     else if (rd_enable == 1'b1)
797
        begin
798
           frame_in_fifo_sync <= wr_frame_in_fifo;
799
           frame_in_fifo <= frame_in_fifo_sync;
800
        end
801
  end
802
 
803
  //---------------------------------------------------------------------------
804
  // Address counters
805
  //---------------------------------------------------------------------------
806
  // Address counters
807
  // write address is incremented when write enable signal has been asserted
808
  always @(posedge wr_clk)
809
  begin
810
     if (wr_sreset == 1'b1)
811
        wr_addr <= 12'b0;
812
     else if (wr_addr_reload == 1'b1)
813
        wr_addr <= wr_start_addr;
814
     else if (wr_addr_inc == 1'b1)
815
        wr_addr <= wr_addr + 1;
816
  end
817
 
818
  // store the start address incase the address must be reset
819
  always @(posedge wr_clk)
820
  begin
821
     if (wr_sreset == 1'b1)
822
        wr_start_addr <= 12'b0;
823
     else if (wr_start_addr_load == 1'b1)
824
        wr_start_addr <= wr_addr + 1;
825
  end
826
 
827
  //---------------------------------------------------------------------------
828
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_addr
829
  // read address is incremented when read enable signal has been asserted
830
  always @(posedge rd_clk)
831
  begin
832
     if (rd_sreset == 1'b1)
833
        rd_addr <= 12'b0;
834
     else if (rd_enable == 1'b1)
835
        if (rd_addr_reload == 1'b1)
836
           rd_addr <= rd_dec_addr;
837
        else if (rd_addr_inc == 1'b1)
838
           rd_addr <= rd_addr + 1;
839
  end
840
 
841
  // do not need to keep a start address, but the address is needed to
842
  // calculate fifo occupancy.
843
  always @(posedge rd_clk)
844
  begin
845
     if (rd_sreset == 1'b1)
846
        rd_start_addr <= 12'b0;
847
     else if (rd_enable == 1'b1)
848
        rd_start_addr <= rd_addr;
849
  end
850
 
851
 
852
 
853
end // gen_fd_addr                           // full duplex address counters
854
endgenerate
855
 
856
  //---------------------------------------------------------------------------
857
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_addr
858
  // read address is incremented when read enable signal has been asserted
859
  always @(posedge rd_clk)
860
  begin
861
     if (rd_sreset == 1'b1)
862
        rd_addr <= 12'b0;
863
     else if (rd_enable == 1'b1)
864
        if (rd_addr_reload == 1'b1)
865
           rd_addr <= rd_dec_addr;
866
        else if (rd_start_addr_reload == 1'b1)
867
           rd_addr <= rd_start_addr;
868
        else if (rd_addr_inc == 1'b1)
869
           rd_addr <= rd_addr + 1;
870
  end
871
 
872
  always @(posedge rd_clk)
873
  begin
874
     if (rd_sreset == 1'b1)
875
        rd_start_addr <= 12'b0;
876
     else if (rd_enable == 1'b1)
877
        if (rd_start_addr_load == 1'b1)
878
           rd_start_addr <= rd_addr - 4;
879
  end
880
 
881
  // Collision window expires after MAC has been transmitting for required slot
882
  // time.  This is 512 clock cycles at 1G.  Also if the end of frame has fully
883
  // been transmitted by the mac then a collision cannot occur.
884
  // this collision expire signal goes high at 768 cycles from the start of the
885
  // frame.
886
  // inefficient for short frames, however should be enough to prevent fifo
887
  // locking up.
888
  always @(posedge rd_clk)
889
  begin
890
     if (rd_sreset == 1'b1)
891
        rd_col_window_expire <= 1'b0;
892
     else if (rd_enable == 1'b1)
893
        if (rd_transmit_frame == 1'b1)
894
           rd_col_window_expire <= 1'b0;
895
        else if (rd_slot_timer[9:8] == 2'b11)
896
           rd_col_window_expire <= 1'b1;
897
  end
898
 
899
  assign rd_idle_state = (rd_state == IDLE_s) ? 1'b1 : 1'b0;
900
 
901
  always @(posedge rd_clk)
902
  begin
903
     if (rd_enable == 1'b1)
904
        begin
905
           rd_col_window_pipe[0] <= rd_col_window_expire & rd_idle_state;
906
           if (rd_txfer_en == 1'b1)
907
              rd_col_window_pipe[1] <= rd_col_window_pipe[0];
908
        end
909
  end
910
 
911
  always @(posedge rd_clk)
912
  begin
913
     if (rd_sreset == 1'b1)         // will not count until after first
914
                                    // frame is sent.
915
        rd_slot_timer <= 10'b0;
916
     else if (rd_enable == 1'b1)
917
        if (rd_transmit_frame == 1'b1)  // reset counter
918
           rd_slot_timer <= 10'b0;
919
        // do not allow counter to role over.
920
        // only count when frame is being transmitted.
921
        else if (rd_slot_timer != 10'b1111111111)
922
           rd_slot_timer <= rd_slot_timer + 1;
923
  end
924
 
925
 
926
end // gen_hd_addr                           // half duplex address counters
927
endgenerate
928
 
929
  always @(posedge rd_clk)
930
  begin
931
     if (rd_sreset == 1'b1)
932
           rd_dec_addr <= 12'b0;
933
     else if (rd_enable == 1'b1)
934
        if (rd_addr_inc == 1'b1)
935
           rd_dec_addr <= rd_addr - 1;
936
  end
937
 
938
  //---------------------------------------------------------------------------
939
  always @(posedge rd_clk)
940
  begin
941
     if (rd_sreset == 1'b1)
942
        begin
943
           rd_bram_u <= 1'b0;
944
           rd_bram_u_reg <= 1'b0;
945
        end
946
     else if (rd_enable == 1'b1)
947
        if (rd_addr_inc == 1'b1)
948
           begin
949
              rd_bram_u <= rd_addr[11];
950
              rd_bram_u_reg <= rd_bram_u;
951
           end
952
  end
953
 
954
  //---------------------------------------------------------------------------
955
  // Data Pipelines
956
  //---------------------------------------------------------------------------
957
  // register input signals to fifo
958
  // no reset to allow srl16 target
959
  always @(posedge wr_clk)
960
  begin
961
     wr_data_pipe[0] <= wr_data;
962
     if (wr_accept_pipe[0] == 1'b1)
963
        wr_data_pipe[1] <= wr_data_pipe[0];
964
     if (wr_accept_pipe[1] == 1'b1)
965
        wr_data_bram    <= wr_data_pipe[1];
966
  end
967
 
968
  // no reset to allow srl16 target
969
  always @(posedge wr_clk)
970
  begin
971
     wr_sof_pipe[0] <= !wr_sof_n;
972
     if (wr_accept_pipe[0] == 1'b1)
973
        wr_sof_pipe[1] <= wr_sof_pipe[0];
974
  end
975
 
976
  always @(posedge wr_clk)
977
  begin
978
     if (wr_sreset == 1'b1)
979
        begin
980
           wr_accept_pipe[0] <= 1'b0;
981
           wr_accept_pipe[1] <= 1'b0;
982
           wr_accept_bram    <= 1'b0;
983
        end
984
     else
985
        begin
986
           wr_accept_pipe[0] <= !wr_src_rdy_n & !wr_dst_rdy_int_n;
987
           wr_accept_pipe[1] <= wr_accept_pipe[0];
988
           wr_accept_bram    <= wr_accept_pipe[1];
989
        end
990
  end
991
 
992
  always @(posedge wr_clk)
993
  begin
994
     wr_eof_pipe[0] <= !wr_eof_n;
995
     if (wr_accept_pipe[0] == 1'b1)
996
        wr_eof_pipe[1] <= wr_eof_pipe[0];
997
     if (wr_accept_pipe[1] == 1'b1)
998
        wr_eof_bram[0] <= wr_eof_pipe[1];
999
  end
1000
 
1001
  // register data outputs from bram
1002
  // no reset to allow srl16 target
1003
  always @(posedge rd_clk)
1004
  begin
1005
     if (rd_enable == 1'b1)
1006
        if (rd_en == 1'b1)
1007
           begin
1008
              rd_data_pipe_u <= rd_data_bram_u;
1009
              rd_data_pipe_l <= rd_data_bram_l;
1010
              if (rd_bram_u_reg == 1'b1)
1011
                 rd_data_pipe <= rd_data_pipe_u;
1012
              else
1013
                 rd_data_pipe <= rd_data_pipe_l;
1014
           end
1015
  end
1016
 
1017
   // register data outputs from bram
1018
  // no reset to allow srl16 target
1019
  always @(posedge rd_clk)
1020
  begin
1021
     if (rd_enable == 1'b1)
1022
        if (rd_en == 1'b1)
1023
           begin
1024
              if (rd_bram_u == 1'b1)
1025
                 rd_eof_pipe <= rd_eof_bram_u[0];
1026
              else
1027
                 rd_eof_pipe <= rd_eof_bram_l[0];
1028
              rd_eof <= rd_eof_pipe;
1029
              rd_eof_reg <= rd_eof | rd_eof_pipe;
1030
           end
1031
  end
1032
 
1033
  //---------------------------------------------------------------------------
1034
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_input
1035
  // register the collision and retransmit signals
1036
  always @(posedge rd_clk)
1037
  begin
1038
     if (rd_enable == 1'b1)
1039
        rd_drop_frame <= tx_collision & !tx_retransmit;
1040
  end
1041
 
1042
  always @(posedge rd_clk)
1043
  begin
1044
     if (rd_enable == 1'b1)
1045
        rd_retransmit <= tx_collision & tx_retransmit;
1046
  end
1047
 
1048
end // gen_hd_input                        // half duplex register input
1049
endgenerate
1050
 
1051
  //---------------------------------------------------------------------------
1052
  // Fifo full functionality
1053
  //---------------------------------------------------------------------------
1054
  // when full duplex full functionality is difference between read and write addresses.
1055
  // when in half duplex is difference between read start and write addresses.
1056
  // Cannot use gray code this time as the read address and read start addresses jump by more than 1
1057
 
1058
  // generate an enable pulse for the read side every 16 read clocks.  This provides for the worst case
1059
  // situation where wr clk is 20Mhz and rd clk is 125 Mhz.
1060
  always @(posedge rd_clk)
1061
  begin
1062
     if (rd_sreset == 1'b1)
1063
        rd_16_count <= 4'b0;
1064
     else if (rd_enable == 1'b1)
1065
        rd_16_count <= rd_16_count + 1;
1066
  end
1067
 
1068
  assign rd_txfer_en = (rd_16_count == 4'b1111) ? 1'b1 : 1'b0;
1069
 
1070
  // register the start address on the enable pulse
1071
  always @(posedge rd_clk)
1072
  begin
1073
     if (rd_sreset == 1'b1)
1074
        rd_addr_txfer <= 12'b0;
1075
     else if (rd_enable == 1'b1)
1076
        begin
1077
        if (rd_txfer_en == 1'b1)
1078
           rd_addr_txfer <= rd_start_addr;
1079
        end
1080
  end
1081
 
1082
  // generate a toggle to indicate that the address has been loaded.
1083
  always @(posedge rd_clk)
1084
  begin
1085
     if (rd_sreset == 1'b1)
1086
        rd_txfer_tog <= 1'b0;
1087
     else if (rd_enable == 1'b1)
1088
        begin
1089
        if (rd_txfer_en == 1'b1)
1090
           rd_txfer_tog <= !rd_txfer_tog;
1091
        end
1092
  end
1093
 
1094
  // pass the toggle to the write side
1095
  always @(posedge wr_clk)
1096
  begin
1097
     if (wr_sreset == 1'b1)
1098
        begin
1099
           wr_txfer_tog <= 1'b0;
1100
           wr_txfer_tog_sync <= 1'b0;
1101
           wr_txfer_tog_delay <= 1'b0;
1102
        end
1103
     else
1104
        begin
1105
           wr_txfer_tog <= rd_txfer_tog;
1106
           wr_txfer_tog_sync <= wr_txfer_tog;
1107
           wr_txfer_tog_delay <= wr_txfer_tog_sync;
1108
        end
1109
  end
1110
 
1111
  // generate an enable pulse from the toggle, the address should have 
1112
  // been steady on the wr clock input for at least one clock
1113
  assign wr_txfer_en = wr_txfer_tog_delay ^ wr_txfer_tog_sync;
1114
 
1115
  // capture the address on the write clock when the enable pulse is high.
1116
  always @(posedge wr_clk)
1117
  begin
1118
     if (wr_sreset == 1'b1)
1119
        wr_rd_addr <= 12'b0;
1120
     else if (wr_txfer_en == 1'b1)
1121
        wr_rd_addr <= rd_addr_txfer;
1122
  end
1123
 
1124
 
1125
  // Obtain the difference between write and read pointers
1126
  always @(posedge wr_clk)
1127
  begin
1128
     if (wr_sreset == 1'b1)
1129
        wr_addr_diff <= 12'b0;
1130
     else
1131
        wr_addr_diff <= wr_rd_addr - wr_addr;
1132
  end
1133
 
1134
 
1135
  // Detect when the FIFO is full
1136
  always @(posedge wr_clk)
1137
  begin
1138
     if (wr_sreset == 1'b1)
1139
        wr_fifo_full <= 1'b0;
1140
     else
1141
        // The FIFO is considered to be full if the write address
1142
        // pointer is within 1 to 3 of the read address pointer.
1143
        if (wr_addr_diff[11:4] == 8'b0 && wr_addr_diff[3:2] != 2'b0)
1144
           wr_fifo_full <= 1'b1;
1145
        else
1146
           wr_fifo_full <= 1'b0;
1147
  end
1148
 
1149
  // memory overflow occurs when the fifo is full and there are no frames
1150
  // available in the fifo for transmission.  If the collision window has
1151
  // expired and there are no frames in the fifo and the fifo is full, then the
1152
  // fifo is in an overflow state.  we must accept the rest of the incoming
1153
  // frame in overflow condition.
1154
 
1155
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_ovflow
1156
     // in full duplex mode, the fifo memory can only overflow if the fifo goes
1157
     // full but there is no frame available to be retranmsitted
1158
     // do not allow to go high when the frame count is being updated, ie wr_store_frame is asserted.
1159
     assign wr_fifo_overflow = (wr_fifo_full == 1'b1 && wr_frame_in_fifo == 1'b0
1160
                                   && wr_eof_state == 1'b0 && wr_eof_state_reg == 1'b0) ? 1'b1 : 1'b0;
1161
end // gen_fd_ovflow
1162
endgenerate
1163
 
1164
generate if (FULL_DUPLEX_ONLY != 1) begin : gen_hd_ovflow
1165
    // register wr col window to give address counter sufficient time to update.
1166
     // do not allow to go high when the frame count is being updated, ie wr_store_frame is asserted.
1167
    assign wr_fifo_overflow = (wr_fifo_full == 1'b1 && wr_frame_in_fifo == 1'b0
1168
                                  && wr_eof_state == 1'b0 && wr_eof_state_reg == 1'b0 && wr_col_window_expire == 1'b1) ? 1'b1 : 1'b0;
1169
 
1170
    // register rd_col_window signal
1171
    // this signal is long, and will remain high until overflow functionality
1172
    // has finished, so save just to register the once.
1173
    always @(posedge wr_clk)
1174
    begin  // process
1175
       if (wr_sreset == 1'b1)
1176
          begin
1177
             wr_col_window_pipe[0] <= 1'b0;
1178
             wr_col_window_pipe[1] <= 1'b0;
1179
             wr_col_window_expire  <= 1'b0;
1180
          end
1181
       else
1182
          begin
1183
             if (wr_txfer_en == 1'b1)
1184
                wr_col_window_pipe[0] <= rd_col_window_pipe[1];
1185
             wr_col_window_pipe[1] <= wr_col_window_pipe[0];
1186
             wr_col_window_expire <= wr_col_window_pipe[1];
1187
          end
1188
    end
1189
 
1190
end // gen_hd_ovflow
1191
endgenerate
1192
 
1193
 
1194
 
1195
  //--------------------------------------------------------------------
1196
  // Create FIFO Status Signals in the Write Domain
1197
  //--------------------------------------------------------------------
1198
 
1199
  // The FIFO status signal is four bits which represents the occupancy
1200
  // of the FIFO in 16'ths.  To generate this signal we therefore only
1201
  // need to compare the 4 most significant bits of the write address
1202
  // pointer with the 4 most significant bits of the read address 
1203
  // pointer.
1204
 
1205
  // The 4 most significant bits of the write pointer minus the 4 msb of
1206
  // the read pointer gives us our FIFO status.
1207
  always @(posedge wr_clk)
1208
  begin
1209
     if (wr_sreset == 1'b1)
1210
        wr_fifo_status <= 4'b0;
1211
     else
1212
        if (wr_addr_diff == 12'b0)
1213
           wr_fifo_status <= 4'b0;
1214
        else
1215
           begin
1216
              wr_fifo_status[3] <= !wr_addr_diff[11];
1217
              wr_fifo_status[2] <= !wr_addr_diff[10];
1218
              wr_fifo_status[1] <= !wr_addr_diff[9];
1219
              wr_fifo_status[0] <= !wr_addr_diff[8];
1220
           end
1221
  end
1222
 
1223
  //---------------------------------------------------------------------------
1224
  // Memory
1225
  //---------------------------------------------------------------------------
1226
  assign rd_en_bram = rd_en & rd_enable_delay2;
1227
 
1228
  // Block Ram for lower address space (rx_addr(11) = 1'b0)
1229
  defparam ramgen_l.WRITE_MODE_A = "READ_FIRST";
1230
  defparam ramgen_l.WRITE_MODE_B = "READ_FIRST";
1231
  RAMB16_S9_S9 ramgen_l (
1232
      .WEA  (wr_en_l),
1233
      .ENA  (VCC),
1234
      .SSRA (wr_sreset),
1235
      .CLKA (wr_clk),
1236
      .ADDRA(wr_addr[10:0]),
1237
      .DIA  (wr_data_bram),
1238
      .DIPA (wr_eof_bram),
1239
      .WEB  (GND),
1240
      .ENB  (rd_en_bram),
1241
      .SSRB (rd_sreset),
1242
      .CLKB (rd_clk),
1243
      .ADDRB(rd_addr[10:0]),
1244
      .DIB  (GND_BUS[7:0]),
1245
      .DIPB (GND_BUS[0:0]),
1246
      .DOA  (),
1247
      .DOPA (),
1248
      .DOB  (rd_data_bram_l),
1249
      .DOPB (rd_eof_bram_l));
1250
 
1251
    // Block Ram for lower address space (rx_addr(11) = 1'b0)
1252
  defparam ramgen_u.WRITE_MODE_A = "READ_FIRST";
1253
  defparam ramgen_u.WRITE_MODE_B = "READ_FIRST";
1254
  RAMB16_S9_S9 ramgen_u (
1255
      .WEA  (wr_en_u),
1256
      .ENA  (VCC),
1257
      .SSRA (wr_sreset),
1258
      .CLKA (wr_clk),
1259
      .ADDRA(wr_addr[10:0]),
1260
      .DIA  (wr_data_bram),
1261
      .DIPA (wr_eof_bram),
1262
      .WEB  (GND),
1263
      .ENB  (rd_en_bram),
1264
      .SSRB (rd_sreset),
1265
      .CLKB (rd_clk),
1266
      .ADDRB(rd_addr[10:0]),
1267
      .DIB  (GND_BUS[7:0]),
1268
      .DIPB (GND_BUS[0:0]),
1269
      .DOA  (),
1270
      .DOPA (),
1271
      .DOB  (rd_data_bram_u),
1272
      .DOPB (rd_eof_bram_u));
1273
 
1274
 
1275
 
1276
endmodule

powered by: WebSVN 2.1.0

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