📄 greth.vhd
字号:
-------------------------------------------------------------------------------- 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;library grlib;library gaisler; use ieee.std_logic_1164.all;use grlib.stdlib.all;use grlib.amba.all;use grlib.devices.all;library techmap;use techmap.gencomp.all;use gaisler.net.all;use gaisler.ethernet_mac.all;use gaisler.misc.all;entity greth is generic( hindex : integer := 0; pindex : integer := 0; paddr : integer := 0; pmask : integer := 16#FFF#; pirq : integer := 0; memtech : integer := 0; ifg_gap : integer := 24; attempt_limit : integer := 16; backoff_limit : integer := 10; slot_time : integer := 128; mdcscaler : integer range 0 to 255 := 25; enable_mdio : integer range 0 to 1 := 0; fifosize : integer range 4 to 64 := 8; nsync : integer range 1 to 2 := 2; edcl : integer range 0 to 1 := 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 31 := 0; rmii : integer range 0 to 1 := 0; oepol : integer range 0 to 1 := 0); port( rst : in std_ulogic; clk : in std_ulogic; ahbmi : in ahb_mst_in_type; ahbmo : out ahb_mst_out_type; apbi : in apb_slv_in_type; apbo : out apb_slv_out_type; ethi : in eth_in_type; etho : out eth_out_type );end entity; architecture rtl of greth is attribute keep : boolean; attribute syn_keep : boolean; attribute syn_preserve : boolean; --host constants constant fabits : integer := log2(fifosize); constant burstlength : integer := fifosize / 2; 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 REVISION : amba_version_type := 0; constant pconfig : apb_config_type := ( 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_ETHMAC, 0, REVISION, pirq), 1 => apb_iobar(paddr, pmask)); function getfifosize(edcl, fifosize, ebufsize : in integer) return integer is begin if (edcl = 1) then return ebufsize; else return fifosize; end if; end function; function mirror(din : in std_logic_vector(3 downto 0)) return std_logic_vector is variable do : std_logic_vector(3 downto 0); begin do(3) := din(0); do(2) := din(1); do(1) := din(2); do(0) := din(3); return do; end function; function calccrc(d : in std_logic_vector(3 downto 0); crc : in std_logic_vector(31 downto 0)) return std_logic_vector is variable ncrc : std_logic_vector(31 downto 0); variable tc : std_logic_vector(3 downto 0); begin tc(0) := d(0) xor crc(31); tc(1) := d(1) xor crc(30); tc(2) := d(2) xor crc(29); tc(3) := d(3) xor crc(28); ncrc(31) := crc(27); ncrc(30) := crc(26); ncrc(29) := tc(0) xor crc(25); ncrc(28) := tc(1) xor crc(24); ncrc(27) := tc(2) xor crc(23); ncrc(26) := tc(0) xor tc(3) xor crc(22); ncrc(25) := tc(0) xor tc(1) xor crc(21); ncrc(24) := tc(1) xor tc(2) xor crc(20); ncrc(23) := tc(2) xor tc(3) xor crc(19); ncrc(22) := tc(3) xor crc(18); ncrc(21) := crc(17); ncrc(20) := crc(16); ncrc(19) := tc(0) xor crc(15); ncrc(18) := tc(1) xor crc(14); ncrc(17) := tc(2) xor crc(13); ncrc(16) := tc(3) xor crc(12); ncrc(15) := tc(0) xor crc(11); ncrc(14) := tc(0) xor tc(1) xor crc(10); ncrc(13) := tc(0) xor tc(1) xor tc(2) xor crc(9); ncrc(12) := tc(1) xor tc(2) xor tc(3) xor crc(8); ncrc(11) := tc(0) xor tc(2) xor tc(3) xor crc(7); ncrc(10) := tc(0) xor tc(1) xor tc(3) xor crc(6); ncrc(9) := tc(1) xor tc(2) xor crc(5); ncrc(8) := tc(0) xor tc(2) xor tc(3) xor crc(4); ncrc(7) := tc(0) xor tc(1) xor tc(3) xor crc(3); ncrc(6) := tc(1) xor tc(2) xor crc(2); ncrc(5) := tc(0) xor tc(2) xor tc(3) xor crc(1); ncrc(4) := tc(0) xor tc(1) xor tc(3) xor crc(0); ncrc(3) := tc(0) xor tc(1) xor tc(2); ncrc(2) := tc(1) xor tc(2) xor tc(3); ncrc(1) := tc(2) xor tc(3); ncrc(0) := tc(3); return ncrc; end function; --16-bit one's complement adder function crcadder(d1 : in std_logic_vector(15 downto 0); d2 : in std_logic_vector(17 downto 0)) return std_logic_vector is variable vd1 : std_logic_vector(17 downto 0); variable vd2 : std_logic_vector(17 downto 0); variable sum : std_logic_vector(17 downto 0); begin vd1 := "00" & d1; vd2 := d2; sum := vd1 + vd2; return sum; end function; function init_ifg( ifg_gap : in integer; rmii : in integer) return integer is begin if rmii = 0 then return log2(ifg_gap); else return log2(ifg_gap*20); end if; end function; --mdio constants constant divisor : std_logic_vector(7 downto 0) := conv_std_logic_vector(mdcscaler, 8); --transmitter constants constant ifg_bits : integer := init_ifg(ifg_gap, rmii); constant ifg_p1 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector((ifg_gap)/3, ifg_bits); constant ifg_p2 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector((ifg_gap*2)/3, ifg_bits); constant ifg_p1_r100 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector((ifg_gap*2)/3, ifg_bits); constant ifg_p2_r100 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector(rmii*(ifg_gap*4)/3, ifg_bits); constant ifg_p1_r10 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector(rmii*(ifg_gap*20)/3, ifg_bits); constant ifg_p2_r10 : std_logic_vector(ifg_bits-1 downto 0) := conv_std_logic_vector(rmii*(ifg_gap*40)/3, ifg_bits); function ifg_sel( rmii : in integer; p1 : in integer; speed : in std_ulogic) return std_logic_vector is begin if p1 = 1 then if rmii = 0 then return ifg_p1; else if speed = '1' then return ifg_p1_r100; else return ifg_p1_r10; end if; end if; else if rmii = 0 then return ifg_p2; else if speed = '1' then return ifg_p2_r100; else return ifg_p2_r10; end if; end if; end if; end function; constant maxattempts : std_logic_vector(4 downto 0) := conv_std_logic_vector(attempt_limit, 5); --receiver constants constant maxsizerx : integer := 1500; constant maxsize : integer := 1518; constant minsize : integer := 64; --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 macaddr : 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); type edclrstate_type is (idle, wrda, wrdsa, wrsa, wrtype, ip, ipdata, oplength, arp, iplength, ipcrc, arpop, udp, spill); type duplexstate_type is (start, checkrst, readrstbit, checkrstbit, 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -