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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [eth/] [core/] [grethc.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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