OpenCores
URL https://opencores.org/ocsvn/udp_ip_stack/udp_ip_stack/trunk

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [contrib/] [Headers sometimes have errors/] [tx_client_fifo.vhd] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 pjf
--------------------------------------------------------------------------------
2
-- Title      : Transmitter FIFO with AxiStream interfaces
3
-- Version    : 1.3
4
-- Project    : Tri-Mode Ethernet MAC
5
--------------------------------------------------------------------------------
6
-- File       : tx_client_fifo.vhd
7
-- Author     : Xilinx Inc.
8
-- Project    : Virtex-6 Embedded Tri-Mode Ethernet MAC Wrapper
9
-- File       : tx_client_fifo.vhd
10
-- Version    : 2.1
11
-------------------------------------------------------------------------------
12
--
13
-- (c) Copyright 2004-2008 Xilinx, Inc. All rights reserved.
14
--
15
-- This file contains confidential and proprietary information
16
-- of Xilinx, Inc. and is protected under U.S. and
17
-- international copyright and other intellectual property
18
-- laws.
19
--
20
-- DISCLAIMER
21
-- This disclaimer is not a license and does not grant any
22
-- rights to the materials distributed herewith. Except as
23
-- otherwise provided in a valid license issued to you by
24
-- Xilinx, and to the maximum extent permitted by applicable
25
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
26
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
27
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
28
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
29
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
30
-- (2) Xilinx shall not be liable (whether in contract or tort,
31
-- including negligence, or under any other theory of
32
-- liability) for any loss or damage of any kind or nature
33
-- related to, arising under or in connection with these
34
-- materials, including for any direct, or any indirect,
35
-- special, incidental, or consequential loss or damage
36
-- (including loss of data, profits, goodwill, or any type of
37
-- loss or damage suffered as a result of any action brought
38
-- by a third party) even if such damage or loss was
39
-- reasonably foreseeable or Xilinx had been advised of the
40
-- possibility of the same.
41
--
42
-- CRITICAL APPLICATIONS
43
-- Xilinx products are not designed or intended to be fail-
44
-- safe, or for use in any application requiring fail-safe
45
-- performance, such as life-support or safety devices or
46
-- systems, Class III medical devices, nuclear facilities,
47
-- applications related to the deployment of airbags, or any
48
-- other applications that could lead to death, personal
49
-- injury, or severe property or environmental damage
50
-- (individually and collectively, "Critical
51
-- Applications"). Customer assumes the sole risk and
52
-- liability of any use of Xilinx products in Critical
53
-- Applications, subject only to applicable laws and
54
-- regulations governing limitations on product liability.
55
--
56
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
57
-- PART OF THIS FILE AT ALL TIMES.
58
--
59
-- Description: This is a transmitter side FIFO for the design example
60
--              of the Tri-Mode Ethernet MAC core. AxiStream interfaces are used.
61
--
62
--              The FIFO is created from 2 Block RAMs of size 2048
63
--              words of 8-bits per word, giving a total frame memory capacity
64
--              of 4096 bytes.
65
--
66
--              Valid frame data received from the user interface is written
67
--              into the Block RAM on the tx_fifo_aclkk. The FIFO will store
68
--              frames up to 4kbytes in length. If larger frames are written
69
--              to the FIFO, the AxiStream interface will accept the rest of the
70
--              frame, but that frame will be dropped by the FIFO and the
71
--              overflow signal will be asserted.
72
--
73
--              The FIFO is designed to work with a minimum frame length of 14
74
--              bytes.
75
--
76
--              When there is at least one complete frame in the FIFO, the MAC
77
--              transmitter AxiStream interface will be driven to request frame
78
--              transmission by placing the first byte of the frame onto
79
--              tx_axis_mac_tdata and by asserting tx_axis_mac_tvalid. The MAC will later
80
--              respond by asserting tx_axis_mac_tready. At this point the remaining
81
--              frame data is read out of the FIFO subject to tx_axis_mac_tready.
82
--              Data is read out of the FIFO on the tx_mac_aclk.
83
--
84
--              If the generic FULL_DUPLEX_ONLY is set to false, the FIFO will
85
--              requeue and retransmit frames as requested by the MAC. Once a
86
--              frame has been transmitted by the FIFO it is stored until the
87
--              possible retransmit window for that frame has expired.
88
--
89
--              The FIFO has been designed to operate with different clocks
90
--              on the write and read sides. The write clock (user-side
91
--              AxiStream clock) can be an equal or faster frequency than the
92
--              read clock (MAC-side AxiStream clock). The minimum write clock
93
--              frequency is the read clock frequency divided by 2.
94
--
95
--              The FIFO memory size can be increased by expanding the rd_addr
96
--              and wr_addr signal widths, to address further BRAMs.
97
--
98
--------------------------------------------------------------------------------
99
 
100
 
101
library unimacro;
102
use unimacro.vcomponents.all;
103
 
104
library ieee;
105
use ieee.std_logic_1164.all;
106
use ieee.std_logic_unsigned.all;
107
use ieee.numeric_std.all;
108
 
109
 
110
--------------------------------------------------------------------------------
111
-- Entity declaration for the Transmitter FIFO
112
--------------------------------------------------------------------------------
113
 
114
entity tx_client_fifo is
115
   generic (
116
      FULL_DUPLEX_ONLY : boolean := false);
117
   port (
118
        -- User-side (write-side) AxiStream interface
119
        tx_fifo_aclk    : in  std_logic;
120
        tx_fifo_resetn  : in  std_logic;
121
        tx_axis_fifo_tdata : in  std_logic_vector(7 downto 0);
122
        tx_axis_fifo_tvalid : in  std_logic;
123
        tx_axis_fifo_tlast : in  std_logic;
124
        tx_axis_fifo_tready : out std_logic;
125
 
126
        -- MAC-side (read-side) AxiStream interface
127
        tx_mac_aclk     : in  std_logic;
128
        tx_mac_resetn   : in  std_logic;
129
        tx_axis_mac_tdata : out std_logic_vector(7 downto 0);
130
        tx_axis_mac_tvalid : out std_logic;
131
        tx_axis_mac_tlast : out std_logic;
132
        tx_axis_mac_tready : in  std_logic;
133
        tx_axis_mac_tuser : out std_logic;
134
 
135
        -- FIFO status and overflow indication,
136
        -- synchronous to write-side (tx_user_aclk) interface
137
        fifo_overflow   : out std_logic;
138
        fifo_status     : out std_logic_vector(3 downto 0);
139
 
140
        -- FIFO collision and retransmission requests from MAC
141
        tx_collision    : in  std_logic;
142
        tx_retransmit   : in  std_logic
143
        );
144
end tx_client_fifo;
145
 
146
 
147
architecture RTL of tx_client_fifo is
148
 
149
 
150
  ------------------------------------------------------------------------------
151
  -- Component declaration for the synchronisation flip-flop pair
152
  ------------------------------------------------------------------------------
153
  component sync_block
154
  port (
155
    clk                 : in  std_logic;
156
    data_in             : in  std_logic;
157
    data_out            : out std_logic
158
    );
159
  end component;
160
 
161
 
162
  ------------------------------------------------------------------------------
163
  -- Define internal signals
164
  ------------------------------------------------------------------------------
165
 
166
  signal VCC                  : std_logic;
167
  signal GND                  : std_logic_vector(0 downto 0);
168
  signal GND_BUS              : std_logic_vector(8 downto 0);
169
 
170
  -- Encoded read state machine states.
171
  type rd_state_typ is       (IDLE_s,
172
                              QUEUE1_s,
173
                              QUEUE2_s,
174
                              QUEUE3_s,
175
                              QUEUE_ACK_s,
176
                              WAIT_ACK_s,
177
                              FRAME_s,
178
                              HANDSHAKE_s,
179
                              FINISH_s,
180
                              DROP_ERROR_s,
181
                              DROP_s,
182
                              RETRANSMIT_ERROR_s,
183
                              RETRANSMIT_s);
184
 
185
  signal rd_state             : rd_state_typ;
186
  signal rd_nxt_state         : rd_state_typ;
187
 
188
  -- Encoded write state machine states,
189
  type wr_state_typ is       (WAIT_s,
190
                              DATA_s,
191
                              EOF_s,
192
                              OVFLOW_s);
193
 
194
  signal wr_state             : wr_state_typ;
195
  signal wr_nxt_state         : wr_state_typ;
196
 
197
  type data_pipe is array (0 to 1) of std_logic_vector(7 downto 0);
198
  type cntl_pipe is array (0 to 1) of std_logic;
199
 
200
  signal wr_eof_data_bram     : std_logic_vector(8 downto 0);
201
  signal wr_data_bram         : std_logic_vector(7 downto 0);
202
  signal wr_data_pipe         : data_pipe;
203
  signal wr_sof_pipe          : cntl_pipe;
204
  signal wr_eof_pipe          : cntl_pipe;
205
  signal wr_accept_pipe       : cntl_pipe;
206
  signal wr_accept_bram       : std_logic;
207
  signal wr_sof_int           : std_logic;
208
  signal wr_eof_bram          : std_logic_vector(0 downto 0);
209
  signal wr_eof_reg           : std_logic;
210
  signal wr_addr              : unsigned(11 downto 0);
211
  signal wr_addr_inc          : std_logic;
212
  signal wr_start_addr_load   : std_logic;
213
  signal wr_addr_reload       : std_logic;
214
  signal wr_start_addr        : unsigned(11 downto 0);
215
  signal wr_fifo_full         : std_logic;
216
  signal wr_en                : std_logic;
217
  signal wr_en_u              : std_logic;
218
  signal wr_en_u_bram         : std_logic_vector(0 downto 0);
219
  signal wr_en_l              : std_logic;
220
  signal wr_en_l_bram         : std_logic_vector(0 downto 0);
221
  signal wr_ovflow_dst_rdy    : std_logic;
222
  signal tx_axis_fifo_tready_int_n : std_logic;
223
 
224
  signal frame_in_fifo        : std_logic;
225
  signal rd_eof               : std_logic;
226
  signal rd_eof_pipe          : std_logic;
227
  signal rd_eof_reg           : std_logic;
228
  signal rd_addr              : unsigned(11 downto 0);
229
  signal rd_addr_inc          : std_logic;
230
  signal rd_addr_reload       : std_logic;
231
  signal rd_bram_u_unused     : std_logic_vector(8 downto 0);
232
  signal rd_bram_l_unused     : std_logic_vector(8 downto 0);
233
  signal rd_eof_data_bram_u   : std_logic_vector(8 downto 0);
234
  signal rd_eof_data_bram_l   : std_logic_vector(8 downto 0);
235
  signal rd_data_bram_u       : std_logic_vector(7 downto 0);
236
  signal rd_data_bram_l       : std_logic_vector(7 downto 0);
237
  signal rd_data_pipe_u       : std_logic_vector(7 downto 0);
238
  signal rd_data_pipe_l       : std_logic_vector(7 downto 0);
239
  signal rd_data_pipe         : std_logic_vector(7 downto 0);
240
  signal rd_eof_bram_u        : std_logic_vector(0 downto 0);
241
  signal rd_eof_bram_l        : std_logic_vector(0 downto 0);
242
  signal rd_en                : std_logic;
243
  signal rd_bram_u            : std_logic;
244
  signal rd_bram_u_reg        : std_logic;
245
 
246
  signal rd_addr_slv          : std_logic_vector(10 downto 0);
247
  signal wr_addr_slv          : std_logic_vector(10 downto 0);
248
 
249
  signal rd_tran_frame_tog    : std_logic := '0';
250
  signal wr_tran_frame_sync   : std_logic;
251
  signal wr_tran_frame_delay  : std_logic := '0';
252
  signal rd_retran_frame_tog  : std_logic := '0';
253
  signal wr_retran_frame_sync : std_logic;
254
  signal wr_retran_frame_delay : std_logic := '0';
255
  signal wr_store_frame       : std_logic;
256
  signal wr_eof_state         : std_logic;
257
  signal wr_eof_state_reg     : std_logic;
258
  signal wr_transmit_frame    : std_logic;
259
  signal wr_retransmit_frame  : std_logic;
260
  signal wr_frames            : std_logic_vector(8 downto 0);
261
  signal wr_frame_in_fifo     : std_logic;
262
 
263
  signal rd_16_count          : unsigned(3 downto 0);
264
  signal rd_txfer_en          : std_logic;
265
  signal rd_addr_txfer        : unsigned(11 downto 0);
266
  signal rd_txfer_tog         : std_logic := '0';
267
  signal wr_txfer_tog_sync    : std_logic;
268
  signal wr_txfer_tog_delay   : std_logic := '0';
269
  signal wr_txfer_en          : std_logic;
270
  signal wr_rd_addr           : unsigned(11 downto 0);
271
  signal wr_addr_diff         : unsigned(11 downto 0);
272
 
273
  signal wr_fifo_status       : unsigned(3 downto 0);
274
 
275
  signal rd_drop_frame        : std_logic;
276
  signal rd_retransmit        : std_logic;
277
 
278
  signal rd_start_addr        : unsigned(11 downto 0);
279
  signal rd_start_addr_load   : std_logic;
280
  signal rd_start_addr_reload : std_logic;
281
 
282
  signal rd_dec_addr          : unsigned(11 downto 0);
283
 
284
  signal rd_transmit_frame    : std_logic;
285
  signal rd_retransmit_frame  : std_logic;
286
  signal rd_col_window_expire : std_logic;
287
  signal rd_col_window_pipe   : cntl_pipe;
288
  signal wr_col_window_pipe   : cntl_pipe;
289
  signal wr_fifo_overflow     : std_logic;
290
  signal rd_slot_timer        : unsigned(9 downto 0);
291
  signal wr_col_window_expire : std_logic;
292
  signal rd_idle_state        : std_logic;
293
 
294
  signal tx_axis_mac_tdata_int_frame       : std_logic_vector(7 downto 0);
295
  signal tx_axis_mac_tdata_int_handshake   : std_logic_vector(7 downto 0);
296
  signal tx_axis_mac_tdata_int             : std_logic_vector(7 downto 0);
297
  signal tx_axis_mac_tvalid_int_finish     : std_logic;
298
  signal tx_axis_mac_tvalid_int_droperror  : std_logic;
299
  signal tx_axis_mac_tvalid_int_retransmiterror : std_logic;
300
  signal tx_axis_mac_tlast_int_frame_handshake : std_logic;
301
  signal tx_axis_mac_tlast_int_finish      : std_logic;
302
  signal tx_axis_mac_tlast_int_droperror   : std_logic;
303
  signal tx_axis_mac_tlast_int_retransmiterror : std_logic;
304
  signal tx_axis_mac_tuser_int_droperror   : std_logic;
305
  signal tx_axis_mac_tuser_int_retransmit  : std_logic;
306
 
307
  signal tx_fifo_reset                     : std_logic;
308
  signal tx_mac_reset                      : std_logic;
309
 
310
  -- Small delay for simulation purposes.
311
  constant dly : time := 1 ps;
312
 
313
 
314
  ------------------------------------------------------------------------------
315
  -- Attributes for FIFO simulation and synthesis
316
  ------------------------------------------------------------------------------
317
  -- ASYNC_REG attributes added to simulate actual behaviour under
318
  -- asynchronous operating conditions.
319
  attribute ASYNC_REG                          : string;
320
  attribute ASYNC_REG of wr_rd_addr            : signal is "TRUE";
321
  attribute ASYNC_REG of wr_col_window_pipe    : signal is "TRUE";
322
 
323
 
324
  ------------------------------------------------------------------------------
325
  -- Begin FIFO architecture
326
  ------------------------------------------------------------------------------
327
 
328
begin
329
 
330
  VCC     <= '1';
331
  GND     <= (others => '0');
332
  GND_BUS <= (others => '0');
333
 
334
  -- invert reset sense as architecture is optimised for active high resets
335
  tx_fifo_reset <= not tx_fifo_resetn;
336
  tx_mac_reset  <= not tx_mac_resetn;
337
 
338
 
339
  ------------------------------------------------------------------------------
340
  -- Write state machine and control
341
  ------------------------------------------------------------------------------
342
 
343
  -- Write state machine.
344
  -- States are WAIT, DATA, EOF, OVFLOW.
345
  -- Clock state to next state.
346
  clock_wrs_p : process(tx_fifo_aclk)
347
  begin
348
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
349
        if tx_fifo_reset = '1' then
350
           wr_state <= WAIT_s after dly;
351
        else
352
           wr_state <= wr_nxt_state after dly;
353
        end if;
354
     end if;
355
  end process clock_wrs_p;
356
 
357
  -- Decode next state, combinitorial.
358
  next_wrs_p : process(wr_state, wr_sof_pipe(1), wr_eof_pipe(0), wr_eof_pipe(1),
359
                       wr_eof_bram(0), wr_fifo_overflow)
360
  begin
361
  case wr_state is
362
     when WAIT_s =>
363
        if wr_sof_pipe(1) = '1'  and wr_eof_pipe(1) = '0' then
364
           wr_nxt_state <= DATA_s;
365
        else
366
           wr_nxt_state <= WAIT_s;
367
        end if;
368
 
369
     when DATA_s =>
370
        -- Wait for the end of frame to be detected.
371
        if wr_fifo_overflow = '1' and wr_eof_pipe(0) = '0'
372
           and wr_eof_pipe(1) = '0' then
373
           wr_nxt_state <= OVFLOW_s;
374
        elsif wr_eof_pipe(1) = '1' then
375
           wr_nxt_state <= EOF_s;
376
        else
377
           wr_nxt_state <= DATA_s;
378
        end if;
379
 
380
     when EOF_s =>
381
        -- If the start of frame is already in the pipe, a back-to-back frame
382
        -- transmission has occured. Move straight back to frame state.
383
        if wr_sof_pipe(1) = '1' and wr_eof_pipe(1) = '0' then
384
           wr_nxt_state <= DATA_s;
385
        elsif wr_eof_bram(0) = '1' then
386
           wr_nxt_state <= WAIT_s;
387
        else
388
           wr_nxt_state <= EOF_s;
389
        end if;
390
 
391
     when OVFLOW_s =>
392
        -- Wait until the end of frame is reached before clearing the overflow.
393
        if wr_eof_bram(0) = '1' then
394
           wr_nxt_state <= WAIT_s;
395
        else
396
           wr_nxt_state <= OVFLOW_s;
397
        end if;
398
 
399
     when others =>
400
        wr_nxt_state <= WAIT_s;
401
  end case;
402
  end process;
403
 
404
  -- Decode output signals, combinatorial.
405
  -- wr_en is used to enable the BRAM write and the address to increment.
406
  wr_en <= '0' when wr_state = OVFLOW_s else wr_accept_bram;
407
 
408
  -- The upper and lower signals are used to distinguish between the upper and
409
  -- lower BRAMs.
410
  wr_en_l <= wr_en and not(wr_addr(11));
411
  wr_en_u <= wr_en and     wr_addr(11);
412
  wr_en_l_bram(0) <= wr_en_l;
413
  wr_en_u_bram(0) <= wr_en_u;
414
 
415
  wr_addr_inc <= wr_en;
416
 
417
  wr_addr_reload <= '1' when wr_state = OVFLOW_s else '0';
418
  wr_start_addr_load <= '1' when wr_state = EOF_s and wr_nxt_state = WAIT_s
419
                        else
420
                        '1' when wr_state = EOF_s and wr_nxt_state = DATA_s
421
                        else  '0';
422
 
423
  -- Pause the AxiStream handshake when the FIFO is full.
424
  tx_axis_fifo_tready_int_n <= wr_ovflow_dst_rdy when wr_state = OVFLOW_s
425
                       else wr_fifo_full;
426
 
427
  tx_axis_fifo_tready <= not tx_axis_fifo_tready_int_n;
428
 
429
  -- Generate user overflow indicator.
430
  fifo_overflow <= '1' when wr_state = OVFLOW_s else '0';
431
 
432
  -- When in overflow and have captured ovflow EOF, set tx_axis_fifo_tready again.
433
  p_ovflow_dst_rdy : process (tx_fifo_aclk)
434
  begin
435
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
436
        if tx_fifo_reset = '1' then
437
           wr_ovflow_dst_rdy <= '0' after dly;
438
        else
439
           if wr_fifo_overflow = '1' and wr_state = DATA_s then
440
              wr_ovflow_dst_rdy <= '0' after dly;
441
           elsif tx_axis_fifo_tvalid = '1' and tx_axis_fifo_tlast = '1' then
442
              wr_ovflow_dst_rdy <= '1' after dly;
443
           end if;
444
        end if;
445
     end if;
446
  end process;
447
 
448
  -- EOF signals for use in overflow logic.
449
  wr_eof_state <= '1' when wr_state = EOF_s else '0';
450
 
451
  p_reg_eof_st : process (tx_fifo_aclk)
452
  begin
453
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
454
        if tx_fifo_reset = '1' then
455
           wr_eof_state_reg <= '0' after dly;
456
        else
457
           wr_eof_state_reg <= wr_eof_state after dly;
458
        end if;
459
     end if;
460
  end process;
461
 
462
 
463
  ------------------------------------------------------------------------------
464
  -- Read state machine and control
465
  ------------------------------------------------------------------------------
466
 
467
  -- Read state machine.
468
  -- States are IDLE, QUEUE1, QUEUE2, QUEUE3, QUEUE_ACK, WAIT_ACK, FRAME,
469
  -- HANDSHAKE, FINISH, DROP_ERROR, DROP, RETRANSMIT_ERROR, RETRANSMIT.
470
  -- Clock state to next state.
471
  clock_rds_p : process(tx_mac_aclk)
472
  begin
473
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
474
        if tx_mac_reset = '1' then
475
           rd_state <= IDLE_s after dly;
476
        else
477
           rd_state <= rd_nxt_state after dly;
478
        end if;
479
     end if;
480
  end process clock_rds_p;
481
 
482
  ------------------------------------------------------------------------------
483
  -- Full duplex-only state machine.
484
gen_fd_sm : if (FULL_DUPLEX_ONLY = TRUE) generate
485
  -- Decode next state, combinatorial.
486
  next_rds_p : process(rd_state, frame_in_fifo, rd_eof, rd_eof_reg, tx_axis_mac_tready)
487
  begin
488
  case rd_state is
489
           when IDLE_s =>
490
              -- If there is a frame in the FIFO, start to queue the new frame
491
              -- to the output.
492
              if frame_in_fifo = '1' then
493
                 rd_nxt_state <= QUEUE1_s;
494
              else
495
                 rd_nxt_state <= IDLE_s;
496
              end if;
497
 
498
           -- Load the output pipeline, which takes three clock cycles.
499
           when QUEUE1_s =>
500
              rd_nxt_state <= QUEUE2_s;
501
 
502
           when QUEUE2_s =>
503
              rd_nxt_state <= QUEUE3_s;
504
 
505
           when QUEUE3_s =>
506
              rd_nxt_state <= QUEUE_ACK_s;
507
 
508
           when QUEUE_ACK_s =>
509
              -- The pipeline is full and the frame output starts now.
510
              rd_nxt_state <= WAIT_ACK_s;
511
 
512
           when WAIT_ACK_s =>
513
              -- Await the tx_axis_mac_tready acknowledge before moving on.
514
              if tx_axis_mac_tready = '1' then
515
                 rd_nxt_state <= FRAME_s;
516
              else
517
                 rd_nxt_state <= WAIT_ACK_s;
518
              end if;
519
 
520
           when FRAME_s =>
521
              -- Read the frame out of the FIFO. If the MAC deasserts
522
              -- tx_axis_mac_tready, stall in the handshake state. If the EOF
523
              -- flag is encountered, move to the finish state.
524
              if tx_axis_mac_tready = '0' then
525
                 rd_nxt_state <= HANDSHAKE_s;
526
              elsif rd_eof = '1' then
527
                 rd_nxt_state <= FINISH_s;
528
              else
529
                 rd_nxt_state <= FRAME_s;
530
              end if;
531
 
532
           when HANDSHAKE_s =>
533
              -- Await tx_axis_mac_tready before continuing frame transmission.
534
              -- If the EOF flag is encountered, move to the finish state.
535
              if tx_axis_mac_tready = '1' and rd_eof_reg = '1' then
536
                 rd_nxt_state <= FINISH_s;
537
              elsif tx_axis_mac_tready = '1' and rd_eof_reg = '0' then
538
                 rd_nxt_state <= FRAME_s;
539
              else
540
                 rd_nxt_state <= HANDSHAKE_s;
541
              end if;
542
 
543
           when FINISH_s =>
544
              -- Frame has finished. Assure that the MAC has accepted the final
545
              -- byte by transitioning to idle only when tx_axis_mac_tready is high.
546
              if tx_axis_mac_tready = '1' then
547
                 rd_nxt_state <= IDLE_s;
548
              else
549
                 rd_nxt_state <= FINISH_s;
550
              end if;
551
 
552
           when others =>
553
                 rd_nxt_state <= IDLE_s;
554
        end case;
555
  end process next_rds_p;
556
end generate gen_fd_sm;
557
 
558
  ------------------------------------------------------------------------------
559
  -- Full and half duplex state machine.
560
gen_hd_sm : if (FULL_DUPLEX_ONLY = FALSE) generate
561
  -- Decode the next state, combinatorial.
562
  next_rds_p : process(rd_state, frame_in_fifo, rd_eof_reg, tx_axis_mac_tready,
563
                       rd_drop_frame, rd_retransmit)
564
  begin
565
  case rd_state is
566
           when IDLE_s =>
567
              -- If a retransmit request is detected then prepare to retransmit.
568
              if rd_retransmit = '1' then
569
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
570
              -- If there is a frame in the FIFO, then queue the new frame to
571
              -- the output.
572
              elsif frame_in_fifo = '1' then
573
                 rd_nxt_state <= QUEUE1_s;
574
              else
575
                 rd_nxt_state <= IDLE_s;
576
              end if;
577
 
578
           -- Load the output pipeline, which takes three clock cycles.
579
           when QUEUE1_s =>
580
              if rd_retransmit = '1' then
581
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
582
              else
583
                rd_nxt_state <= QUEUE2_s;
584
              end if;
585
 
586
           when QUEUE2_s =>
587
              if rd_retransmit = '1' then
588
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
589
              else
590
                 rd_nxt_state <= QUEUE3_s;
591
              end if;
592
 
593
           when QUEUE3_s =>
594
              if rd_retransmit = '1' then
595
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
596
              else
597
                 rd_nxt_state <= QUEUE_ACK_s;
598
              end if;
599
 
600
           when QUEUE_ACK_s =>
601
              -- The pipeline is full and the frame output starts now.
602
              if rd_retransmit = '1' then
603
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
604
              else
605
                 rd_nxt_state <= WAIT_ACK_s;
606
              end if;
607
 
608
           when WAIT_ACK_s =>
609
              -- Await the tx_axis_mac_tready acknowledge before moving on.
610
              if rd_retransmit = '1' then
611
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
612
              elsif tx_axis_mac_tready = '1' then
613
                 rd_nxt_state <= FRAME_s;
614
              else
615
                 rd_nxt_state <= WAIT_ACK_s;
616
              end if;
617
 
618
           when FRAME_s =>
619
              -- If a collision-only request, then must drop the rest of the
620
              -- current frame. If a collision and retransmit, then prepare
621
              -- to retransmit the frame.
622
              if rd_drop_frame = '1' then
623
                 rd_nxt_state <= DROP_ERROR_s;
624
              elsif rd_retransmit = '1' then
625
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
626
              -- Read the frame out of the FIFO. If the MAC deasserts
627
              -- tx_axis_mac_tready, stall in the handshake state. If the EOF
628
              -- flag is encountered, move to the finish state.
629
              elsif tx_axis_mac_tready = '0' then
630
                 rd_nxt_state <= HANDSHAKE_s;
631
              elsif rd_eof_reg = '1' then
632
                 rd_nxt_state <= FINISH_s;
633
              else
634
                 rd_nxt_state <= FRAME_s;
635
              end if;
636
 
637
           when HANDSHAKE_s =>
638
              -- Await tx_axis_mac_tready before continuing frame transmission.
639
              -- If the EOF flag is encountered, move to the finish state.
640
              if rd_retransmit = '1' then
641
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
642
              elsif tx_axis_mac_tready = '1' and rd_eof_reg = '1' then
643
                 rd_nxt_state <= FINISH_s;
644
              elsif tx_axis_mac_tready = '1' and rd_eof_reg = '0' then
645
                 rd_nxt_state <= FRAME_s;
646
              else
647
                 rd_nxt_state <= HANDSHAKE_s;
648
              end if;
649
 
650
           when FINISH_s =>
651
              -- Frame has finished. Assure that the MAC has accepted the final
652
              -- byte by transitioning to idle only when tx_axis_mac_tready is high.
653
              if rd_retransmit = '1' then
654
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
655
              elsif tx_axis_mac_tready = '1' then
656
                 rd_nxt_state <= IDLE_s;
657
              else
658
                 rd_nxt_state <= FINISH_s;
659
              end if;
660
 
661
           when DROP_ERROR_s =>
662
              -- FIFO is ready to drop the frame. Assure that the MAC has
663
              -- accepted the final byte and error signal before dropping.
664
              if tx_axis_mac_tready = '1' then
665
                 rd_nxt_state <= DROP_s;
666
              else
667
                 rd_nxt_state <= DROP_ERROR_s;
668
              end if;
669
 
670
           when DROP_s =>
671
              -- Wait until rest of frame has been cleared.
672
              if rd_eof_reg = '1' then
673
                 rd_nxt_state <= IDLE_s;
674
              else
675
                 rd_nxt_state <= DROP_s;
676
              end if;
677
 
678
           when RETRANSMIT_ERROR_s =>
679
              -- FIFO is ready to retransmit the frame. Assure that the MAC has
680
              -- accepted the final byte and error signal before retransmitting.
681
              if tx_axis_mac_tready = '1' then
682
                 rd_nxt_state <= RETRANSMIT_s;
683
              else
684
                 rd_nxt_state <= RETRANSMIT_ERROR_s;
685
              end if;
686
 
687
           when RETRANSMIT_s =>
688
              -- Reload the data pipeline from the start of the frame.
689
              rd_nxt_state <= QUEUE1_s;
690
 
691
           when others =>
692
              rd_nxt_state <= IDLE_s;
693
        end case;
694
  end process next_rds_p;
695
end generate gen_hd_sm;
696
 
697
 
698
  -- Combinatorially select tdata candidates.
699
  tx_axis_mac_tdata_int_frame <= tx_axis_mac_tdata_int when rd_nxt_state = HANDSHAKE_s
700
                                else rd_data_pipe;
701
  tx_axis_mac_tdata_int_handshake <= rd_data_pipe     when rd_nxt_state = FINISH_s
702
                                else tx_axis_mac_tdata_int;
703
  tx_axis_mac_tdata          <= tx_axis_mac_tdata_int;
704
 
705
  -- Decode output tdata based on current and next read state.
706
  rd_data_decode_p : process(tx_mac_aclk)
707
  begin
708
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
709
        if rd_nxt_state = FRAME_s then
710
           tx_axis_mac_tdata_int <= rd_data_pipe after dly;
711
        elsif (rd_nxt_state = RETRANSMIT_ERROR_s or rd_nxt_state = DROP_ERROR_s)
712
           then tx_axis_mac_tdata_int <= tx_axis_mac_tdata_int after dly;
713
        else
714
           case rd_state is
715
              when QUEUE_ACK_s =>
716
                 tx_axis_mac_tdata_int <= rd_data_pipe after dly;
717
              when FRAME_s =>
718
                 tx_axis_mac_tdata_int <= tx_axis_mac_tdata_int_frame after dly;
719
              when HANDSHAKE_s =>
720
                 tx_axis_mac_tdata_int <= tx_axis_mac_tdata_int_handshake after dly;
721
              when others =>
722
                 tx_axis_mac_tdata_int <= tx_axis_mac_tdata_int after dly;
723
           end case;
724
        end if;
725
     end if;
726
  end process rd_data_decode_p;
727
 
728
  -- Combinatorially select tvalid candidates.
729
  tx_axis_mac_tvalid_int_finish     <= '0' when rd_nxt_state = IDLE_s
730
                                       else '1';
731
  tx_axis_mac_tvalid_int_droperror  <= '0' when rd_nxt_state = DROP_s
732
                                       else '1';
733
  tx_axis_mac_tvalid_int_retransmiterror <= '0' when rd_nxt_state = RETRANSMIT_s
734
                                       else '1';
735
 
736
  -- Decode output tvalid based on current and next read state.
737
  rd_dv_decode_p : process(tx_mac_aclk)
738
  begin
739
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
740
        if rd_nxt_state = FRAME_s then
741
           tx_axis_mac_tvalid <= '1' after dly;
742
        elsif (rd_nxt_state = RETRANSMIT_ERROR_s or rd_nxt_state = DROP_ERROR_s)
743
           then tx_axis_mac_tvalid <= '1' after dly;
744
        else
745
           case rd_state is
746
              when QUEUE_ACK_s =>
747
                 tx_axis_mac_tvalid <= '1' after dly;
748
              when WAIT_ACK_s =>
749
                 tx_axis_mac_tvalid <= '1' after dly;
750
              when FRAME_s =>
751
                 tx_axis_mac_tvalid <= '1' after dly;
752
              when HANDSHAKE_s =>
753
                 tx_axis_mac_tvalid <= '1' after dly;
754
              when FINISH_s =>
755
                 tx_axis_mac_tvalid <= tx_axis_mac_tvalid_int_finish after dly;
756
              when DROP_ERROR_s =>
757
                 tx_axis_mac_tvalid <= tx_axis_mac_tvalid_int_droperror after dly;
758
              when RETRANSMIT_ERROR_s =>
759
                 tx_axis_mac_tvalid <= tx_axis_mac_tvalid_int_retransmiterror after dly;
760
              when others =>
761
                 tx_axis_mac_tvalid <= '0' after dly;
762
           end case;
763
        end if;
764
     end if;
765
  end process rd_dv_decode_p;
766
 
767
  -- Combinatorially select tlast candidates.
768
  tx_axis_mac_tlast_int_frame_handshake <= rd_eof_reg when rd_nxt_state = FINISH_s
769
                                      else '0';
770
  tx_axis_mac_tlast_int_finish     <= '0' when rd_nxt_state = IDLE_s
771
                                      else rd_eof_reg;
772
  tx_axis_mac_tlast_int_droperror  <= '0' when rd_nxt_state = DROP_s
773
                                      else '1';
774
  tx_axis_mac_tlast_int_retransmiterror <= '0' when rd_nxt_state = RETRANSMIT_s
775
                                      else '1';
776
 
777
  -- Decode output tlast based on current and next read state.
778
  rd_last_decode_p : process(tx_mac_aclk)
779
  begin
780
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
781
        if rd_nxt_state = FRAME_s then
782
           tx_axis_mac_tlast <= rd_eof after dly;
783
        elsif (rd_nxt_state = RETRANSMIT_ERROR_s or rd_nxt_state = DROP_ERROR_s)
784
           then tx_axis_mac_tlast <= '1' after dly;
785
        else
786
           case rd_state is
787
              when WAIT_ACK_s =>
788
                 tx_axis_mac_tlast <= rd_eof after dly;
789
              when FRAME_s =>
790
                 tx_axis_mac_tlast <= tx_axis_mac_tlast_int_frame_handshake after dly;
791
              when HANDSHAKE_s =>
792
                 tx_axis_mac_tlast <= tx_axis_mac_tlast_int_frame_handshake after dly;
793
              when FINISH_s =>
794
                 tx_axis_mac_tlast <= tx_axis_mac_tlast_int_finish after dly;
795
              when DROP_ERROR_s =>
796
                 tx_axis_mac_tlast <= tx_axis_mac_tlast_int_droperror after dly;
797
              when RETRANSMIT_ERROR_s =>
798
                 tx_axis_mac_tlast <= tx_axis_mac_tlast_int_retransmiterror after dly;
799
              when others =>
800
                 tx_axis_mac_tlast <= '0' after dly;
801
           end case;
802
        end if;
803
     end if;
804
  end process rd_last_decode_p;
805
 
806
  -- Combinatorially select tuser candidates.
807
  tx_axis_mac_tuser_int_droperror <= '0' when rd_nxt_state = DROP_s
808
                                 else '1';
809
  tx_axis_mac_tuser_int_retransmit <= '0' when rd_nxt_state = RETRANSMIT_s
810
                                 else '1';
811
 
812
  -- Decode output tuser based on current and next read state.
813
  rd_user_decode_p : process(tx_mac_aclk)
814
  begin
815
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
816
        if (rd_nxt_state = RETRANSMIT_ERROR_s or rd_nxt_state = DROP_ERROR_s)
817
           then tx_axis_mac_tuser <= '1' after dly;
818
        else
819
           case rd_state is
820
              when DROP_ERROR_s =>
821
                 tx_axis_mac_tuser <= tx_axis_mac_tuser_int_droperror after dly;
822
              when RETRANSMIT_ERROR_s =>
823
                 tx_axis_mac_tuser <= tx_axis_mac_tuser_int_retransmit after dly;
824
              when others =>
825
                 tx_axis_mac_tuser <= '0' after dly;
826
           end case;
827
        end if;
828
     end if;
829
  end process rd_user_decode_p;
830
 
831
  ------------------------------------------------------------------------------
832
  -- Decode full duplex-only control signals.
833
gen_fd_decode : if (FULL_DUPLEX_ONLY = TRUE) generate
834
 
835
  -- rd_en is used to enable the BRAM read and load the output pipeline.
836
  rd_en <= '0' when rd_state = IDLE_s else
837
           '1' when rd_nxt_state = FRAME_s else
838
           '0' when (rd_state = FRAME_s and rd_nxt_state = HANDSHAKE_s) else
839
           '0' when rd_nxt_state = HANDSHAKE_s else
840
           '0' when rd_state = FINISH_s else
841
           '0' when rd_state = WAIT_ACK_s else '1';
842
 
843
  -- When the BRAM is being read, enable the read address to be incremented.
844
  rd_addr_inc <=  rd_en;
845
 
846
  rd_addr_reload <= '1' when rd_state /= FINISH_s and rd_nxt_state = FINISH_s
847
                    else '0';
848
 
849
  -- Transmit frame pulse must never be more frequent than once per 64 clocks to
850
  -- allow toggle to cross clock domain.
851
  rd_transmit_frame <= '1' when rd_state = WAIT_ACK_s and rd_nxt_state = FRAME_s
852
                       else '0';
853
 
854
  -- Unused for full duplex only.
855
  rd_start_addr_reload <= '0';
856
  rd_start_addr_load   <= '0';
857
  rd_retransmit_frame  <= '0';
858
 
859
end generate gen_fd_decode;
860
 
861
  ------------------------------------------------------------------------------
862
  -- Decode full and half duplex control signals.
863
gen_hd_decode : if (FULL_DUPLEX_ONLY = FALSE) generate
864
 
865
  -- rd_en is used to enable the BRAM read and load the output pipeline.
866
  rd_en <= '0' when rd_state = IDLE_s else
867
           '0' when rd_nxt_state = DROP_ERROR_s else
868
           '0' when (rd_nxt_state = DROP_s and rd_eof = '1') else
869
           '1' when rd_nxt_state = FRAME_s else
870
           '0' when (rd_state = FRAME_s and rd_nxt_state = HANDSHAKE_s) else
871
           '0' when rd_nxt_state = HANDSHAKE_s else
872
           '0' when rd_state = FINISH_s else
873
           '0' when rd_state = RETRANSMIT_ERROR_s else
874
           '0' when rd_state = RETRANSMIT_s else
875
           '0' when rd_state = WAIT_ACK_s else '1';
876
 
877
  -- When the BRAM is being read, enable the read address to be incremented.
878
  rd_addr_inc <=  rd_en;
879
 
880
  rd_addr_reload <= '1' when rd_state /= FINISH_s and rd_nxt_state = FINISH_s
881
                    else
882
                    '1' when rd_state = DROP_s and rd_nxt_state = IDLE_s
883
                    else '0';
884
 
885
  -- Assertion indicates that the starting address must be reloaded to enable
886
  -- the current frame to be retransmitted.
887
  rd_start_addr_reload <= '1' when rd_state = RETRANSMIT_s else '0';
888
 
889
  rd_start_addr_load <= '1' when rd_state= WAIT_ACK_s and rd_nxt_state = FRAME_s
890
                        else
891
                        '1' when rd_col_window_expire = '1' else '0';
892
 
893
  -- Transmit frame pulse must never be more frequent than once per 64 clocks to
894
  -- allow toggle to cross clock domain.
895
  rd_transmit_frame <= '1' when rd_state = WAIT_ACK_s and rd_nxt_state = FRAME_s
896
                       else '0';
897
 
898
  -- Retransmit frame pulse must never be more frequent than once per 16 clocks
899
  -- to allow toggle to cross clock domain.
900
  rd_retransmit_frame <= '1' when rd_state = RETRANSMIT_s else '0';
901
 
902
end generate gen_hd_decode; -- half duplex control signals
903
 
904
 
905
  ------------------------------------------------------------------------------
906
  -- Frame count
907
  -- We need to maintain a count of frames in the FIFO, so that we know when a
908
  -- frame is available for transmission. The counter must be held on the write
909
  -- clock domain as this is the faster clock if they differ.
910
  ------------------------------------------------------------------------------
911
 
912
  -- A frame has been written to the FIFO.
913
  wr_store_frame <= '1' when wr_state = EOF_s and wr_nxt_state /= EOF_s
914
                    else '0';
915
 
916
  -- Generate a toggle to indicate when a frame has been transmitted by the FIFO.
917
  p_rd_trans_tog : process (tx_mac_aclk)
918
  begin
919
     if tx_mac_aclk'event and tx_mac_aclk = '1' then
920
        if rd_transmit_frame = '1' then
921
           rd_tran_frame_tog <= not rd_tran_frame_tog after dly;
922
        end if;
923
     end if;
924
  end process;
925
 
926
  -- Synchronize the read transmit frame signal into the write clock domain.
927
  resync_rd_tran_frame_tog : sync_block
928
  port map (
929
    clk       => tx_fifo_aclk,
930
    data_in   => rd_tran_frame_tog,
931
    data_out  => wr_tran_frame_sync
932
  );
933
 
934
  -- Edge-detect of the resynchronized transmit frame signal.
935
 
936
  p_delay_wr_trans : process (tx_fifo_aclk)
937
  begin
938
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
939
      wr_tran_frame_delay <= wr_tran_frame_sync after dly;
940
    end if;
941
  end process p_delay_wr_trans;
942
 
943
  p_sync_wr_trans : process (tx_fifo_aclk)
944
  begin
945
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
946
      if tx_fifo_reset = '1' then
947
        wr_transmit_frame   <= '0' after dly;
948
      else
949
        -- Edge detector
950
        if (wr_tran_frame_delay xor wr_tran_frame_sync) = '1' then
951
          wr_transmit_frame <= '1' after dly;
952
        else
953
          wr_transmit_frame <= '0' after dly;
954
        end if;
955
      end if;
956
    end if;
957
  end process p_sync_wr_trans;
958
 
959
  ------------------------------------------------------------------------------
960
  -- Full duplex-only frame count.
961
gen_fd_count : if (FULL_DUPLEX_ONLY = TRUE) generate
962
 
963
  -- Count the number of frames in the FIFO. The counter is incremented when a
964
  -- frame is stored and decremented when a frame is transmitted. Need to keep
965
  -- the counter on the write clock as this is the fastest clock if they differ.
966
  p_wr_frames : process (tx_fifo_aclk)
967
  begin
968
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
969
      if tx_fifo_reset = '1' then
970
        wr_frames <= (others => '0') after dly;
971
      else
972
         if (wr_store_frame and not wr_transmit_frame) = '1' then
973
            wr_frames <= wr_frames + 1 after dly;
974
         elsif (not wr_store_frame and wr_transmit_frame) = '1' then
975
            wr_frames <= wr_frames - 1 after dly;
976
         end if;
977
      end if;
978
    end if;
979
  end process p_wr_frames;
980
end generate gen_fd_count;
981
 
982
  ------------------------------------------------------------------------------
983
  -- Full and half duplex frame count.
984
gen_hd_count : if (FULL_DUPLEX_ONLY = FALSE) generate
985
 
986
  -- Generate a toggle to indicate when a frame has been retransmitted from
987
  -- the FIFO.
988
  p_rd_retran_tog : process (tx_mac_aclk)
989
  begin
990
     if tx_mac_aclk'event and tx_mac_aclk = '1' then
991
        if rd_retransmit_frame = '1' then
992
           rd_retran_frame_tog <= not rd_retran_frame_tog after dly;
993
        end if;
994
     end if;
995
  end process;
996
 
997
  -- Synchronize the read retransmit frame signal into the write clock domain.
998
  resync_rd_tran_frame_tog : sync_block
999
  port map (
1000
    clk       => tx_fifo_aclk,
1001
    data_in   => rd_retran_frame_tog,
1002
    data_out  => wr_retran_frame_sync
1003
  );
1004
 
1005
  -- Edge detect of the resynchronized read transmit frame signal.
1006
 
1007
  p_delay_wr_trans : process (tx_fifo_aclk)
1008
  begin
1009
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1010
      wr_retran_frame_delay <= wr_retran_frame_sync after dly;
1011
    end if;
1012
  end process p_delay_wr_trans;
1013
 
1014
  p_sync_wr_trans : process (tx_fifo_aclk)
1015
  begin
1016
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1017
      if tx_fifo_reset = '1' then
1018
        wr_retransmit_frame   <= '0' after dly;
1019
      else
1020
        -- Edge detector
1021
        if (wr_retran_frame_delay xor wr_retran_frame_sync) = '1' then
1022
          wr_retransmit_frame <= '1' after dly;
1023
        else
1024
          wr_retransmit_frame <= '0' after dly;
1025
        end if;
1026
      end if;
1027
    end if;
1028
  end process p_sync_wr_trans;
1029
 
1030
  -- Count the number of frames in the FIFO. The counter is incremented when a
1031
  -- frame is stored or retransmitted and decremented when a frame is
1032
  -- transmitted. Need to keep the counter on the write clock as this is the
1033
  -- fastest clock if they differ. Logic assumes transmit and retransmit cannot
1034
  -- happen at same time.
1035
  p_wr_frames : process (tx_fifo_aclk)
1036
  begin
1037
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1038
      if tx_fifo_reset = '1' then
1039
        wr_frames <= (others => '0') after dly;
1040
      else
1041
         if (wr_store_frame and wr_retransmit_frame) = '1' then
1042
            wr_frames <= wr_frames + 2 after dly;
1043
         elsif ((wr_store_frame or wr_retransmit_frame)
1044
               and not wr_transmit_frame) = '1' then
1045
            wr_frames <= wr_frames + 1 after dly;
1046
         elsif (wr_transmit_frame and not wr_store_frame) = '1' then
1047
            wr_frames <= wr_frames - 1 after dly;
1048
         end if;
1049
      end if;
1050
    end if;
1051
  end process p_wr_frames;
1052
end generate gen_hd_count;
1053
 
1054
  -- Generate a frame in FIFO signal for use in control logic.
1055
  p_wr_avail : process (tx_fifo_aclk)
1056
  begin
1057
    if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1058
      if tx_fifo_reset = '1' then
1059
        wr_frame_in_fifo <= '0' after dly;
1060
      else
1061
        if wr_frames /= (wr_frames'range => '0') then
1062
          wr_frame_in_fifo <= '1' after dly;
1063
        else
1064
          wr_frame_in_fifo <= '0' after dly;
1065
        end if;
1066
      end if;
1067
    end if;
1068
  end process p_wr_avail;
1069
 
1070
  -- Synchronize it back onto read domain for use in the read logic.
1071
  resync_wr_frame_in_fifo : sync_block
1072
  port map (
1073
    clk       => tx_mac_aclk,
1074
    data_in   => wr_frame_in_fifo,
1075
    data_out  => frame_in_fifo
1076
  );
1077
 
1078
 
1079
  ------------------------------------------------------------------------------
1080
  -- Address counters
1081
  ------------------------------------------------------------------------------
1082
 
1083
  -- Write address is incremented when write enable signal has been asserted
1084
  wr_addr_p : process(tx_fifo_aclk)
1085
  begin
1086
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1087
        if tx_fifo_reset = '1' then
1088
           wr_addr <= (others => '0') after dly;
1089
        elsif wr_addr_reload = '1' then
1090
           wr_addr <= wr_start_addr after dly;
1091
        elsif wr_addr_inc = '1' then
1092
           wr_addr <= wr_addr + 1 after dly;
1093
        end if;
1094
     end if;
1095
  end process wr_addr_p;
1096
 
1097
  -- Store the start address in case the address must be reset.
1098
  wr_staddr_p : process(tx_fifo_aclk)
1099
  begin
1100
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1101
        if tx_fifo_reset = '1' then
1102
           wr_start_addr <= (others => '0') after dly;
1103
        elsif wr_start_addr_load = '1' then
1104
           wr_start_addr <= wr_addr + 1 after dly;
1105
        end if;
1106
     end if;
1107
  end process wr_staddr_p;
1108
 
1109
  ------------------------------------------------------------------------------
1110
  -- Half duplex-only read address counters.
1111
gen_fd_addr : if (FULL_DUPLEX_ONLY = TRUE) generate
1112
  -- Read address is incremented when read enable signal has been asserted.
1113
  rd_addr_p : process(tx_mac_aclk)
1114
  begin
1115
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1116
        if tx_mac_reset = '1' then
1117
           rd_addr <= (others => '0') after dly;
1118
        else
1119
           if rd_addr_reload = '1' then
1120
              rd_addr <= rd_dec_addr after dly;
1121
           elsif rd_addr_inc = '1' then
1122
              rd_addr <= rd_addr + 1 after dly;
1123
           end if;
1124
        end if;
1125
     end if;
1126
  end process rd_addr_p;
1127
 
1128
  -- Do not need to keep a start address, but the address is needed to
1129
  -- calculate FIFO occupancy.
1130
  rd_start_p : process(tx_mac_aclk)
1131
  begin
1132
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1133
        if tx_mac_reset = '1' then
1134
           rd_start_addr <= (others => '0') after dly;
1135
        else
1136
           rd_start_addr <= rd_addr after dly;
1137
       end if;
1138
     end if;
1139
  end process rd_start_p;
1140
end generate gen_fd_addr;
1141
 
1142
  ------------------------------------------------------------------------------
1143
  -- Full and half duplex read address counters
1144
gen_hd_addr : if (FULL_DUPLEX_ONLY = FALSE) generate
1145
  -- Read address is incremented when read enable signal has been asserted.
1146
  rd_addr_p : process(tx_mac_aclk)
1147
  begin
1148
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1149
        if tx_mac_reset = '1' then
1150
           rd_addr <= (others => '0') after dly;
1151
        else
1152
           if rd_addr_reload = '1' then
1153
              rd_addr <= rd_dec_addr after dly;
1154
           elsif rd_start_addr_reload = '1' then
1155
              rd_addr <= rd_start_addr after dly;
1156
           elsif rd_addr_inc = '1' then
1157
              rd_addr <= rd_addr + 1 after dly;
1158
           end if;
1159
        end if;
1160
     end if;
1161
  end process rd_addr_p;
1162
 
1163
  rd_staddr_p : process(tx_mac_aclk)
1164
  begin
1165
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1166
        if tx_mac_reset = '1' then
1167
           rd_start_addr <= (others => '0') after dly;
1168
        else
1169
           if rd_start_addr_load = '1' then
1170
              rd_start_addr <= rd_addr - 4 after dly;
1171
           end if;
1172
        end if;
1173
     end if;
1174
  end process rd_staddr_p;
1175
 
1176
  -- Collision window expires after MAC has been transmitting for required slot
1177
  -- time.  This is 512 clock cycles at 1Gbps. Also if the end of frame has fully
1178
  -- been transmitted by the MAC then a collision cannot occur. This collision
1179
  -- expiration signal goes high at 768 cycles from the start of the frame.
1180
  -- This is inefficient for short frames, however it should be enough to
1181
  -- prevent the FIFO from locking up.
1182
  rd_col_p : process(tx_mac_aclk)
1183
  begin
1184
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1185
        if tx_mac_reset = '1' then
1186
           rd_col_window_expire <= '0' after dly;
1187
        else
1188
           if rd_transmit_frame = '1' then
1189
              rd_col_window_expire <= '0' after dly;
1190
           elsif rd_slot_timer(9 downto 8) = "11" then
1191
              rd_col_window_expire <= '1' after dly;
1192
           end if;
1193
        end if;
1194
     end if;
1195
  end process;
1196
 
1197
  rd_idle_state <= '1' when rd_state = IDLE_s else '0';
1198
 
1199
  rd_colreg_p : process(tx_mac_aclk)
1200
  begin
1201
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1202
        rd_col_window_pipe(0) <= rd_col_window_expire
1203
                                 and rd_idle_state after dly;
1204
        if rd_txfer_en = '1' then
1205
           rd_col_window_pipe(1) <= rd_col_window_pipe(0) after dly;
1206
        end if;
1207
     end if;
1208
  end process;
1209
 
1210
  rd_slot_time_p : process(tx_mac_aclk)
1211
  begin
1212
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1213
        -- Will not count until after the first frame is sent.
1214
        if tx_mac_reset = '1' then
1215
           rd_slot_timer <= (others => '0') after dly;
1216
        else
1217
           -- Reset counter.
1218
           if rd_transmit_frame = '1' then
1219
              rd_slot_timer <= (others => '0') after dly;
1220
           -- Do not allow counter to roll over, and
1221
           -- only count when frame is being transmitted.
1222
           elsif rd_slot_timer /= "1111111111" then
1223
              rd_slot_timer <= rd_slot_timer + 1 after dly;
1224
           end if;
1225
        end if;
1226
     end if;
1227
  end process;
1228
end generate gen_hd_addr;
1229
 
1230
  -- Read address generation
1231
  rd_decaddr_p : process(tx_mac_aclk)
1232
  begin
1233
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1234
        if tx_mac_reset = '1' then
1235
           rd_dec_addr <= (others => '0') after dly;
1236
        else
1237
           if rd_addr_inc = '1' then
1238
              rd_dec_addr <= rd_addr - 1 after dly;
1239
           end if;
1240
        end if;
1241
     end if;
1242
  end process rd_decaddr_p;
1243
 
1244
  -- Which BRAM is read from is dependant on the upper bit of the address
1245
  -- space. This needs to be registered to give the correct timing.
1246
  rd_bram_p : process(tx_mac_aclk)
1247
  begin
1248
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1249
        if tx_mac_reset = '1' then
1250
           rd_bram_u <= '0' after dly;
1251
           rd_bram_u_reg <= '0' after dly;
1252
        else
1253
           if rd_addr_inc = '1' then
1254
              rd_bram_u <= rd_addr(11) after dly;
1255
              rd_bram_u_reg <= rd_bram_u after dly;
1256
           end if;
1257
        end if;
1258
     end if;
1259
  end process rd_bram_p;
1260
 
1261
 
1262
  ------------------------------------------------------------------------------
1263
  -- Data pipelines
1264
  ------------------------------------------------------------------------------
1265
 
1266
  -- Register data inputs to BRAM.
1267
  -- No resets to allow for SRL16 target.
1268
  reg_din_p : process(tx_fifo_aclk)
1269
  begin
1270
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1271
        wr_data_pipe(0) <= tx_axis_fifo_tdata after dly;
1272
        if wr_accept_pipe(0) = '1' then
1273
           wr_data_pipe(1) <= wr_data_pipe(0) after dly;
1274
        end if;
1275
        if wr_accept_pipe(1) = '1' then
1276
           wr_data_bram    <= wr_data_pipe(1) after dly;
1277
        end if;
1278
     end if;
1279
  end process reg_din_p;
1280
 
1281
  -- Start of frame set when tvalid is asserted and previous frame has ended.
1282
  wr_sof_int <= tx_axis_fifo_tvalid and wr_eof_reg;
1283
 
1284
  -- Set end of frame flag when tlast and tvalid are asserted together.
1285
  -- Reset to logic 1 to enable first frame's start of frame flag.
1286
  reg_eofreg_p : process(tx_fifo_aclk)
1287
  begin
1288
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1289
        if tx_fifo_reset = '1' then
1290
           wr_eof_reg <= '1';
1291
        else
1292
           if tx_axis_fifo_tvalid = '1' and tx_axis_fifo_tready_int_n = '0'  then
1293
              wr_eof_reg <= tx_axis_fifo_tlast;
1294
           end if;
1295
        end if;
1296
     end if;
1297
  end process reg_eofreg_p;
1298
 
1299
  -- Pipeline the start of frame flag when the pipe is enabled.
1300
  reg_sof_p : process(tx_fifo_aclk)
1301
  begin
1302
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1303
         wr_sof_pipe(0) <= wr_sof_int after dly;
1304
         if wr_accept_pipe(0) = '1' then
1305
            wr_sof_pipe(1) <= wr_sof_pipe(0) after dly;
1306
         end if;
1307
     end if;
1308
  end process reg_sof_p;
1309
 
1310
  -- Pipeline the pipeline enable signal, which is derived from simultaneous
1311
  -- assertion of tvalid and tready.
1312
  reg_acc_p : process(tx_fifo_aclk)
1313
  begin
1314
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1315
        if (tx_fifo_reset = '1') then
1316
           wr_accept_pipe(0) <= '0' after dly;
1317
           wr_accept_pipe(1) <= '0' after dly;
1318
           wr_accept_bram    <= '0' after dly;
1319
        else
1320
           wr_accept_pipe(0) <= tx_axis_fifo_tvalid and (not tx_axis_fifo_tready_int_n) after dly;
1321
           wr_accept_pipe(1) <= wr_accept_pipe(0) after dly;
1322
           wr_accept_bram    <= wr_accept_pipe(1) after dly;
1323
        end if;
1324
     end if;
1325
  end process reg_acc_p;
1326
 
1327
  -- Pipeline the end of frame flag when the pipe is enabled.
1328
  reg_eof_p : process(tx_fifo_aclk)
1329
  begin
1330
     if (tx_fifo_aclk'event and tx_fifo_aclk = '1') then
1331
        wr_eof_pipe(0) <= tx_axis_fifo_tvalid and tx_axis_fifo_tlast after dly;
1332
        if wr_accept_pipe(0) = '1' then
1333
           wr_eof_pipe(1) <= wr_eof_pipe(0) after dly;
1334
        end if;
1335
        if wr_accept_pipe(1) = '1' then
1336
           wr_eof_bram(0) <= wr_eof_pipe(1) after dly;
1337
        end if;
1338
     end if;
1339
  end process reg_eof_p;
1340
 
1341
  -- Register data outputs from BRAM.
1342
  -- No resets to allow SRL16 target.
1343
  reg_dout_p : process(tx_mac_aclk)
1344
  begin
1345
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1346
        if rd_en = '1' then
1347
           rd_data_pipe_u <= rd_data_bram_u after dly;
1348
           rd_data_pipe_l <= rd_data_bram_l after dly;
1349
           if rd_bram_u_reg = '1' then
1350
              rd_data_pipe <= rd_data_pipe_u after dly;
1351
           else
1352
              rd_data_pipe <= rd_data_pipe_l after dly;
1353
           end if;
1354
        end if;
1355
     end if;
1356
  end process reg_dout_p;
1357
 
1358
  reg_eofout_p : process(tx_mac_aclk)
1359
  begin
1360
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1361
        if rd_en = '1' then
1362
           if rd_bram_u = '1' then
1363
              rd_eof_pipe <= rd_eof_bram_u(0) after dly;
1364
           else
1365
              rd_eof_pipe <= rd_eof_bram_l(0) after dly;
1366
           end if;
1367
           rd_eof <= rd_eof_pipe after dly;
1368
           rd_eof_reg <= rd_eof or rd_eof_pipe after dly;
1369
        end if;
1370
     end if;
1371
  end process reg_eofout_p;
1372
 
1373
  ------------------------------------------------------------------------------
1374
  -- Half duplex-only drop and retransmission controls.
1375
gen_hd_input : if (FULL_DUPLEX_ONLY = FALSE) generate
1376
  -- Register the collision without retransmit signal, which is a pulse that
1377
  -- causes the FIFO to drop the frame.
1378
  reg_col_p : process(tx_mac_aclk)
1379
  begin
1380
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1381
        rd_drop_frame <= tx_collision and (not tx_retransmit) after dly;
1382
     end if;
1383
  end process reg_col_p;
1384
 
1385
  -- Register the collision with retransmit signal, which is a pulse that
1386
  -- causes the FIFO to retransmit the frame.
1387
  reg_retr_p : process(tx_mac_aclk)
1388
  begin
1389
     if (tx_mac_aclk'event and tx_mac_aclk = '1') then
1390
        rd_retransmit <= tx_collision and tx_retransmit after dly;
1391
     end if;
1392
  end process reg_retr_p;
1393
end generate gen_hd_input;
1394
 
1395
 
1396
  ------------------------------------------------------------------------------
1397
  -- FIFO full functionality
1398
  ------------------------------------------------------------------------------
1399
 
1400
  -- Full functionality is the difference between read and write addresses.
1401
  -- We cannot use gray code this time as the read address and read start
1402
  -- addresses jump by more than 1.
1403
  -- We generate an enable pulse for the read side every 16 read clocks. This
1404
  -- provides for the worst-case situation where the write clock is 20MHz and
1405
  -- read clock is 125MHz.
1406
  p_rd_16_pulse : process (tx_mac_aclk)
1407
  begin
1408
     if tx_mac_aclk'event and tx_mac_aclk = '1' then
1409
        if tx_mac_reset = '1' then
1410
           rd_16_count <= (others => '0') after dly;
1411
        else
1412
           rd_16_count <= rd_16_count + 1 after dly;
1413
        end if;
1414
     end if;
1415
  end process;
1416
 
1417
  rd_txfer_en <= '1' when rd_16_count = "1111" else '0';
1418
 
1419
  -- Register the start address on the enable pulse.
1420
  p_rd_addr_txfer : process (tx_mac_aclk)
1421
  begin
1422
    if tx_mac_aclk'event and tx_mac_aclk = '1' then
1423
       if tx_mac_reset = '1' then
1424
          rd_addr_txfer <= (others => '0') after dly;
1425
       else
1426
          if rd_txfer_en = '1' then
1427
             rd_addr_txfer <= rd_start_addr after dly;
1428
          end if;
1429
       end if;
1430
    end if;
1431
  end process;
1432
 
1433
  -- Generate a toggle to indicate that the address has been loaded.
1434
  p_rd_tog_txfer : process (tx_mac_aclk)
1435
  begin
1436
    if tx_mac_aclk'event and tx_mac_aclk = '1' then
1437
       if rd_txfer_en = '1' then
1438
          rd_txfer_tog <= not rd_txfer_tog after dly;
1439
       end if;
1440
    end if;
1441
  end process;
1442
 
1443
  -- Synchronize the toggle to the write side.
1444
  resync_rd_txfer_tog : sync_block
1445
  port map (
1446
    clk       => tx_fifo_aclk,
1447
    data_in   => rd_txfer_tog,
1448
    data_out  => wr_txfer_tog_sync
1449
  );
1450
 
1451
  -- Delay the synchronized toggle by one cycle.
1452
  p_wr_tog_txfer : process (tx_fifo_aclk)
1453
  begin
1454
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1455
        wr_txfer_tog_delay <= wr_txfer_tog_sync after dly;
1456
     end if;
1457
  end process;
1458
 
1459
  -- Generate an enable pulse from the toggle. The address should have been
1460
  -- steady on the wr clock input for at least one clock.
1461
  wr_txfer_en <= wr_txfer_tog_delay xor wr_txfer_tog_sync;
1462
 
1463
  -- Capture the address on the write clock when the enable pulse is high.
1464
  p_wr_addr_txfer : process (tx_fifo_aclk)
1465
  begin
1466
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1467
        if tx_fifo_reset = '1' then
1468
           wr_rd_addr <= (others => '0') after dly;
1469
        elsif wr_txfer_en = '1' then
1470
           wr_rd_addr <= rd_addr_txfer after dly;
1471
        end if;
1472
     end if;
1473
  end process;
1474
 
1475
  -- Obtain the difference between write and read pointers
1476
  p_wr_addr_diff : process (tx_fifo_aclk)
1477
  begin
1478
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1479
        if tx_fifo_reset = '1' then
1480
           wr_addr_diff <= (others => '0') after dly;
1481
        else
1482
           wr_addr_diff <= wr_rd_addr - wr_addr after dly;
1483
        end if;
1484
     end if;
1485
  end process;
1486
 
1487
  -- Detect when the FIFO is full.
1488
  -- The FIFO is considered to be full if the write address pointer is
1489
  -- within 0 to 3 of the read address pointer.
1490
  p_wr_full : process (tx_fifo_aclk)
1491
  begin
1492
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1493
       if tx_fifo_reset = '1' then
1494
         wr_fifo_full <= '0' after dly;
1495
       else
1496
         if wr_addr_diff(11 downto 4) = 0
1497
            and wr_addr_diff(3 downto 2) /= "00" then
1498
           wr_fifo_full <= '1' after dly;
1499
         else
1500
           wr_fifo_full <= '0' after dly;
1501
         end if;
1502
       end if;
1503
     end if;
1504
  end process p_wr_full;
1505
 
1506
  -- Memory overflow occurs when the FIFO is full and there are no frames
1507
  -- available in the FIFO for transmission. If the collision window has
1508
  -- expired and there are no frames in the FIFO and the FIFO is full, then the
1509
  -- FIFO is in an overflow state. We must accept the rest of the incoming
1510
  -- frame in overflow condition.
1511
 
1512
gen_fd_ovflow : if (FULL_DUPLEX_ONLY = TRUE) generate
1513
     -- In full duplex mode, the FIFO memory can only overflow if the FIFO goes
1514
     -- full but there is no frame available to be retranmsitted. Therefore,
1515
     -- prevent signal from being asserted when store_frame signal is high, as
1516
     -- frame count is being updated.
1517
     wr_fifo_overflow <= '1' when wr_fifo_full = '1' and wr_frame_in_fifo = '0'
1518
                               and wr_eof_state = '0' and wr_eof_state_reg = '0'
1519
                             else '0';
1520
end generate gen_fd_ovflow;
1521
 
1522
gen_hd_ovflow : if (FULL_DUPLEX_ONLY = FALSE) generate
1523
    -- In half duplex mode, register write collision window to give address
1524
    -- counter sufficient time to update. This will prevent the signal from
1525
    -- being asserted when the store_frame signal is high, as the frame count
1526
    -- is being updated.
1527
    wr_fifo_overflow <= '1' when wr_fifo_full = '1' and wr_frame_in_fifo = '0'
1528
                               and wr_eof_state = '0' and wr_eof_state_reg = '0'
1529
                               and wr_col_window_expire = '1'
1530
                            else '0';
1531
 
1532
    -- Register rd_col_window signal.
1533
    -- This signal is long, and will remain high until overflow functionality
1534
    -- has finished, so save just to register the once.
1535
    p_wr_col_expire : process (tx_fifo_aclk)
1536
    begin
1537
       if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1538
          if tx_fifo_reset = '1' then
1539
             wr_col_window_pipe(0) <= '0' after dly;
1540
             wr_col_window_pipe(1) <= '0' after dly;
1541
             wr_col_window_expire  <= '0' after dly;
1542
          else
1543
             if wr_txfer_en = '1' then
1544
               wr_col_window_pipe(0) <= rd_col_window_pipe(1) after dly;
1545
             end if;
1546
             wr_col_window_pipe(1) <= wr_col_window_pipe(0) after dly;
1547
             wr_col_window_expire  <= wr_col_window_pipe(1) after dly;
1548
          end if;
1549
       end if;
1550
    end process;
1551
end generate gen_hd_ovflow;
1552
 
1553
 
1554
  ------------------------------------------------------------------------------
1555
  -- FIFO status signals
1556
  ------------------------------------------------------------------------------
1557
 
1558
  -- The FIFO status is four bits which represents the occupancy of the FIFO
1559
  -- in sixteenths. To generate this signal we therefore only need to compare
1560
  -- the 4 most significant bits of the write address pointer with the 4 most
1561
  -- significant bits of the read address pointer.
1562
  p_fifo_status : process (tx_fifo_aclk)
1563
  begin
1564
     if tx_fifo_aclk'event and tx_fifo_aclk = '1' then
1565
        if tx_fifo_reset = '1' then
1566
           wr_fifo_status <= "0000" after dly;
1567
        else
1568
           if wr_addr_diff = (wr_addr_diff'range => '0') then
1569
              wr_fifo_status <= "0000" after dly;
1570
           else
1571
              wr_fifo_status(3) <= not wr_addr_diff(11) after dly;
1572
              wr_fifo_status(2) <= not wr_addr_diff(10) after dly;
1573
              wr_fifo_status(1) <= not wr_addr_diff(9) after dly;
1574
              wr_fifo_status(0) <= not wr_addr_diff(8) after dly;
1575
           end if;
1576
        end if;
1577
     end if;
1578
  end process p_fifo_status;
1579
 
1580
  fifo_status <= std_logic_vector(wr_fifo_status);
1581
 
1582
 
1583
  ------------------------------------------------------------------------------
1584
  -- Instantiate FIFO block memory
1585
  ------------------------------------------------------------------------------
1586
 
1587
  wr_eof_data_bram(8)          <= wr_eof_bram(0);
1588
  wr_eof_data_bram(7 downto 0) <= wr_data_bram;
1589
 
1590
  -- Block RAM for lower address space (rd_addr(11) = '0')
1591
  rd_eof_bram_l(0) <= rd_eof_data_bram_l(8);
1592
  rd_data_bram_l   <= rd_eof_data_bram_l(7 downto 0);
1593
  ramgen_l : BRAM_TDP_MACRO
1594
    generic map (
1595
      DEVICE        => "VIRTEX6",
1596
      WRITE_WIDTH_A => 9,
1597
      WRITE_WIDTH_B => 9,
1598
      READ_WIDTH_A  => 9,
1599
      READ_WIDTH_B  => 9)
1600
    port map (
1601
      DOA    => rd_bram_l_unused,
1602
      DOB    => rd_eof_data_bram_l,
1603
      ADDRA  => std_logic_vector(wr_addr(10 downto 0)),
1604
      ADDRB  => std_logic_vector(rd_addr(10 downto 0)),
1605
      CLKA   => tx_fifo_aclk,
1606
      CLKB   => tx_mac_aclk,
1607
      DIA    => wr_eof_data_bram,
1608
      DIB    => GND_BUS(8 downto 0),
1609
      ENA    => VCC,
1610
      ENB    => rd_en,
1611
      REGCEA => VCC,
1612
      REGCEB => VCC,
1613
      RSTA   => tx_fifo_reset,
1614
      RSTB   => tx_mac_reset,
1615
      WEA    => wr_en_l_bram,
1616
      WEB    => GND
1617
  );
1618
 
1619
  -- Block RAM for lower address space (rd_addr(11) = '0')
1620
  rd_eof_bram_u(0) <= rd_eof_data_bram_u(8);
1621
  rd_data_bram_u   <= rd_eof_data_bram_u(7 downto 0);
1622
  ramgen_u : BRAM_TDP_MACRO
1623
    generic map (
1624
      DEVICE        => "VIRTEX6",
1625
      WRITE_WIDTH_A => 9,
1626
      WRITE_WIDTH_B => 9,
1627
      READ_WIDTH_A  => 9,
1628
      READ_WIDTH_B  => 9)
1629
    port map (
1630
      DOA    => rd_bram_u_unused,
1631
      DOB    => rd_eof_data_bram_u,
1632
      ADDRA  => std_logic_vector(wr_addr(10 downto 0)),
1633
      ADDRB  => std_logic_vector(rd_addr(10 downto 0)),
1634
      CLKA   => tx_fifo_aclk,
1635
      CLKB   => tx_mac_aclk,
1636
      DIA    => wr_eof_data_bram,
1637
      DIB    => GND_BUS(8 downto 0),
1638
      ENA    => VCC,
1639
      ENB    => rd_en,
1640
      REGCEA => VCC,
1641
      REGCEB => VCC,
1642
      RSTA   => tx_fifo_reset,
1643
      RSTB   => tx_mac_reset,
1644
      WEA    => wr_en_u_bram,
1645
      WEB    => GND
1646
  );
1647
 
1648
 
1649
end RTL;

powered by: WebSVN 2.1.0

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