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] - Rev 2

Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
--  This file is a part of the GRLIB VHDL IP LIBRARY
--  Copyright (C) 2003, Gaisler Research
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; if not, write to the Free Software
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
-----------------------------------------------------------------------------
-- Entity: 	greth
-- File:	greth.vhd
-- Author:	Marko Isomaki 
-- Description:	Ethernet Media Access Controller with Ethernet Debug
--              Communication Link
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library grlib;
use grlib.stdlib.all;
library eth;
use eth.grethpkg.all;
 
entity grethc is
  generic(
    ifg_gap        : integer := 24; 
    attempt_limit  : integer := 16;
    backoff_limit  : integer := 10;
    mdcscaler      : integer range 0 to 255 := 25; 
    enable_mdio    : integer range 0 to 1 := 0;
    fifosize       : integer range 4 to 512 := 8;
    nsync          : integer range 1 to 2 := 2;
    edcl           : integer range 0 to 2 := 0;
    edclbufsz      : integer range 1 to 64 := 1;
    macaddrh       : integer := 16#00005E#;
    macaddrl       : integer := 16#000000#;
    ipaddrh        : integer := 16#c0a8#;
    ipaddrl        : integer := 16#0035#;
    phyrstadr      : integer range 0 to 32 := 0;
    rmii           : integer range 0 to 1  := 0;
    oepol	   : integer range 0 to 1  := 0; 
    scanen	   : integer range 0 to 1  := 0); 
  port(
    rst            : in  std_ulogic;
    clk            : in  std_ulogic;
    --ahb mst in
    hgrant         : in  std_ulogic;
    hready         : in  std_ulogic;   
    hresp          : in  std_logic_vector(1 downto 0);
    hrdata         : in  std_logic_vector(31 downto 0); 
    --ahb mst out
    hbusreq        : out  std_ulogic;        
    hlock          : out  std_ulogic;
    htrans         : out  std_logic_vector(1 downto 0);
    haddr          : out  std_logic_vector(31 downto 0);
    hwrite         : out  std_ulogic;
    hsize          : out  std_logic_vector(2 downto 0);
    hburst         : out  std_logic_vector(2 downto 0);
    hprot          : out  std_logic_vector(3 downto 0);
    hwdata         : out  std_logic_vector(31 downto 0);
    --apb slv in 
    psel	   : in   std_ulogic;
    penable	   : in   std_ulogic;
    paddr	   : in   std_logic_vector(31 downto 0);
    pwrite	   : in   std_ulogic;
    pwdata	   : in   std_logic_vector(31 downto 0);
    --apb slv out
    prdata	   : out  std_logic_vector(31 downto 0);
    --irq
    irq            : out  std_logic;
    --rx ahb fifo
    rxrenable      : out  std_ulogic;
    rxraddress     : out  std_logic_vector(10 downto 0);
    rxwrite        : out  std_ulogic;
    rxwdata        : out  std_logic_vector(31 downto 0);
    rxwaddress     : out  std_logic_vector(10 downto 0);
    rxrdata        : in   std_logic_vector(31 downto 0);    
    --tx ahb fifo  
    txrenable      : out  std_ulogic;
    txraddress     : out  std_logic_vector(10 downto 0);
    txwrite        : out  std_ulogic;
    txwdata        : out  std_logic_vector(31 downto 0);
    txwaddress     : out  std_logic_vector(10 downto 0);
    txrdata        : in   std_logic_vector(31 downto 0);    
    --edcl buf     
    erenable       : out  std_ulogic;
    eraddress      : out  std_logic_vector(15 downto 0);
    ewritem        : out  std_ulogic;
    ewritel        : out  std_ulogic;
    ewaddressm     : out  std_logic_vector(15 downto 0);
    ewaddressl     : out  std_logic_vector(15 downto 0);
    ewdata         : out  std_logic_vector(31 downto 0);
    erdata         : in   std_logic_vector(31 downto 0);
    --ethernet input signals
    rmii_clk       : in   std_ulogic;
    tx_clk         : in   std_ulogic;
    rx_clk         : in   std_ulogic;
    rxd            : in   std_logic_vector(3 downto 0);   
    rx_dv          : in   std_ulogic; 
    rx_er          : in   std_ulogic; 
    rx_col         : in   std_ulogic;
    rx_crs         : in   std_ulogic;
    mdio_i         : in   std_ulogic;
    phyrstaddr     : in   std_logic_vector(4 downto 0);
    --ethernet output signals
    reset          : out  std_ulogic;
    txd            : out  std_logic_vector(3 downto 0);   
    tx_en          : out  std_ulogic; 
    tx_er          : out  std_ulogic; 
    mdc            : out  std_ulogic;    
    mdio_o         : out  std_ulogic; 
    mdio_oe        : out  std_ulogic;
    --scantest
    testrst        : in   std_ulogic;
    testen         : in   std_ulogic;
    edcladdr       : in  std_logic_vector(3 downto 0) := "0000"
  );
end entity;
 
architecture rtl of grethc is
  procedure sel_op_mode(
    capbil : in std_logic_vector(4 downto 0);
    speed  : out std_ulogic;
    duplex : out std_ulogic) is
    variable vspeed  : std_ulogic;
    variable vduplex : std_ulogic;
  begin
    vspeed := '0'; vduplex := '0';
    vspeed := orv(capbil(4 downto 2));
 
    vduplex := (vspeed and capbil(3)) or ((not vspeed) and capbil(1));
    speed := vspeed;
    duplex := vduplex;
  end procedure;
 
  --host constants
  constant fabits          : integer := log2(fifosize);
  constant burstlength     : integer := setburstlength(fifosize);
  constant burstbits       : integer := log2(burstlength);
  constant ctrlopcode      : std_logic_vector(15 downto 0) := X"8808"; 
  constant broadcast       : std_logic_vector(47 downto 0) := X"FFFFFFFFFFFF";
  constant maxsizetx       : integer := 1514;
  constant index           : integer := log2(edclbufsz);
  constant receiveOK       : std_logic_vector(3 downto 0) := "0000";
  constant frameCheckError : std_logic_vector(3 downto 0) := "0100";
  constant alignmentError  : std_logic_vector(3 downto 0) := "0001";
  constant frameTooLong    : std_logic_vector(3 downto 0) := "0010";
  constant overrun         : std_logic_vector(3 downto 0) := "1000";
  constant minpload        : std_logic_vector(10 downto 0) :=
                             conv_std_logic_vector(60, 11);
 
  --mdio constants
  constant divisor : std_logic_vector(7 downto 0) :=
    conv_std_logic_vector(mdcscaler, 8);
 
  --receiver constants
  constant maxsizerx : std_logic_vector(15 downto 0) :=
    conv_std_logic_vector(1514, 16);
 
  --edcl constants
  type szvct is array (0 to 6) of integer;
  constant ebuf : szvct := (64, 128, 128, 256, 256, 256, 256);
  constant blbits : szvct := (6, 7, 7, 8, 8, 8, 8);
  constant winsz : szvct := (4, 4, 8, 8, 16, 32, 64);
  constant macaddrt : std_logic_vector(47 downto 0) :=
    conv_std_logic_vector(macaddrh, 24) & conv_std_logic_vector(macaddrl, 24);
  constant bpbits : integer := blbits(log2(edclbufsz));
  constant wsz : integer := winsz(log2(edclbufsz));
  constant bselbits : integer := log2(wsz);
  constant eabits: integer := log2(edclbufsz) + 8;
  constant ebufmax : std_logic_vector(bpbits-1 downto 0) := (others => '1');
  constant bufsize : std_logic_vector(2 downto 0) :=
                       conv_std_logic_vector(log2(edclbufsz), 3);
  constant ebufsize : integer := ebuf(log2(edclbufsz));
  constant txfifosize : integer := getfifosize(edcl, fifosize, ebufsize);
  constant txfabits : integer := log2(txfifosize);
  constant txfifosizev : std_logic_vector(txfabits downto 0) :=
    conv_std_logic_vector(txfifosize, txfabits+1);
 
  constant rxburstlen      : std_logic_vector(fabits downto 0) :=
    conv_std_logic_vector(burstlength, fabits+1);
  constant txburstlen      : std_logic_vector(txfabits downto 0) :=
    conv_std_logic_vector(burstlength, txfabits+1);
 
  type edclrstate_type is (idle, wrda, wrdsa, wrsa, wrtype, ip, ipdata,
                           oplength, arp, iplength, ipcrc, arpop, udp, spill);
 
  type duplexstate_type is (start, waitop, nextop, selmode, done);
 
  --host types
  type txd_state_type is (idle, read_desc, check_desc, req, fill_fifo,
                          check_result, write_result, readhdr, start, wrbus,
                          etdone, getlen, ahberror);
  type rxd_state_type is (idle, read_desc, check_desc, read_req, read_fifo,
                          discard, write_status, write_status2);
 
  --mdio types
  type mdio_state_type is (idle, preamble, startst, op, op2, phyadr, regadr,
                           ta, ta2, ta3, data, dataend);
 
  type ctrl_reg_type is record
    txen	: std_ulogic;
    rxen        : std_ulogic;
    tx_irqen    : std_ulogic;
    rx_irqen    : std_ulogic; 
    full_duplex : std_ulogic; 
    prom        : std_ulogic;
    reset       : std_ulogic;
    speed       : std_ulogic;
  end record;
 
  type status_reg_type is record
    tx_int      : std_ulogic;
    rx_int      : std_ulogic;
    rx_err      : std_ulogic;
    tx_err      : std_ulogic;
    txahberr    : std_ulogic;
    rxahberr    : std_ulogic;
    toosmall    : std_ulogic;
    invaddr     : std_ulogic;
  end record;
 
  type mdio_ctrl_reg_type is record
    phyadr   : std_logic_vector(4 downto 0);
    regadr   : std_logic_vector(4 downto 0);
    write    : std_ulogic;
    read     : std_ulogic;
    data     : std_logic_vector(15 downto 0);
    busy     : std_ulogic;
    linkfail : std_ulogic;
  end record;
 
  subtype mac_addr_reg_type is std_logic_vector(47 downto 0); 
 
  type fifo_access_in_type is record
    renable   : std_ulogic;    
    raddress  : std_logic_vector(fabits-1 downto 0);
    write     : std_ulogic;
    waddress  : std_logic_vector(fabits-1 downto 0);
    datain    : std_logic_vector(31 downto 0);
  end record;
 
  type fifo_access_out_type is record
    data      : std_logic_vector(31 downto 0);
  end record;
 
  type tx_fifo_access_in_type is record
    renable   : std_ulogic;    
    raddress  : std_logic_vector(txfabits-1 downto 0);
    write     : std_ulogic;
    waddress  : std_logic_vector(txfabits-1 downto 0);
    datain    : std_logic_vector(31 downto 0);
  end record;
 
  type tx_fifo_access_out_type is record
    data      : std_logic_vector(31 downto 0);
  end record;
 
  type edcl_ram_in_type is record
    renable   : std_ulogic;    
    raddress  : std_logic_vector(eabits-1 downto 0);
    writem    : std_ulogic;
    writel    : std_ulogic;
    waddressm : std_logic_vector(eabits-1 downto 0);
    waddressl : std_logic_vector(eabits-1 downto 0);
    datain    : std_logic_vector(31 downto 0);
  end record;
 
  type edcl_ram_out_type is record
    data      : std_logic_vector(31 downto 0);
  end record;
 
  type reg_type is record
    --user registers
    ctrl        : ctrl_reg_type;
    status      : status_reg_type;
    mdio_ctrl   : mdio_ctrl_reg_type;
    mac_addr    : mac_addr_reg_type;
    txdesc      : std_logic_vector(31 downto 10);
    rxdesc      : std_logic_vector(31 downto 10);
    edclip      : std_logic_vector(31 downto 0);
 
    --master tx interface
    txdsel          : std_logic_vector(9 downto 3);
    tmsto           : eth_tx_ahb_in_type;
    txdstate        : txd_state_type;
    txwrap          : std_ulogic;
    txden           : std_ulogic;
    txirq           : std_ulogic;
    txaddr          : std_logic_vector(31 downto 2);
    txlength        : std_logic_vector(10 downto 0);
    txburstcnt      : std_logic_vector(burstbits downto 0);
    tfwpnt          : std_logic_vector(txfabits-1 downto 0);
    tfrpnt          : std_logic_vector(txfabits-1 downto 0);
    tfcnt           : std_logic_vector(txfabits downto 0); 
    txcnt           : std_logic_vector(10 downto 0);
    txstart         : std_ulogic;
    txirqgen        : std_ulogic;
    txstatus        : std_logic_vector(1 downto 0);
    txvalid         : std_ulogic; 
    txdata          : std_logic_vector(31 downto 0);
    writeok         : std_ulogic;
    txread          : std_logic_vector(nsync-1 downto 0);
    txrestart       : std_logic_vector(nsync downto 0);
    txdone          : std_logic_vector(nsync downto 0);
    txstart_sync    : std_ulogic;
    txreadack       : std_ulogic;
    txdataav        : std_ulogic;
    txburstav       : std_ulogic;
 
    --master rx interface 
    rxdsel          : std_logic_vector(9 downto 3);
    rmsto           : eth_rx_ahb_in_type;
    rxdstate        : rxd_state_type;
    rxstatus        : std_logic_vector(4 downto 0);
    rxaddr          : std_logic_vector(31 downto 2);
    rxlength        : std_logic_vector(10 downto 0);
    rxbytecount     : std_logic_vector(10 downto 0);
    rxwrap          : std_ulogic;
    rxirq           : std_ulogic;
    rfwpnt          : std_logic_vector(fabits-1 downto 0);
    rfrpnt          : std_logic_vector(fabits-1 downto 0);
    rfcnt           : std_logic_vector(fabits downto 0);
    rxcnt           : std_logic_vector(10 downto 0);
    rxdoneold       : std_ulogic;
    rxdoneack       : std_ulogic; 
    rxdone          : std_logic_vector(nsync-1 downto 0);
    rxstart         : std_logic_vector(nsync downto 0);
    rxwrite         : std_logic_vector(nsync-1 downto 0);
    rxwriteack      : std_ulogic; 
    rxburstcnt      : std_logic_vector(burstbits downto 0);
    addrnok         : std_ulogic;
    ctrlpkt         : std_ulogic;
    check           : std_ulogic;
    checkdata       : std_logic_vector(31 downto 0);
    usesizefield    : std_ulogic;
    rxden           : std_ulogic;
    gotframe        : std_ulogic;
    bcast           : std_ulogic;
    rxburstav       : std_ulogic;
 
    --mdio
    mdccnt          : std_logic_vector(7 downto 0);
    mdioclk         : std_ulogic;
    mdioclkold      : std_ulogic;
    mdio_state      : mdio_state_type;
    mdioo           : std_ulogic;
    mdioi           : std_ulogic;
    mdioen          : std_ulogic;
    cnt             : std_logic_vector(4 downto 0);
    duplexstate     : duplexstate_type;
    ext             : std_ulogic;
    extcap          : std_ulogic;
    regaddr         : std_logic_vector(4 downto 0);
    phywr           : std_ulogic;
    rstphy          : std_ulogic;
    capbil          : std_logic_vector(4 downto 0);
    rstaneg         : std_ulogic;
 
    --edcl
    edclrstate      : edclrstate_type;
    edclactive      : std_ulogic;
    nak             : std_ulogic;
    ewr             : std_ulogic;
    write           : std_logic_vector(wsz-1 downto 0);
    seq             : std_logic_vector(13 downto 0);
    abufs           : std_logic_vector(bselbits downto 0);
    tpnt            : std_logic_vector(bselbits-1 downto 0);
    rpnt            : std_logic_vector(bselbits-1 downto 0);
    tcnt            : std_logic_vector(bpbits-1 downto 0);
    rcntm           : std_logic_vector(bpbits-1 downto 0);
    rcntl           : std_logic_vector(bpbits-1 downto 0);
    ipcrc           : std_logic_vector(17 downto 0);
    applength       : std_logic_vector(15 downto 0);
    oplen           : std_logic_vector(9 downto 0);
    udpsrc          : std_logic_vector(15 downto 0);
    ecnt            : std_logic_vector(3 downto 0);
    tarp            : std_ulogic;
    tnak            : std_ulogic;
    tedcl           : std_ulogic;
    edclbcast       : std_ulogic;
  end record;
 
  --host signals
  signal arst             : std_ulogic;
  signal irst             : std_ulogic;
  signal vcc              : std_ulogic;
 
  signal tmsto            : eth_tx_ahb_in_type;
  signal tmsti            : eth_tx_ahb_out_type;
 
  signal rmsto            : eth_rx_ahb_in_type;
  signal rmsti            : eth_rx_ahb_out_type;
 
  signal macaddr         : std_logic_vector(47 downto 0);
 
  signal ahbmi            : ahbc_mst_in_type;
  signal ahbmo            : ahbc_mst_out_type;
 
  signal txi              : host_tx_type;
  signal txo              : tx_host_type;
 
  signal rxi              : host_rx_type;
  signal rxo              : rx_host_type;
 
  signal r, rin           : reg_type;
 
  attribute sync_set_reset : string;
  attribute sync_set_reset of irst : signal is "true";
 
begin
 
  macaddr(47 downto 4) <= macaddrt(47 downto 4);
  macaddr(3 downto 0) <= macaddrt(3 downto 0) when edcl /= 2 else edcladdr;
 
  --reset generators for transmitter and receiver
  vcc <= '1';
  arst <= testrst when (scanen = 1) and (testen = '1') 
          else rst and not r.ctrl.reset;
  irst <= rst and not r.ctrl.reset;
 
  comb : process(rst, irst, r, rmsti, tmsti, txo, rxo, psel, paddr, penable,
                 erdata, pwrite, pwdata, rxrdata, txrdata, mdio_i, phyrstaddr,
                 testen, testrst, macaddr, edcladdr) is
    variable v             : reg_type;
    variable vpirq         : std_ulogic;
    variable vprdata       : std_logic_vector(31 downto 0);
    variable txvalid       : std_ulogic;
    variable vtxfi         : tx_fifo_access_in_type; 
    variable vrxfi         : fifo_access_in_type;
    variable lengthav      : std_ulogic;
    variable txdone        : std_ulogic;
    variable txread        : std_ulogic;
    variable txrestart     : std_ulogic;
    variable rxstart       : std_ulogic;
    variable rxdone        : std_ulogic;
    variable vrxwrite      : std_ulogic;
    variable ovrunstop     : std_ulogic;
    --mdio
    variable mdioindex     : integer range 0 to 31;
    variable mclk          : std_ulogic;
    --edcl
    variable veri          : edcl_ram_in_type;
    variable swap          : std_ulogic;
    variable setmz         : std_ulogic;
    variable ipcrctmp      : std_logic_vector(15 downto 0);
    variable ipcrctmp2     : std_logic_vector(17 downto 0);
    variable vrxenable     : std_ulogic;
    variable crctmp        : std_ulogic;
    variable vecnt         : integer;
  begin 
    v := r; vprdata := (others => '0'); vpirq := '0';
    v.check := '0'; lengthav := r.rxdoneold;-- or r.usesizefield;
    ovrunstop := '0';
 
    vtxfi.datain := tmsti.data; 
    vtxfi.raddress := r.tfrpnt; vtxfi.write := '0';
    vtxfi.waddress := r.tfwpnt; vtxfi.renable := '1';
 
    vrxfi.datain := rxo.dataout; 
    vrxfi.write := '0'; vrxfi.waddress := r.rfwpnt;
    vrxfi.renable := '1'; vrxenable := r.ctrl.rxen;
 
    --synchronization
    v.txdone(0)     := txo.done;
    v.txread(0)     := txo.read;
    v.txrestart(0)  := txo.restart;
    v.rxstart(0)    := rxo.start;
    v.rxdone(0)     := rxo.done;
    v.rxwrite(0)    := rxo.write;
 
    if nsync = 2 then
      v.txdone(1)     := r.txdone(0);
      v.txread(1)     := r.txread(0);
      v.txrestart(1)  := r.txrestart(0);
      v.rxstart(1)    := r.rxstart(0);
      v.rxdone(1)     := r.rxdone(0);
      v.rxwrite(1)    := r.rxwrite(0);
    end if;
 
    txdone     := r.txdone(nsync)     xor r.txdone(nsync-1);
    txread     := r.txreadack         xor r.txread(nsync-1);
    txrestart  := r.txrestart(nsync)  xor r.txrestart(nsync-1);
    rxstart    := r.rxstart(nsync)    xor r.rxstart(nsync-1);
    rxdone     := r.rxdoneack         xor r.rxdone(nsync-1);
    vrxwrite   := r.rxwriteack        xor r.rxwrite(nsync-1);
 
    if txdone = '1' then
      v.txstatus := txo.status;
    end if;
 
-------------------------------------------------------------------------------
-- HOST INTERFACE -------------------------------------------------------------
-------------------------------------------------------------------------------
   --SLAVE INTERFACE
 
   --write
   if (psel and penable and pwrite) = '1' then
     case paddr(5 downto 2) is
     when "0000" => --ctrl reg
       if rmii = 1 then
       v.ctrl.speed       := pwdata(7);  
       end if;
       v.ctrl.reset       := pwdata(6);
       v.ctrl.prom        := pwdata(5); 
       v.ctrl.full_duplex := pwdata(4);
       v.ctrl.rx_irqen    := pwdata(3);
       v.ctrl.tx_irqen    := pwdata(2);
       v.ctrl.rxen        := pwdata(1);
       v.ctrl.txen        := pwdata(0);
     when "0001" => --status/int source reg
       if pwdata(7) = '1' then v.status.invaddr  := '0'; end if;
       if pwdata(6) = '1' then v.status.toosmall := '0'; end if;
       if pwdata(5) = '1' then v.status.txahberr := '0'; end if;
       if pwdata(4) = '1' then v.status.rxahberr := '0';  end if;
       if pwdata(3) = '1' then v.status.tx_int := '0'; end if;
       if pwdata(2) = '1' then v.status.rx_int := '0'; end if;
       if pwdata(1) = '1' then v.status.tx_err := '0'; end if;
       if pwdata(0) = '1' then v.status.rx_err := '0'; end if;
     when "0010" => --mac addr msb
       v.mac_addr(47 downto 32) := pwdata(15 downto 0);
     when "0011" => --mac addr lsb
       v.mac_addr(31 downto 0)  := pwdata(31 downto 0);
     when "0100" => --mdio ctrl/status
       if enable_mdio = 1 then 
         v.mdio_ctrl.data   := pwdata(31 downto 16);
         v.mdio_ctrl.phyadr := pwdata(15 downto 11);
         v.mdio_ctrl.regadr := pwdata(10 downto 6);
         if r.mdio_ctrl.busy = '0' then
           v.mdio_ctrl.read   := pwdata(1);
           v.mdio_ctrl.write  := pwdata(0);
           v.mdio_ctrl.busy   := pwdata(1) or pwdata(0);
         end if;
       end if;
     when "0101" => --tx descriptor 
       v.txdesc := pwdata(31 downto 10);
       v.txdsel := pwdata(9 downto 3);
     when "0110" => --rx descriptor
       v.rxdesc := pwdata(31 downto 10);
       v.rxdsel := pwdata(9 downto 3);
     when "0111" => --edcl ip
       if (edcl /= 0) then
       v.edclip := pwdata;
       end if;
     when others => null; 
     end case; 
   end if;
 
   --read
   case paddr(5 downto 2) is
   when "0000" => --ctrl reg
     if (edcl /= 0) then
       vprdata(31) := '1';
       vprdata(30 downto 28) := bufsize;
     end if;
     if rmii = 1 then
     vprdata(7) := r.ctrl.speed;
     end if;
     vprdata(6) := r.ctrl.reset;
     vprdata(5) := r.ctrl.prom;
     vprdata(4) := r.ctrl.full_duplex;
     vprdata(3) := r.ctrl.rx_irqen;
     vprdata(2) := r.ctrl.tx_irqen;
     vprdata(1) := r.ctrl.rxen;
     vprdata(0) := r.ctrl.txen; 
   when "0001" => --status/int source reg
     vprdata(5) := r.status.invaddr;
     vprdata(4) := r.status.toosmall;
     vprdata(5) := r.status.txahberr;
     vprdata(4) := r.status.rxahberr;
     vprdata(3) := r.status.tx_int;
     vprdata(2) := r.status.rx_int;
     vprdata(1) := r.status.tx_err;
     vprdata(0) := r.status.rx_err; 
   when "0010" => --mac addr msb/mdio address
     vprdata(15 downto 0) := r.mac_addr(47 downto 32);
   when "0011" => --mac addr lsb
     vprdata := r.mac_addr(31 downto 0); 
   when "0100" => --mdio ctrl/status
     vprdata(31 downto 16) := r.mdio_ctrl.data;
     vprdata(15 downto 11) := r.mdio_ctrl.phyadr;
     vprdata(10 downto 6) :=  r.mdio_ctrl.regadr;  
     vprdata(3) := r.mdio_ctrl.busy;
     vprdata(2) := r.mdio_ctrl.linkfail;
     vprdata(1) := r.mdio_ctrl.read;
     vprdata(0) := r.mdio_ctrl.write; 
   when "0101" => --tx descriptor 
     vprdata(31 downto 10) := r.txdesc;
     vprdata(9 downto 3)   := r.txdsel;
   when "0110" => --rx descriptor
     vprdata(31 downto 10) := r.rxdesc;
     vprdata(9 downto 3)   := r.rxdsel;
   when "0111" => --edcl ip
     if (edcl /= 0) then
     vprdata := r.edclip;
     end if;
   when others => null; 
   end case;   
 
   --MASTER INTERFACE
 
   v.txburstav := '0';
   if (txfifosizev - r.tfcnt) >= txburstlen then
     v.txburstav := '1'; 
   end if; 
 
   --tx dma fsm
   case r.txdstate is
   when idle =>
     v.txcnt := (others => '0');
     if (edcl /= 0) then
       v.tedcl := '0';
     end if;
     if (edcl /= 0) and (conv_integer(r.abufs) /= 0)  then
       v.txdstate := getlen;
       v.tcnt := conv_std_logic_vector(10, bpbits);
     elsif r.ctrl.txen = '1' then
       v.txdstate := read_desc; v.tmsto.write := '0';  
       v.tmsto.addr := r.txdesc & r.txdsel & "000"; v.tmsto.req := '1';
     end if;
     if r.txirqgen = '1' then
       vpirq := '1'; v.txirqgen := '0';
     end if;
     if txrestart = '1' then
       v.txrestart(nsync) := r.txrestart(nsync-1);
       v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
       v.tfwpnt := (others => '0');
     end if;
   when read_desc =>
     v.tmsto.write := '0'; v.txstatus := (others => '0'); 
     v.tfwpnt := (others => '0'); v.tfrpnt := (others => '0');
     v.tfcnt := (others => '0');
     if tmsti.grant = '1' then
       v.tmsto.addr := r.tmsto.addr + 4;
     end if;
     if tmsti.ready = '1' then
       v.txcnt := r.txcnt + 1; v.tmsto.req := '0';
       case r.txcnt(1 downto 0) is
         when "00" =>
           v.txlength  := tmsti.data(10 downto 0);
           v.txden     := tmsti.data(11);
           v.txwrap    := tmsti.data(12);
           v.txirq     := tmsti.data(13);
           v.ctrl.txen := tmsti.data(11);
         when "01" =>
           v.txaddr    := tmsti.data(31 downto 2);
           v.txdstate  := check_desc;
         when others => null;
       end case; 
     end if;
   when check_desc =>
     v.txstart := '0'; 
     v.txburstcnt := (others => '0'); 
     if r.txden = '1' then
       if (conv_integer(r.txlength) > maxsizetx) or
                  (conv_integer(r.txlength) = 0) then
         v.txdstate := write_result; v.tmsto.req := '1';
         v.tmsto.write := '1'; v.tmsto.addr := r.txdesc & r.txdsel & "000";
         v.tmsto.data := (others => '0');
       else
         v.txdstate := req;
         v.tmsto.addr := r.txaddr & "00"; v.txcnt(10 downto 0) := r.txlength;
       end if;
     else
       v.txdstate := idle;
     end if;
   when req =>
     if txrestart = '1' then
       v.txdstate := idle; v.txstart := '0'; 
       if (edcl /= 0) and (r.tedcl = '1') then
         v.txdstate := idle; 
       end if;
     elsif txdone = '1' then
       v.txdstate := check_result;
       v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
       v.tfwpnt := (others => '0');
       if (edcl /= 0) and (r.tedcl = '1') then
         v.txdstate := etdone;
       end if;
     elsif conv_integer(r.txcnt) = 0 then
       v.txdstate := check_result;
       if (edcl /= 0) and (r.tedcl = '1') then
         v.txdstate := etdone; v.txstart_sync := not r.txstart_sync;
       end if;
     elsif (r.txburstav = '1') or (r.tedcl = '1') then
       v.tmsto.req := '1'; v.txdstate := fill_fifo;
     end if;
     v.txburstcnt := (others => '0');
   when fill_fifo =>
     v.txburstav := '0';
     if tmsti.grant = '1' then
       v.tmsto.addr := r.tmsto.addr + 4;
       if ((conv_integer(r.txcnt) <= 8) and (tmsti.ready = '1')) or
          ((conv_integer(r.txcnt) <= 4) and (tmsti.ready = '0')) then
         v.tmsto.req := '0'; 
       end if;
       v.txburstcnt := r.txburstcnt + 1;
       if (conv_integer(r.txburstcnt) = burstlength-1) then
         v.tmsto.req := '0';
       end if;
     end if;
     if (tmsti.ready = '1') or ((edcl /= 0) and (r.tedcl and tmsti.error) = '1') then
       v.tfwpnt := r.tfwpnt + 1; v.tfcnt := r.tfcnt + 1; vtxfi.write := '1';
       if r.tmsto.req = '0' then
         v.txdstate := req;
         if (r.txstart = '0') and not ((edcl /= 0) and (r.tedcl = '1')) then
           v.txstart := '1'; v.txstart_sync := not r.txstart_sync; 
         end if;
       end if;
       if conv_integer(r.txcnt) > 3 then
         v.txcnt := r.txcnt - 4;
       else
         v.txcnt := (others => '0');
       end if;
     end if;
   when check_result =>
     if txdone = '1' then
       v.txdstate := write_result; v.tmsto.req := '1'; v.txstart := '0';
       v.tmsto.write := '1'; v.tmsto.addr := r.txdesc & r.txdsel & "000";
       v.tmsto.data(31 downto 16) := (others => '0');
       v.tmsto.data(15 downto 14) := v.txstatus;
       v.tmsto.data(13 downto 0)  := (others => '0');
       v.txdone(nsync) := r.txdone(nsync-1);
     elsif txrestart = '1' then
       v.txdstate := idle; v.txstart := '0'; 
     end if;
   when write_result =>
     if tmsti.grant = '1' then
       v.tmsto.req := '0'; v.tmsto.addr := r.tmsto.addr + 4;
     end if;
     if tmsti.ready = '1' then
       v.txdstate := idle; 
       v.txirqgen := r.ctrl.tx_irqen and r.txirq; 
       if r.txwrap = '0' then v.txdsel := r.txdsel + 1;
       else v.txdsel := (others => '0'); end if;
       if conv_integer(r.txstatus) = 0 then v.status.tx_int := '1';
       else v.status.tx_err := '1'; end if;
     end if;
   when ahberror =>
     v.tfcnt := (others => '0'); v.tfwpnt := (others => '0');
     v.tfrpnt := (others => '0');
     v.status.txahberr := '1'; v.ctrl.txen := '0';
     if not ((edcl /= 0) and (r.tedcl = '1')) then
       if r.txstart = '1' then
         if txdone = '1' then
           v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1);
         end if;
       else
         v.txdstate := idle;
       end if;
     else
       v.txdstate := idle; 
       v.abufs := r.abufs - 1; v.tpnt := r.tpnt + 1;
     end if;
   when others =>
     null;
   end case;
 
   --tx fifo read
   v.txdataav := '0';
   if conv_integer(r.tfcnt) /= 0 then
     v.txdataav := '1';
   end if;
   if txread = '1' then
     v.txreadack := not r.txreadack;
     if r.txdataav = '1' then
       if conv_integer(r.tfcnt) < 2 then
         v.txdataav := '0';
       end if;
       v.txvalid := '1';
       v.tfcnt := v.tfcnt - 1; v.tfrpnt := r.tfrpnt + 1;
     else
       v.txvalid := '0';
     end if;
     v.txdata := txrdata;
   end if;
 
   v.rxburstav := '0';
   if r.rfcnt >= rxburstlen then
     v.rxburstav := '1'; 
   end if;
 
   --rx dma fsm
   case r.rxdstate is
   when idle =>
     v.rmsto.req := '0'; v.rmsto.write := '0'; v.addrnok := '0'; 
     v.rxcnt := (others => '0'); v.rxdoneold := '0';
     v.ctrlpkt := '0'; v.bcast := '0'; v.edclactive := '0';
     if r.ctrl.rxen = '1' then
       v.rxdstate := read_desc; v.rmsto.req := '1';
       v.rmsto.addr := r.rxdesc & r.rxdsel & "000"; 
     elsif rxstart = '1' then
       v.rxstart(nsync) := r.rxstart(nsync-1);
       v.rxdstate := discard;
     end if;
   when read_desc =>
     v.rxstatus := (others => '0');
     if rmsti.grant = '1' then
       v.rmsto.addr := r.rmsto.addr + 4;
     end if;
     if rmsti.ready = '1' then
       v.rxcnt := r.rxcnt + 1; v.rmsto.req := '0';
       case r.rxcnt(1 downto 0) is
         when "00" =>
           v.ctrl.rxen := rmsti.data(11);
           v.rxden     := rmsti.data(11);
           v.rxwrap    := rmsti.data(12);
           v.rxirq     := rmsti.data(13);
         when "01" =>
           v.rxaddr    := rmsti.data(31 downto 2);
           v.rxdstate  := check_desc;
         when others =>
           null;
       end case; 
     end if;
     if rmsti.error = '1' then
       v.rmsto.req := '0'; v.rxdstate := idle;
       v.status.rxahberr := '1'; v.ctrl.rxen := '0';
     end if;
   when check_desc =>
     v.rxcnt := (others => '0'); v.usesizefield := '0'; v.rmsto.write := '1'; 
     if r.rxden = '1' then
       if rxstart = '1' then
         v.rxdstate := read_req; v.rxstart(nsync) := r.rxstart(nsync-1);
       end if; 
     else
       v.rxdstate := idle;
     end if;
     v.rmsto.addr := r.rxaddr & "00";
   when read_req =>
     if r.edclactive = '1' then
       v.rxdstate := discard;
     elsif (r.rxdoneold and r.rxstatus(3)) = '1' then
       v.rxdstate := write_status; 
       v.rfcnt := (others => '0'); v.rfwpnt := (others => '0');
       v.rfrpnt := (others => '0'); v.writeok := '1';
       v.rxbytecount := (others => '0'); v.rxlength := (others => '0');
     elsif (r.addrnok or r.ctrlpkt) = '1' then
       v.rxdstate := discard; v.status.invaddr := '1';
     elsif ((r.rxdoneold = '1') and r.rxcnt >= r.rxlength) then
       if r.gotframe = '1' then
         v.rxdstate := write_status;
       else
         v.rxdstate := discard; v.status.toosmall := '1';
       end if;
     elsif (r.rxburstav or r.rxdoneold) = '1' then
       v.rmsto.req := '1'; v.rxdstate := read_fifo;
       v.rfrpnt := r.rfrpnt + 1; v.rfcnt := r.rfcnt - 1;
     end if;
     v.rxburstcnt := (others => '0'); v.rmsto.data := rxrdata; 
   when read_fifo =>
     v.rxburstav := '0';
     if rmsti.grant = '1' then
       v.rmsto.addr := r.rmsto.addr + 4;
       if (lengthav = '1') then
         if ((conv_integer(r.rxcnt) >=
              (conv_integer(r.rxlength) - 8)) and (rmsti.ready = '1')) or
         ((conv_integer(r.rxcnt) >=
           (conv_integer(r.rxlength) - 4)) and (rmsti.ready = '0')) then
           v.rmsto.req := '0'; 
         end if;
       end if;
       v.rxburstcnt := r.rxburstcnt + 1;
       if (conv_integer(r.rxburstcnt) = burstlength-1) then
         v.rmsto.req := '0';
       end if;
     end if;
     if rmsti.ready = '1' then
       v.rmsto.data := rxrdata; 
       v.rxcnt := r.rxcnt + 4;  
       if r.rmsto.req = '0' then
         v.rxdstate := read_req; 
       else
         v.rfcnt := r.rfcnt - 1; v.rfrpnt := r.rfrpnt + 1;
       end if;
       v.check := '1'; v.checkdata := r.rmsto.data; 
     end if;
     if rmsti.error = '1' then
       v.rmsto.req := '0'; v.rxdstate := discard;
       v.rxcnt := r.rxcnt + 4;
       v.status.rxahberr := '1'; v.ctrl.rxen := '0';
     end if;
   when write_status =>
     v.rmsto.req := '1'; v.rmsto.addr := r.rxdesc & r.rxdsel & "000";
     v.rxdstate := write_status2;
     v.rmsto.data := X"000" & '0' & r.rxstatus & "000" & r.rxlength;  
   when write_status2 =>
     if rmsti.grant = '1' then
       v.rmsto.req := '0'; v.rmsto.addr := r.rmsto.addr + 4;
     end if;
     if rmsti.ready = '1' then
       if (r.rxstatus(4) or not r.rxstatus(3)) = '1' then
         v.rxdstate := discard;
       else
         v.rxdstate := idle;
       end if;
       if (r.ctrl.rx_irqen and r.rxirq) = '1' then
         vpirq := '1';
       end if;
       if conv_integer(r.rxstatus) = 0 then v.status.rx_int := '1';
       else v.status.rx_err := '1'; end if;
       if r.rxwrap = '1' then
         v.rxdsel := (others => '0');
       else
         v.rxdsel := r.rxdsel + 1;
       end if;
     end if;
     if rmsti.error = '1' then
       v.rmsto.req := '0'; v.rxdstate := idle;
       v.status.rxahberr := '1'; v.ctrl.rxen := '0';
     end if;
   when discard =>
     if (r.rxdoneold = '0') or ((r.rxdoneold = '1') and
        (conv_integer(r.rxcnt) < conv_integer(r.rxbytecount))) then
       if conv_integer(r.rfcnt) /= 0 then
         v.rfrpnt := r.rfrpnt + 1; v.rfcnt := r.rfcnt - 1;
         v.rxcnt := r.rxcnt + 4;
       end if;
     elsif (r.rxdoneold = '1') then
       v.rxdstate := idle; v.ctrlpkt := '0';
     end if;
   when others =>
     null;
   end case;
 
   --rx address/type check
   if r.check = '1' and r.rxcnt(10 downto 5) = "000000" then 
     case r.rxcnt(4 downto 2) is
     when "001" =>
       if r.checkdata /= broadcast(47 downto 16) and
          r.checkdata /= r.mac_addr(47 downto 16) and
          (not r.ctrl.prom) = '1'then
         v.addrnok := '1';
       elsif r.checkdata = broadcast(47 downto 16) then
         v.bcast := '1';
       end if;
     when "010" =>
       if r.checkdata(31 downto 16) /= broadcast(15 downto 0) and
          r.checkdata(31 downto 16) /= r.mac_addr(15 downto 0) and
          (not r.ctrl.prom) = '1' then
         v.addrnok := '1';
       elsif (r.bcast = '0') and
             (r.checkdata(31 downto 16) = broadcast(15 downto 0)) then
         v.addrnok := '1';
       end if;
     when "011" =>
       null;
     when "100" =>
       if r.checkdata(31 downto 16) = ctrlopcode then v.ctrlpkt := '1'; end if;
     when others =>
       null;
     end case; 
   end if;
 
   --rx packet done
   if (rxdone and not rxstart) = '1' then
     v.gotframe := rxo.gotframe; v.rxbytecount := rxo.byte_count;
     v.rxstatus(3 downto 0) := rxo.status;
     if (rxo.lentype > maxsizerx) or (rxo.status /= "0000") then
       v.rxlength := rxo.byte_count;
     else
       v.rxlength := rxo.lentype(10 downto 0);
       if (rxo.lentype(10 downto 0) > minpload) and
          (rxo.lentype(10 downto 0) /= rxo.byte_count) then
         if rxo.status(2 downto 0) = "000" then
           v.rxstatus(4) := '1'; v.rxlength := rxo.byte_count;
           v.usesizefield := '0';
         end if;
       elsif (rxo.lentype(10 downto 0) <= minpload) and
             (rxo.byte_count /= minpload) then
         if rxo.status(2 downto 0) = "000" then
           v.rxstatus(4) := '1'; v.rxlength := rxo.byte_count;
           v.usesizefield := '0';
         end if;
       end if;
     end if;
     v.rxdoneold := '1';
     --if ((not rxo.status(3)) or (rxo.status(3) and ovrunstop)) = '1' then
       v.rxdoneack := not r.rxdoneack; 
     --end if;
     --if ovrunstop = '1' then
     --  v.rxbytecount := (others => '0');
     --end if;
   end if; 
 
   --rx fifo write
   if vrxwrite = '1' then
     v.rxwriteack := not r.rxwriteack;
     if (not r.rfcnt(fabits)) = '1' then 
       v.rfwpnt := r.rfwpnt + 1; v.rfcnt := v.rfcnt + 1; v.writeok := '1'; 
       vrxfi.write := '1'; 
     else
       v.writeok := '0'; 
     end if;
   end if;  
 
   --must be placed here because it uses variable  
   vrxfi.raddress := v.rfrpnt;
 
-------------------------------------------------------------------------------
-- MDIO INTERFACE -------------------------------------------------------------
-------------------------------------------------------------------------------
   --mdio commands
   if enable_mdio = 1 then
     mclk := r.mdioclk and not r.mdioclkold;
     v.mdioclkold := r.mdioclk;
     if r.mdccnt = "00000000" then
       v.mdccnt := divisor;
       v.mdioclk := not r.mdioclk;
     else
       v.mdccnt := r.mdccnt - 1;
     end if;
     mdioindex := conv_integer(r.cnt); v.mdioi := mdio_i;
     if mclk = '1' then
       case r.mdio_state is
         when idle =>
           v.cnt := (others => '0');
           if r.mdio_ctrl.busy = '1' then
             v.mdio_ctrl.linkfail := '0'; 
             if r.mdio_ctrl.read = '1' then
               v.mdio_ctrl.write := '0'; 
             end if;
             v.mdio_state := preamble; v.mdioo := '1';
             if OEPOL = 0 then v.mdioen := '0'; else v.mdioen := '1'; end if;
           end if; 
         when preamble =>
           v.cnt := r.cnt + 1; 
           if r.cnt = "11111" then
             v.mdioo := '0'; v.mdio_state := startst; 
           end if; 
         when startst =>
           v.mdioo := '1'; v.mdio_state := op; v.cnt := (others => '0');
         when op =>
           v.mdio_state := op2;    
           if r.mdio_ctrl.read = '1' then v.mdioo := '1';
           else v.mdioo := '0'; end if;
         when op2 =>
           v.mdioo := not r.mdioo; v.mdio_state := phyadr;
           v.cnt := (others => '0');
         when phyadr =>
           v.cnt := r.cnt + 1;
           case mdioindex is
           when 0 => v.mdioo := r.mdio_ctrl.phyadr(4);
           when 1 => v.mdioo := r.mdio_ctrl.phyadr(3);
           when 2 => v.mdioo := r.mdio_ctrl.phyadr(2);
           when 3 => v.mdioo := r.mdio_ctrl.phyadr(1);
           when 4 => v.mdioo := r.mdio_ctrl.phyadr(0);
                     v.mdio_state := regadr; v.cnt := (others => '0');
           when others => null;
           end case;
         when regadr =>
           v.cnt := r.cnt + 1;
           case mdioindex is
           when 0 => v.mdioo := r.mdio_ctrl.regadr(4);
           when 1 => v.mdioo := r.mdio_ctrl.regadr(3);
           when 2 => v.mdioo := r.mdio_ctrl.regadr(2);
           when 3 => v.mdioo := r.mdio_ctrl.regadr(1);
           when 4 => v.mdioo := r.mdio_ctrl.regadr(0);
                     v.mdio_state := ta; v.cnt := (others => '0');
           when others => null;
           end case;
         when ta =>
           v.mdio_state := ta2;
           if r.mdio_ctrl.read = '1' then 
             if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
           else v.mdioo := '1'; end if;
         when ta2 =>
           v.cnt := "01111"; v.mdio_state := ta3; 
           if r.mdio_ctrl.write = '1' then v.mdioo := '0'; v.mdio_state := data; end if;
         when ta3 =>
           v.mdio_state := data;
           if r.mdioi /= '0' then
             v.mdio_ctrl.linkfail := '1';
           end if;
         when data =>
           v.cnt := r.cnt - 1;
           if r.mdio_ctrl.read = '1' then
             v.mdio_ctrl.data(mdioindex) := r.mdioi; 
           else
             v.mdioo := r.mdio_ctrl.data(mdioindex);
           end if;
           if r.cnt = "00000" then
             v.mdio_state := dataend;
           end if;
         when dataend =>
           v.mdio_ctrl.busy := '0'; v.mdio_ctrl.read := '0';
           v.mdio_ctrl.write := '0'; v.mdio_state := idle;
           if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
         when others =>
           null;
       end case;
     end if;
   end if;
 
-------------------------------------------------------------------------------
-- EDCL -----------------------------------------------------------------------
-------------------------------------------------------------------------------
   if (edcl /= 0) then
     veri.renable := '1'; veri.writem := '0'; veri.writel := '0';
     veri.waddressm := r.rpnt & r.rcntm; veri.waddressl := r.rpnt & r.rcntl;
     swap := '0'; vrxenable := '1'; vecnt := conv_integer(r.ecnt); setmz := '0';
     veri.datain := rxo.dataout;
 
     if vrxwrite = '1' then
       v.rxwriteack := not r.rxwriteack;
     end if;
 
     --edcl receiver 
     case r.edclrstate is
       when idle =>
         v.edclbcast := '0';
         if rxstart = '1' then
           v.edclrstate := wrda; v.edclactive := '0';
           v.rcntm := conv_std_logic_vector(2, bpbits);
           v.rcntl := conv_std_logic_vector(1, bpbits);
         end if;
       when wrda =>
         if vrxwrite = '1' then
           v.edclrstate := wrdsa;
           veri.writem := '1'; veri.writel := '1';
           swap := '1';
           v.rcntm := r.rcntm - 2; v.rcntl := r.rcntl + 1;
           if (macaddr(47 downto 16) /= rxo.dataout) and
                        (X"FFFFFFFF" /= rxo.dataout) then
             v.edclrstate := spill;
           elsif (X"FFFFFFFF" = rxo.dataout) then
              v.edclbcast := '1'; 
           end if;
           if conv_integer(r.abufs) = wsz then
             v.edclrstate := spill;
           end if;
         end if;
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when wrdsa =>
         if vrxwrite = '1' then
           v.edclrstate := wrsa; swap := '1';
           veri.writem := '1'; veri.writel := '1';
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl - 2;
           if (macaddr(15 downto 0) /= rxo.dataout(31 downto 16)) and
                           (X"FFFF" /= rxo.dataout(31 downto 16)) then
             v.edclrstate := spill; 
           elsif (X"FFFF" = rxo.dataout(31 downto 16)) then
             v.edclbcast := r.edclbcast; 
           end if;
         end if;
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when wrsa =>
         if vrxwrite = '1' then
           veri.writem := '1'; veri.writel := '1';
           v.edclrstate := wrtype; swap := '1';
           v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl + 3;
         end if;
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when wrtype =>
         if vrxwrite = '1' then
           veri.writem := '1'; veri.writel := '1';
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
           if X"0800" = rxo.dataout(31 downto 16) and (r.edclbcast = '0') then
             v.edclrstate := ip;
           elsif X"0806" = rxo.dataout(31 downto 16) and (r.edclbcast = '1') then
             v.edclrstate := arp;
           else
             v.edclrstate := spill;
           end if;
         end if;
         v.ecnt := (others => '0'); v.ipcrc := (others => '0');
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when ip =>
         if vrxwrite = '1' then
           v.ecnt := r.ecnt + 1;
           veri.writem := '1'; veri.writel := '1';
           case vecnt is
             when 0 =>
               v.ipcrc :=
               crcadder(not rxo.dataout(31 downto 16), r.ipcrc);
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
             when 1 =>
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 2;
             when 2 =>
               v.ipcrc :=
               crcadder(not rxo.dataout(31 downto 16), r.ipcrc);
               v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl - 1;
             when 3 =>
               v.rcntm := r.rcntm - 1; v.rcntl := r.rcntl + 2;
             when 4 =>
               v.udpsrc := rxo.dataout(15 downto 0);
               v.rcntm := r.rcntm + 2; v.rcntl := r.rcntl + 1; 
             when 5 =>
               setmz := '1';
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1; 
             when 6 =>
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1; 
             when 7 =>
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
               if (rxo.dataout(31 downto 18) = r.seq) then
                 v.seq := r.seq + 1; v.nak := '0'; 
               else
                 v.nak := '1'; 
                 veri.datain(31 downto 18) := r.seq;
               end if;
               veri.datain(17) := v.nak; v.ewr := rxo.dataout(17);
               if (rxo.dataout(17) or v.nak) = '1' then
                 veri.datain(16 downto 7) := (others => '0');
               end if;
               v.oplen := rxo.dataout(16 downto 7);
               v.applength := "000000" & veri.datain(16 downto 7);
               v.ipcrc :=
               crcadder(v.applength + 38, r.ipcrc);
               v.write(conv_integer(r.rpnt)) := rxo.dataout(17);
             when 8 =>
               ipcrctmp := (others => '0');
               ipcrctmp(1 downto 0) := r.ipcrc(17 downto 16);
               ipcrctmp2 := "00" & r.ipcrc(15 downto 0);
               v.ipcrc :=
               crcadder(ipcrctmp, ipcrctmp2);
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
               v.edclrstate := ipdata;
             when others =>
               null;
           end case;
         end if;
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when ipdata =>
         if (vrxwrite and r.ewr and not r.nak) = '1' and
                               (r.rcntm /= ebufmax) then
           veri.writem := '1'; veri.writel := '1';
           v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
         end if;
         if rxdone = '1' then
           v.edclrstate := ipcrc; v.rcntm := conv_std_logic_vector(6, bpbits);
           ipcrctmp := (others => '0');
           ipcrctmp(1 downto 0) := r.ipcrc(17 downto 16);
           ipcrctmp2 := "00" & r.ipcrc(15 downto 0);
           v.ipcrc := crcadder(ipcrctmp, ipcrctmp2);
           if conv_integer(v.rxstatus(3 downto 0)) /= 0 then
             v.edclrstate := idle;
           end if;
         end if;
       when ipcrc =>
         veri.writem := '1'; veri.datain(31 downto 16) := not r.ipcrc(15 downto 0);
         v.edclrstate := udp; v.rcntm := conv_std_logic_vector(9, bpbits);
         v.rcntl := conv_std_logic_vector(9, bpbits);
       when udp =>
         veri.writem := '1'; veri.writel := '1';
         v.edclrstate := iplength;
         veri.datain(31 downto 16) := r.udpsrc;
         veri.datain(15 downto 0) := r.applength + 18;
         v.rcntm := conv_std_logic_vector(4, bpbits);
       when iplength =>
         veri.writem := '1';
         veri.datain(31 downto 16) := r.applength + 38;
         v.edclrstate := oplength;
         v.rcntm := conv_std_logic_vector(10, bpbits);
         v.rcntl := conv_std_logic_vector(10, bpbits);
       when oplength =>
         if rxstart = '0' then
           v.abufs := r.abufs + 1; v.rpnt := r.rpnt + 1;
           veri.writel := '1'; veri.writem := '1';
         end if;
         v.edclrstate := idle;
         veri.datain(31 downto 0) := (others => '0');
         veri.datain(15 downto 0) := "00000" & r.nak & r.oplen;
       when arp =>
         if vrxwrite = '1' then
           v.ecnt := r.ecnt + 1;
           veri.writem := '1'; veri.writel := '1';
           case vecnt is
             when 0 =>
               v.rcntm := r.rcntm + 4; 
             when 1 =>
               swap := '1'; veri.writel := '0'; 
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 4;
             when 2 =>
               swap := '1';
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1;
             when 3 =>
               swap := '1';
               v.rcntm := r.rcntm - 4; v.rcntl := r.rcntl - 4;
             when 4 =>
               veri.datain := macaddr(31 downto 16) & macaddr(47 downto 32);
               v.rcntm := r.rcntm + 1; v.rcntl := r.rcntl + 1; 
             when 5 =>
               v.rcntl := r.rcntl + 1;
               veri.datain(31 downto 16) := rxo.dataout(15 downto 0);
               veri.datain(15 downto 0) := macaddr(15 downto 0);
               if rxo.dataout(15 downto 0) /= r.edclip(31 downto 16) then
                 v.edclrstate := spill;
               end if;
             when 6 =>
               swap := '1'; veri.writem := '0'; 
               v.rcntm := conv_std_logic_vector(5, bpbits);
               v.rcntl := conv_std_logic_vector(1, bpbits);
               if rxo.dataout(31 downto 16) /= r.edclip(15 downto 0) then
                 v.edclrstate := spill;
               else
                 v.edclactive := '1'; 
               end if;
             when 7 =>
               veri.writem := '0';
               veri.datain(15 downto 0) := macaddr(47 downto 32);
               v.rcntl := r.rcntl + 1;
               v.rcntm := conv_std_logic_vector(2, bpbits);
             when 8 =>
               v.edclrstate := arpop;
               veri.datain := macaddr(31 downto 0);
               v.rcntm := conv_std_logic_vector(5, bpbits);
             when others =>
               null;
           end case;
         end if;
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
       when arpop =>
         veri.writem := '1'; veri.datain(31 downto 16) := X"0002";
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
           if conv_integer(v.rxstatus) = 0 and (rxo.gotframe = '1') then
             v.abufs := r.abufs + 1; v.rpnt := r.rpnt + 1;
           end if;
         end if;
       when spill =>
         if (rxdone and not rxstart) = '1' then
           v.edclrstate := idle;
         end if;
     end case;
 
     --edcl transmitter
     case r.txdstate is
       when getlen =>
         v.tcnt := r.tcnt + 1;
         if conv_integer(r.tcnt) = 10 then
           v.txlength := '0' & erdata(9 downto 0);
           v.tnak := erdata(10);
           v.txcnt := v.txlength;
           if (r.write(conv_integer(r.tpnt)) or v.tnak) = '1' then
             v.txlength := (others => '0');
           end if;
         end if;
         if conv_integer(r.tcnt) = 11 then
           v.txdstate := readhdr;
           v.tcnt := (others => '0');
         end if;
       when readhdr =>
         v.tcnt := r.tcnt + 1; vtxfi.write := '1';
         v.tfwpnt := r.tfwpnt + 1; v.tfcnt := v.tfcnt + 1; 
         vtxfi.datain := erdata;
         if conv_integer(r.tcnt) = 12 then
           v.txaddr := erdata(31 downto 2);
         end if;
         if conv_integer(r.tcnt) = 3 then
           if erdata(31 downto 16) = X"0806" then
             v.tarp := '1'; v.txlength := conv_std_logic_vector(42, 11);
           else
             v.tarp := '0'; v.txlength := r.txlength + 52;
           end if;
         end if;
         if r.tarp = '0' then
           if conv_integer(r.tcnt) = 12 then
             v.txdstate := start;
           end if;
         else
           if conv_integer(r.tcnt) = 10 then
             v.txdstate := start;
           end if;
         end if;
         if (txrestart or txdone) = '1' then
           v.txdstate := etdone;
         end if;
       when start =>
         v.tmsto.addr := r.txaddr & "00"; 
         v.tmsto.write := r.write(conv_integer(r.tpnt));
         if (conv_integer(r.txcnt) = 0) or (r.tarp or r.tnak) = '1' then
           v.tmsto.req := '0'; v.txdstate := etdone;
           v.txstart_sync := not r.txstart_sync;
         elsif r.write(conv_integer(r.tpnt)) = '0' then
           v.txdstate := req; v.tedcl := '1';
         else
           v.txstart_sync := not r.txstart_sync;
           v.txdstate := wrbus; v.tmsto.req := '1'; v.tedcl := '1';
           v.tmsto.data := erdata; v.tcnt := r.tcnt + 1;
         end if;
         if (txrestart or txdone) = '1' then
           v.txdstate := etdone;
         end if;
       when wrbus =>
         if tmsti.grant = '1' then
           v.tmsto.addr := r.tmsto.addr + 4;
           if ((conv_integer(r.txcnt) <= 4) and (tmsti.ready = '0')) or
              ((conv_integer(r.txcnt) <= 8) and (tmsti.ready = '1')) then
             v.tmsto.req := '0';
           end if;
         end if;
         if (tmsti.ready or tmsti.error) = '1' then
           v.tmsto.data := erdata; v.tcnt := r.tcnt + 1;
           v.txcnt := r.txcnt - 4;
           if r.tmsto.req = '0' then
             v.txdstate := etdone;
           end if;
         end if;
         if tmsti.retry = '1' then
           v.tmsto.addr := r.tmsto.addr - 4; v.tmsto.req := '1';
         end if;
         --if (txrestart or txdone) = '1' then
          -- v.txdstate := etdone; v.tmsto.req := '0';
         --end if;
       when etdone =>
         if txdone = '1' then
           v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1);
           v.abufs := v.abufs - 1; v.tpnt := r.tpnt + 1;
           v.tfcnt := (others => '0'); v.tfrpnt := (others => '0');
           v.tfwpnt := (others => '0');
         elsif txrestart = '1' then
           v.txdstate := idle;
         end if;
       when others =>
         null;
     end case;
 
     if swap = '1' then
       veri.datain(31 downto 16) := rxo.dataout(15 downto 0); 
       veri.datain(15 downto 0)  := rxo.dataout(31 downto 16);
     end if;
     if setmz = '1' then
       veri.datain(31 downto 16) := (others => '0');
     end if;
     veri.raddress := r.tpnt & v.tcnt;
   end if;
 
   --edcl duplex mode read
   if (rmii = 1) or (edcl /= 0) then
     --edcl, gbit link mode check
     case r.duplexstate is
       when start =>
         v.mdio_ctrl.regadr := r.regaddr;
         v.mdio_ctrl.busy := '1'; v.duplexstate := waitop;
         if (r.phywr or r.rstphy) = '1' then
           v.mdio_ctrl.write := '1'; 
         else
           v.mdio_ctrl.read := '1';
         end if;
         if r.rstphy = '1' then
           v.mdio_ctrl.data := X"9000";
         end if;
       when waitop =>
         if r.mdio_ctrl.busy = '0' then
           if r.mdio_ctrl.linkfail = '1' then
             v.duplexstate := start; 
           elsif r.rstphy = '1' then
             v.duplexstate := start; v.rstphy := '0';
           else
             v.duplexstate := nextop;
           end if;
         end if;
       when nextop =>
         case r.regaddr is
           when "00000" =>
             if r.mdio_ctrl.data(15) = '1' then --rst not finished
               v.duplexstate := start; 
             elsif (r.phywr and not r.rstaneg) = '1' then --forced to 10 Mbit HD
               v.duplexstate := selmode;
             elsif r.mdio_ctrl.data(12) = '0' then --no auto neg
               v.duplexstate := start; v.phywr := '1';
               v.mdio_ctrl.data := (others => '0');
             else
               v.duplexstate := start; v.regaddr := "00001";
             end if;
             if r.rstaneg = '1' then
               v.phywr := '0';
             end if;
           when "00001" =>
             v.ext := r.mdio_ctrl.data(8); --extended status register
             v.extcap := r.mdio_ctrl.data(1); --extended register capabilities
             v.duplexstate := start;
             if r.mdio_ctrl.data(0) = '0' then
               --no extended register capabilites, unable to read aneg config
               --forcing 10 Mbit
               v.duplexstate := start; v.phywr := '1';
               v.mdio_ctrl.data := (others => '0');
               v.regaddr := (others => '0');
             elsif (r.mdio_ctrl.data(8) and not r.rstaneg) = '1' then
               --phy gbit capable, disable gbit
               v.regaddr := "01001"; 
             elsif r.mdio_ctrl.data(5) = '1' then --auto neg completed
               v.regaddr := "00100"; 
             end if;
           when "00100" =>
             v.duplexstate := start; v.regaddr := "00101";
             v.capbil(4 downto 0) := r.mdio_ctrl.data(9 downto 5);
           when "00101" =>
             v.duplexstate := selmode;
             v.capbil(4 downto 0) :=
             r.capbil(4 downto 0) and r.mdio_ctrl.data(9 downto 5);
           when "01001" =>
             if r.phywr = '0' then
               v.duplexstate := start; v.phywr := '1';
               v.mdio_ctrl.data(9 downto 8) := (others => '0');
             else
               v.regaddr := "00000";
               v.duplexstate := start; v.phywr := '1';
               v.mdio_ctrl.data := X"3300"; v.rstaneg := '1';
             end if;
           when others =>
             null;
         end case;
       when selmode =>
         v.duplexstate := done;
         if r.phywr = '1' then
           v.ctrl.full_duplex := '0'; v.ctrl.speed := '0';
         else
           sel_op_mode(r.capbil, v.ctrl.speed, v.ctrl.full_duplex);
         end if;
       when done =>
         null;
     end case;
   end if;
 
   --transmitter retry
   if tmsti.retry = '1' then
     v.tmsto.req := '1'; v.tmsto.addr := r.tmsto.addr - 4;
     v.txburstcnt := r.txburstcnt - 1;
   end if;
 
   --transmitter AHB error
   if tmsti.error = '1' and (not ((edcl /= 0) and (r.tedcl = '1'))) then
     v.tmsto.req := '0'; v.txdstate := ahberror;
   end if;
 
   --receiver retry
   if rmsti.retry = '1' then
     v.rmsto.req := '1'; v.rmsto.addr := r.rmsto.addr - 4;
     v.rxburstcnt := r.rxburstcnt - 1;
   end if;
 
------------------------------------------------------------------------------
-- RESET ----------------------------------------------------------------------
-------------------------------------------------------------------------------
    if irst = '0' then
      v.txdstate := idle; v.rxdstate := idle; v.rfrpnt := (others => '0');
      v.tmsto.req := '0'; v.tmsto.req := '0'; v.rfwpnt := (others => '0'); 
      v.rfcnt := (others => '0');  v.mdio_ctrl.read := '0';
      v.mdio_ctrl.write := '0'; v.ctrl.txen := '0';
      v.mdio_ctrl.busy := '0'; v.txirqgen := '0'; v.ctrl.rxen := '0';
      v.mdio_ctrl.data := (others => '0');
      v.mdio_ctrl.regadr := (others => '0');
      v.txdsel := (others => '0'); v.txstart_sync := '0';
      v.txread := (others => '0'); v.txrestart := (others => '0');
      v.txdone := (others => '0'); v.txreadack := '0'; 
      v.rxdsel := (others => '0'); v.rxdone := (others => '0');
      v.rxdoneold := '0'; v.rxdoneack := '0'; v.rxwriteack := '0';
      v.rxstart := (others => '0'); v.rxwrite := (others => '0');
      v.mdio_ctrl.linkfail := '1'; v.ctrl.reset := '0';
      v.status.invaddr := '0'; v.status.toosmall := '0';
      v.ctrl.full_duplex := '0'; v.writeok := '0';
      if (enable_mdio = 1) then
        v.mdccnt := (others => '0'); v.mdioclk := '0';
        v.mdio_state := idle;
        if OEPOL = 0 then v.mdioen := '1'; else v.mdioen := '0'; end if;
      end if;
      if (edcl /= 0) then
        v.tpnt := (others => '0'); v.rpnt := (others => '0');
        v.tcnt := (others => '0'); v.edclactive := '0';
        v.tarp := '0'; v.abufs := (others => '0');
        v.edclrstate := idle;
      end if;
      if (rmii = 1) then
        v.ctrl.speed := '1';
      end if;
      v.ctrl.tx_irqen := '0';
      v.ctrl.rx_irqen := '0';
      v.ctrl.prom := '0';
    end if;
 
    if edcl = 0 then
      v.edclrstate := idle; v.edclactive := '0'; v.nak := '0'; v.ewr := '0';
      v.write := (others => '0'); v.seq := (others => '0'); v.abufs := (others => '0');
      v.tpnt := (others => '0'); v.rpnt := (others => '0'); v.tcnt := (others => '0');
      v.rcntm := (others => '0'); v.rcntl := (others => '0'); v.ipcrc := (others => '0');
      v.applength := (others => '0'); v.oplen := (others => '0');
      v.udpsrc := (others => '0'); v.ecnt := (others => '0'); v.tarp := '0';
      v.tnak := '0'; v.tedcl := '0'; v.edclbcast := '0';
    end if;
 
    --some parts of edcl are only affected by hw reset
    if rst = '0' then
      v.edclip := conv_std_logic_vector(ipaddrh, 16) &
                  conv_std_logic_vector(ipaddrl, 16);
      if edcl = 2 then v.edclip(3 downto 0) := edcladdr; end if;
      v.duplexstate := start; v.regaddr := (others => '0');
      v.phywr := '0'; v.rstphy := '1'; v.rstaneg := '0';
      if phyrstadr /= 32 then 
        v.mdio_ctrl.phyadr := conv_std_logic_vector(phyrstadr, 5);
      else
        v.mdio_ctrl.phyadr := phyrstaddr;
      end if;
      v.seq := (others => '0');
    end if;
-------------------------------------------------------------------------------
-- SIGNAL ASSIGNMENTS ---------------------------------------------------------
-------------------------------------------------------------------------------
    rin           <= v;
    prdata        <= vprdata;                          	
    irq           <= vpirq;
 
    --rx ahb fifo
    rxrenable                         <= vrxfi.renable;
    rxraddress(10 downto fabits)      <= (others => '0');
    rxraddress(fabits-1 downto 0)     <= vrxfi.raddress;
    rxwrite                           <= vrxfi.write;  
    rxwdata                           <= vrxfi.datain;
    rxwaddress(10 downto fabits)      <= (others => '0');
    rxwaddress(fabits-1 downto 0)     <= vrxfi.waddress;
 
    --tx ahb fifo  
    txrenable                         <= vtxfi.renable;
    txraddress(10 downto txfabits)    <= (others => '0');
    txraddress(txfabits-1 downto 0)   <= vtxfi.raddress;
    txwrite                           <= vtxfi.write;
    txwdata                           <= vtxfi.datain;
    txwaddress(10 downto txfabits)    <= (others => '0');
    txwaddress(txfabits-1 downto 0)   <= vtxfi.waddress;
 
    --edcl buf     
    erenable                          <= veri.renable;
    eraddress(15 downto eabits)       <= (others => '0');
    eraddress(eabits-1 downto 0)      <= veri.raddress;
    ewritem                           <= veri.writem;
    ewritel                           <= veri.writel;
    ewaddressm(15 downto eabits)      <= (others => '0');
    ewaddressm(eabits-1 downto 0)     <= veri.waddressm(eabits-1 downto 0);
    ewaddressl(15 downto eabits)      <= (others => '0');
    ewaddressl(eabits-1 downto 0)     <= veri.waddressl(eabits-1 downto 0);
    ewdata                            <= veri.datain;
 
    rxi.enable    <= vrxenable;
  end process;
 
  rxi.writeack    <= r.rxwriteack;
  rxi.doneack     <= r.rxdoneack;
  rxi.speed       <= r.ctrl.speed;
  rxi.writeok     <= r.writeok;
  rxi.rxd         <= rxd;
  rxi.rx_dv       <= rx_dv;
  rxi.rx_crs      <= rx_crs;
  rxi.rx_er       <= rx_er;
 
  txi.rx_col      <= rx_col;
  txi.rx_crs      <= rx_crs;
  txi.full_duplex <= r.ctrl.full_duplex;
  txi.start       <= r.txstart_sync;
  txi.readack     <= r.txreadack;
  txi.speed       <= r.ctrl.speed;
  txi.data        <= r.txdata;
  txi.valid       <= r.txvalid;
  txi.len         <= r.txlength;
 
  mdc             <= r.mdioclk;
  mdio_o          <= r.mdioo; 
  mdio_oe         <= r.mdioen;
  tmsto           <= r.tmsto;
  rmsto           <= r.rmsto;
 
  txd             <= txo.txd;
  tx_en           <= txo.tx_en;
  tx_er           <= txo.tx_er;
 
  ahbmi.hgrant    <= hgrant;
  ahbmi.hready    <= hready;
  ahbmi.hresp     <= hresp;
  ahbmi.hrdata    <= hrdata;
 
  hbusreq         <= ahbmo.hbusreq;
  hlock           <= ahbmo.hlock;
  htrans          <= ahbmo.htrans;
  haddr           <= ahbmo.haddr;
  hwrite          <= ahbmo.hwrite;
  hsize           <= ahbmo.hsize;
  hburst          <= ahbmo.hburst;
  hprot           <= ahbmo.hprot;
  hwdata          <= ahbmo.hwdata;
 
  reset 	  <= irst;
 
  regs : process(clk) is
  begin
    if rising_edge(clk) then r <= rin; end if;
  end process;
-------------------------------------------------------------------------------
-- TRANSMITTER-----------------------------------------------------------------
-------------------------------------------------------------------------------
  tx_rmii0 : if rmii = 0 generate
    tx0: greth_tx
      generic map(
        ifg_gap        => ifg_gap,
        attempt_limit  => attempt_limit,
        backoff_limit  => backoff_limit,
        nsync          => nsync,
        rmii           => rmii)
      port map(
        rst            => arst,
        clk            => tx_clk,
        txi            => txi,
        txo            => txo);
  end generate;
 
  tx_rmii1 : if rmii = 1 generate
    tx0: greth_tx
      generic map(
        ifg_gap        => ifg_gap,
        attempt_limit  => attempt_limit,
        backoff_limit  => backoff_limit,
        nsync          => nsync,
        rmii           => rmii)
      port map(
        rst            => arst,
        clk            => rmii_clk,
        txi            => txi,
        txo            => txo);
  end generate;
 
-------------------------------------------------------------------------------
-- RECEIVER -------------------------------------------------------------------
-------------------------------------------------------------------------------
  rx_rmii0 : if rmii = 0 generate
    rx0 : greth_rx
      generic map(
        nsync => nsync,
        rmii  => rmii)
      port map(
        rst   => arst,
        clk   => rx_clk,
        rxi   => rxi,  
        rxo   => rxo);
  end generate;
 
  rx_rmii1 : if rmii = 1 generate
    rx0 : greth_rx
      generic map(
        nsync => nsync,
        rmii  => rmii)
      port map(
        rst   => arst,
        clk   => rmii_clk,
        rxi   => rxi,  
        rxo   => rxo);
  end generate;
 
-------------------------------------------------------------------------------
-- AHB MST INTERFACE ----------------------------------------------------------
-------------------------------------------------------------------------------
  ahb0 : eth_ahb_mst 
    port map(rst, clk, ahbmi, ahbmo, tmsto, tmsti, rmsto, rmsti);
 
end architecture;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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