📄 greth.vhd
字号:
-- etho.tedcl <= "0010";-- when wrsa =>-- etho.tedcl <= "0011";-- when wrtype =>-- etho.tedcl <= "0100";-- when ip =>-- etho.tedcl <= "0101";-- when ipdata =>-- etho.tedcl <= "0110";-- when oplength =>-- etho.tedcl <= "0111";-- when arp =>-- etho.tedcl <= "1000";-- when iplength =>-- etho.tedcl <= "1001";-- when ipcrc =>-- etho.tedcl <= "1010";-- when arpop =>-- etho.tedcl <= "1011";-- when udp =>-- etho.tedcl <= "1100";-- when spill =>-- etho.tedcl <= "1101";-- when others =>-- etho.tedcl <= "1110";-- end case;-- end process; --reset generators for transmitter and receiver vcc <= '1'; irst <= rst and not r.ctrl.reset; tx_rst : rstgen generic map (syncrst => 1) port map(irst, txclk, vcc, txrst, open); rx_rst : rstgen generic map (syncrst => 1) port map(irst, rxclk, vcc, rxrst, open); --clock assignments, needed because synopsys DC does --not allow record elements in rising_edge statement rmii0 : if rmii = 0 generate rxclk <= ethi.rx_clk; txclk <= ethi.tx_clk; end generate; rmii1 : if rmii = 1 generate rxclk <= ethi.rmii_clk; txclk <= ethi.rmii_clk; end generate; comb : process(rst, irst, ethi, r, apbi, rmsti, tmsti, txfo, rxfo, rr, tr, ero) is variable v : reg_type; variable vpirq : std_logic_vector(NAHBIRQ-1 downto 0); variable prdata : 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 rxwrite : 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; prdata := (others => '0'); vpirq := (others => '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 := rr.dataout; vrxfi.write := '0'; vrxfi.waddress := r.rfwpnt; vrxfi.renable := '1'; vrxenable := r.ctrl.rxen; --synchronization v.txdone(0) := tr.done; v.txread(0) := tr.read; v.txrestart(0) := tr.restart; v.rxstart(0) := rr.sync_start; v.rxdone(0) := rr.done; v.rxwrite(0) := rr.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); rxwrite := r.rxwriteack xor r.rxwrite(nsync-1); if txdone = '1' then v.txstatus := tr.status; end if; --------------------------------------------------------------------------------- HOST INTERFACE -------------------------------------------------------------------------------------------------------------------------------------------- --SLAVE INTERFACE --write if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then case apbi.paddr(5 downto 2) is when "0000" => --ctrl reg if rmii = 1 then v.ctrl.speed := apbi.pwdata(7); end if; v.ctrl.reset := apbi.pwdata(6); v.ctrl.prom := apbi.pwdata(5); v.ctrl.full_duplex := apbi.pwdata(4); v.ctrl.rx_irqen := apbi.pwdata(3); v.ctrl.tx_irqen := apbi.pwdata(2); v.ctrl.rxen := apbi.pwdata(1); v.ctrl.txen := apbi.pwdata(0); when "0001" => --status/int source reg if apbi.pwdata(7) = '1' then v.status.invaddr := '0'; end if; if apbi.pwdata(6) = '1' then v.status.toosmall := '0'; end if; if apbi.pwdata(5) = '1' then v.status.txahberr := '0'; end if; if apbi.pwdata(4) = '1' then v.status.rxahberr := '0'; end if; if apbi.pwdata(3) = '1' then v.status.tx_int := '0'; end if; if apbi.pwdata(2) = '1' then v.status.rx_int := '0'; end if; if apbi.pwdata(1) = '1' then v.status.tx_err := '0'; end if; if apbi.pwdata(0) = '1' then v.status.rx_err := '0'; end if; when "0010" => --mac addr msb/mdio address v.mac_addr(47 downto 32) := apbi.pwdata(15 downto 0); when "0011" => --mac addr lsb v.mac_addr(31 downto 0) := apbi.pwdata(31 downto 0); when "0100" => --mdio ctrl/status if enable_mdio = 1 then v.mdio_ctrl.data := apbi.pwdata(31 downto 16); v.mdio_ctrl.phyadr := apbi.pwdata(15 downto 11); v.mdio_ctrl.regadr := apbi.pwdata(10 downto 6); if r.mdio_ctrl.busy = '0' then v.mdio_ctrl.read := apbi.pwdata(1); v.mdio_ctrl.write := apbi.pwdata(0); v.mdio_ctrl.busy := apbi.pwdata(1) or apbi.pwdata(0); end if; end if; when "0101" => --tx descriptor v.txdesc := apbi.pwdata(31 downto 10); v.txdsel := apbi.pwdata(9 downto 3); when "0110" => --rx descriptor v.rxdesc := apbi.pwdata(31 downto 10); v.rxdsel := apbi.pwdata(9 downto 3); when "0111" => --edcl ip if (edcl = 1) then v.edclip := apbi.pwdata; end if; when others => null; end case; end if; --read case apbi.paddr(5 downto 2) is when "0000" => --ctrl reg if (edcl = 1) then prdata(31) := '1'; prdata(30 downto 28) := bufsize; end if; if rmii = 1 then prdata(7) := r.ctrl.speed; end if; prdata(6) := r.ctrl.reset; prdata(5) := r.ctrl.prom; prdata(4) := r.ctrl.full_duplex; prdata(3) := r.ctrl.rx_irqen; prdata(2) := r.ctrl.tx_irqen; prdata(1) := r.ctrl.rxen; prdata(0) := r.ctrl.txen; when "0001" => --status/int source reg prdata(5) := r.status.invaddr; prdata(4) := r.status.toosmall; prdata(5) := r.status.txahberr; prdata(4) := r.status.rxahberr; prdata(3) := r.status.tx_int; prdata(2) := r.status.rx_int; prdata(1) := r.status.tx_err; prdata(0) := r.status.rx_err; when "0010" => --mac addr msb/mdio address prdata(15 downto 0) := r.mac_addr(47 downto 32); when "0011" => --mac addr lsb prdata := r.mac_addr(31 downto 0); when "0100" => --mdio ctrl/status prdata(31 downto 16) := r.mdio_ctrl.data; prdata(15 downto 11) := r.mdio_ctrl.phyadr; prdata(10 downto 6) := r.mdio_ctrl.regadr; prdata(3) := r.mdio_ctrl.busy; prdata(2) := r.mdio_ctrl.linkfail; prdata(1) := r.mdio_ctrl.read; prdata(0) := r.mdio_ctrl.write; when "0101" => --tx descriptor prdata(31 downto 10) := r.txdesc; prdata(9 downto 3) := r.txdsel; when "0110" => --rx descriptor prdata(31 downto 10) := r.rxdesc; prdata(9 downto 3) := r.rxdsel; when "0111" => --edcl ip if (edcl = 1) then prdata := r.edclip; end if; when others => null; end case; --MASTER INTERFACE --tx dma fsm case r.txdstate is when idle => v.txcnt := (others => '0'); if (edcl = 1) then v.tedcl := '0'; v.tedclstarted := '0'; end if; if (edcl = 1) 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(pirq) := '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 = 1) 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 = 1) and (r.tedcl = '1') then v.txdstate := etdone; end if; elsif conv_integer(r.txcnt) = 0 then v.txdstate := check_result; if (edcl = 1) and (r.tedcl = '1') then v.txdstate := etdone; v.txstart_sync := not r.txstart_sync; end if; elsif (r.tfcnt(txfabits downto txfabits-1) = "00") or (r.tedcl = '1') then v.tmsto.req := '1'; v.txdstate := fill_fifo; end if; v.txburstcnt := (others => '0'); when fill_fifo => 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; if (conv_integer(r.txburstcnt) = burstlength-1) then v.tmsto.req := '0'; else v.txburstcnt := r.txburstcnt + 1; end if; end if; if (tmsti.ready = '1') or ((edcl = 1) 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 = 1) 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'); if not ((edcl = 1) and (r.tedcl = '1')) then v.status.txahberr := '1'; v.ctrl.txen := '0'; if r.txstart = '1' then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -