📄 greth.vhd
字号:
if txdone = '1' then v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1); end if; else v.txdstate := idle; end if; else if r.tedclstarted = '1' then if txdone = '1' then v.txdstate := idle; v.txdone(nsync) := r.txdone(nsync-1); v.abufs := r.abufs - 1; v.tpnt := r.tpnt + 1; end if; else v.txdstate := idle; v.abufs := r.abufs - 1; v.tpnt := r.tpnt + 1; end if; 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 := txfo.data; 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'; 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 (rxdone and rr.status(3)) = '1' then v.rxdstate := write_status; ovrunstop := '1'; v.rfcnt := (others => '0'); v.rfwpnt := (others => '0'); v.rfrpnt := (others => '0'); v.writeok := '1'; 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.rfcnt(fabits) or r.rfcnt(fabits-1) 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 := rxfo.data; when read_fifo => 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; if (conv_integer(r.rxburstcnt) = burstlength-1) then v.rmsto.req := '0'; else v.rxburstcnt := r.rxburstcnt + 1; end if; end if; if rmsti.ready = '1' then v.rmsto.data := rxfo.data; 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" & "00" & 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(3) = '0' then v.rxdstate := discard; else v.rxdstate := idle; end if; if (r.ctrl.rx_irqen and r.rxirq) = '1' then vpirq(pirq) := '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; if conv_integer(r.checkdata(31 downto 16)) <= maxsizerx then v.usesizefield := '1'; v.rxlength := r.checkdata(26 downto 16) + 14; end if; when others => null; end case; end if; --rx packet overrun if (rxdone and not rxstart) = '1' then v.gotframe := rr.gotframe; v.rxbytecount := rr.byte_count; v.rxstatus := rr.status; if r.usesizefield = '0' then v.rxlength := rr.byte_count; end if; v.rxdoneold := '1'; if ((not rr.status(3)) or (rr.status(3) and ovrunstop)) = '1' then v.rxdoneack := not r.rxdoneack; end if; end if; --rx fifo write if rxwrite = '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 := ethi.mdio_i; if mclk = '1' then case r.mdio_state is when idle => v.error := '0'; v.cnt := (others => '0'); if r.mdio_ctrl.busy = '1' then if r.mdio_ctrl.read = '1' then v.mdio_ctrl.write := '0'; v.mdio_ctrl.linkfail := '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 = 1) 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 := rr.dataout; if rxwrite = '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 rxwrite = '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) /= rr.dataout) and (X"FFFFFFFF" /= rr.dataout) then v.edclrstate := spill; elsif (X"FFFFFFFF" = rr.dataout) then v.edclbcast := '1'; end if;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -