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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [source/] [gigabit_ethernet.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jondawson
--------------------------------------------------------------------------------
2
---
3
---  Gigabit Ethernet MAC
4
---
5
---  :Author: Jonathan P Dawson
6
---  :Date: 17/10/2013
7
---  :email: chips@jondawson.org.uk
8
---  :license: MIT
9
---  :Copyright: Copyright (C) Jonathan P Dawson 2013
10
---
11
---  A gigabit ethernet MAC
12
---
13
--------------------------------------------------------------------------------
14
---
15
---Gigabit Ethernet
16
---================
17
---
18
---Send and receive Ethernet packets. Using a Ethernet Physical Interface.
19
---
20
---Features:
21
---
22
---+ Supports 1Gbit/s ethernet only via a gmii interface.
23
---+ Supports full duplex mode only.
24
---
25
---Interface
26
------------
27
---:input: TX - Data to send (16 bits).
28
---:output: RX - Data to send (16 bits).
29
---
30
---Ethernet Packet Structure
31
----------------------------
32
---
33
---+-------------+-------------+--------+--------+---------+---------+-----+
34
---| Description | destination | source | length | payload | padding | FSC |
35
---+=============+=============+========+========+=========+=========+=====+
36
---|    Bytes    |      6      |   6    |    2   |  0-1500 |   0-46  |  4  |
37
---+-------------+-------------+--------+--------+---------+---------+-----+
38
---
39
---Notes:
40
---
41
---+ The *length* field is the length of the ethernet payload.
42
---+ The *Ethernet Output* block will automatically append the FSC to 
43
---  outgoing packets.
44
---+ The *FSC* of incoming packets will be checked, and bad packets will
45
---  be discarded. The *FSC* will be stripped from incoming packets.
46
---+ The length of the *payload* + *padding* must be 46-1500 bytes.
47
---+ Incoming packets of incorrect *length* will be discarded.
48
---
49
---Usage
50
--------
51
---
52
---Transmit
53
---~~~~~~~~
54
---The first 16 bit word on the TX input is interpreted as the length of the
55
---packet in bytes (including the MAC address, length and payload, but not the 
56
---preamble or FSC). Subsequent words on the TX input are interpreted as the
57
---content of the packet. If length is an odd number of bytes, then the least
58
---significant byte of the last word will be ignored.
59
---The FSC will be appended for you, but you need to supply the destination,
60
---source and length fields.
61
---
62
---Receive
63
---~~~~~~~~
64
---The first 16 bit word on the RX output will be the length of the packet in 
65
---bytes (including the MAC address, length and payload, but not the 
66
---preamble or FSC). Subsequent words on the RX output will be the
67
---content of the packet. If length is an odd number of bytes, then the least
68
---significant byte of the last word will not contain usefull data.
69
---The FSC will be stripped from incoming packets, but the destination,
70
---source and length fields will be included.
71
---
72
---Hardware details
73
-------------------
74
---This component used two clocks, the local clock used to transfer data
75
---between components, and a 125MHz clock source for sending data to the
76
---Ethernet physical interface. This clock is also forwarded along with the
77
---data to the ethernet phy.
78
---
79
 
80
library ieee;
81
use ieee.numeric_std.all;
82
use ieee.std_logic_1164.all;
83
 
84
entity gigabit_ethernet is
85
  port(
86
    CLK         : in  std_logic;
87
    RST         : in  std_logic;
88
 
89
    --Ethernet Clock
90
    CLK_125_MHZ : in  std_logic;
91
 
92
    --GMII IF
93
    GTXCLK      : out std_logic;
94
    TXCLK       : in  std_logic;
95
    TXER        : out std_logic;
96
    TXEN        : out std_logic;
97
    TXD         : out std_logic_vector(7 downto 0);
98
    PHY_RESET   : out std_logic;
99
    RXCLK       : in  std_logic;
100
    RXER        : in  std_logic;
101
    RXDV        : in  std_logic;
102
    RXD         : in  std_logic_vector(7 downto 0);
103
 
104
    --RX STREAM
105
    TX          : in  std_logic_vector(15 downto 0);
106
    TX_STB      : in  std_logic;
107
    TX_ACK      : out std_logic;
108
 
109
    --RX STREAM
110
    RX          : out std_logic_vector(15 downto 0);
111
    RX_STB      : out std_logic;
112
    RX_ACK      : in  std_logic
113
  );
114
end entity gigabit_ethernet;
115
 
116
architecture RTL of gigabit_ethernet is
117
 
118
  -- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32)
119
  -- data width: 8
120
  -- convention: the first serial bit is D[0]
121
  function NEXTCRC32_D8
122
    (DATA: std_logic_vector(7 downto 0);
123
    CRC:  std_logic_vector(31 downto 0))
124
    return std_logic_vector is
125
 
126
    variable D:      std_logic_vector(7 downto 0);
127
    variable C:      std_logic_vector(31 downto 0);
128
    variable NEWCRC: std_logic_vector(31 downto 0);
129
 
130
  begin
131
    D := DATA;
132
    C := CRC;
133
    NewCRC(0):=C(24) xor C(30) xor D(1) xor D(7);
134
    NewCRC(1):=C(25) xor C(31) xor D(0) xor D(6) xor C(24) xor C(30) xor D(1)
135
               xor D(7);
136
    NewCRC(2):=C(26) xor D(5) xor C(25) xor C(31) xor D(0) xor D(6) xor C(24)
137
               xor C(30) xor D(1) xor D(7);
138
    NewCRC(3):=C(27) xor D(4) xor C(26) xor D(5) xor C(25) xor C(31) xor D(0)
139
               xor D(6);
140
    NewCRC(4):=C(28) xor D(3) xor C(27) xor D(4) xor C(26) xor D(5) xor C(24)
141
              xor C(30) xor D(1) xor D(7);
142
    NewCRC(5):=C(29) xor D(2) xor C(28) xor D(3) xor C(27) xor D(4) xor C(25)
143
              xor C(31) xor D(0) xor D(6) xor C(24) xor C(30) xor D(1) xor D(7);
144
    NewCRC(6):=C(30) xor D(1) xor C(29) xor D(2) xor C(28) xor D(3) xor C(26)
145
              xor D(5) xor C(25) xor C(31) xor D(0) xor D(6);
146
    NewCRC(7):=C(31) xor D(0) xor C(29) xor D(2) xor C(27) xor D(4) xor C(26)
147
              xor D(5) xor C(24) xor D(7);
148
    NewCRC(8):=C(0) xor C(28) xor D(3) xor C(27) xor D(4) xor C(25) xor D(6)
149
              xor C(24) xor D(7);
150
    NewCRC(9):=C(1) xor C(29) xor D(2) xor C(28) xor D(3) xor C(26) xor D(5)
151
              xor C(25) xor D(6);
152
    NewCRC(10):=C(2) xor C(29) xor D(2) xor C(27) xor D(4) xor C(26) xor D(5)
153
              xor C(24) xor D(7);
154
    NewCRC(11):=C(3) xor C(28) xor D(3) xor C(27) xor D(4) xor C(25) xor D(6)
155
              xor C(24) xor D(7);
156
    NewCRC(12):=C(4) xor C(29) xor D(2) xor C(28) xor D(3) xor C(26) xor D(5)
157
              xor C(25) xor D(6) xor C(24) xor C(30) xor D(1) xor D(7);
158
    NewCRC(13):=C(5) xor C(30) xor D(1) xor C(29) xor D(2) xor C(27) xor D(4)
159
              xor C(26) xor D(5) xor C(25) xor C(31) xor D(0) xor D(6);
160
    NewCRC(14):=C(6) xor C(31) xor D(0) xor C(30) xor D(1) xor C(28) xor D(3)
161
              xor C(27) xor D(4) xor C(26) xor D(5);
162
    NewCRC(15):=C(7) xor C(31) xor D(0) xor C(29) xor D(2) xor C(28) xor D(3)
163
              xor C(27) xor D(4);
164
    NewCRC(16):=C(8) xor C(29) xor D(2) xor C(28) xor D(3) xor C(24) xor D(7);
165
    NewCRC(17):=C(9) xor C(30) xor D(1) xor C(29) xor D(2) xor C(25) xor D(6);
166
    NewCRC(18):=C(10) xor C(31) xor D(0) xor C(30) xor D(1) xor C(26) xor D(5);
167
    NewCRC(19):=C(11) xor C(31) xor D(0) xor C(27) xor D(4);
168
    NewCRC(20):=C(12) xor C(28) xor D(3);
169
    NewCRC(21):=C(13) xor C(29) xor D(2);
170
    NewCRC(22):=C(14) xor C(24) xor D(7);
171
    NewCRC(23):=C(15) xor C(25) xor D(6) xor C(24) xor C(30) xor D(1) xor D(7);
172
    NewCRC(24):=C(16) xor C(26) xor D(5) xor C(25) xor C(31) xor D(0) xor D(6);
173
    NewCRC(25):=C(17) xor C(27) xor D(4) xor C(26) xor D(5);
174
    NewCRC(26):=C(18) xor C(28) xor D(3) xor C(27) xor D(4) xor C(24) xor C(30)
175
              xor D(1) xor D(7);
176
    NewCRC(27):=C(19) xor C(29) xor D(2) xor C(28) xor D(3) xor C(25) xor C(31)
177
              xor D(0) xor D(6);
178
    NewCRC(28):=C(20) xor C(30) xor D(1) xor C(29) xor D(2) xor C(26) xor D(5);
179
    NewCRC(29):=C(21) xor C(31) xor D(0) xor C(30) xor D(1) xor C(27) xor D(4);
180
    NewCRC(30):=C(22) xor C(31) xor D(0) xor C(28) xor D(3);
181
    NewCRC(31):=C(23) xor C(29) xor D(2);
182
 
183
    return NEWCRC;
184
  end NEXTCRC32_D8;
185
 
186
  -- Reverse the input vector.
187
  function REVERSED(slv: std_logic_vector) return std_logic_vector is
188
     variable result: std_logic_vector(slv'reverse_range);
189
  begin
190
     for i in slv'range loop
191
       result(i) := slv(i);
192
     end loop;
193
     return result;
194
  end REVERSED;
195
 
196
  --constants
197
  constant ADDRESS_BITS : integer := 11;
198
  constant ADDRESS_MAX : integer := (2**ADDRESS_BITS) - 1;
199
 
200
  --memories
201
  type TX_MEMORY_TYPE is array (0 to 511) of
202
    std_logic_vector(15 downto 0);
203
  shared variable TX_MEMORY : TX_MEMORY_TYPE;
204
 
205
  type RX_MEMORY_TYPE is array (0 to ADDRESS_MAX) of
206
    std_logic_vector(15 downto 0);
207
  shared variable RX_MEMORY : RX_MEMORY_TYPE;
208
 
209
  type ADDRESS_ARRAY is array (0 to 31) of
210
    unsigned(ADDRESS_BITS - 1 downto 0);
211
 
212
  --state variables
213
  type TX_PHY_STATE_TYPE is (WAIT_NEW_PACKET, PREAMBLE_0, PREAMBLE_1,
214
    PREAMBLE_2, PREAMBLE_3, PREAMBLE_4, PREAMBLE_5, PREAMBLE_6, SFD,
215
    SEND_DATA_HI, SEND_DATA_LO, SEND_CRC_3, SEND_CRC_2, SEND_CRC_1,
216
    SEND_CRC_0, DONE_STATE);
217
  signal TX_PHY_STATE : TX_PHY_STATE_TYPE;
218
 
219
  type TX_PACKET_STATE_TYPE is(GET_LENGTH, GET_DATA, SEND_PACKET,
220
    WAIT_NOT_DONE);
221
  signal TX_PACKET_STATE : TX_PACKET_STATE_TYPE;
222
 
223
  type RX_PHY_STATE_TYPE is (WAIT_START, PREAMBLE, DATA_HIGH, DATA_LOW,
224
    END_OF_FRAME, NOTIFY_NEW_PACKET);
225
  signal RX_PHY_STATE : RX_PHY_STATE_TYPE;
226
 
227
  type RX_PACKET_STATE_TYPE is (WAIT_INITIALISE, WAIT_NEW_PACKET,
228
    SEND_DATA, PREFETCH0, PREFETCH1, SEND_LENGTH);
229
  signal RX_PACKET_STATE : RX_PACKET_STATE_TYPE;
230
 
231
  --TX signals
232
  signal TX_WRITE                  : std_logic;
233
  signal TX_WRITE_DATA             : std_logic_vector(15 downto 0);
234
  signal TX_READ_DATA              : std_logic_vector(15 downto 0);
235
  signal TX_WRITE_ADDRESS          : integer range 0 to 1513;
236
  signal TX_WRITE_ADDRESS_DEL      : integer range 0 to 1513;
237
  signal TX_READ_ADDRESS           : integer range 0 to 1513;
238
  signal TX_CRC                    : std_logic_vector(31 downto 0);
239
  signal TX_IN_COUNT               : integer range 0 to 1513;
240
  signal TX_OUT_COUNT              : integer range 0 to 1513;
241
  signal TX_PACKET_LENGTH          : std_logic_vector(15 downto 0);
242
  signal GO, GO_DEL, GO_SYNC       : std_logic;
243
  signal DONE, DONE_DEL, DONE_SYNC : std_logic;
244
  signal S_TX_ACK                  : std_logic;
245
 
246
  --RX signals
247
  signal RX_WRITE_ADDRESS          : unsigned(ADDRESS_BITS - 1 downto 0);
248
  signal RX_READ_ADDRESS           : unsigned(ADDRESS_BITS - 1 downto 0);
249
  signal RX_START_ADDRESS          : unsigned(ADDRESS_BITS - 1 downto 0);
250
  signal RX_PACKET_LENGTH          : unsigned(ADDRESS_BITS - 1 downto 0);
251
  signal RX_START_ADDRESS_BUFFER   : ADDRESS_ARRAY;
252
  signal RX_PACKET_LENGTH_BUFFER   : ADDRESS_ARRAY;
253
  signal RX_WRITE_BUFFER           : integer range 0 to 31;
254
  signal RX_READ_BUFFER            : integer range 0 to 31;
255
  signal RX_BUFFER_BUSY            : std_logic_vector(31 downto 0);
256
  signal RX_BUFFER_BUSY_DEL        : std_logic_vector(31 downto 0);
257
  signal RX_BUFFER_BUSY_SYNC       : std_logic_vector(31 downto 0);
258
  signal RX_START_ADDRESS_SYNC     : unsigned(ADDRESS_BITS - 1 downto 0);
259
  signal RX_PACKET_LENGTH_SYNC     : unsigned(ADDRESS_BITS - 1 downto 0);
260
  signal RX_END_ADDRESS            : unsigned(ADDRESS_BITS - 1 downto 0);
261
  signal RX_WRITE_DATA             : std_logic_vector(15 downto 0);
262
  signal RX_WRITE_ENABLE           : std_logic;
263
  signal RX_ERROR                  : std_logic;
264
  signal RX_CRC                    : std_logic_vector(31 downto 0);
265
  signal RXD_D                     : std_logic_vector(7 downto 0);
266
  signal RXDV_D                    : std_logic;
267
  signal RXER_D                    : std_logic;
268
 
269
begin
270
 
271
  --This process is in the local clock domain. 
272
  --It gets data and puts it into a RAM.
273
  --Once a packets worth of data has been stored it is
274
  --sent to the packet sending state machine.
275
  TX_PACKET_FSM : process
276
  begin
277
    wait until rising_edge(CLK);
278
    TX_WRITE <= '0';
279
    case TX_PACKET_STATE is
280
 
281
      when GET_LENGTH =>
282
        S_TX_ACK <= '1';
283
        if S_TX_ACK = '1' and TX_STB = '1' then
284
          S_TX_ACK <= '0';
285
          TX_PACKET_LENGTH <= TX;
286
                TX_IN_COUNT <= 2;
287
          TX_PACKET_STATE <= GET_DATA;
288
        end if;
289
 
290
      when GET_DATA =>
291
        S_TX_ACK <= '1';
292
        if S_TX_ACK = '1' and TX_STB = '1' then
293
          TX_WRITE_DATA <= TX;
294
          TX_WRITE <= '1';
295
          if TX_IN_COUNT >= unsigned(TX_PACKET_LENGTH) then
296
            TX_PACKET_STATE <= SEND_PACKET;
297
            S_TX_ACK <= '0';
298
          else
299
            TX_WRITE_ADDRESS <= TX_WRITE_ADDRESS + 1;
300
            TX_IN_COUNT <= TX_IN_COUNT + 2;
301
          end if;
302
        end if;
303
 
304
      when SEND_PACKET =>
305
        GO <= '1';
306
        TX_WRITE_ADDRESS <= 0;
307
        if DONE_SYNC = '1' then
308
          GO <= '0';
309
          TX_PACKET_STATE <= WAIT_NOT_DONE;
310
        end if;
311
 
312
      when WAIT_NOT_DONE =>
313
        if DONE_SYNC = '0' then
314
          TX_PACKET_STATE <= GET_LENGTH;
315
        end if;
316
 
317
    end case;
318
    if RST = '1' then
319
      TX_PACKET_STATE <= GET_LENGTH;
320
      TX_WRITE_ADDRESS <= 0;
321
      S_TX_ACK <= '0';
322
      GO <= '0';
323
    end if;
324
  end process TX_PACKET_FSM;
325
 
326
  TX_ACK <= S_TX_ACK;
327
 
328
 
329
  --This process writes data into a dual port RAM
330
  WRITE_DUAL_PORT_MEMORY : process
331
  begin
332
    wait until rising_edge(CLK);
333
    TX_WRITE_ADDRESS_DEL <= TX_WRITE_ADDRESS;
334
    if TX_WRITE = '1' then
335
      TX_MEMORY(TX_WRITE_ADDRESS_DEL) := TX_WRITE_DATA;
336
    end if;
337
  end process;
338
 
339
  --This process read data from a dual port RAM
340
  READ_DUAL_PORT_MEMORY : process
341
  begin
342
    wait until rising_edge(CLK_125_MHZ);
343
    TX_READ_DATA <= TX_MEMORY(TX_READ_ADDRESS);
344
  end process;
345
 
346
  --This process synchronises ethernet signals
347
  --to the local clock domain
348
  LOCAL_TO_CLK_125 : process
349
  begin
350
    wait until rising_edge(CLK_125_MHZ);
351
    GO_DEL <= GO; GO_SYNC <= GO_DEL;
352
  end process;
353
 
354
  --This process synchronises local signals to the ethernet clock domain
355
  CLK_125_TO_LOCAL : process
356
  begin
357
    wait until rising_edge(CLK);
358
    DONE_DEL <= DONE; DONE_SYNC <= DONE_DEL;
359
  end process;
360
 
361
  --Transmit the stored packet via the phy.
362
  TX_PHY_FSM : process
363
  begin
364
    wait until rising_edge(CLK_125_MHZ);
365
    case TX_PHY_STATE is
366
 
367
      when WAIT_NEW_PACKET =>
368
        if GO_SYNC = '1' then
369
          TX_PHY_STATE <= PREAMBLE_0;
370
          TX_READ_ADDRESS <= 0;
371
          TX_OUT_COUNT <= to_integer(unsigned(TX_PACKET_LENGTH)-1);
372
        end if;
373
 
374
      when PREAMBLE_0 =>
375
        TXD <= X"55";
376
        TX_PHY_STATE <= PREAMBLE_1;
377
        TXEN <= '1';
378
 
379
      when PREAMBLE_1 =>
380
        TXD <= X"55";
381
        TX_PHY_STATE <= PREAMBLE_2;
382
 
383
      when PREAMBLE_2 =>
384
        TXD <= X"55";
385
        TX_PHY_STATE <= PREAMBLE_3;
386
 
387
      when PREAMBLE_3 =>
388
        TXD <= X"55";
389
        TX_PHY_STATE <= PREAMBLE_4;
390
 
391
      when PREAMBLE_4 =>
392
        TXD <= X"55";
393
        TX_PHY_STATE <= PREAMBLE_5;
394
 
395
      when PREAMBLE_5 =>
396
        TXD <= X"55";
397
        TX_PHY_STATE <= PREAMBLE_6;
398
 
399
      when PREAMBLE_6 =>
400
        TXD <= X"55";
401
        TX_PHY_STATE <= SFD;
402
 
403
      when SFD =>
404
        TXD <= X"D5";
405
        TX_PHY_STATE <= SEND_DATA_HI;
406
        TX_CRC <= X"FFFFFFFF";
407
 
408
      when SEND_DATA_HI =>
409
        TX_CRC <= NEXTCRC32_D8(TX_READ_DATA(15 downto 8), TX_CRC);
410
        TXD <= TX_READ_DATA(15 downto 8);
411
        If TX_OUT_COUNT = 0 then
412
          TX_PHY_STATE <= SEND_CRC_3;
413
        else
414
                      TX_PHY_STATE <= SEND_DATA_LO;
415
          TX_READ_ADDRESS <= TX_READ_ADDRESS + 1;
416
          TX_OUT_COUNT <= TX_OUT_COUNT - 1;
417
        end if;
418
 
419
      when SEND_DATA_LO =>
420
        TX_CRC   <= NEXTCRC32_D8(TX_READ_DATA(7 downto 0), TX_CRC);
421
        TXD   <= TX_READ_DATA(7 downto 0);
422
        If TX_OUT_COUNT = 0 then
423
          TX_PHY_STATE <= SEND_CRC_3;
424
        else
425
          TX_PHY_STATE <= SEND_DATA_HI;
426
          TX_OUT_COUNT <= TX_OUT_COUNT - 1;
427
        end if;
428
 
429
      when SEND_CRC_3 =>
430
        TXD <= not REVERSED(TX_CRC(31 downto  24));
431
        TX_PHY_STATE <= SEND_CRC_2;
432
 
433
      when SEND_CRC_2 =>
434
        TXD <= not REVERSED(TX_CRC(23 downto  16));
435
        TX_PHY_STATE <= SEND_CRC_1;
436
 
437
      when SEND_CRC_1 =>
438
        TXD <= not REVERSED(TX_CRC(15 downto   8));
439
        TX_PHY_STATE <= SEND_CRC_0;
440
 
441
      when SEND_CRC_0 =>
442
        TXD <= not REVERSED(TX_CRC(7  downto   0));
443
        TX_PHY_STATE <= DONE_STATE;
444
 
445
      when DONE_STATE =>
446
        TXEN <= '0';
447
        DONE <= '1';
448
        if GO_SYNC = '0' then
449
          TX_PHY_STATE <= WAIT_NEW_PACKET;
450
          DONE <= '0';
451
        end if;
452
 
453
    end case;
454
    if RST = '1' then
455
      TXEN <= '0';
456
      TX_PHY_STATE <= WAIT_NEW_PACKET;
457
      DONE <= '0';
458
      TXD <= (others => '0');
459
    end if;
460
  end process TX_PHY_FSM;
461
 
462
  TXER   <= '0';
463
  GTXCLK <= CLK_125_MHZ;
464
 
465
  --This process reads data out of the phy and puts it into a buffer.
466
  --There are many buffers on the RX side to cope with data arriving at
467
  --a high rate. If a very large packet is received, followed by many small
468
  --packets, a large number of packets need to be stored.
469
  RX_PHY_FSM : process
470
  begin
471
    wait until rising_edge(RXCLK);
472
    RX_WRITE_ENABLE <= '0';
473
    RXDV_D <= RXDV;
474
    RXER_D <= RXER;
475
    RXD_D <= RXD;
476
    case RX_PHY_STATE is
477
 
478
      when WAIT_START =>
479
        if RXDV_D = '1' and RXD_D = X"55" then
480
          RX_PHY_STATE <= PREAMBLE;
481
          RX_ERROR <= '0';
482
        end if;
483
 
484
      when PREAMBLE =>
485
        if RXD_D = X"d5" then
486
          RX_PHY_STATE <= DATA_HIGH;
487
          RX_START_ADDRESS <= RX_WRITE_ADDRESS;
488
          RX_PACKET_LENGTH <= to_unsigned(0, ADDRESS_BITS);
489
          RX_CRC <= X"ffffffff";
490
        elsif RXD_D /= X"55" or RXDV_D = '0' then
491
          RX_PHY_STATE <= WAIT_START;
492
        end if;
493
 
494
      when DATA_HIGH =>
495
        RX_WRITE_DATA(15 downto 8) <= RXD_D;
496
        if RXDV_D = '1' then
497
          RX_PACKET_LENGTH <= RX_PACKET_LENGTH + 1;
498
          RX_PHY_STATE <= DATA_LOW;
499
          RX_CRC <= nextCRC32_D8(RXD_D, RX_CRC);
500
        else
501
          RX_PHY_STATE <= END_OF_FRAME;
502
        end if;
503
 
504
      when DATA_LOW =>
505
        RX_WRITE_DATA(7 downto 0) <= RXD_D;
506
        RX_WRITE_ENABLE <= '1';
507
        if RXDV_D = '1' then
508
          RX_PACKET_LENGTH <= RX_PACKET_LENGTH + 1;
509
          RX_PHY_STATE <= DATA_HIGH;
510
          RX_CRC <= nextCRC32_D8(RXD_D, RX_CRC);
511
        else
512
          RX_PHY_STATE <= END_OF_FRAME;
513
        end if;
514
 
515
      when END_OF_FRAME =>
516
        if RX_ERROR = '1' then
517
          RX_PHY_STATE <= WAIT_START;
518
        elsif RX_PACKET_LENGTH < 64 then
519
          RX_PHY_STATE <= WAIT_START;
520
        elsif RX_PACKET_LENGTH > 1518 then
521
          RX_PHY_STATE <= WAIT_START;
522
        elsif RX_CRC /= X"C704dd7B" then
523
          RX_PHY_STATE <= WAIT_START;
524
        else
525
          RX_PHY_STATE <= NOTIFY_NEW_PACKET;
526
        end if;
527
 
528
      when NOTIFY_NEW_PACKET =>
529
        RX_PHY_STATE <= WAIT_START;
530
        RX_START_ADDRESS_BUFFER(RX_WRITE_BUFFER) <= RX_START_ADDRESS;
531
        RX_PACKET_LENGTH_BUFFER(RX_WRITE_BUFFER) <= RX_PACKET_LENGTH;
532
        if RX_WRITE_BUFFER = 31 then
533
          RX_WRITE_BUFFER <= 0;
534
        else
535
          RX_WRITE_BUFFER <= RX_WRITE_BUFFER + 1;
536
        end if;
537
 
538
    end case;
539
 
540
    if RXER_D = '1' then
541
      RX_ERROR <= '1';
542
    end if;
543
 
544
    if RST = '1' then
545
      RX_PHY_STATE <= WAIT_START;
546
    end if;
547
  end process RX_PHY_FSM;
548
 
549
  --generate a signal for each buffer to indicate that is is being used.
550
  GENERATE_BUFFER_BUSY : process
551
  begin
552
    wait until rising_edge(RXCLK);
553
    for I in 0 to 31 loop
554
      if I = RX_WRITE_BUFFER then
555
        RX_BUFFER_BUSY(I) <= '1';
556
      else
557
        RX_BUFFER_BUSY(I) <= '0';
558
      end if;
559
    end loop;
560
  end process GENERATE_BUFFER_BUSY;
561
 
562
  --This is the memory that implements the RX buffers
563
  WRITE_RX_MEMORY : process
564
  begin
565
    wait until rising_edge(RXCLK);
566
    if RX_WRITE_ENABLE = '1' then
567
      RX_MEMORY(to_integer(RX_WRITE_ADDRESS)) := RX_WRITE_DATA;
568
      RX_WRITE_ADDRESS <= RX_WRITE_ADDRESS + 1;
569
    end if;
570
    if RST = '1' then
571
      RX_WRITE_ADDRESS <= (others => '0');
572
    end if;
573
  end process WRITE_RX_MEMORY;
574
 
575
  SYNCHRONISE_BUFFER_BUSY : process
576
  begin
577
    wait until rising_edge(CLK);
578
    RX_BUFFER_BUSY_DEL <= RX_BUFFER_BUSY;
579
    RX_BUFFER_BUSY_SYNC <= RX_BUFFER_BUSY_DEL;
580
  end process SYNCHRONISE_BUFFER_BUSY;
581
 
582
  --CLK                  __/""\__/"   _/" "\__/""\
583
  --RX_BUFFER_BUSY_SYNC[0] ""\_______   ____________
584
  --RX_BUFFER_BUSY_SYNC[1] ________/"   "\__________
585
  --RX_BUFFER_BUSY_SYNC[2] __________   _______/""""
586
  --                       ^
587
  --                       Start to read packet 0 here.
588
  -- Note: since RX_BUFFER_BUSY originates in a different clock domain,
589
  -- it is possible that a clock cycle or so could elapse between
590
  -- RX_BUFFER_BUSY_SYNC[0] becoming low and RX_BUFFER_BUSY_SYNC[1] becoming
591
  -- high. We are relying on the delay through the state machine to be
592
  -- long enough that we don't try to read BUFFER1 during this period.
593
 
594
  RX_PACKET_FSM : process
595
  begin
596
    wait until rising_edge(CLK);
597
    case RX_PACKET_STATE is
598
 
599
      when WAIT_INITIALISE =>
600
        if RX_BUFFER_BUSY_SYNC(0) = '1' then
601
          RX_PACKET_STATE <= WAIT_NEW_PACKET;
602
          RX_READ_BUFFER <= 0;
603
        end if;
604
 
605
      when WAIT_NEW_PACKET =>
606
        if RX_BUFFER_BUSY_SYNC(RX_READ_BUFFER) = '0' then
607
          RX_PACKET_STATE <= SEND_LENGTH;
608
          RX_START_ADDRESS_SYNC <= RX_START_ADDRESS_BUFFER(RX_READ_BUFFER);
609
          RX_PACKET_LENGTH_SYNC <= RX_PACKET_LENGTH_BUFFER(RX_READ_BUFFER);
610
          RX <=
611
            std_logic_vector(
612
              resize(RX_PACKET_LENGTH_BUFFER(RX_READ_BUFFER)-4, 16));
613
          RX_STB <= '1';
614
        end if;
615
 
616
      when SEND_LENGTH =>
617
        if RX_ACK = '1' then
618
          RX_PACKET_STATE <= PREFETCH0;
619
          RX_STB <= '0';
620
        end if;
621
 
622
      when PREFETCH0 =>
623
        RX_READ_ADDRESS <= RX_START_ADDRESS_SYNC;
624
        RX_END_ADDRESS <= RX_START_ADDRESS_SYNC + (RX_PACKET_LENGTH_SYNC-3)/2;
625
        RX_PACKET_STATE <= PREFETCH1;
626
 
627
      when PREFETCH1 =>
628
        RX_READ_ADDRESS <= RX_READ_ADDRESS + 1;
629
        RX <= RX_MEMORY(to_integer(RX_READ_ADDRESS));
630
        RX_STB <= '1';
631
        RX_PACKET_STATE <= SEND_DATA;
632
 
633
      when SEND_DATA =>
634
        if RX_ACK = '1' then
635
          RX_READ_ADDRESS <= RX_READ_ADDRESS + 1;
636
          RX <= RX_MEMORY(to_integer(RX_READ_ADDRESS));
637
          if RX_READ_ADDRESS = RX_END_ADDRESS then --don't send last packet
638
            RX_STB <= '0';
639
            RX_PACKET_STATE <= WAIT_NEW_PACKET;
640
            if RX_READ_BUFFER = 31 then
641
              RX_READ_BUFFER <= 0;
642
            else
643
              RX_READ_BUFFER <= RX_READ_BUFFER + 1;
644
            end if;
645
          end if;
646
        end if;
647
 
648
    end case;
649
    if RST = '1' then
650
      RX_STB <= '0';
651
      RX_PACKET_STATE <= WAIT_INITIALISE;
652
    end if;
653
  end process RX_PACKET_FSM;
654
 
655
  ----------------------------------------------------------------------
656
  -- RESET PHY CHIP
657
  ----------------------------------------------------------------------
658
  PHY_RESET <= not RST;
659
 
660
end architecture RTL;

powered by: WebSVN 2.1.0

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