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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [ethlib/] [grethc64.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003 - 2008, Gaisler Research
4
--  Copyright (C) 2008 - 2014, Aeroflex Gaisler
5
--  Copyright (C) 2015 - 2016, Cobham Gaisler
6
--
7
--  This program is free software; you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation; either version 2 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program; if not, write to the Free Software
19
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
20
-----------------------------------------------------------------------------
21
-- Entity:  grethc
22
-- File:  grethc.vhd
23
-- Author:  Marko Isomaki 
24
-- Description: Ethernet Media Access Controller with Ethernet Debug
25
--              Communication Link
26
------------------------------------------------------------------------------
27
library ieee;
28
use ieee.std_logic_1164.all;
29
use ieee.numeric_std.all;
30
library commonlib;
31
use commonlib.types_common.all;
32
library techmap;
33
use techmap.gencomp.all;
34
use techmap.types_mem.all;
35
library ethlib;
36
use ethlib.types_eth.all;
37
 
38
entity grethc64 is
39
  generic(
40
    memtech        : integer := 0;
41
    ifg_gap        : integer := 24;
42
    attempt_limit  : integer := 16;
43
    backoff_limit  : integer := 10;
44
    mdcscaler      : integer range 0 to 255 := 25;
45
    enable_mdio    : integer range 0 to 1 := 0;
46
    fifosize       : integer range 4 to 512 := 8;
47
    nsync          : integer range 1 to 2 := 2;
48
    edcl           : integer range 0 to 3 := 0;
49
    edclbufsz      : integer range 1 to 64 := 1;
50
    macaddrh       : integer := 16#00005E#;
51
    macaddrl       : integer := 16#000000#;
52
    ipaddrh        : integer := 16#c0a8#;
53
    ipaddrl        : integer := 16#0035#;
54
    phyrstadr      : integer range 0 to 32 := 0;
55
    rmii           : integer range 0 to 1  := 0;
56
    oepol          : integer range 0 to 1  := 0;
57
    scanen         : integer range 0 to 1  := 0;
58
    mdint_pol      : integer range 0 to 1  := 0;
59
    enable_mdint   : integer range 0 to 1  := 0;
60
    multicast      : integer range 0 to 1  := 0;
61
    edclsepahbg    : integer range 0 to 1  := 0;
62
    ramdebug       : integer range 0 to 2  := 0;
63
    mdiohold       : integer := 1;
64
    maxsize        : integer := 1500;
65
    gmiimode       : integer range 0 to 1 := 0
66
    );
67
  port(
68
    rst           : in  std_ulogic;
69
    clk           : in  std_ulogic;
70
    ctrli         : in eth_control_type;
71
    cmdi          : in eth_command_type;
72
    statuso       : out eth_mac_status_type;
73
    --! Debug value read from internal buffers suing external bus interface
74
    rdbgdatao     : out  std_logic_vector(31 downto 0);
75
    --irq
76
    irq            : out  std_logic;
77
    --ethernet input signals
78
    rmii_clk       : in   std_ulogic;
79
    tx_clk         : in   std_ulogic;
80
    rx_clk         : in   std_ulogic;
81
    tx_dv          : in   std_ulogic;
82
    rxd            : in   std_logic_vector(3 downto 0);
83
    rx_dv          : in   std_ulogic;
84
    rx_er          : in   std_ulogic;
85
    rx_col         : in   std_ulogic;
86
    rx_en          : in   std_ulogic;
87
    rx_crs         : in   std_ulogic;
88
    mdio_i         : in   std_ulogic;
89
    phyrstaddr     : in   std_logic_vector(4 downto 0);
90
    mdint          : in   std_ulogic;
91
    --ethernet output signals
92
    reset          : out  std_ulogic;
93
    txd            : out  std_logic_vector(3 downto 0);
94
    tx_en          : out  std_ulogic;
95
    tx_er          : out  std_ulogic;
96
    mdc            : out  std_ulogic;
97
    mdio_o         : out  std_ulogic;
98
    mdio_oe        : out  std_ulogic;
99
    --scantest
100
    testrst        : in   std_ulogic;
101
    testen         : in   std_ulogic;
102
    testoen        : in   std_ulogic;
103
    edcladdr       : in   std_logic_vector(3 downto 0) := "0000";
104
    edclsepahb     : in   std_ulogic;
105
    edcldisable    : in   std_ulogic;
106
    speed          : out  std_ulogic;
107
 
108
    tmsto          : out eth_tx_ahb_in_type;
109
    tmsti          : in eth_tx_ahb_out_type;
110
 
111
    tmsto2         : out eth_tx_ahb_in_type;
112
    tmsti2         : in eth_tx_ahb_out_type;
113
 
114
    rmsto          : out eth_rx_ahb_in_type;
115
    rmsti          : in eth_rx_ahb_out_type
116
  );
117
end entity;
118
 
119
architecture rtl of grethc64 is
120
  procedure sel_op_mode(
121
    capbil : in std_logic_vector(4 downto 0);
122
    speed  : out std_ulogic;
123
    duplex : out std_ulogic) is
124
    variable vspeed  : std_ulogic;
125
    variable vduplex : std_ulogic;
126
  begin
127
    vspeed := '0'; vduplex := '0';
128
    vspeed := capbil(4) or capbil(3) or capbil(2);
129
 
130
    vduplex := (vspeed and capbil(3)) or ((not vspeed) and capbil(1));
131
    speed := vspeed;
132
    duplex := vduplex;
133
  end procedure;
134
 
135
  --host constants
136
  constant fabits          : integer := log2(fifosize);
137
  constant burstlength     : integer := setburstlength(fifosize);
138
  constant burstbits       : integer := log2(burstlength);
139
  constant ctrlopcode      : std_logic_vector(15 downto 0) := X"8808";
140
  constant broadcast       : std_logic_vector(47 downto 0) := X"FFFFFFFFFFFF";
141
--  constant maxsizetx       : integer := 1514;
142
  constant index           : integer := log2(edclbufsz);
143
  constant receiveOK       : std_logic_vector(3 downto 0) := "0000";
144
  constant frameCheckError : std_logic_vector(3 downto 0) := "0100";
145
  constant alignmentError  : std_logic_vector(3 downto 0) := "0001";
146
  constant frameTooLong    : std_logic_vector(3 downto 0) := "0010";
147
  constant overrun         : std_logic_vector(3 downto 0) := "1000";
148
  constant minpload        : std_logic_vector(10 downto 0) :=
149
                             conv_std_logic_vector(60, 11);
150
 
151
  --mdio constants
152
  constant divisor : std_logic_vector(7 downto 0) :=
153
    conv_std_logic_vector(mdcscaler, 8);
154
 
155
  --receiver constants
156
  constant maxsizerx : unsigned(15 downto 0) :=
157
    to_unsigned(maxsize + 18 - 4, 16);
158
 
159
  --tranceiver constants
160
  constant maxsizetx : unsigned(15 downto 0) :=
161
    to_unsigned(maxsize + 18 - 4, 16);
162
 
163
  --edcl constants
164
  type szvct is array (0 to 6) of integer;
165
  constant ebuf : szvct := (64, 128, 128, 256, 256, 256, 256);
166
  constant blbits : szvct := (6, 7, 7, 8, 8, 8, 8);
167
  constant winsz : szvct := (4, 4, 8, 8, 16, 32, 64);
168
  constant macaddrt : std_logic_vector(47 downto 0) :=
169
    conv_std_logic_vector(macaddrh, 24) & conv_std_logic_vector(macaddrl, 24);
170
  constant bpbits : integer := blbits(log2(edclbufsz));
171
  constant wsz : integer := winsz(log2(edclbufsz));
172
  constant bselbits : integer := log2(wsz);
173
  constant eabits: integer := log2(edclbufsz) + 8;
174
  constant ebufmax : std_logic_vector(bpbits-1 downto 0) := (others => '1');
175
  constant bufsize : std_logic_vector(2 downto 0) :=
176
                       conv_std_logic_vector(log2(edclbufsz), 3);
177
  constant ebufsize : integer := ebuf(log2(edclbufsz));
178
  constant txfifosize : integer := getfifosize(edcl, fifosize, ebufsize);
179
  constant txfabits : integer := log2(txfifosize);
180
  constant txfifosizev : std_logic_vector(txfabits downto 0) :=
181
    conv_std_logic_vector(txfifosize, txfabits+1);
182
 
183
  constant rxburstlen      : std_logic_vector(fabits downto 0) :=
184
    conv_std_logic_vector(burstlength, fabits+1);
185
  constant txburstlen      : std_logic_vector(txfabits downto 0) :=
186
    conv_std_logic_vector(burstlength, txfabits+1);
187
 
188
  type edclrstate_type is (idle, wrda, wrdsa, wrsa, wrtype, ip, ipdata,
189
                           oplength, arp, iplength, ipcrc, arpop, udp, spill);
190
 
191
  type duplexstate_type is (start, waitop, nextop, selmode, done);
192
 
193
  --host types
194
  type txd_state_type is (idle, read_desc, check_desc, req, fill_fifo,
195
                          check_result, write_result, readhdr, start, wrbus1,
196
                          etdone, getlen, ahberror, fill_fifo2, wrbus2);
197
  type rxd_state_type is (idle, read_desc, check_desc, read_req, read_fifo,
198
                          discard, write_status, write_status2);
199
 
200
  --mdio types
201
  type mdio_state_type is (idle, preamble, startst, op, op2, phyadr, regadr,
202
                           ta, ta2, ta3, data, dataend);
203
 
204
 
205
  type fifo_access_in_type is record
206
    renable   : std_ulogic;
207
    raddress  : std_logic_vector(fabits-1 downto 0);
208
    write     : std_ulogic;
209
    waddress  : std_logic_vector(fabits-1 downto 0);
210
    datain    : std_logic_vector(31 downto 0);
211
  end record;
212
 
213
  type fifo_access_out_type is record
214
    data      : std_logic_vector(31 downto 0);
215
  end record;
216
 
217
  type tx_fifo_access_in_type is record
218
    renable   : std_ulogic;
219
    raddress  : std_logic_vector(txfabits-1 downto 0);
220
    write     : std_ulogic;
221
    waddress  : std_logic_vector(txfabits-1 downto 0);
222
    datain    : std_logic_vector(31 downto 0);
223
  end record;
224
 
225
  type tx_fifo_access_out_type is record
226
    data      : std_logic_vector(31 downto 0);
227
  end record;
228
 
229
  type edcl_ram_in_type is record
230
    renable   : std_ulogic;
231
    raddress  : std_logic_vector(eabits-1 downto 0);
232
    writem    : std_ulogic;
233
    writel    : std_ulogic;
234
    waddressm : std_logic_vector(eabits-1 downto 0);
235
    waddressl : std_logic_vector(eabits-1 downto 0);
236
    datain    : std_logic_vector(31 downto 0);
237
  end record;
238
 
239
  type edcl_ram_out_type is record
240
    data      : std_logic_vector(31 downto 0);
241
  end record;
242
 
243
  type reg_type is record
244
    --user registers
245
    status      : eth_mac_status_type;
246
 
247
    --master tx interface
248
    tmsto           : eth_tx_ahb_in_type;
249
    tmsto2          : eth_tx_ahb_in_type;
250
    txdstate        : txd_state_type;
251
    txwrap          : std_ulogic;
252
    txden           : std_ulogic;
253
    txirq           : std_ulogic;
254
    txaddr          : std_logic_vector(31 downto 2);
255
    txlength        : std_logic_vector(10 downto 0);
256
    txburstcnt      : std_logic_vector(burstbits downto 0);
257
    tfwpnt          : std_logic_vector(txfabits-1 downto 0);
258
    tfrpnt          : std_logic_vector(txfabits-1 downto 0);
259
    tfcnt           : std_logic_vector(txfabits downto 0);
260
    txcnt           : std_logic_vector(10 downto 0);
261
    txstart         : std_ulogic;
262
    txirqgen        : std_ulogic;
263
    txstatus        : std_logic_vector(1 downto 0);
264
    txvalid         : std_ulogic;
265
    txdata          : std_logic_vector(31 downto 0);
266
    writeok         : std_ulogic;
267
    txread          : std_logic_vector(nsync-1 downto 0);
268
    txrestart       : std_logic_vector(nsync downto 0);
269
    txdone          : std_logic_vector(nsync downto 0);
270
    txstart_sync    : std_ulogic;
271
    txreadack       : std_ulogic;
272
    txdataav        : std_ulogic;
273
    txburstav       : std_ulogic;
274
 
275
    --master rx interface
276
    rxrenable       : std_ulogic;
277
    rmsto           : eth_rx_ahb_in_type;
278
    rxdstate        : rxd_state_type;
279
    rxstatus        : std_logic_vector(4 downto 0);
280
    rxaddr          : std_logic_vector(31 downto 2);
281
    rxlength        : std_logic_vector(10 downto 0);
282
    rxbytecount     : std_logic_vector(10 downto 0);
283
    rxwrap          : std_ulogic;
284
    rxirq           : std_ulogic;
285
    rfwpnt          : std_logic_vector(fabits-1 downto 0);
286
    rfrpnt          : std_logic_vector(fabits-1 downto 0);
287
    rfcnt           : std_logic_vector(fabits downto 0);
288
    rxcnt           : std_logic_vector(10 downto 0);
289
    rxdoneold       : std_ulogic;
290
    rxdoneack       : std_ulogic;
291
    rxdone          : std_logic_vector(nsync-1 downto 0);
292
    rxstart         : std_logic_vector(nsync downto 0);
293
    rxwrite         : std_logic_vector(nsync-1 downto 0);
294
    rxwriteack      : std_ulogic;
295
    rxburstcnt      : std_logic_vector(burstbits downto 0);
296
    addrok          : std_ulogic;
297
    addrdone        : std_ulogic;
298
    ctrlpkt         : std_ulogic;
299
    check           : std_ulogic;
300
    checkdata       : std_logic_vector(31 downto 0);
301
    usesizefield    : std_ulogic;
302
    rxden           : std_ulogic;
303
    gotframe        : std_ulogic;
304
    bcast           : std_ulogic;
305
    msbgood         : std_ulogic;
306
    rxburstav       : std_ulogic;
307
    hashlookup      : std_ulogic;
308
    mcast           : std_ulogic;
309
    mcastacc        : std_ulogic;
310
 
311
    --mdio
312
    mdccnt          : std_logic_vector(7 downto 0);
313
    mdioclk         : std_ulogic;
314
    mdioclkold      : std_logic_vector(mdiohold-1 downto 0);
315
    mdio_state      : mdio_state_type;
316
    mdioo           : std_ulogic;
317
    mdioi           : std_ulogic;
318
    mdioen          : std_ulogic;
319
    cnt             : std_logic_vector(4 downto 0);
320
    duplexstate     : duplexstate_type;
321
    init_busy       : std_ulogic;
322
    ext             : std_ulogic;
323
    extcap          : std_ulogic;
324
    regaddr         : std_logic_vector(4 downto 0);
325
    phywr           : std_ulogic;
326
    rstphy          : std_ulogic;
327
    capbil          : std_logic_vector(4 downto 0);
328
    rstaneg         : std_ulogic;
329
    mdint_sync      : std_logic_vector(2 downto 0);
330
 
331
    --edcl
332
    erenable        : std_ulogic;
333
    edclrstate      : edclrstate_type;
334
    edclactive      : std_ulogic;
335
    nak             : std_ulogic;
336
    ewr             : std_ulogic;
337
    write           : std_logic_vector(wsz-1 downto 0);
338
    seq             : std_logic_vector(13 downto 0);
339
    abufs           : std_logic_vector(bselbits downto 0);
340
    tpnt            : std_logic_vector(bselbits-1 downto 0);
341
    rpnt            : std_logic_vector(bselbits-1 downto 0);
342
    tcnt            : std_logic_vector(bpbits-1 downto 0);
343
    rcntm           : std_logic_vector(bpbits-1 downto 0);
344
    rcntl           : std_logic_vector(bpbits-1 downto 0);
345
    ipcrc           : std_logic_vector(17 downto 0);
346
    applength       : std_logic_vector(15 downto 0);
347
    oplen           : std_logic_vector(9 downto 0);
348
    udpsrc          : std_logic_vector(15 downto 0);
349
    ecnt            : std_logic_vector(3 downto 0);
350
    tarp            : std_ulogic;
351
    tnak            : std_ulogic;
352
    tedcl           : std_ulogic;
353
    edclbcast       : std_ulogic;
354
    edclsepahb      : std_ulogic;
355
  end record;
356
 
357
  --host signals
358
  signal arst             : std_ulogic;
359
  signal irst             : std_ulogic;
360
  signal vcc              : std_ulogic;
361
 
362
  signal txi              : host_tx_type;
363
  signal txo              : tx_host_type;
364
 
365
  signal rxi              : host_rx_type;
366
  signal rxo              : rx_host_type;
367
 
368
    --rx ahb fifo
369
  signal rxrenable      : std_ulogic;
370
  signal rxraddress     : std_logic_vector(10 downto 0);
371
  signal rxwrite        : std_ulogic;
372
  signal rxwdata        : std_logic_vector(31 downto 0);
373
  signal rxwaddress     : std_logic_vector(10 downto 0);
374
  signal rxrdata        : std_logic_vector(31 downto 0);
375
    --tx ahb fifo  
376
  signal txrenable      : std_ulogic;
377
  signal txraddress     : std_logic_vector(10 downto 0);
378
  signal txwrite        : std_ulogic;
379
  signal txwdata        : std_logic_vector(31 downto 0);
380
  signal txwaddress     : std_logic_vector(10 downto 0);
381
  signal txrdata        : std_logic_vector(31 downto 0);
382
    --edcl buf     
383
  signal erenable       : std_ulogic;
384
  signal eraddress      : std_logic_vector(15 downto 0);
385
  signal ewritem        : std_ulogic;
386
  signal ewritel        : std_ulogic;
387
  signal ewaddressm     : std_logic_vector(15 downto 0);
388
  signal ewaddressl     : std_logic_vector(15 downto 0);
389
  signal ewdata         : std_logic_vector(31 downto 0);
390
  signal erdata         : std_logic_vector(31 downto 0);
391
 
392
  signal r, rin           : reg_type;
393
 
394
begin
395
 
396
  --reset generators for transmitter and receiver
397
  vcc <= '1';
398
  arst <= testrst when (scanen = 1) and (testen = '1')
399
          else rst and not r.status.reset;
400
  irst <= rst and not r.status.reset;
401
 
402
  comb : process(rst, irst, ctrli, cmdi, r, rmsti, tmsti, txo, rxo,
403
                 erdata, rxrdata, txrdata, mdio_i, phyrstaddr,
404
                 testen, testrst, edcladdr, mdint, tmsti2, edcldisable,
405
                 edclsepahb) is
406
    variable v             : reg_type;
407
    variable vpirq         : std_ulogic;
408
    variable vrdbgdata     : std_logic_vector(31 downto 0);
409
    variable txvalid       : std_ulogic;
410
    variable vtxfi         : tx_fifo_access_in_type;
411
    variable vrxfi         : fifo_access_in_type;
412
    variable lengthav      : std_ulogic;
413
    variable txdone        : std_ulogic;
414
    variable txread        : std_ulogic;
415
    variable txrestart     : std_ulogic;
416
    variable rxstart       : std_ulogic;
417
    variable rxdone        : std_ulogic;
418
    variable vrxwrite      : std_ulogic;
419
    variable ovrunstop     : std_ulogic;
420
    --mdio
421
    variable mdioindex     : integer range 0 to 31;
422
    variable mclk          : std_ulogic;  --rising mdio clk edge
423
    variable nmclk         : std_ulogic;  --falling mdio clk edge
424
    variable mclkvec       : std_logic_vector(mdiohold downto 0);
425
    --edcl
426
    variable veri          : edcl_ram_in_type;
427
    variable swap          : std_ulogic;
428
    variable setmz         : std_ulogic;
429
    variable ipcrctmp      : std_logic_vector(15 downto 0);
430
    variable ipcrctmp2     : std_logic_vector(17 downto 0);
431
    variable vrxenable     : std_ulogic;
432
    variable crctmp        : std_ulogic;
433
    variable vecnt         : integer;
434
  begin
435
    v := r; vrdbgdata := (others => '0'); vpirq := '0';
436
    v.check := '0'; lengthav := r.rxdoneold;-- or r.usesizefield;
437
    ovrunstop := '0'; vrxfi.raddress := v.rfrpnt;
438
 
439
    if edcl /= 0 then
440
      veri.renable := r.erenable;
441
      veri.datain := rxo.dataout;
442
      veri.writem := '0'; veri.writel := '0';
443
      veri.waddressm := r.rpnt & r.rcntm; veri.waddressl := r.rpnt & r.rcntl;
444
    end if;
445
 
446
    vtxfi.renable := '0';
447
    vtxfi.datain := tmsti.data;
448
    vtxfi.raddress := r.tfrpnt; vtxfi.write := '0';
449
    vtxfi.waddress := r.tfwpnt;
450
 
451
    vrxfi.datain := rxo.dataout;
452
    vrxfi.write := '0'; vrxfi.waddress := r.rfwpnt;
453
    vrxfi.renable := r.rxrenable; vrxenable := r.status.rxen;
454
 
455
    --synchronization
456
    v.txdone(0)     := txo.done;
457
    v.txread(0)     := txo.read;
458
    v.txrestart(0)  := txo.restart;
459
    v.rxstart(0)    := rxo.start;
460
    v.rxdone(0)     := rxo.done;
461
    v.rxwrite(0)    := rxo.write;
462
 
463
    if nsync = 2 then
464
      v.txdone(1)     := r.txdone(0);
465
      v.txread(1)     := r.txread(0);
466
      v.txrestart(1)  := r.txrestart(0);
467
      v.rxstart(1)    := r.rxstart(0);
468
      v.rxdone(1)     := r.rxdone(0);
469
      v.rxwrite(1)    := r.rxwrite(0);
470
    end if;
471
 
472
    if enable_mdint = 1 then
473
      v.mdint_sync(0) := mdint;
474
      v.mdint_sync(1) := r.mdint_sync(0);
475
      v.mdint_sync(2) := r.mdint_sync(1);
476
    end if;
477
 
478
    txdone     := r.txdone(nsync)     xor r.txdone(nsync-1);
479
    txread     := r.txreadack         xor r.txread(nsync-1);
480
    txrestart  := r.txrestart(nsync)  xor r.txrestart(nsync-1);
481
    rxstart    := r.rxstart(nsync)    xor r.rxstart(nsync-1);
482
    rxdone     := r.rxdoneack         xor r.rxdone(nsync-1);
483
    vrxwrite   := r.rxwriteack        xor r.rxwrite(nsync-1);
484
 
485
    if txdone = '1' then
486
      v.txstatus := txo.status;
487
    end if;
488
 
489
-------------------------------------------------------------------------------
490
-- HOST INTERFACE -------------------------------------------------------------
491
-------------------------------------------------------------------------------
492
    --SLAVE INTERFACE
493
    if cmdi.set_speed = '1' then v.status.speed := '1';
494
    elsif cmdi.clr_speed = '1' then v.status.speed := '0';
495
    end if;
496
    if cmdi.set_reset = '1' then v.status.reset := '1';
497
    elsif cmdi.clr_reset = '1' then v.status.reset := '0';
498
    end if;
499
    if cmdi.set_full_duplex = '1' then v.status.full_duplex := '1';
500
    elsif cmdi.clr_full_duplex = '1' then v.status.full_duplex := '0';
501
    end if;
502
    if cmdi.set_rxena = '1' then v.status.rxen := '1';
503
    elsif cmdi.clr_rxena = '1' then v.status.rxen := '0';
504
    end if;
505
    if cmdi.set_txena = '1' then v.status.txen := '1';
506
    elsif cmdi.clr_txena = '1' then v.status.txen := '0';
507
    end if;
508
 
509
    if cmdi.clr_status_phystat = '1' then v.status.phystat  := '0'; end if;
510
    if cmdi.clr_status_invaddr = '1' then v.status.invaddr  := '0'; end if;
511
    if cmdi.clr_status_toosmall = '1' then v.status.toosmall := '0'; end if;
512
    if cmdi.clr_status_txahberr = '1' then v.status.txahberr := '0'; end if;
513
    if cmdi.clr_status_rxahberr = '1' then v.status.rxahberr := '0';  end if;
514
    if cmdi.clr_status_tx_int = '1' then v.status.tx_int := '0'; end if;
515
    if cmdi.clr_status_rx_int = '1' then v.status.rx_int := '0'; end if;
516
    if cmdi.clr_status_tx_err = '1' then v.status.tx_err := '0'; end if;
517
    if cmdi.clr_status_rx_err = '1' then v.status.rx_err := '0'; end if;
518
 
519
    if cmdi.mdio_cmd.valid = '1' then
520
       v.status.mdio.cmd.data   := cmdi.mdio_cmd.data;
521
       v.status.mdio.cmd.regadr := cmdi.mdio_cmd.regadr;
522
       v.status.mdio.cmd.read   := cmdi.mdio_cmd.read;
523
       v.status.mdio.cmd.write  := cmdi.mdio_cmd.write;
524
       v.status.mdio.busy       := cmdi.mdio_cmd.read or cmdi.mdio_cmd.write;
525
    end if;
526
 
527
    if cmdi.dbg_access_id = DBG_ACCESS_TX_BUFFER then
528
       vtxfi.write    := cmdi.dbg_wr_ena;
529
       vtxfi.waddress := cmdi.dbg_addr(txfabits+1 downto 2);
530
       vtxfi.datain   := cmdi.dbg_wdata;
531
       vtxfi.raddress := cmdi.dbg_addr(txfabits+1 downto 2);
532
       vtxfi.renable  := cmdi.dbg_rd_ena;
533
       vrdbgdata      := txrdata;
534
    end if;
535
    if cmdi.dbg_access_id = DBG_ACCESS_RX_BUFFER then
536
       vrxfi.write    := cmdi.dbg_wr_ena;
537
       vrxfi.waddress := cmdi.dbg_addr(fabits+1 downto 2);
538
       vrxfi.datain   := cmdi.dbg_wdata;
539
       vrxfi.raddress := cmdi.dbg_addr(fabits+1 downto 2);
540
       vrxfi.renable  := cmdi.dbg_rd_ena;
541
       vrdbgdata      := rxrdata;
542
    end if;
543
    if cmdi.dbg_access_id = DBG_ACCESS_EDCL_BUFFER then
544
       veri.writem    := cmdi.dbg_wr_ena;
545
       veri.writel    := cmdi.dbg_wr_ena;
546
       veri.waddressm := cmdi.dbg_addr(eabits+1 downto 2);
547
       veri.waddressl := cmdi.dbg_addr(eabits+1 downto 2);
548
       veri.datain    := cmdi.dbg_wdata;
549
       veri.raddress  := cmdi.dbg_addr(eabits+1 downto 2);
550
       veri.renable   := cmdi.dbg_rd_ena;
551
       vrdbgdata      := erdata;
552
    end if;
553
 
554
 
555
   --PHY STATUS DETECTION
556
   if enable_mdint = 1 then
557
     if mdint_pol = 0 then
558
       if (r.mdint_sync(2) and not r.mdint_sync(1)) = '1' then
559
         v.status.phystat := '1';
560
         if ctrli.pstatirqen = '1' then
561
           vpirq := '1';
562
         end if;
563
       end if;
564
     else
565
       if (r.mdint_sync(1) and not r.mdint_sync(2)) = '1' then
566
         v.status.phystat := '1';
567
         if ctrli.pstatirqen = '1' then
568
           vpirq := '1';
569
         end if;
570
       end if;
571
     end if;
572
   end if;
573
 
574
   --MASTER INTERFACE
575
 
576
   v.txburstav := '0';
577
   if (txfifosizev - r.tfcnt) >= txburstlen then
578
     v.txburstav := '1';
579
   end if;
580
 
581
   if (conv_integer(r.abufs) /= 0) then
582
     v.status.edcltx_idle := '0';
583
   else
584
     v.status.edcltx_idle := '1';
585
   end if;
586
 
587
   --tx dma fsm
588
   case r.txdstate is
589
   when idle =>
590
     v.txcnt := (others => '0'); v.txburstcnt := (others => '0');
591
     if (edcl /= 0) then
592
       v.tedcl := '0'; v.erenable := '0';
593
     end if;
594
     if (edcl /= 0) and (conv_integer(r.abufs) /= 0) and
595
        (ctrli.edcldis = '0') then
596
       v.erenable := '1'; v.status.edcltx_idle := '0';
597
       if r.erenable = '1' then
598
         v.txdstate := getlen;
599
       end if;
600
       v.tcnt := conv_std_logic_vector(10, bpbits);
601
     elsif r.status.txen = '1' then
602
       v.txdstate := read_desc;
603
       v.tmsto.write := '0';
604
       v.tmsto.addr := ctrli.txdesc & r.status.txdsel & "000";
605
       v.tmsto.req := '1';
606
       --! AXI_ENABLE: burst transaction size in bytes
607
       v.tmsto.burst_bytes := conv_std_logic_vector(8, 11);
608
     end if;
609
     if r.txirqgen = '1' then
610
       vpirq := '1'; v.txirqgen := '0';
611
     end if;
612
     if txrestart = '1' then
613
       v.txrestart(nsync) := r.txrestart(nsync-1);
614
       v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
615
       v.tfwpnt := (others => '0');
616
     end if;
617
   when read_desc =>
618
     v.tmsto.write := '0'; v.txstatus := (others => '0');
619
     v.tfwpnt := (others => '0'); v.tfrpnt := (others => '0');
620
     v.tfcnt := (others => '0');
621
     if tmsti.grant = '1' then
622
       v.txburstcnt := r.txburstcnt + 1; v.tmsto.addr := r.tmsto.addr + 4;
623
       if r.txburstcnt(0) = '1' then
624
         v.tmsto.req := '0';
625
       end if;
626
     end if;
627
     if tmsti.ready = '1' then
628
       v.txcnt := r.txcnt + 1;
629
       case r.txcnt(1 downto 0) is
630
         when "00" =>
631
           v.txlength  := tmsti.data(10 downto 0);
632
           v.txden     := tmsti.data(11);
633
           v.txwrap    := tmsti.data(12);
634
           v.txirq     := tmsti.data(13);
635
           v.status.txen := tmsti.data(11);
636
         when "01" =>
637
           v.txaddr    := tmsti.data(31 downto 2);
638
           v.txdstate  := check_desc;
639
         when others => null;
640
       end case;
641
     end if;
642
   when check_desc =>
643
     v.txstart := '0';
644
     v.txburstcnt := (others => '0');
645
     if r.txden = '1' then
646
       if (unsigned(r.txlength) > unsigned(maxsizetx)) or
647
                  (conv_integer(r.txlength) = 0) then
648
         v.txdstate := write_result;
649
         v.tmsto.req := '1';
650
         v.tmsto.write := '1';
651
         v.tmsto.addr := ctrli.txdesc & r.status.txdsel & "000";
652
         v.tmsto.data := (others => '0');
653
         --! AXI_ENABLE: length of transaction not defined so use simple DMA access
654
         v.tmsto.burst_bytes := conv_std_logic_vector(4,11);
655
       else
656
         v.txdstate := req;
657
         v.tmsto.addr := r.txaddr & "00";
658
         v.txcnt(10 downto 0) := r.txlength;
659
         --! AXI_ENABLE: length of transaction defined
660
         v.tmsto.burst_bytes := r.txlength;
661
       end if;
662
     else
663
       v.txdstate := idle;
664
     end if;
665
   when req =>
666
     if txrestart = '1' then
667
       v.txdstate := idle; v.txstart := '0';
668
       if (edcl /= 0) and (r.tedcl = '1') then
669
         v.txdstate := idle;
670
       end if;
671
     elsif txdone = '1' then
672
       v.txdstate := check_result;
673
       v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
674
       v.tfwpnt := (others => '0');
675
       if (edcl /= 0) and (r.tedcl = '1') then
676
         v.txdstate := etdone;
677
       end if;
678
     elsif conv_integer(r.txcnt) = 0 then
679
       v.txdstate := check_result;
680
       if (edcl /= 0) and (r.tedcl = '1') then
681
         v.txdstate := etdone; v.txstart_sync := not r.txstart_sync;
682
       end if;
683
     elsif (r.txburstav = '1') or (r.tedcl = '1') then
684
       if (edclsepahbg = 0) or (edcl = 0) or
685
          (r.edclsepahb = '0') or (r.tedcl = '0') then
686
         v.tmsto.req := '1'; v.txdstate := fill_fifo;
687
       else
688
         v.tmsto2.req := '1'; v.txdstate := fill_fifo2;
689
       end if;
690
     end if;
691
     v.txburstcnt := (others => '0');
692
   when fill_fifo =>
693
     v.txburstav := '0';
694
     if tmsti.grant = '1' then
695
       v.tmsto.addr := r.tmsto.addr + 4;
696
       if ((conv_integer(r.txcnt) <= 8) and (tmsti.ready = '1')) or
697
          ((conv_integer(r.txcnt) <= 4) and (tmsti.ready = '0')) then
698
         v.tmsto.req := '0';
699
       end if;
700
       v.txburstcnt := r.txburstcnt + 1;
701
       if (conv_integer(r.txburstcnt) = burstlength-1) then
702
         v.tmsto.req := '0';
703
       end if;
704
     end if;
705
     if (tmsti.ready = '1') or ((edcl /= 0) and (r.tedcl and tmsti.error) = '1') then
706
       v.tfwpnt := r.tfwpnt + 1; v.tfcnt := r.tfcnt + 1; vtxfi.write := '1';
707
       if r.tmsto.req = '0' then
708
         v.txdstate := req;
709
         if (r.txstart = '0') and not ((edcl /= 0) and (r.tedcl = '1')) then
710
           v.txstart := '1'; v.txstart_sync := not r.txstart_sync;
711
         end if;
712
       end if;
713
       if conv_integer(r.txcnt) > 3 then
714
         v.txcnt := r.txcnt - 4;
715
       else
716
         v.txcnt := (others => '0');
717
       end if;
718
     end if;
719
   when fill_fifo2 =>
720
     if edclsepahbg = 1 then
721
       v.txburstav := '0';
722
       vtxfi.datain := tmsti2.data;
723
       if tmsti2.grant = '1' then
724
         v.tmsto2.addr := r.tmsto2.addr + 4;
725
         if ((conv_integer(r.txcnt) <= 8) and (tmsti2.ready = '1')) or
726
            ((conv_integer(r.txcnt) <= 4) and (tmsti2.ready = '0')) then
727
           v.tmsto2.req := '0';
728
         end if;
729
         v.txburstcnt := r.txburstcnt + 1;
730
         if (conv_integer(r.txburstcnt) = burstlength-1) then
731
           v.tmsto2.req := '0';
732
         end if;
733
       end if;
734
       if (tmsti2.ready = '1') or ((edcl /= 0) and (r.tedcl and tmsti2.error) = '1') then
735
         v.tfwpnt := r.tfwpnt + 1; v.tfcnt := r.tfcnt + 1; vtxfi.write := '1';
736
         if r.tmsto2.req = '0' then
737
           v.txdstate := req;
738
           if (r.txstart = '0') and not ((edcl /= 0) and (r.tedcl = '1')) then
739
             v.txstart := '1'; v.txstart_sync := not r.txstart_sync;
740
           end if;
741
         end if;
742
         if conv_integer(r.txcnt) > 3 then
743
           v.txcnt := r.txcnt - 4;
744
         else
745
           v.txcnt := (others => '0');
746
         end if;
747
       end if;
748
     end if;
749
   when check_result =>
750
     if txdone = '1' then
751
       v.txdstate := write_result; v.tmsto.req := '1'; v.txstart := '0';
752
       v.tmsto.write := '1'; v.tmsto.addr := ctrli.txdesc & r.status.txdsel & "000";
753
       v.tmsto.data(31 downto 16) := (others => '0');
754
       v.tmsto.data(15 downto 14) := v.txstatus;
755
       v.tmsto.data(13 downto 0)  := (others => '0');
756
       v.txdone(nsync) := r.txdone(nsync-1);
757
     elsif txrestart = '1' then
758
       v.txdstate := idle; v.txstart := '0';
759
     end if;
760
   when write_result =>
761
     if tmsti.grant = '1' then
762
       v.tmsto.req := '0'; v.tmsto.addr := r.tmsto.addr + 4;
763
     end if;
764
     if tmsti.ready = '1' then
765
       v.txdstate := idle;
766
       v.txirqgen := ctrli.tx_irqen and r.txirq;
767
       if r.txwrap = '0' then v.status.txdsel := r.status.txdsel + 1;
768
       else v.status.txdsel := (others => '0'); end if;
769
       if conv_integer(r.txstatus) = 0 then v.status.tx_int := '1';
770
       else v.status.tx_err := '1'; end if;
771
     end if;
772
   when ahberror =>
773
     v.tfcnt := (others => '0'); v.tfwpnt := (others => '0');
774
     v.tfrpnt := (others => '0');
775
     v.status.txahberr := '1'; v.status.txen := '0';
776
     if not ((edcl /= 0) and (r.tedcl = '1')) then
777
       if r.txstart = '1' then
778
         if txdone = '1' then
779
           v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1);
780
         end if;
781
       else
782
         v.txdstate := idle;
783
       end if;
784
     else
785
       v.txdstate := idle;
786
       v.abufs := r.abufs - 1; v.tpnt := r.tpnt + 1;
787
     end if;
788
   when others =>
789
     null;
790
   end case;
791
 
792
   --tx fifo read
793
   v.txdataav := '0';
794
   if conv_integer(r.tfcnt) /= 0 then
795
     v.txdataav := '1';
796
   end if;
797
   if txread = '1' then
798
     v.txreadack := not r.txreadack;
799
     if r.txdataav = '1' then
800
       if conv_integer(r.tfcnt) < 2 then
801
         v.txdataav := '0';
802
       end if;
803
       v.txvalid := '1';
804
       v.tfcnt := v.tfcnt - 1; v.tfrpnt := r.tfrpnt + 1;
805
     else
806
       v.txvalid := '0';
807
     end if;
808
     v.txdata := txrdata;
809
   end if;
810
 
811
   v.rxburstav := '0';
812
   if r.rfcnt >= rxburstlen then
813
     v.rxburstav := '1';
814
   end if;
815
 
816
   if ramdebug = 0 then
817
     vtxfi.renable := v.txdataav;
818
   else
819
     vtxfi.renable := vtxfi.renable or v.txdataav;
820
   end if;
821
 
822
   --rx dma fsm
823
   case r.rxdstate is
824
   when idle =>
825
     v.rmsto.req := '0'; v.rmsto.write := '0'; v.addrok := '0';
826
     v.rxburstcnt := (others => '0'); v.addrdone := '0';
827
     v.rxcnt := (others => '0'); v.rxdoneold := '0';
828
     v.ctrlpkt := '0'; v.bcast := '0'; v.edclactive := '0';
829
     v.msbgood := '0'; v.rxrenable := '0';
830
     if multicast = 1 then
831
       v.mcast := '0'; v.mcastacc := '0';
832
     end if;
833
     if r.status.rxen = '1' then
834
       v.rxdstate := read_desc;
835
       v.rmsto.req := '1';
836
       v.rmsto.addr := ctrli.rxdesc & r.status.rxdsel & "000";
837
       --! AXI_ENABLE: burst transaction descriptor header size in bytes
838
       v.rmsto.burst_bytes := conv_std_logic_vector(8, 11);
839
     elsif rxstart = '1' then
840
       v.rxstart(nsync) := r.rxstart(nsync-1);
841
       v.rxdstate := discard;
842
     end if;
843
   when read_desc =>
844
     v.rxstatus := (others => '0');
845
     if rmsti.grant = '1' then
846
       v.rxburstcnt := r.rxburstcnt + 1; v.rmsto.addr := r.rmsto.addr + 4;
847
       if r.rxburstcnt(0) = '1' then
848
         v.rmsto.req := '0';
849
         --! AXI_ENABLE: don't use burst operation:
850
         v.rmsto.burst_bytes := conv_std_logic_vector(4,11);
851
       end if;
852
     end if;
853
     if rmsti.ready = '1' then
854
       v.rxcnt := r.rxcnt + 1;
855
       case r.rxcnt(1 downto 0) is
856
         when "00" =>
857
           v.status.rxen := rmsti.data(11);
858
           v.rxden     := rmsti.data(11);
859
           v.rxwrap    := rmsti.data(12);
860
           v.rxirq     := rmsti.data(13);
861
         when "01" =>
862
           v.rxaddr    := rmsti.data(31 downto 2);
863
           v.rxdstate  := check_desc;
864
           v.rxrenable := '1';
865
         when others =>
866
           null;
867
       end case;
868
     end if;
869
     if rmsti.error = '1' then
870
       v.rmsto.req := '0'; v.rxdstate := idle;
871
       v.status.rxahberr := '1'; v.status.rxen := '0';
872
     end if;
873
   when check_desc =>
874
     v.rxcnt := (others => '0'); v.usesizefield := '0'; v.rmsto.write := '1';
875
     if r.rxden = '1' then
876
       if rxstart = '1' then
877
         v.rxdstate := read_req; v.rxstart(nsync) := r.rxstart(nsync-1);
878
       end if;
879
     else
880
       v.rxdstate := idle;
881
     end if;
882
     v.rmsto.addr := r.rxaddr & "00";
883
   when read_req =>
884
     if r.edclactive = '1' then
885
       v.rxdstate := discard;
886
     elsif (r.rxdoneold and r.rxstatus(3)) = '1' then
887
       v.rxdstate := write_status;
888
       v.rfcnt := (others => '0'); v.rfwpnt := (others => '0');
889
       v.rfrpnt := (others => '0'); v.writeok := '1';
890
       v.rxbytecount := (others => '0'); v.rxlength := (others => '0');
891
     elsif ((r.addrdone and not r.addrok) or r.ctrlpkt) = '1' then
892
       v.rxdstate := discard; v.status.invaddr := '1';
893
     elsif ((r.rxdoneold = '1') and r.rxcnt >= r.rxlength) then
894
       if r.gotframe = '1' then
895
         v.rxdstate := write_status;
896
       else
897
         v.rxdstate := discard; v.status.toosmall := '1';
898
       end if;
899
     elsif (r.rxburstav or r.rxdoneold) = '1' then
900
       v.rmsto.req := '1'; v.rxdstate := read_fifo;
901
       v.rfrpnt := r.rfrpnt + 1; v.rfcnt := r.rfcnt - 1;
902
     end if;
903
     v.rxburstcnt := (others => '0'); v.rmsto.data := rxrdata;
904
   when read_fifo =>
905
     v.rxburstav := '0';
906
     if rmsti.grant = '1' then
907
       v.rmsto.addr := r.rmsto.addr + 4;
908
       if (lengthav = '1') then
909
         if ((conv_integer(r.rxcnt) >=
910
              (conv_integer(r.rxlength) - 8)) and (rmsti.ready = '1')) or
911
         ((conv_integer(r.rxcnt) >=
912
           (conv_integer(r.rxlength) - 4)) and (rmsti.ready = '0')) then
913
           v.rmsto.req := '0';
914
         end if;
915
       end if;
916
       v.rxburstcnt := r.rxburstcnt + 1;
917
       if (conv_integer(r.rxburstcnt) = burstlength-1) then
918
         v.rmsto.req := '0';
919
       end if;
920
     end if;
921
     if rmsti.ready = '1' then
922
       v.rmsto.data := rxrdata;
923
       v.rxcnt := r.rxcnt + 4;
924
       if r.rmsto.req = '0' then
925
         v.rxdstate := read_req;
926
       else
927
         v.rfcnt := r.rfcnt - 1; v.rfrpnt := r.rfrpnt + 1;
928
       end if;
929
       v.check := '1'; v.checkdata := r.rmsto.data;
930
     end if;
931
     if rmsti.error = '1' then
932
       v.rmsto.req := '0'; v.rxdstate := discard;
933
       v.rxcnt := r.rxcnt + 4;
934
       v.status.rxahberr := '1'; v.status.rxen := '0';
935
     end if;
936
   when write_status =>
937
     v.rmsto.req := '1'; v.rmsto.addr := ctrli.rxdesc & r.status.rxdsel & "000";
938
     v.rxdstate := write_status2;
939
     if multicast = 1 then
940
       v.rmsto.data := "00000" & r.mcastacc & "0000000" &
941
                        r.rxstatus & "000" & r.rxlength;
942
     else
943
       v.rmsto.data := "0000000000000" &
944
                        r.rxstatus & "000" & r.rxlength;
945
     end if;
946
   when write_status2 =>
947
     if rmsti.grant = '1' then
948
       v.rmsto.req := '0'; v.rmsto.addr := r.rmsto.addr + 4;
949
     end if;
950
     if rmsti.ready = '1' then
951
       if (r.rxstatus(4) or not r.rxstatus(3)) = '1' then
952
         v.rxdstate := discard;
953
       else
954
         v.rxdstate := idle;
955
       end if;
956
       if (ctrli.rx_irqen and r.rxirq) = '1' then
957
         vpirq := '1';
958
       end if;
959
       if conv_integer(r.rxstatus) = 0 then v.status.rx_int := '1';
960
       else v.status.rx_err := '1'; end if;
961
       if r.rxwrap = '1' then
962
         v.status.rxdsel := (others => '0');
963
       else
964
         v.status.rxdsel := r.status.rxdsel + 1;
965
       end if;
966
     end if;
967
     if rmsti.error = '1' then
968
       v.rmsto.req := '0'; v.rxdstate := idle;
969
       v.status.rxahberr := '1'; v.status.rxen := '0';
970
     end if;
971
   when discard =>
972
     if (r.rxdoneold = '0') then
973
       if conv_integer(r.rfcnt) /= 0 then
974
         v.rfrpnt := r.rfrpnt + 1; v.rfcnt := r.rfcnt - 1;
975
         v.rxcnt := r.rxcnt + 4;
976
       end if;
977
     else
978
       if r.rxstatus(3) = '1' then
979
         v.rfcnt := (others => '0'); v.rfwpnt := (others => '0');
980
         v.rfrpnt := (others => '0'); v.writeok := '1';
981
         v.rxbytecount := (others => '0'); v.rxlength := (others => '0');
982
         v.rxdstate := idle;
983
       elsif (conv_integer(r.rxcnt) < conv_integer(r.rxbytecount)) then
984
         if conv_integer(r.rfcnt) /= 0 then
985
           v.rfrpnt := r.rfrpnt + 1; v.rfcnt := r.rfcnt - 1;
986
           v.rxcnt := r.rxcnt + 4;
987
         end if;
988
       else
989
         v.rxdstate := idle; v.ctrlpkt := '0';
990
       end if;
991
     end if;
992
   when others =>
993
     null;
994
   end case;
995
 
996
   --rx address/type check
997
   if r.check = '1' and r.rxcnt(10 downto 5) = "000000" then
998
     case r.rxcnt(4 downto 2) is
999
     when "001" =>
1000
       if ctrli.prom = '1' then
1001
         v.addrok := '1';
1002
       end if;
1003
       v.mcast := r.checkdata(24);
1004
       if r.checkdata = broadcast(47 downto 16) then
1005
         v.bcast := '1';
1006
       end if;
1007
       if r.checkdata = ctrli.mac_addr(47 downto 16) then
1008
         v.msbgood := '1';
1009
       end if;
1010
     when "010" =>
1011
       if r.checkdata(31 downto 16) = broadcast(15 downto 0) then
1012
         if r.bcast = '1' then
1013
           v.addrok := '1';
1014
         end if;
1015
       else
1016
         v.bcast := '0';
1017
       end if;
1018
       if r.checkdata(31 downto 16) = ctrli.mac_addr(15 downto 0) then
1019
         if r.msbgood = '1' then
1020
           v.addrok := '1';
1021
         end if;
1022
       end if;
1023
       if multicast = 1 then
1024
         v.hashlookup := ctrli.hash(conv_integer(rxo.mcasthash));
1025
       end if;
1026
     when "011" =>
1027
       if multicast = 1 then
1028
         if (r.hashlookup and ctrli.mcasten and r.mcast) = '1' then
1029
           v.addrok := '1';
1030
           if r.bcast = '0' then
1031
             v.mcastacc := '1';
1032
           end if;
1033
         end if;
1034
       end if;
1035
     when "100" =>
1036
       if r.checkdata(31 downto 16) = ctrlopcode then v.ctrlpkt := '1'; end if;
1037
       v.addrdone := '1';
1038
     when others =>
1039
       null;
1040
     end case;
1041
   end if;
1042
 
1043
   --rx packet done
1044
   if (rxdone and not rxstart) = '1' then
1045
     v.gotframe := rxo.gotframe; v.rxbytecount := rxo.byte_count;
1046
     v.rxstatus(3 downto 0) := rxo.status;
1047
     if (unsigned(rxo.lentype) > maxsizerx) or (rxo.status /= "0000") then
1048
       v.rxlength := rxo.byte_count;
1049
     else
1050
       v.rxlength := rxo.lentype(10 downto 0);
1051
       if (rxo.lentype(10 downto 0) > minpload) and
1052
          (rxo.lentype(10 downto 0) /= rxo.byte_count) then
1053
         if rxo.status(2 downto 0) = "000" then
1054
           v.rxstatus(4) := '1'; v.rxlength := rxo.byte_count;
1055
           v.usesizefield := '0';
1056
         end if;
1057
       elsif (rxo.lentype(10 downto 0) <= minpload) and
1058
             (rxo.byte_count /= minpload) then
1059
         if rxo.status(2 downto 0) = "000" then
1060
           v.rxstatus(4) := '1'; v.rxlength := rxo.byte_count;
1061
           v.usesizefield := '0';
1062
         end if;
1063
       end if;
1064
     end if;
1065
     v.rxdoneold := '1';
1066
     v.rxdoneack := not r.rxdoneack;
1067
   end if;
1068
 
1069
   --rx fifo write
1070
   if vrxwrite = '1' then
1071
     v.rxwriteack := not r.rxwriteack;
1072
     if (not r.rfcnt(fabits)) = '1' then
1073
       v.rfwpnt := r.rfwpnt + 1; v.rfcnt := v.rfcnt + 1; v.writeok := '1';
1074
       vrxfi.write := '1';
1075
     else
1076
       v.writeok := '0';
1077
     end if;
1078
   end if;
1079
 
1080
   --must be placed here because it uses variable
1081
   if (ramdebug = 0) or (ctrli.ramdebugen = '0') then
1082
     vrxfi.raddress := v.rfrpnt;
1083
   end if;
1084
 
1085
-------------------------------------------------------------------------------
1086
-- MDIO INTERFACE -------------------------------------------------------------
1087
-------------------------------------------------------------------------------
1088
   --mdio commands
1089
   if enable_mdio = 1 then
1090
     mclkvec := r.mdioclkold & r.mdioclk;
1091
     mclk := mclkvec(mdiohold-1) and not mclkvec(mdiohold);
1092
     nmclk := mclkvec(1) and not mclkvec(0);
1093
     v.mdioclkold := mclkvec(mdiohold-1 downto 0);
1094
     if r.mdccnt = "00000000" then
1095
       v.mdccnt := divisor;
1096
       v.mdioclk := not r.mdioclk;
1097
     else
1098
       v.mdccnt := r.mdccnt - 1;
1099
     end if;
1100
     mdioindex := conv_integer(r.cnt); v.mdioi := mdio_i;
1101
     case r.mdio_state is
1102
       when idle =>
1103
         if (enable_mdio = 1) and (edcl = 0) and (r.status.reset = '1') then
1104
           v.mdio_state := idle; v.status.mdio.cmd.read := '0';
1105
           v.status.mdio.cmd.write := '0'; v.status.mdio.busy := '0';
1106
           v.status.mdio.cmd.data := (others => '0');
1107
           v.status.mdio.cmd.regadr := (others => '0');
1108
           v.status.reset := '0';
1109
           if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
1110
         end if;
1111
         if mclk = '1' then
1112
           v.cnt := (others => '0');
1113
           if r.status.mdio.busy = '1' then
1114
             v.status.mdio.linkfail := '0';
1115
             if r.status.mdio.cmd.read = '1' then
1116
               v.status.mdio.cmd.write := '0';
1117
             end if;
1118
             v.mdio_state := preamble; v.mdioo := '1';
1119
             if OEPOL = 0 then v.mdioen := '0'; else v.mdioen := '1'; end if;
1120
           end if;
1121
         end if;
1122
       when preamble =>
1123
         if mclk = '1' then
1124
           v.cnt := r.cnt + 1;
1125
           if r.cnt = "11111" then
1126
             v.mdioo := '0'; v.mdio_state := startst;
1127
           end if;
1128
         end if;
1129
       when startst =>
1130
         if mclk = '1' then
1131
           v.mdioo := '1'; v.mdio_state := op; v.cnt := (others => '0');
1132
         end if;
1133
       when op =>
1134
         if mclk = '1' then
1135
           v.mdio_state := op2;
1136
           if r.status.mdio.cmd.read = '1' then v.mdioo := '1';
1137
           else v.mdioo := '0'; end if;
1138
         end if;
1139
       when op2 =>
1140
         if mclk = '1' then
1141
           v.mdioo := not r.mdioo; v.mdio_state := phyadr;
1142
           v.cnt := (others => '0');
1143
         end if;
1144
       when phyadr =>
1145
         if mclk = '1' then
1146
           v.cnt := r.cnt + 1;
1147
           case mdioindex is
1148
           when 0 => v.mdioo := ctrli.mdio_phyadr(4);
1149
           when 1 => v.mdioo := ctrli.mdio_phyadr(3);
1150
           when 2 => v.mdioo := ctrli.mdio_phyadr(2);
1151
           when 3 => v.mdioo := ctrli.mdio_phyadr(1);
1152
           when 4 => v.mdioo := ctrli.mdio_phyadr(0);
1153
                     v.mdio_state := regadr; v.cnt := (others => '0');
1154
           when others => null;
1155
           end case;
1156
         end if;
1157
       when regadr =>
1158
         if mclk = '1' then
1159
           v.cnt := r.cnt + 1;
1160
           case mdioindex is
1161
           when 0 => v.mdioo := r.status.mdio.cmd.regadr(4);
1162
           when 1 => v.mdioo := r.status.mdio.cmd.regadr(3);
1163
           when 2 => v.mdioo := r.status.mdio.cmd.regadr(2);
1164
           when 3 => v.mdioo := r.status.mdio.cmd.regadr(1);
1165
           when 4 => v.mdioo := r.status.mdio.cmd.regadr(0);
1166
                     v.mdio_state := ta; v.cnt := (others => '0');
1167
           when others => null;
1168
           end case;
1169
         end if;
1170
       when ta =>
1171
         if mclk = '1' then
1172
           v.mdio_state := ta2;
1173
           if r.status.mdio.cmd.read = '1' then
1174
             if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
1175
           else v.mdioo := '1'; end if;
1176
         end if;
1177
       when ta2 =>
1178
         if mclk = '1' then
1179
           v.cnt := "01111"; v.mdio_state := ta3;
1180
           if r.status.mdio.cmd.write = '1' then v.mdioo := '0'; v.mdio_state := data; end if;
1181
         end if;
1182
       when ta3 =>
1183
         if mclk = '1' then
1184
           v.mdio_state := data;
1185
         end if;
1186
         if nmclk = '1' then
1187
           if r.mdioi /= '0' then
1188
             v.status.mdio.linkfail := '1';
1189
           end if;
1190
         end if;
1191
       when data =>
1192
         if mclk = '1' then
1193
           v.cnt := r.cnt - 1;
1194
           if r.cnt = "00000" then
1195
             v.mdio_state := dataend;
1196
           end if;
1197
           if r.status.mdio.cmd.read = '0' then
1198
             v.mdioo := r.status.mdio.cmd.data(mdioindex);
1199
           end if;
1200
         end if;
1201
         if nmclk = '1' then
1202
           if r.status.mdio.cmd.read = '1' then
1203
             v.status.mdio.cmd.data(mdioindex) := r.mdioi;
1204
           end if;
1205
         end if;
1206
       when dataend =>
1207
         if mclk = '1' then
1208
           if (rmii = 1) or (edcl /= 0) then
1209
             v.init_busy := '0';
1210
             if (r.duplexstate = done or ctrli.edcldis = '1' or ctrli.disableduplex = '1') then
1211
               v.status.mdio.busy := '0';
1212
             end if;
1213
           else
1214
             v.status.mdio.busy := '0';
1215
           end if;
1216
           v.status.mdio.cmd.read := '0';
1217
           v.status.mdio.cmd.write := '0'; v.mdio_state := idle;
1218
           if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
1219
         end if;
1220
       when others =>
1221
         null;
1222
     end case;
1223
   end if;
1224
 
1225
-------------------------------------------------------------------------------
1226
-- EDCL -----------------------------------------------------------------------
1227
-------------------------------------------------------------------------------
1228
   if (edcl /= 0) then
1229
     if (ramdebug /= 2) or (ctrli.ramdebugen = '0') then
1230
       veri.renable := r.erenable; veri.writem := '0'; veri.writel := '0';
1231
       veri.waddressm := r.rpnt & r.rcntm; veri.waddressl := r.rpnt & r.rcntl;
1232
       vrxenable := '1';
1233
     end if;
1234
 
1235
     swap := '0'; vecnt := conv_integer(r.ecnt); setmz := '0';
1236
 
1237
     if vrxwrite = '1' then
1238
       if ctrli.edcldis = '0' then
1239
         v.rxwriteack := not r.rxwriteack;
1240
       end if;
1241
     end if;
1242
 
1243
     --edcl receiver 
1244
     case r.edclrstate is
1245
       when idle =>
1246
         v.edclbcast := '0'; v.status.edclrx_idle := '1';
1247
         if (ramdebug /= 2) or (ctrli.ramdebugen = '0') then
1248
           if (rxstart and not ctrli.edcldis) = '1' then
1249
             v.edclrstate := wrda; v.edclactive := '0'; v.status.edclrx_idle := '0';
1250
             v.rcntm := conv_std_logic_vector(2, bpbits);
1251
             v.rcntl := conv_std_logic_vector(1, bpbits);
1252
           end if;
1253
         end if;
1254
       when wrda =>
1255
         if vrxwrite = '1' then
1256
           v.edclrstate := wrdsa;
1257
           veri.writem := '1'; veri.writel := '1';
1258
           swap := '1';
1259
           v.rcntm := r.rcntm - 2; v.rcntl := r.rcntl + 1;
1260
           if (ctrli.emacaddr(47 downto 16) /= rxo.dataout) and
1261
                        (X"FFFFFFFF" /= rxo.dataout) then
1262
             v.edclrstate := spill;
1263
           elsif (X"FFFFFFFF" = rxo.dataout) then
1264
              v.edclbcast := '1';
1265
           end if;
1266
           if conv_integer(r.abufs) = wsz then
1267
             v.edclrstate := spill;
1268
           end if;
1269
         end if;
1270
         if (rxdone and not rxstart) = '1' then
1271
           v.edclrstate := idle;
1272
         end if;
1273
       when wrdsa =>
1274
         if vrxwrite = '1' then
1275
           v.edclrstate := wrsa; swap := '1';
1276
           veri.writem := '1'; veri.writel := '1';
1277
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl - 2;
1278
           if (ctrli.emacaddr(15 downto 0) /= rxo.dataout(31 downto 16)) and
1279
                           (X"FFFF" /= rxo.dataout(31 downto 16)) then
1280
             v.edclrstate := spill;
1281
           elsif (X"FFFF" = rxo.dataout(31 downto 16)) then
1282
             v.edclbcast := r.edclbcast;
1283
           end if;
1284
         end if;
1285
         if (rxdone and not rxstart) = '1' then
1286
           v.edclrstate := idle;
1287
         end if;
1288
       when wrsa =>
1289
         if vrxwrite = '1' then
1290
           veri.writem := '1'; veri.writel := '1';
1291
           v.edclrstate := wrtype; swap := '1';
1292
           v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl + 3;
1293
         end if;
1294
         if (rxdone and not rxstart) = '1' then
1295
           v.edclrstate := idle;
1296
         end if;
1297
       when wrtype =>
1298
         if vrxwrite = '1' then
1299
           veri.writem := '1'; veri.writel := '1';
1300
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1301
           if X"0800" = rxo.dataout(31 downto 16) and (r.edclbcast = '0') then
1302
             v.edclrstate := ip;
1303
           elsif X"0806" = rxo.dataout(31 downto 16) and (r.edclbcast = '1') then
1304
             v.edclrstate := arp;
1305
           else
1306
             v.edclrstate := spill;
1307
           end if;
1308
         end if;
1309
         v.ecnt := (others => '0'); v.ipcrc := (others => '0');
1310
         if (rxdone and not rxstart) = '1' then
1311
           v.edclrstate := idle;
1312
         end if;
1313
       when ip =>
1314
         if vrxwrite = '1' then
1315
           v.ecnt := r.ecnt + 1;
1316
           veri.writem := '1'; veri.writel := '1';
1317
           case vecnt is
1318
             when 0 =>
1319
               v.ipcrc :=
1320
               crcadder(not rxo.dataout(31 downto 16), r.ipcrc);
1321
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1322
             when 1 =>
1323
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 2;
1324
             when 2 =>
1325
               v.ipcrc :=
1326
               crcadder(not rxo.dataout(31 downto 16), r.ipcrc);
1327
               v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl - 1;
1328
             when 3 =>
1329
               v.rcntm := r.rcntm - 1; v.rcntl := r.rcntl + 2;
1330
             when 4 =>
1331
               v.udpsrc := rxo.dataout(15 downto 0);
1332
               v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl + 1;
1333
             when 5 =>
1334
               setmz := '1';
1335
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1336
             when 6 =>
1337
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1338
             when 7 =>
1339
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1340
               if (rxo.dataout(31 downto 18) = r.seq) then
1341
                 v.nak := '0';
1342
               else
1343
                 v.nak := '1';
1344
                 veri.datain(31 downto 18) := r.seq;
1345
               end if;
1346
               veri.datain(17) := v.nak; v.ewr := rxo.dataout(17);
1347
               if (rxo.dataout(17) or v.nak) = '1' then
1348
                 veri.datain(16 downto 7) := (others => '0');
1349
               end if;
1350
               v.oplen := rxo.dataout(16 downto 7);
1351
               v.applength := "000000" & veri.datain(16 downto 7);
1352
               v.ipcrc :=
1353
               crcadder(v.applength + 38, r.ipcrc);
1354
               v.write(conv_integer(r.rpnt)) := rxo.dataout(17);
1355
             when 8 =>
1356
               ipcrctmp := (others => '0');
1357
               ipcrctmp(1 downto 0) := r.ipcrc(17 downto 16);
1358
               ipcrctmp2 := "00" & r.ipcrc(15 downto 0);
1359
               v.ipcrc :=
1360
               crcadder(ipcrctmp, ipcrctmp2);
1361
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1362
               v.edclrstate := ipdata;
1363
             when others =>
1364
               null;
1365
           end case;
1366
         end if;
1367
         if (rxdone and not rxstart) = '1' then
1368
           v.edclrstate := idle;
1369
         end if;
1370
       when ipdata =>
1371
         if (vrxwrite and r.ewr and not r.nak) = '1' and
1372
                               (r.rcntm /= ebufmax) then
1373
           veri.writem := '1'; veri.writel := '1';
1374
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1375
         end if;
1376
         if rxdone = '1' then
1377
           v.edclrstate := ipcrc; v.rcntm := conv_std_logic_vector(6, bpbits);
1378
           ipcrctmp := (others => '0');
1379
           ipcrctmp(1 downto 0) := r.ipcrc(17 downto 16);
1380
           ipcrctmp2 := "00" & r.ipcrc(15 downto 0);
1381
           v.ipcrc := crcadder(ipcrctmp, ipcrctmp2);
1382
           if conv_integer(v.rxstatus(3 downto 0)) /= 0 then
1383
             v.edclrstate := idle;
1384
           end if;
1385
         end if;
1386
       when ipcrc =>
1387
         veri.writem := '1'; veri.datain(31 downto 16) := not r.ipcrc(15 downto 0);
1388
         v.edclrstate := udp; v.rcntm := conv_std_logic_vector(9, bpbits);
1389
         v.rcntl := conv_std_logic_vector(9, bpbits);
1390
       when udp =>
1391
         veri.writem := '1'; veri.writel := '1';
1392
         v.edclrstate := iplength;
1393
         veri.datain(31 downto 16) := r.udpsrc;
1394
         veri.datain(15 downto 0) := r.applength + 18;
1395
         v.rcntm := conv_std_logic_vector(4, bpbits);
1396
       when iplength =>
1397
         veri.writem := '1';
1398
         veri.datain(31 downto 16) := r.applength + 38;
1399
         v.edclrstate := oplength;
1400
         v.rcntm := conv_std_logic_vector(10, bpbits);
1401
         v.rcntl := conv_std_logic_vector(10, bpbits);
1402
       when oplength =>
1403
         if rxstart = '0' then
1404
           v.abufs := r.abufs + 1; v.rpnt := r.rpnt + 1;
1405
           veri.writel := '1'; veri.writem := '1';
1406
         end if;
1407
         if r.nak = '0' then
1408
           v.seq := r.seq + 1;
1409
         end if;
1410
         v.edclrstate := idle;
1411
         veri.datain(31 downto 0) := (others => '0');
1412
         veri.datain(15 downto 0) := "00000" & r.nak & r.oplen;
1413
       when arp =>
1414
         if vrxwrite = '1' then
1415
           v.ecnt := r.ecnt + 1;
1416
           veri.writem := '1'; veri.writel := '1';
1417
           case vecnt is
1418
             when 0 =>
1419
               v.rcntm := r.rcntm + 4;
1420
             when 1 =>
1421
               swap := '1'; veri.writel := '0';
1422
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 4;
1423
             when 2 =>
1424
               swap := '1';
1425
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1426
             when 3 =>
1427
               swap := '1';
1428
               v.rcntm := r.rcntm - 4; v.rcntl := r.rcntl - 4;
1429
             when 4 =>
1430
               veri.datain := ctrli.emacaddr(31 downto 16) & ctrli.emacaddr(47 downto 32);
1431
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
1432
             when 5 =>
1433
               v.rcntl := r.rcntl + 1;
1434
               veri.datain(31 downto 16) := rxo.dataout(15 downto 0);
1435
               veri.datain(15 downto 0) := ctrli.emacaddr(15 downto 0);
1436
               if rxo.dataout(15 downto 0) /= ctrli.edclip(31 downto 16) then
1437
                 v.edclrstate := spill;
1438
               end if;
1439
             when 6 =>
1440
               swap := '1'; veri.writem := '0';
1441
               v.rcntm := conv_std_logic_vector(5, bpbits);
1442
               v.rcntl := conv_std_logic_vector(1, bpbits);
1443
               if rxo.dataout(31 downto 16) /= ctrli.edclip(15 downto 0) then
1444
                 v.edclrstate := spill;
1445
               else
1446
                 v.edclactive := '1';
1447
               end if;
1448
             when 7 =>
1449
               veri.writem := '0';
1450
               veri.datain(15 downto 0) := ctrli.emacaddr(47 downto 32);
1451
               v.rcntl := r.rcntl + 1;
1452
               v.rcntm := conv_std_logic_vector(2, bpbits);
1453
             when 8 =>
1454
               v.edclrstate := arpop;
1455
               veri.datain := ctrli.emacaddr(31 downto 0);
1456
               v.rcntm := conv_std_logic_vector(5, bpbits);
1457
             when others =>
1458
               null;
1459
           end case;
1460
         end if;
1461
         if (rxdone and not rxstart) = '1' then
1462
           v.edclrstate := idle;
1463
         end if;
1464
       when arpop =>
1465
         veri.writem := '1'; veri.datain(31 downto 16) := X"0002";
1466
         if (rxdone and not rxstart) = '1' then
1467
           v.edclrstate := idle;
1468
           if conv_integer(v.rxstatus) = 0 and (rxo.gotframe = '1') then
1469
             v.abufs := r.abufs + 1; v.rpnt := r.rpnt + 1;
1470
           end if;
1471
         end if;
1472
       when spill =>
1473
         if (rxdone and not rxstart) = '1' then
1474
           v.edclrstate := idle;
1475
         end if;
1476
     end case;
1477
 
1478
     --edcl transmitter
1479
     case r.txdstate is
1480
       when getlen =>
1481
         v.tcnt := r.tcnt + 1;
1482
         if conv_integer(r.tcnt) = 10 then
1483
           v.txlength := '0' & erdata(9 downto 0);
1484
           v.tnak := erdata(10);
1485
           v.txcnt := v.txlength;
1486
           if (r.write(conv_integer(r.tpnt)) or v.tnak) = '1' then
1487
             v.txlength := (others => '0');
1488
           end if;
1489
         end if;
1490
         if conv_integer(r.tcnt) = 11 then
1491
           v.txdstate := readhdr;
1492
           v.tcnt := (others => '0');
1493
         end if;
1494
       when readhdr =>
1495
         v.tcnt := r.tcnt + 1; vtxfi.write := '1';
1496
         v.tfwpnt := r.tfwpnt + 1; v.tfcnt := v.tfcnt + 1;
1497
         vtxfi.datain := erdata;
1498
         if conv_integer(r.tcnt) = 12 then
1499
           v.txaddr := erdata(31 downto 2);
1500
         end if;
1501
         if conv_integer(r.tcnt) = 3 then
1502
           if erdata(31 downto 16) = X"0806" then
1503
             v.tarp := '1'; v.txlength := conv_std_logic_vector(42, 11);
1504
           else
1505
             v.tarp := '0'; v.txlength := r.txlength + 52;
1506
           end if;
1507
         end if;
1508
         if r.tarp = '0' then
1509
           if conv_integer(r.tcnt) = 12 then
1510
             v.txdstate := start;
1511
           end if;
1512
         else
1513
           if conv_integer(r.tcnt) = 10 then
1514
             v.txdstate := start;
1515
           end if;
1516
         end if;
1517
         if (txrestart or txdone) = '1' then
1518
           v.txdstate := etdone;
1519
         end if;
1520
       when start =>
1521
         v.tmsto.addr := r.txaddr & "00";
1522
         v.tmsto.write := r.write(conv_integer(r.tpnt));
1523
         -- AXI_ENABLE: EDCL burst length decoded from payload
1524
         v.tmsto.burst_bytes := r.txcnt;
1525
         if (edclsepahbg /= 0) and (edcl /= 0) then
1526
           v.tmsto2.addr := r.txaddr & "00";
1527
           v.tmsto2.write := r.write(conv_integer(r.tpnt));
1528
           -- AXI_ENABLE: EDCL burst length decoded from payload
1529
           v.tmsto2.burst_bytes := r.txcnt;
1530
         end if;
1531
         if (conv_integer(r.txcnt) = 0) or (r.tarp or r.tnak) = '1' then
1532
           v.txdstate := etdone;
1533
           v.txstart_sync := not r.txstart_sync;
1534
           v.tmsto.req := '0';
1535
           if (edclsepahbg /= 0) and (edcl /= 0) then
1536
             v.tmsto2.req := '0';
1537
           end if;
1538
         elsif r.write(conv_integer(r.tpnt)) = '0' then
1539
           v.txdstate := req; v.tedcl := '1';
1540
         else
1541
           v.txstart_sync := not r.txstart_sync;
1542
           v.tedcl := '1';
1543
           v.tcnt := r.tcnt + 1;
1544
           if (edclsepahbg = 0) or (edcl = 0) or (r.edclsepahb = '0') then
1545
             v.tmsto.req := '1'; v.tmsto.data := erdata;
1546
             v.txdstate := wrbus1;
1547
           else
1548
             v.tmsto2.req := '1'; v.tmsto2.data := erdata;
1549
             v.txdstate := wrbus2;
1550
           end if;
1551
         end if;
1552
         if (txrestart or txdone) = '1' then
1553
           v.txdstate := etdone;
1554
         end if;
1555
       when wrbus1 =>
1556
         if tmsti.grant = '1' then
1557
           v.tmsto.addr := r.tmsto.addr + 4;
1558
           if ((conv_integer(r.txcnt) <= 4) and (tmsti.ready = '0')) or
1559
              ((conv_integer(r.txcnt) <= 8) and (tmsti.ready = '1')) then
1560
             v.tmsto.req := '0';
1561
           end if;
1562
         end if;
1563
         if (tmsti.ready or tmsti.error) = '1' then
1564
           v.tmsto.data := erdata; v.tcnt := r.tcnt + 1;
1565
           v.txcnt := r.txcnt - 4;
1566
           if r.tmsto.req = '0' then
1567
             v.txdstate := etdone;
1568
           end if;
1569
         end if;
1570
         if tmsti.retry = '1' then
1571
           v.tmsto.addr := r.tmsto.addr - 4; v.tmsto.req := '1';
1572
         end if;
1573
       when wrbus2 =>
1574
         if tmsti2.grant = '1' then
1575
           v.tmsto2.addr := r.tmsto2.addr + 4;
1576
           if ((conv_integer(r.txcnt) <= 4) and (tmsti2.ready = '0')) or
1577
              ((conv_integer(r.txcnt) <= 8) and (tmsti2.ready = '1')) then
1578
             v.tmsto2.req := '0';
1579
           end if;
1580
         end if;
1581
         if (tmsti2.ready or tmsti2.error) = '1' then
1582
           v.tmsto2.data := erdata; v.tcnt := r.tcnt + 1;
1583
           v.txcnt := r.txcnt - 4;
1584
           if r.tmsto2.req = '0' then
1585
             v.txdstate := etdone;
1586
           end if;
1587
         end if;
1588
         if tmsti2.retry = '1' then
1589
           v.tmsto2.addr := r.tmsto2.addr - 4; v.tmsto2.req := '1';
1590
         end if;
1591
       when etdone =>
1592
         if txdone = '1' then
1593
           v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1);
1594
           v.abufs := v.abufs - 1; v.tpnt := r.tpnt + 1;
1595
           v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
1596
           v.tfwpnt := (others => '0');
1597
         elsif txrestart = '1' then
1598
           v.txdstate := idle;
1599
         end if;
1600
       when others =>
1601
         null;
1602
     end case;
1603
 
1604
     if swap = '1' then
1605
       veri.datain(31 downto 16) := rxo.dataout(15 downto 0);
1606
       veri.datain(15 downto 0)  := rxo.dataout(31 downto 16);
1607
     end if;
1608
     if setmz = '1' then
1609
       veri.datain(31 downto 16) := (others => '0');
1610
     end if;
1611
     if (ramdebug /= 2) or (edcl = 0) or (cmdi.dbg_rd_ena = '0') then
1612
       veri.raddress := r.tpnt & v.tcnt;
1613
     end if;
1614
   end if;
1615
 
1616
   --edcl duplex mode read
1617
   if (rmii = 1) or (edcl /= 0) then
1618
     --edcl, gbit link mode check
1619
     case r.duplexstate is
1620
       when start =>
1621
         if (ctrli.edcldis = '0' and ctrli.disableduplex = '0') then
1622
           v.status.mdio.cmd.regadr := r.regaddr; v.init_busy := '1';
1623
           v.status.mdio.busy := '1'; v.duplexstate := waitop;
1624
           if (r.phywr or r.rstphy) = '1' then
1625
             v.status.mdio.cmd.write := '1';
1626
           else
1627
             v.status.mdio.cmd.read := '1';
1628
           end if;
1629
           if r.rstphy = '1' then
1630
             v.status.mdio.cmd.data := X"9000";
1631
           end if;
1632
         end if;
1633
       when waitop =>
1634
         if r.init_busy = '0' then
1635
           if r.status.mdio.linkfail = '1' then
1636
             v.duplexstate := start;
1637
           elsif r.rstphy = '1' then
1638
             v.duplexstate := start; v.rstphy := '0';
1639
           else
1640
             v.duplexstate := nextop;
1641
           end if;
1642
         end if;
1643
       when nextop =>
1644
         case r.regaddr is
1645
           when "00000" =>
1646
             if r.status.mdio.cmd.data(15) = '1' then --rst not finished
1647
               v.duplexstate := start;
1648
             elsif (r.phywr and not r.rstaneg) = '1' then --forced to 10 Mbit HD
1649
               v.duplexstate := selmode;
1650
             elsif r.status.mdio.cmd.data(12) = '0' then --no auto neg
1651
               v.duplexstate := start; v.phywr := '1';
1652
               v.status.mdio.cmd.data := (others => '0');
1653
             else
1654
               v.duplexstate := start; v.regaddr := "00001";
1655
             end if;
1656
             if r.rstaneg = '1' then
1657
               v.phywr := '0';
1658
             end if;
1659
             if ctrli.disableduplex = '1' then
1660
               v.duplexstate := done; v.status.mdio.busy := '0';
1661
             end if;
1662
           when "00001" =>
1663
             v.ext := r.status.mdio.cmd.data(8); --extended status register
1664
             v.extcap := r.status.mdio.cmd.data(1); --extended register capabilities
1665
             v.duplexstate := start;
1666
             if r.status.mdio.cmd.data(0) = '0' then
1667
               --no extended register capabilites, unable to read aneg config
1668
               --forcing 10 Mbit
1669
               v.duplexstate := start; v.phywr := '1';
1670
               v.status.mdio.cmd.data := (others => '0');
1671
               v.regaddr := (others => '0');
1672
             elsif (r.status.mdio.cmd.data(8) and not r.rstaneg) = '1' then
1673
               --phy gbit capable, disable gbit
1674
               v.regaddr := "01001";
1675
             elsif r.status.mdio.cmd.data(5) = '1' then --auto neg completed
1676
               v.regaddr := "00100";
1677
             end if;
1678
             if ctrli.disableduplex = '1' then
1679
               v.duplexstate := done; v.status.mdio.busy := '0';
1680
             end if;
1681
           when "00100" =>
1682
             v.duplexstate := start; v.regaddr := "00101";
1683
             v.capbil(4 downto 0) := r.status.mdio.cmd.data(9 downto 5);
1684
           when "00101" =>
1685
             v.duplexstate := selmode;
1686
             v.capbil(4 downto 0) :=
1687
             r.capbil(4 downto 0) and r.status.mdio.cmd.data(9 downto 5);
1688
           when "01001" =>
1689
             if r.phywr = '0' then
1690
               v.duplexstate := start; v.phywr := '1';
1691
               v.status.mdio.cmd.data(9 downto 8) := (others => '0');
1692
             else
1693
               v.regaddr := "00000";
1694
               v.duplexstate := start; v.phywr := '1';
1695
               v.status.mdio.cmd.data := X"3300"; v.rstaneg := '1';
1696
             end if;
1697
           when others =>
1698
             null;
1699
         end case;
1700
       when selmode =>
1701
         v.duplexstate := done; v.status.mdio.busy := '0';
1702
         if r.phywr = '1' then
1703
           v.status.full_duplex := '0'; v.status.speed := '0';
1704
         else
1705
           sel_op_mode(r.capbil, v.status.speed, v.status.full_duplex);
1706
         end if;
1707
       when done =>
1708
         null;
1709
     end case;
1710
 
1711
     -- MDIO Disable
1712
     if ctrli.edcldis = '1' or ctrli.disableduplex = '1' then
1713
        if  v.duplexstate /= start then
1714
          v.duplexstate := start;
1715
          v.status.mdio.cmd.regadr := (others => '0');
1716
          v.status.mdio.busy := '0';
1717
          v.init_busy := '0';
1718
          v.status.mdio.cmd.write := '0';
1719
          v.status.mdio.cmd.read := '0';
1720
          v.status.mdio.cmd.data := X"0000";
1721
        end if;
1722
     end if;
1723
 
1724
   end if;
1725
 
1726
   --transmitter retry
1727
   if tmsti.retry = '1' then
1728
     v.tmsto.req := '1'; v.tmsto.addr := r.tmsto.addr - 4;
1729
     v.txburstcnt := r.txburstcnt - 1;
1730
   end if;
1731
 
1732
   --transmitter AHB error
1733
   if tmsti.error = '1' and (not ((edcl /= 0) and (r.tedcl = '1'))) then
1734
     v.tmsto.req := '0'; v.txdstate := ahberror;
1735
   end if;
1736
 
1737
   if (edclsepahbg /= 0) and (edcl /= 0) then
1738
     --transmitter retry
1739
     if tmsti2.retry = '1' then
1740
       v.tmsto2.req := '1'; v.tmsto2.addr := r.tmsto2.addr - 4;
1741
       v.txburstcnt := r.txburstcnt - 1;
1742
     end if;
1743
 
1744
     --transmitter AHB error
1745
     if tmsti2.error = '1' and (not ((edcl /= 0) and (r.tedcl = '1'))) then
1746
       v.tmsto2.req := '0'; v.txdstate := ahberror;
1747
     end if;
1748
   end if;
1749
 
1750
   --receiver retry
1751
   if rmsti.retry = '1' then
1752
     v.rmsto.req := '1'; v.rmsto.addr := r.rmsto.addr - 4;
1753
     v.rxburstcnt := r.rxburstcnt - 1;
1754
   end if;
1755
 
1756
------------------------------------------------------------------------------
1757
-- RESET ----------------------------------------------------------------------
1758
-------------------------------------------------------------------------------
1759
    if irst = '0' then
1760
      v.txdstate := idle; v.rxdstate := idle; v.rfrpnt := (others => '0');
1761
      v.rfwpnt := (others => '0');
1762
      v.rfcnt := (others => '0');
1763
      v.status.txen := '0';
1764
      v.status.tx_int := '0';
1765
      v.status.rx_int := '0';
1766
      v.status.tx_err := '0';
1767
      v.status.rx_err := '0';
1768
      v.status.txahberr := '0';
1769
      v.status.rxahberr := '0';
1770
      v.txirqgen := '0'; v.status.rxen := '0';
1771
      v.status.txdsel := (others => '0'); v.txstart_sync := '0';
1772
      v.txread := (others => '0'); v.txrestart := (others => '0');
1773
      v.txdone := (others => '0'); v.txreadack := '0';
1774
      v.status.rxdsel := (others => '0'); v.rxdone := (others => '0');
1775
      v.rxdoneold := '0'; v.rxdoneack := '0'; v.rxwriteack := '0';
1776
      v.rxstart := (others => '0'); v.rxwrite := (others => '0');
1777
      v.status.invaddr := '0'; v.status.toosmall := '0';
1778
      v.status.full_duplex := '0'; v.writeok := '1';
1779
      if (enable_mdio = 0) or (edcl /= 0) then
1780
        v.status.reset := '0';
1781
      end if;
1782
      if enable_mdint = 1 then
1783
        v.status.phystat := '0';
1784
      end if;
1785
      if (edcl /= 0) then
1786
        v.tpnt := (others => '0'); v.rpnt := (others => '0');
1787
        v.tcnt := (others => '0'); v.edclactive := '0';
1788
        v.tarp := '0'; v.abufs := (others => '0');
1789
        v.edclrstate := idle;
1790
      end if;
1791
      if (rmii = 1) then
1792
        v.status.speed := '1';
1793
      else
1794
        v.status.speed := '1';
1795
      end if;
1796
    end if;
1797
 
1798
    if edcl = 0 then
1799
      v.edclrstate := idle; v.edclactive := '0'; v.nak := '0'; v.ewr := '0';
1800
      v.write := (others => '0'); v.seq := (others => '0'); v.abufs := (others => '0');
1801
      v.tpnt := (others => '0'); v.rpnt := (others => '0'); v.tcnt := (others => '0');
1802
      v.rcntm := (others => '0'); v.rcntl := (others => '0'); v.ipcrc := (others => '0');
1803
      v.applength := (others => '0'); v.oplen := (others => '0');
1804
      v.udpsrc := (others => '0'); v.ecnt := (others => '0'); v.tarp := '0';
1805
      v.tnak := '0'; v.tedcl := '0'; v.edclbcast := '0';
1806
    end if;
1807
 
1808
    --some parts of edcl are only affected by hw reset
1809
    if rst = '0' then
1810
      v.duplexstate := start; v.regaddr := (others => '0');
1811
      v.phywr := '0'; v.rstphy := '1'; v.rstaneg := '0';
1812
      v.seq := (others => '0');
1813
      v.mdioo := '0';
1814
      if (enable_mdio = 1) then
1815
        v.mdccnt := divisor; v.mdioclk := '0';
1816
      end if;
1817
      v.status.reset := '0';
1818
      if (enable_mdio = 1) then
1819
        v.mdio_state := idle; v.status.mdio.cmd.read := '0';
1820
        v.status.mdio.cmd.valid := '0';
1821
        v.status.mdio.cmd.write := '0'; v.status.mdio.busy := '0';
1822
        v.status.mdio.cmd.data := (others => '0');
1823
        v.status.mdio.cmd.regadr := (others => '0');
1824
        v.status.reset := '0'; v.status.mdio.linkfail := '1';
1825
        if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
1826
        v.cnt := (others => '0');
1827
      end if;
1828
      if edclsepahbg /= 0 then
1829
        v.edclsepahb := edclsepahb;
1830
      end if;
1831
     v.txcnt := (others => '0'); v.txburstcnt := (others => '0');
1832
     v.tedcl := '0'; v.erenable := '0';
1833
     v.addrok := '0';
1834
     v.rxburstcnt := (others => '0'); v.addrdone := '0';
1835
     v.rxcnt := (others => '0'); v.rxdoneold := '0';
1836
     v.ctrlpkt := '0'; v.bcast := '0'; v.edclactive := '0';
1837
     v.msbgood := '0'; v.rxrenable := '0';
1838
     if multicast = 1 then
1839
       v.mcast := '0'; v.mcastacc := '0';
1840
     end if;
1841
     v.tnak := '0'; v.tedcl := '0'; v.edclbcast := '0';
1842
     v.gotframe := '0';
1843
     v.rxbytecount := (others => '0'); v.rxlength := (others => '0');
1844
     v.txburstav := '0'; v.txdataav := '0';
1845
     v.txstatus := (others => '0'); v.txstart := '0';
1846
     v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
1847
     v.tfwpnt := (others => '0'); v.txaddr := (others => '0');
1848
     v.txdata := (others => '0');
1849
     v.txvalid := '0';
1850
     v.txlength := (others => '0');
1851
     v.cnt := (others => '0');
1852
     v.rxaddr := (others => '0');
1853
     v.rxstatus := (others => '0');
1854
     v.rxwrap := '0'; v.rxden := '0';
1855
 
1856
     v.rmsto.req := '0';
1857
     v.rmsto.write := '0';
1858
     v.rmsto.addr := (others => '0');
1859
     v.rmsto.data := (others => '0');
1860
     v.tmsto.req := '0';
1861
     v.tmsto.write := '0';
1862
     v.tmsto.addr := (others => '0');
1863
     v.tmsto.data := (others => '0');
1864
     v.tmsto2.req := '0';
1865
     v.tmsto2.write := '0';
1866
     v.tmsto2.addr := (others => '0');
1867
     v.tmsto2.data := (others => '0');
1868
     v.nak := '0'; v.ewr := '0';
1869
     v.write := (others => '0');
1870
     v.applength := (others => '0');
1871
     v.oplen := (others => '0');
1872
     v.udpsrc := (others => '0'); v.ecnt := (others => '0');
1873
     v.rcntm := (others => '0'); v.rcntl := (others => '0');
1874
     v.txwrap := '0';
1875
     v.txden := '0';
1876
     v.txirq := '0';
1877
     v.rxirq := '0';
1878
    end if;
1879
-------------------------------------------------------------------------------
1880
-- SIGNAL ASSIGNMENTS ---------------------------------------------------------
1881
-------------------------------------------------------------------------------
1882
    rin           <= v;
1883
    rdbgdatao     <= vrdbgdata;
1884
    irq           <= vpirq;
1885
 
1886
    --rx ahb fifo
1887
    rxrenable                         <= vrxfi.renable;
1888
    rxraddress(10 downto fabits)      <= (others => '0');
1889
    rxraddress(fabits-1 downto 0)     <= vrxfi.raddress;
1890
    rxwrite                           <= vrxfi.write;
1891
    rxwdata                           <= vrxfi.datain;
1892
    rxwaddress(10 downto fabits)      <= (others => '0');
1893
    rxwaddress(fabits-1 downto 0)     <= vrxfi.waddress;
1894
 
1895
    --tx ahb fifo  
1896
    txrenable                         <= vtxfi.renable;
1897
    txraddress(10 downto txfabits)    <= (others => '0');
1898
    txraddress(txfabits-1 downto 0)   <= vtxfi.raddress;
1899
    txwrite                           <= vtxfi.write;
1900
    txwdata                           <= vtxfi.datain;
1901
    txwaddress(10 downto txfabits)    <= (others => '0');
1902
    txwaddress(txfabits-1 downto 0)   <= vtxfi.waddress;
1903
 
1904
    --edcl buf     
1905
    erenable                          <= veri.renable;
1906
    eraddress(15 downto eabits)       <= (others => '0');
1907
    eraddress(eabits-1 downto 0)      <= veri.raddress;
1908
    ewritem                           <= veri.writem;
1909
    ewritel                           <= veri.writel;
1910
    ewaddressm(15 downto eabits)      <= (others => '0');
1911
    ewaddressm(eabits-1 downto 0)     <= veri.waddressm(eabits-1 downto 0);
1912
    ewaddressl(15 downto eabits)      <= (others => '0');
1913
    ewaddressl(eabits-1 downto 0)     <= veri.waddressl(eabits-1 downto 0);
1914
    ewdata                            <= veri.datain;
1915
 
1916
    rxi.enable    <= vrxenable;
1917
  end process;
1918
 
1919
  statuso <= r.status;
1920
 
1921
  rxi.writeack    <= r.rxwriteack;
1922
  rxi.doneack     <= r.rxdoneack;
1923
  rxi.speed       <= r.status.speed;
1924
  rxi.writeok     <= r.writeok;
1925
  rxi.rxd         <= rxd;
1926
  rxi.rx_dv       <= rx_dv;
1927
  rxi.rx_crs      <= rx_crs;
1928
  rxi.rx_er       <= rx_er;
1929
  rxi.rx_en       <= rx_en;
1930
 
1931
  txi.rx_col      <= rx_col;
1932
  txi.rx_crs      <= rx_crs;
1933
  txi.full_duplex <= r.status.full_duplex;
1934
  txi.start       <= r.txstart_sync;
1935
  txi.readack     <= r.txreadack;
1936
  txi.speed       <= r.status.speed;
1937
  txi.data        <= r.txdata;
1938
  txi.valid       <= r.txvalid;
1939
  txi.len         <= r.txlength;
1940
  txi.datavalid   <= tx_dv;
1941
 
1942
  mdc             <= r.mdioclk;
1943
  mdio_o          <= r.mdioo;
1944
  mdio_oe         <= testoen when (scanen/=0 and testen/='0') else r.mdioen;
1945
  tmsto           <= r.tmsto;
1946
  rmsto           <= r.rmsto;
1947
  tmsto2          <= r.tmsto2;
1948
 
1949
  txd             <= txo.txd;
1950
  tx_en           <= txo.tx_en;
1951
  tx_er           <= txo.tx_er;
1952
 
1953
  speed           <= r.status.speed;
1954
 
1955
  reset     <= irst;
1956
 
1957
  regs : process(clk) is
1958
  begin
1959
    if rising_edge(clk) then r <= rin; end if;
1960
  end process;
1961
-------------------------------------------------------------------------------
1962
-- TRANSMITTER-----------------------------------------------------------------
1963
-------------------------------------------------------------------------------
1964
  tx_rmii0 : if rmii = 0 generate
1965
    tx0: greth_tx
1966
      generic map(
1967
        ifg_gap        => ifg_gap,
1968
        attempt_limit  => attempt_limit,
1969
        backoff_limit  => backoff_limit,
1970
        nsync          => nsync,
1971
        rmii           => rmii,
1972
        gmiimode       => gmiimode
1973
        )
1974
      port map(
1975
        rst            => arst,
1976
        clk            => tx_clk,
1977
        txi            => txi,
1978
        txo            => txo);
1979
  end generate;
1980
 
1981
  tx_rmii1 : if rmii = 1 generate
1982
    tx0: greth_tx
1983
      generic map(
1984
        ifg_gap        => ifg_gap,
1985
        attempt_limit  => attempt_limit,
1986
        backoff_limit  => backoff_limit,
1987
        nsync          => nsync,
1988
        rmii           => rmii,
1989
        gmiimode       => gmiimode
1990
        )
1991
      port map(
1992
        rst            => arst,
1993
        clk            => rmii_clk,
1994
        txi            => txi,
1995
        txo            => txo);
1996
  end generate;
1997
 
1998
-------------------------------------------------------------------------------
1999
-- RECEIVER -------------------------------------------------------------------
2000
-------------------------------------------------------------------------------
2001
  rx_rmii0 : if rmii = 0 generate
2002
    rx0 : greth_rx
2003
      generic map(
2004
        nsync     => nsync,
2005
        rmii      => rmii,
2006
        multicast => multicast,
2007
        maxsize   => maxsize,
2008
        gmiimode  => gmiimode
2009
        )
2010
      port map(
2011
        rst   => arst,
2012
        clk   => rx_clk,
2013
        rxi   => rxi,
2014
        rxo   => rxo);
2015
  end generate;
2016
 
2017
  rx_rmii1 : if rmii = 1 generate
2018
    rx0 : greth_rx
2019
      generic map(
2020
        nsync     => nsync,
2021
        rmii      => rmii,
2022
        multicast => multicast,
2023
        maxsize   => maxsize,
2024
        gmiimode  => gmiimode)
2025
      port map(
2026
        rst   => arst,
2027
        clk   => rmii_clk,
2028
        rxi   => rxi,
2029
        rxo   => rxo);
2030
  end generate;
2031
 
2032
  --! Tx FIFO
2033
  tx_fifo0 : syncram_2p_tech generic map (
2034
    tech => memtech,
2035
    abits => txfabits,
2036
    dbits => 32,
2037
    sepclk => 0
2038
  ) port map (
2039
    clk,
2040
    txrenable,
2041
    txraddress(txfabits-1 downto 0),
2042
    txrdata,
2043
    clk,
2044
    txwrite,
2045
    txwaddress(txfabits-1 downto 0),
2046
    txwdata
2047
  );
2048
 
2049
  --! Rx FIFO
2050
  rx_fifo0 : syncram_2p_tech generic map (
2051
    tech => memtech,
2052
    abits => fabits,
2053
    dbits => 32,
2054
    sepclk => 0
2055
  ) port map (
2056
    clk,
2057
    rxrenable,
2058
    rxraddress(fabits-1 downto 0),
2059
    rxrdata,
2060
    clk,
2061
    rxwrite,
2062
    rxwaddress(fabits-1 downto 0),
2063
    rxwdata
2064
  );
2065
 
2066
  --! EDCL buffer ram
2067
  edclramnft : if (edcl /= 0) generate
2068
    r0 : syncram_2p_tech generic map (
2069
       memtech,
2070
       eabits,
2071
       16
2072
    ) port map (
2073
       clk,
2074
       erenable,
2075
       eraddress(eabits-1 downto 0),
2076
       erdata(31 downto 16),
2077
       clk,
2078
       ewritem,
2079
       ewaddressm(eabits-1 downto 0),
2080
       ewdata(31 downto 16)
2081
    );
2082
    r1 : syncram_2p_tech generic map (
2083
       memtech,
2084
       eabits,
2085
       16
2086
    ) port map(
2087
       clk,
2088
       erenable,
2089
       eraddress(eabits-1 downto 0),
2090
       erdata(15 downto 0),
2091
       clk,
2092
       ewritel,
2093
       ewaddressl(eabits-1 downto 0),
2094
       ewdata(15 downto 0)
2095
    );
2096
  end generate;
2097
 
2098
 
2099
end architecture;
2100
 

powered by: WebSVN 2.1.0

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