ctrlunit.vhd
来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 844 行 · 第 1/3 页
VHD
844 行
v.dmao.address:=r.baseadr(31 downto 6) & "011110"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0) := r.readbuf2(15 downto 0); v.ipchksum := r.ipchksum + r.readbuf2(15 downto 0); when 4 => v.dmao.address := r.baseadr(31 downto 6) & "011100"; v.dmao.write := '0'; v.dmao.size := "01"; when 5 => v.dmao.address := r.baseadr(31 downto 6) & "100000"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf2(31 downto 16); v.ipchksum := r.ipchksum + r.readbuf2(31 downto 16); when 6 => v.dmao.address := r.baseadr(31 downto 6) & "010110"; v.dmao.write := '0'; v.dmao.size := "01"; when 7 => v.ipchksum := r.ipchksum + r.readbuf2(15 downto 0); when 8 => v.dmao.address := r.baseadr(31 downto 6) & "011010"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0) := ip_adr(31 downto 16); v.ipchksum := "0000" & r.ipchksum(15 downto 0) + r.ipchksum(19 downto 16); when 9 => v.dmao.address := r.baseadr(31 downto 6) & "011100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := ip_adr(15 downto 0); v.ipchksum := "0000" & not (r.ipchksum(15 downto 0) + r.ipchksum(16)); when 10 => v.dmao.address := r.baseadr(31 downto 6) & "011000"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.ipchksum(15 downto 0); when others => null; end case; when finished => if r.main_state /= ip then v.ip_state := idle; end if; when others => v.ip_state := idle; end case;-------------------------------------------------------------------------------- --ARP FSM-------------------------------------------------------------------------------- case r.arp_state is when idle => if v.main_state = arp then v.arp_state := arp_1; v.dmao.address := r.baseadr(31 downto 6) & "100110"; v.dmao.write := '0'; v.dmao.size := "01"; end if; when arp_1 => case r.counter2 is when 0 => start := '1'; if dmain.ready = '1' then start := '0'; v.readbuf2(31 downto 16) := dmain.rdata(15 downto 0); v.counter2 := r.counter2 + 1; v.dmao.address := r.baseadr(31 downto 6) & "101000"; v.dmao.write := '0'; v.dmao.size := "01"; end if; when 1 => start := '1'; if dmain.ready = '1' then start := '0'; v.readbuf2(15 downto 0) := dmain.rdata(31 downto 16); v.counter2 := r.counter2 + 1; end if; when 2 => if r.readbuf2 = ip_adr then v.arp_state := arp_2; else v.arp_state := finished; v.arp_bad_ip := '1'; end if; v.counter2 := 0; when others => null; end case; when arp_2 => case r.counter2 is when 0 => v.dmao.address := r.baseadr(31 downto 6) & "010100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := X"0002"; when 1 => v.dmao.address := r.baseadr(31 downto 6) & "010110"; v.dmao.write := '0'; v.dmao.size := "01"; when 2 => v.dmao.address := r.baseadr(31 downto 6) & "100000"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf2(15 downto 0); when 3 => v.dmao.address := r.baseadr(31 downto 6) & "011000"; v.dmao.write := '0'; v.dmao.size := "10"; when 4 => v.dmao.address := r.baseadr(31 downto 6) & "100010"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0) := r.readbuf2(31 downto 16); when 5 => v.dmao.address := r.baseadr(31 downto 6) & "100100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf2(15 downto 0); when 6 => v.dmao.address := r.baseadr(31 downto 6) & "011100"; v.dmao.write := '0'; v.dmao.size := "10"; when 7 => v.dmao.address := r.baseadr(31 downto 6) & "100110"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0) := r.readbuf2(31 downto 16); when 8 => v.dmao.address := r.baseadr(31 downto 6) & "101000"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf2(15 downto 0); when 9 => v.dmao.address := r.baseadr(31 downto 6) & "011100"; v.dmao.write := '1'; v.dmao.size := "10"; v.dmao.wdata := ip_adr; when 10 => v.dmao.address := r.baseadr(31 downto 6) & "011000"; v.dmao.write := '1'; v.dmao.size := "10"; v.dmao.wdata := eth_adr(31 downto 0); when 11 => v.dmao.address := r.baseadr(31 downto 6) & "010110"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0):=eth_adr(47 downto 32); when others => null; end case; if r.counter2 < 12 then v.counter2 := r.counter2 + 1; v.arp_state := arp_3; else v.counter2 := 0; v.arp_state := finished; end if; when arp_3 => start := '1'; if dmain.ready = '1' then start := '0'; v.arp_state := arp_2; if r.dmao.write = '0' then v.readbuf2 := dmain.rdata; end if; end if; when finished => if r.main_state /= arp then v.arp_state := idle; end if; end case; -------------------------------------------------------------------------------- --MAC INITIALIZATION-------------------------------------------------------------------------------- case r.initmacstate is when idle => if mdioenabled = 0 and autoneg = 1 then v.initmacstate := addrSel; v.dmao.size := "10"; v.dmao.write := '1'; v.dmao.address := X"FFF01018"; v.dmao.wdata := X"0040" & conv_std_logic_vector(block_size, 16); else v.initmacstate := waitphy; -- pragma translate_off if sim = 1 then v.initmacstate := setphy; end if; -- pragma translate_on end if; when waitphy => if unsigned(r.resetcounter) < phyrstcls then v.resetcounter := r.resetcounter + 1; else v.resetcounter := (others => '0'); v.initmacstate := setphy; end if; when setphy => if autoneg = 1 then case r.counter2 is when 0 => v.dmao.address := X"FFF01030"; v.dmao.size := "10"; v.dmao.write := '1'; v.dmao.wdata := X"000000" & conv_std_logic_vector(phyadr,8); v.initmacstate := setphy2; when 1 => v.dmao.address := X"FFF0102C"; v.dmao.size := "10"; v.dmao.write := '1'; v.dmao.wdata := X"00000002"; v.initmacstate := setphy2; when 2 => v.dmao.address := X"FFF0103C"; v.dmao.size := "10"; v.dmao.write := '0'; v.initmacstate := pollstat; v.counter2 := 0; when others => null; end case; else case r.counter2 is when 0 => v.dmao.address := X"FFF01030"; v.dmao.size := "10"; v.dmao.write := '1'; v.dmao.wdata := X"000000" & conv_std_logic_vector(phyadr,8); v.initmacstate := setphy2; when 1 => v.dmao.address := X"FFF01034"; v.dmao.size := "10"; v.dmao.write := '1'; v.initmacstate := setphy2; if speed = 1 and fullduplex = 1 then v.dmao.wdata := X"00002100"; elsif speed = 1 and fullduplex = 0 then v.dmao.wdata := X"00002000"; elsif speed = 0 and fullduplex = 1 then v.dmao.wdata := X"00000100"; else v.dmao.wdata := X"00000000"; end if; when 2 => v.dmao.address := X"FFF0102C"; v.dmao.size := "10"; v.dmao.write := '1'; v.dmao.wdata := X"00000004"; v.initmacstate := setphy2; when 3 => v.initmacstate := addrSel; v.dmao.address := X"FFF01018"; v.counter2 := 0; v.dmao.wdata := X"0040" & conv_std_logic_vector(block_size, 16); when others => null; end case; end if; when setphy2 => start := '1'; if dmain.ready = '1' then v.initmacstate := setphy; start := '0'; v.counter2 := r.counter2 + 1; end if; when pollstat => start := '1'; if dmain.ready = '1' and dmain.rdata(1) = '0' then start := '0'; v.initmacstate := readdata; v.dmao.address := X"FFF01038"; end if; when readdata => start := '1'; if dmain.ready = '1' then v.readbuf2 := dmain.rdata; start := '0'; v.initmacstate := addrSel; v.dmao.address := X"FFF01018"; v.dmao.write := '1'; v.dmao.wdata := X"0040" & conv_std_logic_vector(block_size, 16); end if; when addrSel => start := '1'; if dmain.ready = '1' then v.initmacstate := addrSel2; start := '0'; end if; when addrSel2 => if r.counter2 < 4 then v.counter2 := r.counter2 + 1; v.initmacstate := addrSel; case r.counter2 is when 0 => v.dmao.address := X"FFF01008"; v.dmao.wdata := X"0000000F"; when 1 => v.dmao.address := X"FFF01040"; v.dmao.wdata := eth_adr(31 downto 0); when 2 => v.dmao.address := X"FFF01044"; v.dmao.wdata := X"0000" & eth_adr(47 downto 32); when 3 => v.dmao.address := X"FFF01000"; if autoneg = 1 and mdioenabled = 1 then if r.readbuf(2) = '1' then v.dmao.wdata := X"0000A403"; else v.dmao.wdata := X"0000A003"; end if; else if fullduplex = 1 then v.dmao.wdata := X"0000A403"; else v.dmao.wdata := X"0000A003"; end if; end if; -- pragma translate_off if sim = 1 then v.dmao.wdata(6) := '1'; end if; -- pragma translate_on when others => null; end case; else v.initmacstate := finished; v.counter2 := 0; end if; when finished => null; when others => v.initmacstate := finished; end case; if rst = '0' then v.tx_offset := 0; v.tx2_offset := 0; v.rx_offset := 0; v.rx2_offset := 0; v.tx3_offset := 0; v.baseadr := ram_addr; v.counter := 0; v.counter2 := 0; v.resetcounter := (others => '0'); v.laddr2 := X"C000"; v.ip_state := idle; v.arp_state := idle; v.udp_state := idle; v.app_state := idle; v.initmacstate := idle; v.main_state := idle; v.rx_tx_state := init; v.write_stat := (others => '0'); v.no_snd := (others => '1'); v.read_stat := (others => '0'); v.read_error := (others => '0'); -- pragma translate_off if sim = 1 then v.rcv_nxt := (others => '0'); end if; -- pragma translate_on end if;------------------------------------------------------------------------------- --SIGNAL ASSIGNMENTS------------------------------------------------------------------------------- rin <= v; dmaout.address <= r.dmao.address; dmaout.wdata <= r.dmao.wdata; dmaout.start <= start; dmaout.burst <=r.dmao.burst; dmaout.write <= r.dmao.write; dmaout.busy <= r.dmao.busy; dmaout.irq <= r.dmao.irq; dmaout.size <= r.dmao.size; dmaout_m.address <= r.dmao_m.address; dmaout_m.wdata <= r.dmao_m.wdata; dmaout_m.start <= mstart; dmaout_m.burst <= r.dmao_m.burst; dmaout_m.write <= r.dmao_m.write; dmaout_m.busy <= r.dmao_m.busy; dmaout_m.irq <= r.dmao_m.irq; dmaout_m.size <= r.dmao_m.size; dmaout_rt.address <= r.dmao_rt.address; dmaout_rt.wdata <= r.dmao_rt.wdata; dmaout_rt.start <= rtstart; dmaout_rt.burst <= r.dmao_rt.burst; dmaout_rt.write <= r.dmao_rt.write; dmaout_rt.busy <= r.dmao_rt.busy; dmaout_rt.irq <= r.dmao_rt.irq; dmaout_rt.size <= r.dmao_rt.size; end process;-------------------------------------------------------------------------------- --REGISTERS-------------------------------------------------------------------------------- reg0: process(rst,clk) begin if rising_edge(clk) then r<=rin; end if; end process;end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?