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

Subversion Repositories gigabit_udp_mac

[/] [gigabit_udp_mac/] [trunk/] [MAC/] [MAC_Controller.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 boa_a_m
-------------------------------------------------------------
2
--      Filename:  MAC_Controller.VHD
3
--      Version: 5
4
--      Date last modified: 9/16/11
5
-- Inheritance: COM5401.VHD, rev5, 9/16/11
6
--
7
-- description:  10/100/1000 MAC
8
-- Features include
9
-- (a) Automatic appending of 32-bit CRC to tx packets. Users don't have to.
10
-- (b) discarding of rx packets with bad CRC.
11
-- 
12
-- Usage: the following KSZ9021RN strapping options MUST be set in the .ucf file
13
-- pin35 RX_CLK/PHYAD2 pull-down  LEFT_CONNECTOR_A(1),A(19),B(1),B(21)
14
-- pins32,31,28,27 RXDx/MODEx  pull-up, advertise all modes
15
--      LEFT_CONNECTOR_A(2,4,5,6,21,22,23,24),B(3,4,6,7,23,24,25,26)
16
-- pin33 RX_DV(RX_CTL)/CLK125_EN        
17
--      pull-down on all ICs. No need for an external 125 MHz clock (not very clean).
18
--      LEFT_CONNECTOR_A(2) pullup, LEFT_CONNECTOR_A(20),B(2),B(22) pull-down
19
-- pin41 CLK125_NDO/LED_MODE pulldown dual leds, tri-color.
20
--      LEFT_CONNECTOR_A(13,31),_B(14,34)
21
-- 
22
-- The transmit elastic buffer is large enough for 2 maximum size frame. The tx Clear To Send (MAC_TX_CTS)
23
-- signal is raised when the the MAC is ready to accept one complete frame without interruption.
24
-- In this case, MAC_TX_CTS may go low while the frame transfer has started, but there is guaranteed
25
-- space for the entire frame.  
26
--
27
---------------------------------------------------------------
28
library IEEE;
29
use IEEE.STD_LOGIC_1164.ALL;
30
use IEEE.STD_LOGIC_ARITH.ALL;
31
use IEEE.STD_LOGIC_UNSIGNED.ALL;
32
library UNISIM;
33
use UNISIM.VComponents.all;
34
 
35
entity MAC_Controller is
36
        generic (
37
                PHY_ADDR: std_logic_vector(4 downto 0) := "00001";
38
                        -- PHY_AD0/1 pulled-down by 1KOhm, PHY_AD2 pulled-up in .ucf file.
39
                CLK_FREQUENCY: integer := 125
40
                        -- CLK frequency in MHz. Needed to compute actual delays.
41
        );
42
    Port (
43
                --// CLK, RESET
44
                CLK: in std_logic;
45
                        -- USER-side GLOBAL CLOCK
46
                IDELAYREFCLK200MHZ: in std_logic;
47
                        -- 190-210 MHz clock required for implementing IO delay(s).
48
                ASYNC_RESET: in std_logic;
49
                        -- reset pulse must be > slowest clock period  (>400ns)
50
                        -- minimum width 50ns for Virtex 5 (IDELAYCTRL contraint)
51
                        -- MANDATORY at power up.
52
 
53
                --// MAC CONFIGURATION
54
                -- configuration signals are synchonous with the user-side CLK
55
                MAC_TX_CONFIG: in std_logic_vector(15 downto 0);
56
                        -- bit 0: (1) Automatic padding of short frames. Requires that auto-CRC insertion be enabled too. 
57
                        --                       (0) Skip padding. User is responsible for adding padding to meet the minimum 60 byte frame size
58
                        -- bit 1: (1) Automatic appending of 32-bit CRC at the end of the frame
59
                        --                       (0) Skip CRC32 insertion. User is responsible for including the frame check sequence
60
                        -- Note: use 0x03 when interfacing with COM-5402 IP/UDP/TCP stack.
61
                MAC_RX_CONFIG: in std_logic_vector(15 downto 0);
62
                        -- bit 0: (1) promiscuous mode enabled (0) disabled, i.e. destination address is verified for each incoming packet 
63
                        -- bit 1: (1) accept broadcast rx packets (0) reject
64
                        -- bit 2: (1) accept multi-cast rx packets (0) reject
65
                        -- bit 3: (1) filter out the 4-byte CRC field (0) pass along the CRC field.
66
                        -- Note2: use 0x0F when interfacing with COM-5402 IP/UDP/TCP stack.
67
                MAC_ADDR: in std_logic_vector(47 downto 0);
68
                        -- This network node 48-bit MAC address. The receiver checks incoming packets for a match between 
69
                        -- the destination address field and this MAC address.
70
                        -- The user is responsible for selecting a unique ‘hardware’ address for each instantiation.
71
                        -- Natural bit order: enter x0123456789ab for the MAC address 01:23:45:67:89:ab
72
 
73
                --// PHY CONFIGURATION
74
                -- configuration signals are synchonous with the user-side CLK.
75
                PHY_CONFIG_CHANGE: in std_logic;
76
                        -- optional pulse to activate any configuration change below.
77
                        -- Not needed if the default values are acceptable.
78
                        -- Ignored if sent during the initial PHY reset (10ms after power up)
79
                PHY_RESET: in std_logic;
80
                        -- 1 = PHY software reset (default), 0 = no reset
81
                SPEED: in std_logic_vector(1 downto 0);
82
                        -- 00 = force 10 Mbps
83
                        -- 01 = force 100 Mbps
84
                        -- 10 = force 1000 Mbps
85
                        -- 11 = auto-negotiation (default)
86
                DUPLEX: in std_logic;
87
                        -- 1 = full-duplex (default), 0 = half-duplex
88
                TEST_MODE: in std_logic_vector(1 downto 0);
89
                        -- 00 = normal mode (default)
90
                        -- 01 = loopback mode (at the phy)
91
                        -- 10 = remote loopback
92
                        -- 11 = led test mode
93
                POWER_DOWN: in std_logic;
94
                        -- software power down mode. 1 = enabled, 0 = disabled (default).
95
 
96
                --// USER -> Transmit MAC Interface
97
                -- 32-bit CRC is automatically appended. User should not supply it.
98
                -- Synchonous with the user-side CLK
99
                MAC_TX_DATA: in std_logic_vector(7 downto 0);
100
                        -- MAC reads the data at the rising edge of CLK when MAC_TX_DATA_VALID = '1'
101
                MAC_TX_DATA_VALID: in std_logic;
102
                        -- data valid
103
                MAC_TX_EOF: in std_logic;
104
                        -- '1' when sending the last byte in a packet to be transmitted. 
105
                        -- Aligned with MAC_TX_DATA_VALID
106
                MAC_TX_CTS: out std_logic;
107
                        -- MAC-generated Clear To Send flow control signal, indicating room in the 
108
                        -- tx elastic buffer for a complete maximum size frame 1518B. 
109
                        -- The user should check that this signal is high before deciding to send
110
                        -- sending the next frame. 
111
                        -- Note: MAC_TX_CTS may go low while the frame is transfered in. Ignore it.
112
 
113
                --// Receive MAC -> USER Interface
114
                -- Valid rx packets only: packets with bad CRC or invalid address are discarded.
115
                -- Synchonous with the user-side CLK
116
                -- The short-frame padding is included .
117
                MAC_RX_DATA: out std_logic_vector(7 downto 0);
118
                        -- USER reads the data at the rising edge of CLK when MAC_RX_DATA_VALID = '1'
119
                MAC_RX_DATA_VALID: out std_logic;
120
                        -- data valid
121
                MAC_RX_SOF: out std_logic;
122
                        -- '1' when sending the first byte in a received packet. 
123
                        -- Aligned with MAC_RX_DATA_VALID
124
                MAC_RX_EOF: out std_logic;
125
                        -- '1' when sending the last byte in a received packet. 
126
                        -- Aligned with MAC_RX_DATA_VALID
127
                MAC_RX_CTS: in std_logic;
128
                        -- User-generated Clear To Send flow control signal. The receive MAC checks that this 
129
                        -- signal is high before sending the next MAC_RX_DATA byte. 
130
 
131
 
132
 
133
                --// RGMII PHY Interface (when RGMII is enabled. See MII_SEL generic flag above)
134
                RESET_N: out std_logic;
135
                        -- PHY reset
136
                MCLK: out std_logic;
137
                MDIO: inout std_logic:='0';  -- (tri-state)
138
                        -- serial interface
139
 
140
                --// GMII/MII PHY Interface (when GMII/MII is enabled.  See MII_SEL generic flag above)
141
                MII_TX_CLK: in std_logic:='0';
142
                        -- MII tx clock from PHY. Continuous clock. (10/100 Mbps only) 
143
                        -- 25 MHz (100 Mbps), or 2.5 MHz (10 Mbps) depending on speed
144
                        -- accuracy: +/- 100ppm (MII)
145
                        -- duty cycle between 35% and 65% inclusive (MII).
146
                GMII_TX_CLK: out std_logic;
147
                        -- GMII tx clock to PHY. Continuous clock. 125MHz (1000 Mbps only)
148
                        -- 2ns delay inside (user adjustable).
149
                GMII_MII_TXD: out std_logic_vector(7 downto 0);  -- tx data
150
                        -- tx data (when TX_EN = '1' and TX_ER = '0') or special codes otherwise (carrier extend, 
151
                        -- carrier extend error, transmit error propagation). See 802.3 table 35-1 for definitions.
152
                GMII_MII_TX_EN: out std_logic;
153
                GMII_MII_TX_ER: out std_logic;
154
                        -- to deliberately corrupt the contents of the frame (so as to be detected as such by the receiver)
155
                GMII_MII_CRS: in std_logic:='0';
156
                GMII_MII_COL: in std_logic:='0';
157
 
158
                GMII_MII_RX_CLK: in std_logic;
159
                        -- continuous receive reference clock recovered by the PHY from the received signal
160
                        -- 125/25/2.5 MHz +/- 50 ppm. 
161
                        -- Duty cycle better than 35%/65% (MII)
162
                        -- 125 MHz must be delayed by 1.5 to 2.1 ns to prevent glitches (TBC. true for RGMII, but for GMII TOO???)
163
 
164
                GMII_MII_RXD: in std_logic_vector(7 downto 0);
165
                        -- rx data. 8-bit when 1000 Mbps. 4-bit nibble (3:0) when 10/100 Mbps.
166
                GMII_MII_RX_DV: in std_logic;
167
                GMII_MII_RX_ER: in std_logic;
168
 
169
 
170
                --// PHY status
171
                -- The link, speed and duplex status are read from the RXD when RX_CTL is inactive
172
                -- synchronous with RXCG global clock
173
                LINK_STATUS: out std_logic;
174
                        -- 0 = link down, 1 = link up
175
                SPEED_STATUS: out std_logic_vector(1 downto 0);
176
                        -- RXC clock speed, 00 = 2.5 MHz, 01 = 25 MHz, 10 = 125 MHz, 11 = reserved
177
                DUPLEX_STATUS: out std_logic;
178
                        -- 0 = half duplex, 1 = full duplex
179
                PHY_ID: out std_logic_vector(15 downto 0)
180
 
181
 );
182
end entity;
183
 
184
architecture Behavioral of MAC_Controller is
185
--------------------------------------------------------
186
--      COMPONENTS
187
--------------------------------------------------------
188
        COMPONENT RESET_TIMER
189
        GENERIC (
190
                CLK_FREQUENCY: in integer
191
        );
192
        PORT(
193
                CLK : IN std_logic;
194
                RESET_START : IN std_logic;
195
                RESET_COMPLETE : OUT std_logic;
196
                INITIAL_CONFIG_PULSE : OUT std_logic;
197
                RESET_N : OUT std_logic
198
                );
199
        END COMPONENT;
200
 
201
        COMPONENT PHY_CONFIG
202
        GENERIC (
203
                PHY_ADDR: std_logic_vector(4 downto 0)
204
        );
205
        PORT(
206
                SYNC_RESET : IN std_logic;
207
                CLK : IN std_logic;
208
                CONFIG_CHANGE : IN std_logic;
209
                PHY_RESET : IN std_logic;
210
                SPEED : IN std_logic_vector(1 downto 0);
211
                DUPLEX : IN std_logic;
212
                TEST_MODE : IN std_logic_vector(1 downto 0);
213
                POWER_DOWN : IN std_logic;
214
                CLK_SKEW: in std_logic_vector(15 downto 0);
215
                SREG_READ_START : IN std_logic;
216
                SREG_REGAD : IN std_logic_vector(8 downto 0);
217
                LINK_STATUS: out std_logic;
218
                MDI: in std_logic;  -- MDIO input
219
                MDO: out std_logic;  -- MDIO output
220
                MDT: out std_logic;  -- MDIO tri-state
221
                SREG_DATA : OUT std_logic_vector(15 downto 0);
222
                SREG_SAMPLE_CLK : OUT std_logic;
223
                MCLK : OUT std_logic
224
                );
225
        END COMPONENT;
226
 
227
        COMPONENT RGMII_WRAPPER_V6
228
        GENERIC (
229
                CLK_FREQUENCY: in integer
230
        );
231
        PORT(
232
                SYNC_RESET : IN std_logic;
233
                CLK : IN std_logic;
234
                IDELAYREFCLK200MHZ: in std_logic;
235
                RXC : IN std_logic;
236
                RXD : IN std_logic_vector(3 downto 0);
237
                RX_CTL : IN std_logic;
238
                MAC_TXD : IN std_logic_vector(7 downto 0);
239
                MAC_TX_EN : IN std_logic;
240
                MAC_TX_ER : IN std_logic;
241
                MAC_TX_SAMPLE_CLK : IN std_logic;
242
                TX_SPEED : IN std_logic_vector(1 downto 0);
243
                TXC : OUT std_logic;
244
                TXD : OUT std_logic_vector(3 downto 0);
245
                TX_CTL : OUT std_logic;
246
                MAC_RXD : OUT std_logic_vector(7 downto 0);
247
                MAC_RX_SAMPLE_CLK: OUT std_logic;
248
                MAC_RX_DV : OUT std_logic;
249
                MAC_RX_ER : OUT std_logic;
250
                RXCG_OUT : OUT std_logic;
251
                CRS : OUT std_logic;
252
                COL : OUT std_logic;
253
                LINK_STATUS : OUT std_logic;
254
                SPEED_STATUS : OUT std_logic_vector(1 downto 0);
255
                DUPLEX_STATUS : OUT std_logic;
256
                TP: out std_logic_vector(10 downto 1)
257
                );
258
        END COMPONENT;
259
 
260
        COMPONENT GMII_MII_WRAPPER_V6
261
        PORT(
262
                SYNC_RESET : IN std_logic;
263
                CLK : IN std_logic;
264
                IDELAYREFCLK200MHZ: in std_logic;
265
                TX_CLK : IN std_logic;
266
                RX_CLK : IN std_logic;
267
                RXD : IN std_logic_vector(7 downto 0);
268
                RX_DV : IN std_logic;
269
                RX_ER : IN std_logic;
270
                CRS : IN std_logic;
271
                COL : IN std_logic;
272
                MAC_TXD : IN std_logic_vector(7 downto 0);
273
                MAC_TX_EN : IN std_logic;
274
                MAC_TX_ER : IN std_logic;
275
                MAC_TX_SAMPLE_CLK : IN std_logic;
276
                MAC_TX_SPEED : IN std_logic_vector(1 downto 0);
277
                GTX_CLK : OUT std_logic;
278
                TXD : OUT std_logic_vector(7 downto 0);
279
                TX_EN : OUT std_logic;
280
                TX_ER : OUT std_logic;
281
                MAC_RX_CLK : OUT std_logic;
282
                MAC_RXD : OUT std_logic_vector(7 downto 0);
283
                MAC_RX_DV : OUT std_logic;
284
                MAC_RX_ER : OUT std_logic;
285
                MAC_RX_SAMPLE_CLK : OUT std_logic;
286
                MAC_CRS : OUT std_logic;
287
                MAC_COL : OUT std_logic;
288
                LINK_STATUS : OUT std_logic;
289
                SPEED_STATUS : OUT std_logic_vector(1 downto 0);
290
                DUPLEX_STATUS : OUT std_logic
291
                );
292
        END COMPONENT;
293
 
294
        COMPONENT CRC32_8B
295
        PORT(
296
                SYNC_RESET : IN std_logic;
297
                CLK : IN std_logic;
298
                CRC32_IN : IN std_logic_vector(31 downto 0);
299
                DATA_IN : IN std_logic_vector(7 downto 0);
300
                SAMPLE_CLK_IN : IN std_logic;
301
                CRC32_OUT : OUT std_logic_vector(31 downto 0);
302
                CRC32_VALID : OUT std_logic
303
                );
304
        END COMPONENT;
305
 
306
        COMPONENT LFSR11C
307
        PORT(
308
                ASYNC_RESET : IN std_logic;
309
                CLK : IN std_logic;
310
                BIT_CLK_REQ : IN std_logic;
311
                SYNC_RESET : IN std_logic;
312
                SEED : IN std_logic_vector(10 downto 0);
313
                LFSR_BIT : OUT std_logic;
314
                BIT_CLK_OUT : OUT std_logic;
315
                SOF_OUT : OUT std_logic;
316
                LFSR_REG_OUT: OUT std_logic_vector(10 downto 0)
317
                );
318
        END COMPONENT;
319
 
320
--------------------------------------------------------
321
--     SIGNALS
322
--------------------------------------------------------
323
-- NOTATIONS: 
324
-- _E as one-CLK early sample
325
-- _D as one-CLK delayed sample
326
-- _D2 as two-CLKs delayed sample
327
 
328
--// CLK & RESETS ---------
329
signal RESETFLAG_D: std_logic := '0';
330
signal RESETFLAG_D2: std_logic := '0';
331
signal SYNC_RESET: std_logic := '0';
332
signal SYNC_RESETRX: std_logic := '0';
333
signal RESETRX_FLAG_D: std_logic := '0';
334
signal RESETRX_FLAG_D2: std_logic := '0';
335
 
336
 
337
--// PHY RESET AND CONFIGURATION ----------------------------------------------------------
338
signal RESET_N_LOCAL: std_logic := '0';
339
signal INITIAL_CONFIG_PULSE: std_logic := '1';
340
signal PHY_CONFIG_CHANGE_A: std_logic := '0';
341
signal PHY_RESET_A: std_logic := '0';
342
signal SPEED_A: std_logic_vector(1 downto 0);
343
signal DUPLEX_A: std_logic := '0';
344
signal TEST_MODE_A: std_logic_vector(1 downto 0);
345
signal POWER_DOWN_A: std_logic := '0';
346
signal CLK_SKEW_A: std_logic_vector(15 downto 0);
347
signal MDI: std_logic := '0';
348
signal MDO: std_logic := '0';
349
signal MDT: std_logic := '0';
350
signal RESET_COMPLETE: std_logic := '0';
351
signal PHY_IF_WRAPPER_RESET: std_logic := '0';
352
signal SREG_READ_START: std_logic := '0';
353
signal SREG_SAMPLE_CLK: std_logic := '0';
354
signal PHY_ID_LOCAL: std_logic_vector(15 downto 0);
355
signal LINK_STATUS_local: std_logic := '0';
356
signal DUPLEX_STATUS_local: std_logic := '0';
357
signal SPEED_STATUS_LOCAL: std_logic_vector(1 downto 0) := (others => '0');
358
signal TP_RGMII_WRAPPER: std_logic_vector(10 downto 1) := (others => '0');
359
 
360
--//  PHY INTERFACE: GMII to RGMII CONVERSION ----------------------------------------------------------
361
signal CRS: std_logic := '0';
362
signal CRS_D: std_logic := '0';
363
signal COL: std_logic := '0';
364
signal MAC_TXD: std_logic_vector(7 downto 0) := (others => '0');
365
signal MAC_TX_EN: std_logic := '0';
366
signal MAC_TX_ER: std_logic := '0';
367
signal MAC_TX_SAMPLE_CLK: std_logic := '0';
368
signal MAC_RXD0: std_logic_vector(7 downto 0);
369
signal MAC_RX_DV0: std_logic := '0';
370
signal MAC_RX_ER0: std_logic := '0';
371
signal MAC_RX_SAMPLE_CLK0: std_logic := '0';
372
signal MAC_RXD: std_logic_vector(7 downto 0);
373
signal MAC_RX_DV: std_logic := '0';
374
signal MAC_RX_ER: std_logic := '0';
375
signal MAC_RX_SAMPLE_CLK: std_logic := '0';
376
 
377
 
378
--//  TX ELASTIC BUFFER ----------------------------------------------------------
379
signal MAC_TX_DIA: std_logic_vector(31 downto 0) := (others => '0');
380
signal MAC_TX_DIPA: std_logic_vector(0 downto 0) := (others => '0');
381
signal MAC_TX_WPTR: std_logic_vector(11 downto 0) := (others => '0');
382
signal MAC_TX_WPTR_D: std_logic_vector(11 downto 0) := (others => '0');
383
signal MAC_TX_WPTR_D2: std_logic_vector(11 downto 0) := (others => '0');
384
signal MAC_TX_WPTR_D3: std_logic_vector(11 downto 0) := (others => '0');
385
signal MAC_TX_WPTR_STABLE: std_logic := '0';
386
signal MAC_TX_WPTR_STABLE_D: std_logic := '0';
387
signal TX_COUNTER8: std_logic_vector(2 downto 0) :=(others => '0');
388
signal MAC_TX_WEA: std_logic_vector(1 downto 0) := (others => '0');
389
signal MAC_TX_BUF_SIZE: std_logic_vector(11 downto 0) := (others => '0');
390
signal MAC_TX_RPTR: std_logic_vector(11 downto 0) := (others => '1');
391
signal MAC_TX_RPTR_D: std_logic_vector(11 downto 0) := (others => '1');
392
signal MAC_TX_RPTR_CONFIRMED: std_logic_vector(11 downto 0) := (others => '1');
393
signal MAC_TX_RPTR_CONFIRMED_D: std_logic_vector(11 downto 0) := (others => '1');
394
signal MAC_TX_SAMPLE2_CLK_E: std_logic := '0';
395
signal MAC_TX_SAMPLE2_CLK: std_logic := '0';
396
type DOBtype is array(integer range 0 to 1) of std_logic_vector(7 downto 0);
397
signal MAC_TX_DOB: DOBtype;
398
type DOPBtype is array(integer range 0 to 1) of std_logic_vector(0 downto 0);
399
signal MAC_TX_DOPB: DOPBtype;
400
signal MAC_TX_DATA2: std_logic_vector(7 downto 0) := (others => '0');
401
signal MAC_TX_EOF2: std_logic := '0';
402
signal MAC_TX_EOF2_D: std_logic := '0';
403
signal COMPLETE_TX_FRAMES_INBUF: std_logic_vector(7 downto 0) := x"00";  -- can't have more than 147 frames in a 16k buffer
404
signal ATLEAST1_COMPLETE_TX_FRAME_INBUF: std_logic := '0';
405
signal MAC_TX_EOF_TOGGLE: std_logic := '0';
406
signal MAC_TX_EOF_TOGGLE_D: std_logic := '0';
407
signal MAC_TX_EOF_TOGGLE_D2: std_logic := '0';
408
signal MAC_TX_CTS_local: std_logic := '0';
409
 
410
--//-- TX FLOW CONTROL --------------------------------
411
signal TX_SUCCESS_TOGGLE: std_logic := '0';
412
signal TX_SUCCESS_TOGGLE_D: std_logic := '0';
413
signal TX_SUCCESS_TOGGLE_D2: std_logic := '0';
414
signal MAC_TX_BUF_FREE: std_logic_vector(11 downto 0) := (others => '0');
415
 
416
 
417
--// MAC TX STATE MACHINE ----------------------------------------------------------
418
signal TX_SPEED: std_logic_vector(1 downto 0) := (others => '0');
419
signal TX_CLK: std_logic := '0';
420
signal TX_BYTE_CLK: std_logic := '0';
421
signal TX_BYTE_CLK_D: std_logic := '0';
422
signal TX_HALF_BYTE_FLAG: std_logic := '0';
423
signal IPG: std_logic := '0';
424
signal IPG_CNTR: std_logic_vector(7 downto 0) := (others => '0');  -- TODO CHECK CONSISTENCY WITH TIMER VALUES
425
signal TX_EVENT1: std_logic := '0';
426
signal TX_EVENT2: std_logic := '0';
427
signal TX_EVENT3: std_logic := '0';
428
signal TX_STATE: integer range 0 to 15 := 0;
429
signal TX_BYTE_COUNTER: std_logic_vector(18 downto 0) := (others => '0');  -- large enough for counting 2000 bytes in max size packet
430
signal TX_BYTE_COUNTER2: std_logic_vector(2 downto 0) := (others => '0');  -- small auxillary byte counter for small fields
431
signal TX_PREAMBLE: std_logic_vector(7 downto 0) := (others => '0');
432
signal MAC_TX_SAMPLE4_CLK: std_logic := '0';
433
signal MAC_TX_DATA4: std_logic_vector(7 downto 0) := (others => '0');
434
signal MAC_TX_DATA4_D: std_logic_vector(7 downto 4) := (others => '0');
435
signal RETX_ATTEMPT_COUNTER: std_logic_vector(4 downto 0) := (others => '0'); -- re-transmission attempts counter
436
signal RAND: std_logic_vector(10 downto 0) := (others => '0');
437
signal RETX_RANDOM_BKOFF: std_logic_vector(9 downto 0) := (others => '0');
438
signal TX_SUCCESS: std_logic := '0';
439
signal TX_EN: std_logic := '0';
440
signal TX_ER: std_logic := '0';
441
 
442
--//  TX 32-BIT CRC COMPUTATION -------------------------------------------------------
443
signal TX_CRC32: std_logic_vector(31 downto 0) := (others => '0');
444
signal TX_CRC32_FLIPPED_INV: std_logic_vector(31 downto 0) := (others => '0');
445
signal TX_CRC32_RESET: std_logic := '0';
446
signal TX_FCS: std_logic_vector(7 downto 0) := (others => '0');
447
signal MAC_TX_SAMPLE3_CLK: std_logic := '0';
448
signal MAC_TX_DATA3: std_logic_vector(7 downto 0) := (others => '0');
449
 
450
--// MAC RX STATE MACHINE ----------------------------------------------------------
451
signal RX_CLKG: std_logic := '0';
452
signal RX_STATE: integer range 0 to 15 := 0;
453
signal RX_EVENT1: std_logic := '0';
454
--signal RX_EVENT2: std_logic := '0';
455
signal RX_EVENT3: std_logic := '0';
456
signal RX_EVENT4: std_logic := '0';
457
signal RX_EVENT5: std_logic := '0';
458
signal RX_BYTE_COUNTER: std_logic_vector(18 downto 0);  -- large enough for counting 2000 bytes in max size packet
459
signal RX_BYTE_COUNTER_INC: std_logic_vector(18 downto 0);  -- large enough for counting 2000 bytes in max size packet
460
signal RX_TOO_SHORT: std_logic := '0';
461
signal RX_TOO_LONG: std_logic := '0';
462
signal RX_VALID_ADDR: std_logic := '0';
463
signal RX_LENGTH_ERR: std_logic := '0';
464
signal LAST6B: std_logic_vector(47 downto 0) := (others => '0');
465
signal RX_LENGTH: std_logic_vector(10 downto 0) := (others => '0');
466
signal RX_LENGTH_TYPEN: std_logic := '0';
467
signal RX_DIFF: std_logic_vector(11 downto 0) := (others => '0');
468
signal MAC_RXD_D: std_logic_vector(7 downto 0) := (others => '0');
469
signal MAC_RX_SAMPLE2_CLK: std_logic := '0';
470
 
471
--//  RX 32-BIT CRC COMPUTATION -------------------------------------------------------
472
signal RX_CRC32_RESET: std_logic := '0';
473
signal RX_CRC32: std_logic_vector(31 downto 0) := (others => '0');
474
signal RX_CRC32_VALID: std_logic := '0';
475
signal RX_BAD_CRC: std_logic := '0';
476
 
477
--// PARSE RX DATA -------------------------------------------------------------------
478
signal MAC_RXD3: std_logic_vector(7 downto 0);
479
signal MAC_RX_SAMPLE3_CLK: std_logic := '0';
480
--signal MAC_RX_SOF3: std_logic := '0';
481
signal MAC_RX_EOF3A: std_logic := '0';
482
signal MAC_RX_EOF3B: std_logic := '0';
483
signal MAC_RX_EOF3B_D: std_logic := '0';
484
signal MAC_RX_EOF3: std_logic := '0';
485
signal RX_FRAME_EN3: std_logic := '0';
486
 
487
--//  RX INPUT ELASTIC BUFFER ----------------------------------------------------------
488
signal MAC_RX_DIPA: std_logic_vector(0 downto 0);
489
signal MAC_RX_DOPB: std_logic_vector(0 downto 0);
490
signal MAC_RX_WPTR: std_logic_vector(10 downto 0);
491
signal MAC_RX_WPTR_D: std_logic_vector(10 downto 0);
492
signal MAC_RX_WPTR_D2: std_logic_vector(10 downto 0);
493
signal MAC_RX_WPTR_D3: std_logic_vector(10 downto 0);
494
signal MAC_RX_WPTR_CONFIRMED: std_logic_vector(10 downto 0) := (others => '0');
495
signal MAC_RX_WPTR_STABLE: std_logic := '0';
496
signal MAC_RX_WPTR_STABLE_D: std_logic := '0';
497
signal RX_COUNTER8: std_logic_vector(2 downto 0) := "000";
498
signal MAC_RX_RPTR: std_logic_vector(10 downto 0);
499
signal MAC_RXD4: std_logic_vector(7 downto 0);
500
signal MAC_RX_SAMPLE4_CLK: std_logic := '0';
501
signal MAC_RX_SAMPLE4_CLK_E: std_logic := '0';
502
signal MAC_RX_EOF4: std_logic := '0';
503
signal MAC_RX_BUF_SIZE: std_logic_vector(10 downto 0);
504
signal MAC_RX_EOF4_FLAG: std_logic := '1';
505
 
506
signal PHY_CONFIG_TP: std_logic_vector(10 downto 1);
507
 
508
 
509
--------------------------------------------------------
510
--      IMPLEMENTATION
511
--------------------------------------------------------
512
begin
513
 
514
 
515
-- PHY-supplied RX global clock
516
RECLOCK_003: process(ASYNC_RESET, RX_CLKG)
517
begin
518
        if rising_edge(RX_CLKG) then
519
                RESETRX_FLAG_D <= ASYNC_RESET;
520
                RESETRX_FLAG_D2 <= RESETRX_FLAG_D;
521
 
522
                -- 1-CLK clock synchronous reset pulse at the end of the async pulse
523
                if(RESETRX_FLAG_D = '0') and (RESETRX_FLAG_D2 = '1') then
524
                        -- end of external reset pulse. generate a CLK synchronous reset
525
                        SYNC_RESETRX <= '1';
526
                else
527
                        SYNC_RESETRX <= '0';
528
                end if;
529
        end if;
530
end process;
531
 
532
 
533
--// PHY RESET AND CONFIGURATION ----------------------------------------------------------
534
-- First generate a RESET_N pulse 10ms long, then wait 50ms before programming the PHY
535
-- We cannot assume that the 125 MHz reference clock is present. 
536
 
537
-- convert ASYNC_RESET to a CLK-synchronous RESET pulse
538
RECLOCK_002: process(ASYNC_RESET, CLK)
539
begin
540
        if rising_edge(CLK) then
541
                RESETFLAG_D <= ASYNC_RESET;
542
                RESETFLAG_D2 <= RESETFLAG_D;
543
 
544
                -- 1-CLK clock synchronous reset pulse at the end of the async pulse
545
                if(RESETFLAG_D = '0') and (RESETFLAG_D2 = '1') then
546
                        -- end of external reset pulse. generate a CLK synchronous reset
547
                        SYNC_RESET <= '1';
548
                else
549
                        SYNC_RESET <= '0';
550
                end if;
551
        end if;
552
end process;
553
 
554
-- PHY reset at power up or SYNC_RESET
555
-- Generates a 10ms RESET_N pulse followed by a TBD ms delay and a INITIAL_CONFIG_PULSE.
556
-- The delay between RESET_N de-assertion and config pulse is 50ms (conservative. It takes time for PHY to configure.
557
-- even though the specs states 100us is sufficient, we find that 40ms min is needed).
558
Inst_RESET_TIMER: RESET_TIMER
559
GENERIC MAP(
560
        CLK_FREQUENCY => CLK_FREQUENCY  -- user clock frequency in MHz
561
)
562
PORT MAP(
563
        CLK => CLK,     -- user clock, always present
564
        RESET_START => SYNC_RESET,
565
        RESET_COMPLETE => RESET_COMPLETE,
566
        INITIAL_CONFIG_PULSE => INITIAL_CONFIG_PULSE,  -- config pulse 50ms after RESET_N deassertion
567
        RESET_N => RESET_N_LOCAL
568
);
569
 
570
RESET_N <= RESET_N_LOCAL;
571
 
572
--
573
---- enact the configuration
574
PHY_CONFIG_CHANGE_001: process(CLK)
575
begin
576
        if rising_edge(CLK) then
577
                if(INITIAL_CONFIG_PULSE = '1') then
578
                        -- A default configuration is loaded automatically after power up. 
579
                        PHY_CONFIG_CHANGE_A <= '1';
580
                        PHY_RESET_A <= '0';      -- no software PHY reset, we just did a hardware reset
581
                        SPEED_A <= "11";                -- auto
582
                        DUPLEX_A <= '1';
583
                        TEST_MODE_A <= "00";
584
                        POWER_DOWN_A <= '0';
585
                elsif(PHY_CONFIG_CHANGE = '1') then
586
                        -- PHY_CONFIG_CHANGE indicates a user-triggered configuration change.
587
                        PHY_CONFIG_CHANGE_A <= '1';
588
                        PHY_RESET_A <= PHY_RESET;
589
                        SPEED_A <= SPEED;
590
                        DUPLEX_A <= DUPLEX;
591
                        TEST_MODE_A <= TEST_MODE;
592
                        POWER_DOWN_A <= POWER_DOWN;
593
                else
594
                        PHY_CONFIG_CHANGE_A <= '0';
595
                end if;
596
        end if;
597
end process;
598
 
599
 
600
-- PHY monitoring and control
601
Inst_PHY_CONFIG: PHY_CONFIG
602
GENERIC MAP(
603
        PHY_ADDR => PHY_ADDR
604
)
605
PORT MAP(
606
        SYNC_RESET => SYNC_RESET,
607
        CLK => CLK,
608
        CONFIG_CHANGE => PHY_CONFIG_CHANGE_A,
609
        PHY_RESET => PHY_RESET_A,
610
        SPEED => SPEED_A,
611
        DUPLEX => DUPLEX_A,
612
        TEST_MODE => TEST_MODE_A,
613
        POWER_DOWN => POWER_DOWN_A,
614
        CLK_SKEW => CLK_SKEW_A,
615
        SREG_READ_START => SREG_READ_START,
616
        SREG_REGAD => "000000010",      -- register 2: PHY Identifier 1
617
        SREG_DATA => PHY_ID_LOCAL,
618
        SREG_SAMPLE_CLK => SREG_SAMPLE_CLK,
619
        LINK_STATUS => LINK_STATUS_local,
620
        MCLK => MCLK,
621
        MDI => MDI,
622
        MDO => MDO,
623
        MDT => MDT
624
        );
625
PHY_ID <= PHY_ID_LOCAL;
626
 
627
---- tri-state MDIO port
628
--IOBUF_inst : IOBUF
629
--generic map (
630
--      DRIVE => 12,
631
--      IOSTANDARD => "DEFAULT",
632
--      SLEW => "SLOW")
633
--port map (
634
--      O => MDI,     -- Buffer output
635
--      IO => MDIO,   -- Buffer inout port (connect directly to top-level port)
636
--      I => MDO,     -- Buffer input
637
--      T => MDT      -- 3-state enable input, high=input, low=output 
638
--);
639
 
640
 
641
-- read PHY identification once at power-up or reset (hardware self-test)
642
PHY_STATUS_001: process(CLK)
643
begin
644
        if rising_edge(CLK) then
645
                if(PHY_CONFIG_CHANGE_A = '1') then      -- power-up/reset
646
                        SREG_READ_START <= '1';                         -- start asking for status register
647
                elsif(SREG_SAMPLE_CLK = '1') then
648
                        SREG_READ_START <= '0';
649
                end if;
650
        end if;
651
end process;
652
--//  PHY INTERFACE: RGMII FORMATTING ----------------------------------------------------------
653
 
654
-- Translation RGMII (PHY interface) - GMII (MAC interface)
655
-- Adjust the TXC and RXC clock 2ns delays within as needed.
656
PHY_IF_WRAPPER_RESET <= SYNC_RESETRX;
657
 
658
LINK_STATUS <= LINK_STATUS_local;
659
DUPLEX_STATUS <= DUPLEX_STATUS_local;
660
SPEED_STATUS <= SPEED_STATUS_LOCAL;
661
 
662
--//  PHY INTERFACE: GMII/MII FORMATTING ----------------------------------------------------------
663
-- TODO: make tx clk the same as rx clk (same RGMII_WRAPPER).
664
        Inst_GMII_MII_WRAPPER: GMII_MII_WRAPPER_V6 PORT MAP(
665
                SYNC_RESET => PHY_IF_WRAPPER_RESET,
666
                CLK => CLK,
667
                IDELAYREFCLK200MHZ => IDELAYREFCLK200MHZ,
668
                TX_CLK => MII_TX_CLK,  -- MII tx clock from PHY
669
                GTX_CLK => GMII_TX_CLK, -- GMII tx clock to PHY
670
                TXD => GMII_MII_TXD,
671
                TX_EN => GMII_MII_TX_EN,
672
                TX_ER => GMII_MII_TX_ER,
673
                RX_CLK => GMII_MII_RX_CLK,
674
                RXD => GMII_MII_RXD,
675
                RX_DV => GMII_MII_RX_DV,
676
                RX_ER => GMII_MII_RX_ER,
677
                CRS => GMII_MII_CRS,
678
                COL => GMII_MII_COL,
679
                MAC_RX_CLK => RX_CLKG,
680
                MAC_RXD => MAC_RXD0,
681
                MAC_RX_DV => MAC_RX_DV0,
682
                MAC_RX_ER => MAC_RX_ER0,
683
                MAC_RX_SAMPLE_CLK => MAC_RX_SAMPLE_CLK0,
684
                MAC_TXD => MAC_TXD,
685
                MAC_TX_EN => MAC_TX_EN,
686
                MAC_TX_ER => MAC_TX_ER,
687
                MAC_TX_SAMPLE_CLK => MAC_TX_SAMPLE_CLK,
688
                MAC_TX_SPEED => TX_SPEED,
689
                MAC_CRS => CRS,
690
                MAC_COL => COL,
691
                LINK_STATUS => open,--LINK_STATUS_local,
692
                SPEED_STATUS => SPEED_STATUS_LOCAL,
693
                DUPLEX_STATUS => DUPLEX_STATUS_local
694
        );
695
 
696
        -- Vodoo code (Isim simulator is confused otherwise). Reclock RX signals.
697
        -- My guess: simulator does not like the BUFG or delay within the GMII_MII_WRAPPER.
698
        -- Small penalty: just a few Flip Flops. 
699
        RX_RECLOCK_001: process(RX_CLKG)
700
        begin
701
                if rising_edge(RX_CLKG) then
702
                        MAC_RXD <= MAC_RXD0;
703
                        MAC_RX_DV <= MAC_RX_DV0;
704
                        MAC_RX_ER <= MAC_RX_ER0;
705
                        MAC_RX_SAMPLE_CLK <= MAC_RX_SAMPLE_CLK0;
706
                end if;
707
        end process;
708
 
709
--//  TX ELASTIC BUFFER ----------------------------------------------------------
710
-- The purpose of the elastic buffer is two-fold:
711
-- (a) a transition between the CLK-synchronous user side, and the RX_CLKG synchronous PHY side
712
-- (b) storage for Ethernet transmit frames, to absorb traffic peaks, minimize the number of 
713
-- UDP packets lost at high throughput.
714
-- The tx elastic buffer is 16Kbits, large enough for TWO complete maximum size 
715
-- (14addr+1500data+4FCS = 1518B) frames.
716
 
717
-- write pointer management
718
MAC_TX_WPTR_001: process(ASYNC_RESET, CLK)
719
begin
720
        if(ASYNC_RESET = '1') then
721
                MAC_TX_WPTR <= (others => '0');
722
        elsif rising_edge(CLK) then
723
                TX_COUNTER8 <= TX_COUNTER8 + 1;
724
 
725
                if (SYNC_RESET = '1') then
726
                        MAC_TX_WPTR <= (others => '0');
727
                elsif(MAC_TX_DATA_VALID = '1') then
728
                        MAC_TX_WPTR <= MAC_TX_WPTR + 1;
729
                end if;
730
 
731
                -- update WPTR_D once every 8 clocks.
732
                if(TX_COUNTER8 = 7) then
733
                        MAC_TX_WPTR_D <= MAC_TX_WPTR;
734
                end if;
735
 
736
                -- allow WPTR reclocking with another clock, as long as it is away from the transition area
737
                if(TX_COUNTER8 < 6) then
738
                        MAC_TX_WPTR_STABLE <= '1';
739
                else
740
                        MAC_TX_WPTR_STABLE <= '0';
741
                end if;
742
 
743
 
744
        end if;
745
end process;
746
 
747
MAC_TX_DIPA(0) <= MAC_TX_EOF;  -- indicates last byte in the tx packet
748
 
749
-- select which RAMBlock to write to.
750
MAC_TX_WEA(0) <= MAC_TX_DATA_VALID and (not MAC_TX_WPTR(11));
751
MAC_TX_WEA(1) <= MAC_TX_DATA_VALID and MAC_TX_WPTR(11);
752
 
753
-- No need for initialization
754
RAMB16_X: for I in 0 to 1 generate
755
        RAMB16_001: RAMB16_S9_S9
756
        port map(
757
                DIA => MAC_TX_DATA,
758
                DIB => x"00",
759
                DIPA => MAC_TX_DIPA(0 downto 0),
760
                DIPB => "0",
761
                DOPA => open,
762
                DOPB => MAC_TX_DOPB(I)(0 downto 0),
763
                ENA => '1',
764
                ENB => '1',
765
                WEA => MAC_TX_WEA(I),
766
                WEB => '0',
767
                SSRA => '0',
768
                SSRB => '0',
769
                CLKA => CLK,
770
                CLKB => RX_CLKG,
771
                ADDRA => MAC_TX_WPTR(10 downto 0),
772
                ADDRB => MAC_TX_RPTR(10 downto 0),
773
                DOA => open,
774
                DOB => MAC_TX_DOB(I)
775
        );
776
end generate;
777
 
778
MAC_TX_DATA2 <= MAC_TX_DOB(conv_integer(MAC_TX_RPTR_D(11)));
779
MAC_TX_EOF2 <= MAC_TX_DOPB(conv_integer(MAC_TX_RPTR_D(11)))(0);
780
 
781
-- RX_CLKG zone. Reclock WPTR
782
MAC_TX_WPTR_002: process(RX_CLKG)
783
begin
784
        if rising_edge(RX_CLKG) then
785
                MAC_TX_WPTR_STABLE_D <= MAC_TX_WPTR_STABLE;
786
                MAC_TX_WPTR_D2 <= MAC_TX_WPTR_D;
787
 
788
                if(MAC_TX_WPTR_STABLE_D = '1') then
789
                        -- WPTR is stable. OK to resample with the RX_CLKG clock.
790
                        MAC_TX_WPTR_D3 <= MAC_TX_WPTR_D2;
791
                end if;
792
        end if;
793
end process;
794
 
795
MAC_TX_BUF_SIZE <= MAC_TX_WPTR_D3 + not(MAC_TX_RPTR);
796
-- occupied tx buffer size for reading purposes (CLKG clock domain)(
797
-- always lags, could be a bit more, never less.
798
 
799
--//-- TX FLOW CONTROL --------------------------------
800
-- ask for more input data if there is room for at least 1K more input bytes
801
-- Never write past the last confirmed read pointer location.
802
 
803
-- read the last confirmed read pointer location and reclock in CLK domain when stable
804
MAC_TX_CTS_001: process(CLK)
805
begin
806
        if rising_edge(CLK) then
807
                TX_SUCCESS_TOGGLE_D <= TX_SUCCESS_TOGGLE;
808
                TX_SUCCESS_TOGGLE_D2 <= TX_SUCCESS_TOGGLE_D;
809
                if(TX_SUCCESS_TOGGLE_D2 /= TX_SUCCESS_TOGGLE_D) then
810
                        -- shortly after successful packet transmission. 
811
                        MAC_TX_RPTR_CONFIRMED_D <= MAC_TX_RPTR_CONFIRMED;
812
                end if;
813
        end if;
814
end process;
815
 
816
-- Compute available room for more tx data
817
MAC_TX_CTS_002: process(CLK)
818
begin
819
        if rising_edge(CLK) then
820
                MAC_TX_BUF_FREE <= not (MAC_TX_WPTR_D2 + not MAC_TX_RPTR_CONFIRMED_D);
821
        end if;
822
end process;
823
-- Is there enough room for a complete max size frame?
824
-- Don't cut it too close because user interface can flood the buffer very quickly (CLK @ 125 MHz clock)
825
-- while we compute the buffer size with the possibly much slower RX_CLG (could be 2.5 MHz for 10Mbps).
826
MAC_TX_CTS_003: process(CLK)
827
begin
828
        if rising_edge(CLK) then
829
                if(SYNC_RESETRX = '1') then
830
                        MAC_TX_CTS_local <= '0'; -- reset
831
                elsif(LINK_STATUS_local = '0') then
832
                        -- don't ask the stack for data if there is no link
833
                        MAC_TX_CTS_local <= '0'; -- reset
834
                elsif(MAC_TX_BUF_FREE(11) = '0') then
835
                        -- room for less than 2KB. Activate flow control
836
                        MAC_TX_CTS_local <= '0';
837
                else
838
                        MAC_TX_CTS_local <= '1';
839
                end if;
840
        end if;
841
end process;
842
MAC_TX_CTS <=  LINK_STATUS_local;--LINK_STATUS_local;--MAC_TX_CTS_local;
843
 
844
 
845
-- manage read pointer
846
MAC_TX_RPTR_001: process(ASYNC_RESET, RX_CLKG)
847
begin
848
        if(ASYNC_RESET = '1') then
849
                MAC_TX_RPTR <= (others => '1');
850
                MAC_TX_RPTR_D <= (others => '1');
851
        elsif rising_edge(RX_CLKG) then
852
                MAC_TX_RPTR_D <= MAC_TX_RPTR;
853
 
854
                if(TX_STATE = 2) and (TX_BYTE_CLK = '1') and (MAC_TX_EOF2 = '1') then
855
                        -- special case. Immediately block output sample clk because we have just read past the end of 
856
                        -- packet (nothing we could do about it).
857
                        MAC_TX_SAMPLE2_CLK <= '0';
858
                else
859
                        -- regular case:  1 clk delay to extract data from ramb.
860
                        -- aligned with MAC_TX_DATA2 byte.
861
                        MAC_TX_SAMPLE2_CLK <= MAC_TX_SAMPLE2_CLK_E;
862
                end if;
863
 
864
                if(SYNC_RESETRX = '1') then
865
                        MAC_TX_RPTR <= (others => '1');
866
                elsif(TX_STATE = 1) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(2 downto 0) <= 1) then
867
                        -- read the first byte(s) in advance (need 2 RX_CLKG to get the data out)
868
                        -- Note: we may temporarily read past the write pointer (by one location) 
869
                        -- but will rewind immediately thereafter
870
                        MAC_TX_SAMPLE2_CLK_E <= '1';
871
                        MAC_TX_RPTR <= MAC_TX_RPTR + 1;
872
                elsif(TX_STATE = 2) and (TX_EVENT3 = '1') then
873
                        -- we are done reading the packet. rewind the read pointer, as we went past the end of packet.
874
                        MAC_TX_SAMPLE2_CLK_E <= '0';
875
                        MAC_TX_RPTR <= MAC_TX_RPTR - 1;
876
                elsif(TX_STATE = 2) and (TX_BYTE_CLK = '1') then
877
                        -- read the rest of the packet
878
                        -- forward data from input elastic buffer to RGMII interface
879
                        -- Note: we may temporarily read past the write pointer (by one location) 
880
                        -- but will rewind immediately thereafter
881
                        MAC_TX_SAMPLE2_CLK_E <= '1';
882
                        MAC_TX_RPTR <= MAC_TX_RPTR + 1;
883
                elsif(TX_STATE = 6) then
884
                        -- collision detected. rewind read pointer to the start of frame.
885
                        MAC_TX_RPTR <= MAC_TX_RPTR_CONFIRMED;
886
                else
887
                        MAC_TX_SAMPLE2_CLK_E <= '0';
888
                end if;
889
        end if;
890
end process;
891
 
892
-- update confirmed read pointer after successful frame transmission
893
MAC_TX_RPTR_002: process(RX_CLKG)
894
begin
895
        if rising_edge(RX_CLKG) then
896
                if(SYNC_RESETRX = '1') then
897
                        MAC_TX_RPTR_CONFIRMED <= (others => '1');
898
                        TX_SUCCESS_TOGGLE <= '0';
899
                elsif(TX_SUCCESS = '1') then
900
                        MAC_TX_RPTR_CONFIRMED <= MAC_TX_RPTR;
901
                        TX_SUCCESS_TOGGLE <= not TX_SUCCESS_TOGGLE;
902
                end if;
903
        end if;
904
end process;
905
 
906
-- How many COMPLETE tx frames are available for transmission in the input elastic buffer?
907
-- Transmission is triggered by the availability of a COMPLETE frame in the buffer (not just a few frame bytes)
908
-- It is therefore important to keep track of the number of complete frames.
909
-- At the elastic buffer input, a new complete frame is detected upon receiving the EOF pulse.
910
COMPLETE_TX_FRAMES_001: process(ASYNC_RESET, CLK)
911
begin
912
        if (ASYNC_RESET = '1') then
913
                MAC_TX_EOF_TOGGLE <= '0';
914
        elsif rising_edge(CLK) then
915
                if(MAC_TX_DATA_VALID = '1') and (MAC_TX_EOF = '1') then
916
                        MAC_TX_EOF_TOGGLE <= not MAC_TX_EOF_TOGGLE;  -- Need toggle signal to generate copy in RX_CLKG clock domain
917
                end if;
918
        end if;
919
end process;
920
 
921
 
922
COMPLETE_TX_FRAMES_002: process(RX_CLKG)
923
begin
924
        if rising_edge(RX_CLKG) then
925
                MAC_TX_EOF_TOGGLE_D <= MAC_TX_EOF_TOGGLE;       -- reclock in RX_CLKG clock domain (to prevent glitches)
926
                MAC_TX_EOF_TOGGLE_D2 <= MAC_TX_EOF_TOGGLE_D;
927
 
928
                if (SYNC_RESETRX = '1') then
929
                        COMPLETE_TX_FRAMES_INBUF <= (others => '0');
930
 
931
                elsif(MAC_TX_EOF_TOGGLE_D2 /= MAC_TX_EOF_TOGGLE_D) and (TX_SUCCESS = '0') then
932
                        -- just added another complete frame into the tx buffer (while no successful transmission concurrently)
933
                        COMPLETE_TX_FRAMES_INBUF <= COMPLETE_TX_FRAMES_INBUF + 1;
934
                elsif(MAC_TX_EOF_TOGGLE_D2 = MAC_TX_EOF_TOGGLE_D) and (TX_SUCCESS = '1')
935
                                and (ATLEAST1_COMPLETE_TX_FRAME_INBUF = '1') then
936
                        -- a frame was successfully transmitted (and none was added at the very same instant)
937
                        COMPLETE_TX_FRAMES_INBUF <= COMPLETE_TX_FRAMES_INBUF - 1;
938
                end if;
939
        end if;
940
end process;
941
 
942
-- Flag to indicate at least one complete tx frame in buffer.
943
ATLEAST1_COMPLETE_TX_FRAME_INBUF <= '0' when (COMPLETE_TX_FRAMES_INBUF = 0) else '1';
944
 
945
 
946
DELAY_EOF2: process(RX_CLKG)
947
begin
948
        if rising_edge(RX_CLKG) then
949
                if(TX_BYTE_CLK = '1') then
950
                        -- delay by one byte
951
                        MAC_TX_EOF2_D <= MAC_TX_EOF2;
952
                end if;
953
        end if;
954
end process;
955
 
956
 
957
--// MAC TX STATE MACHINE ----------------------------------------------------------
958
TX_SPEED <= SPEED_STATUS_LOCAL;  -- transmit speed is as auto-negotiated by the rx PHY.
959
-- test test test simulation at various LAN speeds
960
--TX_SPEED <= "01";  
961
 
962
-- Tx timers ------------------------
963
-- Generate transmit clock. Depends on the tx_speed.
964
-- Clock is always enabled, even when not transmitting (reason: we need to be
965
-- able to convey to the RGMII wrapper when to stop, etc).
966
-- Important distinction between TX_CLK and TX_BYTE_CLK because GMII interface is 4-bit wide
967
-- for 10/100 Mbps and 8-bit wide for 1000 Mbps.
968
-- Thus, TX_BYTE_CLK is half the frequency of TX_CLK, but pulses are aligned.
969
TX_CLK_GEN_001: process(RX_CLKG)
970
begin
971
        if rising_edge(RX_CLKG) then
972
                if (SYNC_RESETRX = '1') then
973
                        TX_BYTE_CLK <= '0';
974
                        TX_HALF_BYTE_FLAG <= '0';
975
                elsif (TX_SPEED = "10") then
976
                        -- 1000 Mbps
977
                        TX_BYTE_CLK <= '1';
978
                elsif (TX_SPEED = "01") or (TX_SPEED = "00") then
979
                        -- 10/100 Mbps. 
980
                        -- divide by two to get the byte clock when 10/100 Mbps
981
                        TX_HALF_BYTE_FLAG <= not TX_HALF_BYTE_FLAG;
982
                        if(TX_HALF_BYTE_FLAG = '1') then
983
                                TX_BYTE_CLK <= '1';
984
                        else
985
                                TX_BYTE_CLK <= '0';
986
                        end if;
987
                else
988
                        TX_BYTE_CLK <= '0';
989
                end if;
990
        end if;
991
end process;
992
 
993
 
994
-- 96-bit InterPacketGap (Interframe Delay) timer
995
IPG_001: process(RX_CLKG)
996
begin
997
        if rising_edge(RX_CLKG) then
998
                if (SYNC_RESETRX = '1') then
999
                        IPG_CNTR <= (others => '0');
1000
                        CRS_D <= '0';
1001
                else
1002
                        CRS_D <= CRS;  -- reclock with RX_CLKG
1003
 
1004
                        if((CRS_D = '1') and (DUPLEX = '0')) or (TX_EN = '1') or (TX_STATE = 5) then
1005
                                -- detected passing packet (half-duplex only) or transmission is in progress 
1006
                                -- or carrier extension in progress
1007
                                -- Arm InterPacketGap timer
1008
                                IPG_CNTR <= x"0C"  ; -- 96 bits = 12 bytes  802.3 section 4.4.2
1009
                        elsif(IPG_CNTR > 0) and (TX_BYTE_CLK = '1') then
1010
                                -- after end of passing packet, decrement counter downto to zero (InterPacketGap).
1011
                                IPG_CNTR <= IPG_CNTR - 1;
1012
                        end if;
1013
                end if;
1014
        end if;
1015
end process;
1016
IPG <= '1' when (IPG_CNTR = 0) else '0';  -- '1' last passing packet was more than InterPacketGap ago. OK to start tx.
1017
 
1018
-- Events ------------------------
1019
-- First tx packet trigger
1020
TX_EVENT1 <= '0' when (ATLEAST1_COMPLETE_TX_FRAME_INBUF = '0') else -- no COMPLETE frame in tx input buffer
1021
                                 '0' when (MAC_TX_BUF_SIZE = 0) else -- no data in tx input buffer
1022
                                 '0' when (IPG = '0') else -- medium is not clear. need to wait after the InterPacketGap. Deferring on.
1023
                                 '0' when (TX_SUCCESS = '1') else  -- don't act too quickly. It takes one RX_CLKG to update the complete_tx_frame_inbuf counter.
1024
                                 '0' when (PHY_IF_WRAPPER_RESET = '1') else -- PHY/RGMII wrapper are being reset. Do not start tx.
1025
                                 TX_BYTE_CLK;  -- go ahead..start transmitting. align event pulse with TX_BYTE_CLK
1026
 
1027
-- collision detection, half-duplex mode, within the timeSlot
1028
-- Timeslot is 64 bytes for 10/100 Mbps and 512 bytes for 1000 Mbps, starting at the preamble.
1029
TX_EVENT2 <= '1' when ((COL = '1') and (DUPLEX = '0') and (TX_SPEED = "10") and (TX_BYTE_COUNTER(10 downto 0) < 503)) else
1030
                                 '1' when ((COL = '1') and (DUPLEX = '0') and (TX_SPEED(1) = '0') and (TX_BYTE_COUNTER(10 downto 0) < 55)) else
1031
                                 '0';
1032
 
1033
-- end of frame detected at tx buffer output. 
1034
-- Timing depends on the TX_SPEED (because of the delay in reading data from tx buffer output)
1035
TX_EVENT3 <= '1' when (TX_BYTE_CLK = '1') and (MAC_TX_EOF2 = '1') and (TX_SPEED = "10") else
1036
                            '1' when (TX_BYTE_CLK = '1') and (MAC_TX_EOF2_D = '1') and (TX_SPEED(1) = '0') else
1037
                                 '0';
1038
 
1039
-- Tx state machine ------------------------
1040
TX_STATE_GEN_001: process(RX_CLKG, MAC_ADDR)
1041
begin
1042
        if rising_edge(RX_CLKG) then
1043
                if (SYNC_RESETRX = '1') or (LINK_STATUS_local = '0') then
1044
                        TX_STATE <= 0;   -- idle state
1045
                        TX_SUCCESS <= '0';
1046
                        TX_BYTE_CLK_D <= '0';
1047
                        RETX_ATTEMPT_COUNTER <= (Others => '0');  -- re-transmission attempts counter
1048
                else
1049
 
1050
                        TX_BYTE_CLK_D <= TX_BYTE_CLK;  -- output byte ready one RX_CLKG later 
1051
 
1052
                        if(TX_STATE = 0) then
1053
                                TX_SUCCESS <= '0';
1054
                                RETX_ATTEMPT_COUNTER <= (Others => '0');  -- reset re-transmission attempts counter
1055
                                if (TX_EVENT1 = '1') then
1056
                                        -- start tx packet: send 1st byte of preamble
1057
                                        TX_STATE <= 1;
1058
                                        TX_BYTE_COUNTER2 <= "111"; -- 8-byte preamble + start of frame sequence
1059
                                end if;
1060
                        elsif(TX_STATE = 1) and (DUPLEX = '0') and (COL = '1')  then
1061
                                -- collision sensing while in half-duplex mode. 
1062
                                -- The packet header being transmitted is well within the slot time limit.
1063
                                TX_STATE <= 6;  -- send jam
1064
                                TX_BYTE_COUNTER2 <= "011"; -- jamSize = 32 bits = 4 Bytes
1065
                        elsif(TX_STATE = 1) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(2 downto 0) /= 0) then
1066
                                -- counting through the preamble + start frame sequence
1067
                                TX_BYTE_COUNTER2 <= TX_BYTE_COUNTER2 - 1;
1068
                        elsif(TX_STATE = 1) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(2 downto 0) = 0) then
1069
                                -- end of preamble. start forwarding data from elastic buffer to RGMII wrapper
1070
                                TX_STATE <= 2;
1071
                                TX_BYTE_COUNTER <= (others => '0');
1072
                        elsif(TX_STATE = 2) and (TX_EVENT2 = '1') then
1073
                                -- collision sensing while in half-duplex mode and within the specified slot time (starting at the preamble)
1074
                                TX_STATE <= 6;  -- send jam
1075
                                TX_BYTE_COUNTER2 <= "011"; -- jamSize = 32 bits = 4 Bytes
1076
                        elsif(TX_STATE = 2) and (TX_BYTE_CLK = '1') and (TX_EVENT3 = '0') then
1077
                                -- keep track of the payload byte count (to detect the need for padding)
1078
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1079
                        elsif(TX_STATE = 2) and (TX_BYTE_CLK = '1') and (TX_EVENT3 = '1')  then
1080
                                -- found end of frame
1081
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1082
                                if (TX_BYTE_COUNTER(10 downto 0) < 59) then
1083
                                        if (MAC_TX_CONFIG(1 downto 0) = "11") then
1084
                                                -- frame is too short: payload data does not meet minimum 60-byte size.
1085
                                                -- user enabled automatic padding and automatic CRC32 insertion
1086
                                                TX_STATE <= 3;
1087
                                        else
1088
                                                -- error: frame is too short. abort.
1089
                                                TX_STATE <= 10;
1090
                                        end if;
1091
                                elsif (MAC_TX_CONFIG(1) = '1') then
1092
                                        -- user enabled auto-CRC32 insertion. Start inserting CRC
1093
                                        TX_STATE <= 4;
1094
                                        TX_BYTE_COUNTER2 <= "011";      -- 4-byte CRC(FCS)
1095
                                elsif (TX_BYTE_COUNTER(10 downto 0) >= 63) then
1096
                                        -- complete packet (including user-supplied CRC)
1097
                                        -- Carrier Extension?  Applicable to 1000 Mbps half-duplex
1098
                                        if(TX_SPEED = "10") and (DUPLEX = '0') and (TX_BYTE_COUNTER(10 downto 0) < 511) then
1099
                                                -- Carrier extension to slotTime (512 bytes) as per 802.3 Section 4.2.3.4
1100
                                                TX_STATE <= 5;
1101
                                        else
1102
                                                -- we are done here
1103
                                                TX_STATE <= 0;
1104
                                                TX_SUCCESS <= '1'; -- completed frame transmission
1105
                                        end if;
1106
                                else
1107
                                        -- error. frame is too short (< 64 bytes including 4-byte CRC). abort.
1108
                                        TX_STATE <= 10;
1109
                                end if;
1110
                        elsif(TX_STATE = 3) and (TX_EVENT2 = '1') then
1111
                                -- collision sensing while in half-duplex mode and within the specified slot time (starting at the preamble)
1112
                                TX_STATE <= 6;  -- send jam
1113
                                TX_BYTE_COUNTER2 <= "011"; -- jamSize = 32 bits = 4 Bytes
1114
                        elsif(TX_STATE = 3) and (TX_BYTE_CLK = '1') then
1115
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1116
                                if(TX_BYTE_COUNTER(10 downto 0) < 59) then
1117
                                        -- padding payload field to the minimum size.
1118
                                        -- keep track of the byte count 
1119
                                elsif (MAC_TX_CONFIG(1) = '1') then
1120
                                        -- Completed padding. User enabled CRC32 insertion. Start inserting CRC
1121
                                        TX_STATE <= 4;
1122
                                        TX_BYTE_COUNTER2 <= "011";      -- 4-byte CRC(FCS)
1123
                                else
1124
                                        -- error. Illegal user configuration. auto-pad requires auto-CRC. abort.
1125
                                        TX_STATE <= 10;
1126
                                end if;
1127
                        elsif(TX_STATE = 4) and (TX_EVENT2 = '1') then
1128
                                -- collision sensing while in half-duplex mode and within the specified slot time (starting at the preamble)
1129
                                TX_STATE <= 6;  -- send jam
1130
                                TX_BYTE_COUNTER2 <= "011"; -- jamSize = 32 bits = 4 Bytes
1131
                        elsif(TX_STATE = 4) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) /= 0) then
1132
                                -- counting through the CRC/FCS sequence
1133
                                TX_BYTE_COUNTER2 <= TX_BYTE_COUNTER2 - 1;
1134
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1135
                        elsif(TX_STATE = 4) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) = 0) then
1136
                                -- end of CRC/FCS. Packet is now complete. 
1137
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1138
                                -- Carrier Extension?  Applicable to 1000 Mbps half-duplex
1139
                                if(TX_SPEED = "10") and (DUPLEX = '0') and (TX_BYTE_COUNTER(10 downto 0) < 511) then
1140
                                        -- Carrier extension to slotTime (512 bytes) as per 802.3 Section 4.2.3.4
1141
                                        TX_STATE <= 5;
1142
                                else
1143
                                        -- we are done here
1144
                                        TX_STATE <= 0;
1145
                                        TX_SUCCESS <= '1'; -- completed frame transmission
1146
                                end if;
1147
                        elsif(TX_STATE = 5) and (TX_EVENT2 = '1') then
1148
                                -- collision sensing while in half-duplex mode and within the specified slot time (starting at the preamble)
1149
                                TX_STATE <= 6;  -- send jam
1150
                                TX_BYTE_COUNTER2 <= "011"; -- jamSize = 32 bits = 4 Bytes
1151
                        elsif(TX_STATE = 5) and (TX_BYTE_CLK = '1') then
1152
                                -- Carrier extension
1153
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER + 1;
1154
                                if(TX_BYTE_COUNTER(10 downto 0) >= 511) then
1155
                                        -- met slotTime requirement.
1156
                                        TX_STATE <= 0;
1157
                                        TX_SUCCESS <= '1'; -- completed frame transmission
1158
                                end if;
1159
                        elsif(TX_STATE = 6) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) /= 0) then
1160
                                -- Jam . counting through the 4-byte jam
1161
                                TX_BYTE_COUNTER2 <= TX_BYTE_COUNTER2 - 1;
1162
                        elsif(TX_STATE = 6) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) = 0) then
1163
                                -- end of Jam
1164
 
1165
                                -- re-transmit?
1166
                                if(RETX_ATTEMPT_COUNTER < 16) then
1167
                                        -- we have not yet reached the attemptLimit
1168
                                        TX_STATE <= 7;  -- backoff 
1169
                                        RETX_ATTEMPT_COUNTER <= RETX_ATTEMPT_COUNTER + 1;
1170
                                        -- set backoff
1171
                                        if(TX_SPEED = "10") then
1172
                                                -- 1000 Mbps. Backoff is an integer multiple of slotTime: 
1173
                                                -- random * slotTime. slotTime = 512 Bytes
1174
                                                TX_BYTE_COUNTER(8 downto 0) <= (others => '1');
1175
                                                TX_BYTE_COUNTER(18 downto 9) <= RETX_RANDOM_BKOFF;  -- uniform random variable. range 0 - 1023
1176
                                        elsif(TX_SPEED(1) = '0') then
1177
                                                -- 10/100 Mbps. Backoff is an integer multiple of slotTime:
1178
                                                -- random * slotTime. slotTime = 64 Bytes
1179
                                                TX_BYTE_COUNTER(5 downto 0) <= (others => '1');
1180
                                                TX_BYTE_COUNTER(15  downto 6) <= RETX_RANDOM_BKOFF;  -- uniform random variable. range 0 - 1023;
1181
                                                TX_BYTE_COUNTER(18 downto 16) <= (others => '0');
1182
                                        end if;
1183
                                else
1184
                                        TX_STATE <= 10; -- error. could not transmit packet
1185
                                end if;
1186
                        elsif(TX_STATE = 7) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER /= 0) then
1187
                                -- backoff timer
1188
                                TX_BYTE_COUNTER <= TX_BYTE_COUNTER - 1;
1189
                        elsif(TX_STATE = 7) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER = 0) then
1190
                                -- backoff timer expired. try sending again
1191
                                -- start tx packet: send 1st byte of preamble
1192
                                TX_STATE <= 1;
1193
                                TX_BYTE_COUNTER2 <= "111"; -- 8-byte preamble + start of frame sequence
1194
                        end if;
1195
                end if;
1196
        end if;
1197
end process;
1198
 
1199
-- Tx packet assembly ------------------------
1200
-- generate 7-byte preamble, 1-byte start frame sequence
1201
-- TX_PREAMBLE is aligned with TX_BYTE_CLK_D
1202
PREAMBLE_GEN_001: process(RX_CLKG)
1203
begin
1204
        if rising_edge(RX_CLKG) then
1205
                if(TX_STATE = 1) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(2 downto 0) = 1) then
1206
                        TX_PREAMBLE <= "11010101";  -- start frame delimiter (SFD). 
1207
                        -- [note: standard shows LSb D0 to the left, MSb D7 to the right, as per serial transmission sequence.]
1208
                elsif(TX_BYTE_CLK = '1') then
1209
                        -- new packet or re-transmission
1210
                        TX_PREAMBLE <= "01010101";  -- preamble
1211
                        -- [note: standard shows LSb to the left, MSb to the right, as per serial transmission sequence.]
1212
                end if;
1213
        end if;
1214
end process;
1215
 
1216
-- mux 4-byte frame check sequence
1217
-- TX_FCS is aligned with TX_BYTE_CLK_D
1218
FCS_GEN_001: process(RX_CLKG)
1219
begin
1220
        if rising_edge(RX_CLKG) then
1221
                -- send MSB first (802.11 Section 3.2.9).
1222
                -- Don't have time to reclock TX_CRC32_FLIPPED_INV(31 downto 24): will be muxed without reclocking.
1223
                if(TX_STATE = 4) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) = 3) then
1224
                        TX_FCS <= TX_CRC32_FLIPPED_INV(23 downto 16);
1225
                elsif(TX_STATE = 4) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) = 2) then
1226
                        TX_FCS <= TX_CRC32_FLIPPED_INV(15 downto 8);
1227
                elsif(TX_STATE = 4) and (TX_BYTE_CLK = '1') and (TX_BYTE_COUNTER2(1 downto 0) = 1) then
1228
                        TX_FCS <= TX_CRC32_FLIPPED_INV(7 downto 0);
1229
                end if;
1230
        end if;
1231
end process;
1232
 
1233
 
1234
TX_EN <= '0' when (TX_STATE = 0) else  -- idle
1235
                        '1' when (TX_STATE < 5) else  -- normal transmission
1236
                        '1' when (TX_STATE = 6) else  -- 32-bit jam after collision detection
1237
                        '0';
1238
 
1239
TX_ER <= '1' when (TX_STATE = 5) else  -- carrier extension
1240
                        '0';
1241
 
1242
-- mux preamble, start frame sequence, data, fcs, etc and forward to GMII tx interface
1243
-- MAC_TX_DATA4 is aligned with TX_BYTE_CLK_D
1244
TX_MUX_001: process(TX_STATE, TX_BYTE_COUNTER2, TX_PREAMBLE, MAC_TX_DATA2, TX_CRC32_FLIPPED_INV, TX_FCS)
1245
begin
1246
        if(TX_STATE = 1) then
1247
                -- 7-byte preamble and 1-byte start frame sequence
1248
                MAC_TX_DATA4 <= TX_PREAMBLE;
1249
        elsif(TX_STATE = 2) then
1250
                -- payload data
1251
                MAC_TX_DATA4 <= MAC_TX_DATA2;
1252
        elsif(TX_STATE = 3) then
1253
                -- padding
1254
                MAC_TX_DATA4 <= x"00";  -- padding with zeros.
1255
        elsif(TX_STATE = 4) and (TX_BYTE_COUNTER2(1 downto 0) = 3) then
1256
                -- Frame Check Sequence
1257
                MAC_TX_DATA4 <= TX_CRC32_FLIPPED_INV(31 downto 24);     -- no time to reclock. need it now
1258
        elsif(TX_STATE = 4) and (TX_BYTE_COUNTER2(1 downto 0) < 3) then
1259
                -- Frame Check Sequence
1260
                MAC_TX_DATA4 <= TX_FCS;
1261
        elsif(TX_STATE = 5) then
1262
                -- carrier extend
1263
                MAC_TX_DATA4 <= x"0F";
1264
        else
1265
        -- TODO tail end
1266
                MAC_TX_DATA4 <= x"00";
1267
        end if;
1268
end process;
1269
 
1270
MAC_TX_SAMPLE4_CLK <= TX_BYTE_CLK_D when (TX_STATE /= 0) else '0';
1271
 
1272
-- signal conditioning for the TX GMII interface
1273
GMII_TX_GEN: process(RX_CLKG)
1274
begin
1275
        if rising_edge(RX_CLKG) then
1276
                if (SYNC_RESETRX = '1') then
1277
                        MAC_TXD <= (others => '0');
1278
                        MAC_TX_EN <= '0';
1279
                        MAC_TX_ER <= '0';
1280
                        MAC_TX_SAMPLE_CLK <= '0';
1281
                        MAC_TX_DATA4_D <= (others => '0');
1282
                elsif(TX_BYTE_CLK_D = '1') then
1283
                        MAC_TXD <= MAC_TX_DATA4;
1284
                        MAC_TX_EN <= TX_EN;
1285
                        MAC_TX_ER <= TX_ER;
1286
                        MAC_TX_SAMPLE_CLK <= '1';
1287
                else
1288
                        MAC_TX_SAMPLE_CLK <= '0';
1289
                end if;
1290
        end if;
1291
end process;
1292
 
1293
 
1294
-- Tx random backoff ------------------------
1295
-- Use LFSR11 as generator of a uniform random distribution of numbers between 0 and 2047
1296
Inst_LFSR11C: LFSR11C PORT MAP(
1297
        ASYNC_RESET => '0',
1298
        CLK => RX_CLKG,
1299
        BIT_CLK_REQ => TX_BYTE_CLK,     -- keep generating new random number
1300
        SYNC_RESET => SYNC_RESETRX,
1301
        SEED => "00000000001",
1302
        LFSR_BIT => open,
1303
        BIT_CLK_OUT => open,
1304
        SOF_OUT => open,
1305
        LFSR_REG_OUT => RAND
1306
);
1307
 
1308
 
1309
 
1310
-- limit the random number range depending on the number of transmission attempts
1311
-- see 802.3 standard section 4.2.3.2.5 for details.
1312
RETX_RAND_BKOFF_GEN: process(RAND, RETX_ATTEMPT_COUNTER)
1313
begin
1314
        case RETX_ATTEMPT_COUNTER is
1315
                when "00000" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000000001";  -- first attempt: r = 0,1       
1316
                when "00001" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000000011";  -- second attempt: r = 0-3
1317
                when "00010" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000000111";  -- third attempt: r = 0-7       
1318
                when "00011" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000001111";  -- etc  
1319
                when "00100" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000011111";
1320
                when "00101" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0000111111";
1321
                when "00110" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0001111111";
1322
                when "00111" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0011111111";
1323
                when "01000" => RETX_RANDOM_BKOFF <= RAND(9 downto 0) and "0111111111";
1324
                when others => RETX_RANDOM_BKOFF <= RAND(9 downto 0);   -- cap range to r = 0-1023       
1325
        end case;
1326
end process;
1327
 
1328
 
1329
--//  TX 32-BIT CRC COMPUTATION -------------------------------------------------------
1330
-- 802.3 section 3.2.9: 
1331
-- protected fields: payload data + padding (excludes preamble and start of frame sequence)
1332
MAC_TX_DATA3 <= MAC_TX_DATA2 when (TX_STATE = 2) else x"00";  -- padding with zeros
1333
MAC_TX_SAMPLE3_CLK <= TX_BYTE_CLK_D when ((TX_STATE = 2) or (TX_STATE = 3)) else '0';
1334
 
1335
TX_CRC32_RESET <= '1' when (TX_STATE = 1) else '0';  -- reset CRC2 during the packet preamble (covers the re-transmission case)
1336
 
1337
-- latency 1 RX_CLKG
1338
TX_CRC32_8B: CRC32_8B PORT MAP(
1339
        SYNC_RESET => TX_CRC32_RESET,
1340
        CLK => RX_CLKG,
1341
        CRC32_IN => TX_CRC32,  -- feedback previous iteration
1342
        DATA_IN => MAC_TX_DATA3,
1343
        SAMPLE_CLK_IN => MAC_TX_SAMPLE3_CLK,
1344
        CRC32_OUT => TX_CRC32,
1345
        CRC32_VALID => open
1346
);
1347
 
1348
-- flip LSb<->MSb and invert
1349
TX_CRC32_002: process(TX_CRC32)
1350
begin
1351
        for I in 0 to 7 loop
1352
                TX_CRC32_FLIPPED_INV(I) <= not TX_CRC32(7 - I);
1353
                TX_CRC32_FLIPPED_INV(I + 8) <= not TX_CRC32(15 - I);
1354
                TX_CRC32_FLIPPED_INV(I + 16) <= not TX_CRC32(23 - I);
1355
                TX_CRC32_FLIPPED_INV(I + 24) <= not TX_CRC32(31 - I);
1356
        end loop;
1357
end process;
1358
 
1359
--// MAC RX STATE MACHINE ----------------------------------------------------------
1360
-- remember the last rx byte
1361
RX_DELAY_001: process(RX_CLKG)
1362
begin
1363
        if rising_edge(RX_CLKG) then
1364
                if (MAC_RX_SAMPLE_CLK = '1') then
1365
                        MAC_RXD_D <= MAC_RXD;
1366
                end if;
1367
        end if;
1368
end process;
1369
 
1370
 
1371
-- Rx events ------------------------
1372
-- new packet. RX_DV is asserted and detected start of frame delimiter (SFD)
1373
RX_EVENT1 <= '1' when (MAC_RX_SAMPLE_CLK = '1') and (MAC_RX_DV = '1') and (MAC_RX_ER = '0')
1374
                                                        and (MAC_RXD_D = x"D5")  else '0';
1375
-- false carrier indication  (TODO: what for???)  xE for 10/1000, x0E for 1000 Mbps
1376
--RX_EVENT2 <= '1' when (MAC_RX_SAMPLE_CLK = '1') and (MAC_RX_DV = '0') and (MAC_RX_ER = '1') 
1377
--                                                      and (MAC_RXD(3 downto 0) = x"E")  else '0';     
1378
 
1379
-- end of frame delimiter
1380
RX_EVENT3 <= '1' when (MAC_RX_SAMPLE_CLK = '1') and (MAC_RX_DV = '0') else
1381
                                 '0';
1382
 
1383
-- valid frame byte (data, padding, crc)
1384
RX_EVENT4 <= '1' when (MAC_RX_SAMPLE_CLK = '1') and (MAC_RX_DV = '1') and (MAC_RX_ER = '0') else
1385
                                 '0';
1386
 
1387
-- frame complete, all checks complete
1388
RX_EVENT5 <= MAC_RX_EOF3B_D;
1389
 
1390
 
1391
 
1392
-- Rx state machine ------------------------
1393
RX_BYTE_COUNTER_INC <= RX_BYTE_COUNTER + 1;
1394
 
1395
RX_STATE_GEN_001: process(RX_CLKG)
1396
begin
1397
        if rising_edge(RX_CLKG) then
1398
                if (SYNC_RESETRX = '1') then
1399
                        RX_STATE <= 0;
1400
                elsif(RX_STATE = 0) and (RX_EVENT1 = '1') then
1401
                        -- RX_DV is asserted and detected start of frame delimiter (SFD)
1402
                        -- Note: the preamble could be full, partial or entirely missing.
1403
                        RX_STATE <= 1;
1404
                        RX_BYTE_COUNTER <= (others => '0');
1405
                elsif(RX_STATE = 1) and (RX_EVENT3 = '1') then
1406
                        -- end of frame delimiter
1407
                        RX_STATE <= 2;
1408
                elsif(RX_STATE = 1) and (RX_EVENT4 = '1') then
1409
                        -- count bytes within frame
1410
                        RX_BYTE_COUNTER <= RX_BYTE_COUNTER_INC;
1411
                        -- shift-in the last 6 bytes (efficient when decoding address field or length/type field)
1412
                        -- MSB (47 downto 40) is received first.
1413
                        LAST6B(47 downto 8) <= LAST6B(39 downto 0);
1414
                        LAST6B(7 downto 0) <= MAC_RXD_D;
1415
                elsif(RX_STATE = 2) and (RX_EVENT5 = '1') then
1416
                        -- frame complete, all checks complete
1417
                        RX_STATE <= 0;
1418
                end if;
1419
        end if;
1420
end process;
1421
 
1422
-- Assess whether rx frame is too short (collision) or too long?
1423
-- ready at RX_STATE 2
1424
RX_TOO_SHORT_GEN: process(RX_CLKG)
1425
begin
1426
        if rising_edge(RX_CLKG) then
1427
                if(RX_STATE = 1) and (RX_EVENT3 = '1') then
1428
                        -- end of frame delimiter
1429
                        if(RX_BYTE_COUNTER_INC(18 downto 6) = 0) then  -- < 64 bytes
1430
                                -- too short 6+6+2+46+4 = 64
1431
                                RX_TOO_SHORT <= '1';
1432
                                RX_TOO_LONG <= '0';
1433
                        elsif(RX_BYTE_COUNTER_INC(18 downto 11) /= 0) or
1434
                                (RX_BYTE_COUNTER_INC(10 downto 0)> 1518) then  -- > 1518 bytes
1435
                                -- too long. 6+6+2+1500+4 = 1418
1436
                                RX_TOO_SHORT <= '0';
1437
                                RX_TOO_LONG <= '1';
1438
                        else
1439
                                RX_TOO_SHORT <= '0';
1440
                                RX_TOO_LONG <= '0';
1441
                        end if;
1442
                end if;
1443
        end if;
1444
end process;
1445
 
1446
-- Destination address check
1447
ADDR_CHECK_GEN: process(RX_CLKG, MAC_RX_CONFIG, MAC_ADDR)
1448
begin
1449
        if rising_edge(RX_CLKG) then
1450
                if(MAC_RX_CONFIG(0) = '1') then
1451
                        -- promiscuous mode. No destination address check
1452
                        RX_VALID_ADDR <= '1';
1453
                elsif(RX_STATE = 1) and (RX_EVENT4 = '1') and (RX_BYTE_COUNTER = 6) then
1454
                        -- end of destination address field. Check address
1455
                        if(LAST6B = MAC_ADDR) then
1456
                                -- destination address matches
1457
                                RX_VALID_ADDR <= '1';
1458
                        elsif (LAST6B = x"FFFFFFFFFFFF") and (MAC_RX_CONFIG(1) = '1') then
1459
                                -- accepts broadcast packets with the broadcast destination address FF:FF:FF:FF:FF:FF. 
1460
                                RX_VALID_ADDR <= '1';
1461
                        elsif (LAST6B(42) = '1') and (MAC_RX_CONFIG(2) = '1') then
1462
                                -- accept multicast packets with the multicast bit set in the destination address. 
1463
                                -- '1' in the LSb of the first address byte.
1464
                                RX_VALID_ADDR <= '1';
1465
                   else
1466
                                RX_VALID_ADDR <= '0';
1467
                        end if;
1468
                end if;
1469
        end if;
1470
end process;
1471
 
1472
-- Length/type field check
1473
LENGTH_CHECK_GEN: process(RX_CLKG, MAC_RX_CONFIG, MAC_ADDR)
1474
begin
1475
        if rising_edge(RX_CLKG) then
1476
                if(RX_EVENT1 = '1') then
1477
                        -- assume type field by default at the start of frame
1478
                        RX_LENGTH_TYPEN <= '0';  -- length/type field represents a type. ignore the length value.
1479
                elsif(RX_STATE = 1) and (RX_EVENT4 = '1') and (RX_BYTE_COUNTER = 14) then
1480
                        -- end of length/type field
1481
                        if(LAST6B(15 downto 11) = 0) and (LAST6B(10 downto 0) <= 1500) then
1482
                                -- this field is interpreted as "Length" = client data field size
1483
                                -- MSB first (802.3 section 3.2.6)
1484
                                RX_LENGTH <= LAST6B(10 downto 0);
1485
                                RX_LENGTH_TYPEN <= '1';  -- length/type field represents a length
1486
                        else
1487
                                RX_LENGTH_TYPEN <= '0';  -- length/type field represents a type. ignore the length value.
1488
                        end if;
1489
                end if;
1490
        end if;
1491
end process;
1492
 
1493
-- compute the difference between RX_BYTE_COUNTER and RX_LENGTH (meaningless, but help minimize gates)
1494
RX_DIFF <= RX_BYTE_COUNTER(11 downto 0) - ('0' & RX_LENGTH);
1495
 
1496
-- Length field consistency with actual rx frame length. Check if the length/type field is 'length'
1497
RX_LENGTH_ERR_GEN: process(RX_CLKG)
1498
begin
1499
        if rising_edge(RX_CLKG) then
1500
                if(RX_LENGTH_TYPEN = '0') then
1501
                        -- type field. No explicit length info. Can't validate actual length.
1502
                        RX_LENGTH_ERR <= '0';
1503
                elsif(MAC_RX_EOF3B = '1') then
1504
                        if(RX_LENGTH <= 46) then
1505
                                -- short rx frame is padded to the minimum size of 60 bytes + 4 CRC
1506
                                if(RX_BYTE_COUNTER = 63) then
1507
                                        -- correct answer.
1508
                                        RX_LENGTH_ERR <= '0';
1509
                                else
1510
                                        -- inconsistency
1511
                                        RX_LENGTH_ERR <= '1';
1512
                                end if;
1513
                        else
1514
                                -- normal size frame. no pad.
1515
                                if(RX_DIFF = 17) then
1516
                                        -- correct answer.
1517
                                        RX_LENGTH_ERR <= '0';
1518
                                else
1519
                                        -- inconsistency
1520
                                        RX_LENGTH_ERR <= '1';
1521
                                end if;
1522
                        end if;
1523
                end if;
1524
        end if;
1525
end process;
1526
 
1527
 
1528
 
1529
--//  RX 32-BIT CRC COMPUTATION -------------------------------------------------------
1530
-- 802.3 section 3.2.9: 
1531
-- protected fields: payload data + optional pad + CRC (excludes preamble and start of frame sequence)
1532
MAC_RX_SAMPLE2_CLK <= '1' when (RX_STATE = 1) and (MAC_RX_SAMPLE_CLK = '1')  else '0';
1533
 
1534
RX_CRC32_RESET <= '1' when (RX_STATE = 0) else '0';  -- reset CRC2 during the packet preamble 
1535
 
1536
-- latency 1 RX_CLKG
1537
RX_CRC32_8B: CRC32_8B PORT MAP(
1538
        SYNC_RESET => RX_CRC32_RESET,
1539
        CLK => RX_CLKG,
1540
        CRC32_IN => RX_CRC32,  -- feedback previous iteration
1541
        DATA_IN => MAC_RXD_D,
1542
        SAMPLE_CLK_IN => MAC_RX_SAMPLE2_CLK,
1543
        CRC32_OUT => RX_CRC32,
1544
        CRC32_VALID => RX_CRC32_VALID
1545
);
1546
 
1547
-- assess whether the frame check sequence is valid
1548
-- ready one RX_CLKG after the start of RX_STATE 2
1549
RX_BAD_CRC_GEN: process(RX_CLKG)
1550
begin
1551
        if rising_edge(RX_CLKG) then
1552
                if(RX_STATE = 2) then
1553
                        -- end of frame delimiter
1554
                        RX_BAD_CRC <= not RX_CRC32_VALID;
1555
                end if;
1556
        end if;
1557
end process;
1558
 
1559
--// PARSE RX DATA -------------------------------------------------------------------
1560
-- Delay data by 1 byte (otherwise we will only know about EOF AFTER the last byte is received)
1561
MAC_RXD3 <= MAC_RXD_D;
1562
 
1563
-- SOF
1564
--MAC_RX_SOF3 <= MAC_RX_SAMPLE_CLK when (RX_STATE = 1) and (RX_BYTE_COUNTER = 0) else '0';
1565
 
1566
-- EOF based on the length field (does not include pad nor CRC). Meaningless when the type/length field 
1567
-- is used as type. 
1568
MAC_RX_EOF3A <= '1' when (RX_STATE = 1) and (RX_EVENT4 = '1') and (RX_DIFF = 13) else '0';
1569
 
1570
-- EOF based on the RX_DV deassertion.
1571
MAC_RX_EOF3B <= '1' when (RX_STATE = 1) and (RX_EVENT3 = '1') else '0';
1572
 
1573
MAC_RX_EOF3 <=  MAC_RX_EOF3B when (RX_LENGTH_TYPEN = '0') else MAC_RX_EOF3A;
1574
MAC_RX_SAMPLE3_CLK <= MAC_RX_SAMPLE_CLK and RX_FRAME_EN3;
1575
 
1576
RX_FILTEROUT_001: process(RX_CLKG)
1577
begin
1578
        if rising_edge(RX_CLKG) then
1579
                if (SYNC_RESETRX = '1') then
1580
                        RX_FRAME_EN3 <= '0';
1581
                elsif(RX_STATE = 0) and (RX_EVENT1 = '1') then
1582
                        RX_FRAME_EN3 <= '1';
1583
                elsif(MAC_RX_EOF3 = '1') then
1584
                        RX_FRAME_EN3 <= '0';
1585
                end if;
1586
        end if;
1587
end process;
1588
 
1589
--//  VALID RX FRAME? ----------------------------------------------------------
1590
-- Is the rx frame valid? If so, confirm the wptr location.
1591
 
1592
MAC_RX_VALID_001: process(RX_CLKG)
1593
begin
1594
        if rising_edge(RX_CLKG) then
1595
                -- wait one more CLK period until all validity checks are complete
1596
                MAC_RX_EOF3B_D <= MAC_RX_EOF3B;
1597
 
1598
                if(SYNC_RESETRX = '1') then
1599
                        MAC_RX_WPTR_CONFIRMED <= (others => '0');
1600
                else
1601
                        if(RX_EVENT5 = '1') then
1602
                                -- frame complete, all checks complete
1603
                                if(RX_CRC32_VALID = '0') then
1604
                                        -- BAD_CRC
1605
                                        -- TODO error counter
1606
                                elsif(RX_TOO_SHORT = '1') then
1607
                                        -- frame is too short (<64B)
1608
                                        -- TODO error counter
1609
                                elsif(RX_TOO_LONG = '1') then
1610
                                        -- frame is too long (>1518B)
1611
                                        -- TODO error counter
1612
                                elsif(RX_VALID_ADDR = '0') then
1613
                                        -- address does not match (and promiscuous mode is off)
1614
                                        -- TODO counter
1615
                                elsif(RX_LENGTH_ERR = '1') then
1616
                                        -- length field is inconsistent with actual rx frame length
1617
                                        -- TODO counter
1618
                                else
1619
                                        -- passed all checks
1620
                                        -- update confirmed value for MAC_RX_WPTR
1621
                                        if(MAC_RX_CONFIG(3) = '1') then
1622
                                                -- filter out 4-byte CRC-32
1623
                                                MAC_RX_WPTR_CONFIRMED <= MAC_RX_WPTR - 4;
1624
                                        else
1625
                                                -- include 4-byte CRC-32
1626
                                                MAC_RX_WPTR_CONFIRMED <= MAC_RX_WPTR;
1627
                                        end if;
1628
                                end if;
1629
 
1630
                        end if;
1631
                end if;
1632
        end if;
1633
end process;
1634
 
1635
 
1636
 
1637
--//  RX INPUT ELASTIC BUFFER ----------------------------------------------------------
1638
-- The purpose of the elastic buffer is two-fold:
1639
-- (a) a transition between the RX_CLKG synchronous PHY side and the CLK-synchronous user side.
1640
-- (b) storage for receive packets, to absorb traffic peaks, minimize the number of 
1641
-- UDP packets lost at high throughput.
1642
-- The rx elastic buffer is 16Kbits, large enough for a complete maximum size (14addr+1500data+4FCS = 1518B) frame.
1643
 
1644
-- write pointer management
1645
MAC_RX_WPTR_001: process(ASYNC_RESET, RX_CLKG)
1646
begin
1647
        if(ASYNC_RESET = '1') then
1648
                MAC_RX_WPTR <= (others => '0');
1649
                MAC_RX_WPTR_D <= (others => '0');
1650
        elsif rising_edge(RX_CLKG) then
1651
                RX_COUNTER8 <= RX_COUNTER8 + 1;
1652
 
1653
                if(SYNC_RESETRX = '1') then
1654
                        MAC_RX_WPTR <= (others => '0');
1655
                elsif(RX_STATE = 0) then
1656
                        -- re-position the write pointer (same or rewind if previous frame was invalid
1657
                        MAC_RX_WPTR <= MAC_RX_WPTR_CONFIRMED;
1658
                elsif(MAC_RX_SAMPLE3_CLK = '1') then
1659
                        MAC_RX_WPTR <= MAC_RX_WPTR + 1;
1660
                end if;
1661
 
1662
                -- update WPTR_D once every 8 clocks.
1663
                if(SYNC_RESETRX = '1') then
1664
                        MAC_RX_WPTR_D <= (others => '0');
1665
                elsif(RX_COUNTER8 = 7) then
1666
                        MAC_RX_WPTR_D <= MAC_RX_WPTR_CONFIRMED;
1667
                end if;
1668
 
1669
                -- allow WPTR reclocking with another clock, as long as it is away from the transition area
1670
                if(RX_COUNTER8 < 6) then
1671
                        MAC_RX_WPTR_STABLE <= '1';
1672
                else
1673
                        MAC_RX_WPTR_STABLE <= '0';
1674
                end if;
1675
 
1676
 
1677
        end if;
1678
end process;
1679
 
1680
 
1681
 
1682
MAC_RX_DIPA(0) <= MAC_RX_EOF3;  -- indicates last byte in the rx packet
1683
 
1684
-- No need for initialization
1685
RAMB16_002: RAMB16_S9_S9
1686
port map(
1687
        DIA => MAC_RXD3,
1688
        DIB => x"00",
1689
        DIPA => MAC_RX_DIPA(0 downto 0),
1690
        DIPB => "0",
1691
        DOPA => open,
1692
        DOPB => MAC_RX_DOPB(0 downto 0),
1693
        ENA => '1',
1694
        ENB => '1',
1695
        WEA => MAC_RX_SAMPLE3_CLK,
1696
        WEB => '0',
1697
        SSRA => '0',
1698
        SSRB => '0',
1699
        CLKA => RX_CLKG,
1700
        CLKB => CLK,
1701
        ADDRA => MAC_RX_WPTR,
1702
        ADDRB => MAC_RX_RPTR,
1703
        DOA => open,
1704
        DOB => MAC_RXD4
1705
);
1706
 
1707
 
1708
-- CLK zone. Reclock WPTR
1709
MAC_RX_WPTR_002: process(ASYNC_RESET, CLK)
1710
begin
1711
        if(ASYNC_RESET = '1') then
1712
                MAC_RX_WPTR_D2 <= (others => '0');
1713
                MAC_RX_WPTR_D3 <= (others => '0');
1714
                MAC_RX_WPTR_STABLE_D <= '0';
1715
        elsif rising_edge(CLK) then
1716
                MAC_RX_WPTR_STABLE_D <= MAC_RX_WPTR_STABLE;
1717
                MAC_RX_WPTR_D2 <= MAC_RX_WPTR_D;
1718
 
1719
                if(MAC_RX_WPTR_STABLE_D = '1') then
1720
                        -- WPTR is stable. OK to resample with the RX_CLKG clock.
1721
                        MAC_RX_WPTR_D3 <= MAC_RX_WPTR_D2;
1722
                end if;
1723
        end if;
1724
end process;
1725
 
1726
MAC_RX_BUF_SIZE <= MAC_RX_WPTR_D3 + not(MAC_RX_RPTR);
1727
-- occupied tx buffer size
1728
 
1729
-- manage read pointer
1730
MAC_RX_RPTR_001: process(ASYNC_RESET, CLK)
1731
begin
1732
        if(ASYNC_RESET = '1') then
1733
                MAC_RX_RPTR <= (others => '1');
1734
        elsif rising_edge(CLK) then
1735
                MAC_RX_SAMPLE4_CLK <= MAC_RX_SAMPLE4_CLK_E;  -- it takes one CLK to read data from the RAMB
1736
 
1737
                if(SYNC_RESET = '1') then
1738
                        MAC_RX_RPTR <= (others => '1');
1739
                        MAC_RX_SAMPLE4_CLK_E <= '0';
1740
                        MAC_RX_SAMPLE4_CLK <= '0';
1741
                elsif(MAC_RX_CTS = '1') and (MAC_RX_BUF_SIZE /= 0) then
1742
                        -- user requests data and the buffer is not empty
1743
                        MAC_RX_RPTR <= MAC_RX_RPTR + 1;
1744
                        MAC_RX_SAMPLE4_CLK_E <= '1';
1745
                else
1746
                        MAC_RX_SAMPLE4_CLK_E <= '0';
1747
                end if;
1748
        end if;
1749
end process;
1750
 
1751
-- reconstruct an EOF aligned with the last output byte
1752
EOF_GEN_001: process(ASYNC_RESET, CLK)
1753
begin
1754
        if(ASYNC_RESET = '1') then
1755
                MAC_RX_EOF4 <= '0';
1756
        elsif rising_edge(CLK) then
1757
                if(SYNC_RESET = '1') then
1758
                        MAC_RX_EOF4 <= '0';
1759
                elsif(MAC_RX_SAMPLE4_CLK_E = '1') and  (MAC_RX_BUF_SIZE = 0)then
1760
                        MAC_RX_EOF4 <= '1';
1761
                else
1762
                        MAC_RX_EOF4 <= '0';
1763
                end if;
1764
        end if;
1765
end process;
1766
-- alternate code (does not work when CRC32 is stripped)
1767
-- MAC_RX_EOF4 <= MAC_RX_DOPB(0) and MAC_RX_SAMPLE4_CLK; -- reconstruct EOF pulse (1 CLK wide)
1768
 
1769
-- reconstruct a SOF
1770
SOF_GEN_001: process(ASYNC_RESET, CLK)
1771
begin
1772
        if(ASYNC_RESET = '1') then
1773
                MAC_RX_EOF4_FLAG <= '1';
1774
        elsif rising_edge(CLK) then
1775
                if(SYNC_RESET = '1') then
1776
                        MAC_RX_EOF4_FLAG <= '1';
1777
                elsif(MAC_RX_EOF4 = '1') then
1778
                        MAC_RX_EOF4_FLAG <= '1';
1779
                elsif(MAC_RX_SAMPLE4_CLK = '1') then
1780
                        MAC_RX_EOF4_FLAG <= '0';
1781
                end if;
1782
        end if;
1783
end process;
1784
 
1785
-- output to user
1786
MAC_RX_DATA <= MAC_RXD4;
1787
MAC_RX_DATA_VALID <= MAC_RX_SAMPLE4_CLK;
1788
MAC_RX_EOF <= MAC_RX_EOF4;
1789
MAC_RX_SOF <= MAC_RX_EOF4_FLAG and MAC_RX_SAMPLE4_CLK;
1790
 
1791
end Behavioral;
1792
 

powered by: WebSVN 2.1.0

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