ctrlunit.vhd
来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 844 行 · 第 1/3 页
VHD
844 行
start := '1'; if dmain.ready = '1' then start := '0'; v.main_state := wr_eth_adr; if r.dmao.write = '0' then v.readbuf := dmain.rdata; end if; v.counter := r.counter + 1; end if; when set_txbd => start := '1'; if dmain.ready = '1' then start := '0'; v.main_state := set_txbd2; if r.tx2_offset = win_size - 1 then laddr := X"F800"; else laddr := X"D800"; end if; if r.arp = '1' then haddr := X"002A"; elsif r.nak = '1' then haddr := X"0030"; else haddr := conv_std_logic_vector(r.app_layer_size + 52, 16); end if; v.dmao.address := r.dmao.address - 4; v.dmao.wdata := haddr & laddr; end if; when set_txbd2 => start := '1'; if dmain.ready = '1' then start := '0'; v.main_state := upd_tx_offset; if r.tx2_offset < win_size - 1 then v.tx2_offset := r.tx2_offset + 1; else v.tx2_offset := 0; end if; end if; when no_snd => v.main_state := upd_tx_offset; v.write_stat(r.tx_offset) := '0'; when upd_tx_offset => if r.tx_offset < win_size - 1 then v.tx_offset := r.tx_offset + 1; else v.tx_offset := 0; end if; v.main_state := idle; v.baseadr := ram_addr + v.tx_offset * block_size; when others => null; end case; -------------------------------------------------------------------------------- --RX_TX FSM -------------------------------------------------------------------------------- case r.rx_tx_state is when init => if r.initmacstate = finished then v.rx_tx_state := idle; end if; when idle => if r.write_stat(r.rx_offset) = '0' then v.rx_tx_state := updrxbd; v.dmao_rt.address := X"FFF01604" + r.rx_offset * 8; v.dmao_rt.wdata := ram_addr + r.rx_offset * block_size; v.dmao_rt.write := '1'; elsif ahbmi_rt.hirq(11) = '1' then v.rx_tx_state := readint; v.dmao_rt.address := X"FFF01004"; v.dmao_rt.write := '0'; end if; when readint => rtstart := '1'; if dmain_rt.ready = '1' then rtstart := '0'; v.readbuf3 := dmain_rt.rdata(3 downto 0); if dmain_rt.rdata(0) = '1' or dmain_rt.rdata(1) = '1' then v.rx_tx_state := clrintw; v.dmao_rt.wdata := X"00000003"; else v.rx_tx_state := clrintr; v.dmao_rt.wdata := X"0000000C"; end if; v.dmao_rt.write := '1'; end if; when clrintr => if r.readbuf3(3) = '1' then v.read_error(r.rx2_offset) := '1'; end if; rtstart := '1'; if dmain_rt.ready = '1' then v.read_stat(r.rx2_offset) := '1'; v.rx_tx_state := idle; rtstart := '0'; if r.rx2_offset < win_size - 1 then v.rx2_offset := r.rx2_offset + 1; else v.rx2_offset := 0; end if; end if; when clrintw => rtstart := '1'; if dmain_rt.ready = '1' then rtstart := '0'; v.rx_tx_state := clrintw2; end if; when clrintw2=> if r.no_snd(r.tx3_offset) = '0' then v.no_snd(r.tx3_offset) := '1'; v.write_stat(r.tx3_offset) := '0'; v.rx_tx_state := idle; end if; if v.tx3_offset < win_size - 1 then v.tx3_offset := r.tx3_offset + 1; else v.tx3_offset := 0; end if; when updrxbd => rtstart := '1'; if dmain_rt.ready = '1' then rtstart := '0'; v.dmao_rt.address := r.dmao_rt.address - 4; v.dmao_rt.wdata := X"0000" & r.laddr2; v.write_stat(r.rx_offset) := '1'; v.rx_tx_state := updrxbd2; end if; when updrxbd2 => rtstart := '1'; if dmain_rt.ready = '1' then rtstart := '0'; v.rx_tx_state := idle; if r.rx_offset < win_size - 1 then v.rx_offset := r.rx_offset + 1; else v.rx_offset := 0; end if; end if; if r.rx_offset = win_size - 2 then v.laddr2 := X"E000"; else v.laddr2 := X"C000"; end if; when others => null; end case;-------------------------------------------------------------------------------- --APP LAYER FSM-------------------------------------------------------------------------------- case r.app_state is when idle => if r.main_state = app then v.app_state := app1; v.dmao.address := r.baseadr(31 downto 6) & "101100"; v.dmao.write := '0'; v.dmao.size := "10"; end if; when app1 => start := '1'; if dmain.ready = '1' then v.app_state := app2; v.readbuf := dmain.rdata; start := '0'; v.app_layer_size := conv_integer(dmain.rdata(16 downto 7)); end if; when app2 => v.dmao.address := r.baseadr(31 downto 6) & "101100"; v.dmao.write := '1'; v.dmao.size := "10"; if r.nak = '1' then v.app_state := nak; v.dmao.wdata := r.rcv_nxt & '1' & r.readbuf(16 downto 0); else v.app_state := app3; v.dmao.wdata(31 downto 17) := r.readbuf(31 downto 18) & '0'; if r.readbuf(17) = '1' then v.dmao.wdata(16 downto 0) := "0000000000" & r.readbuf(6 downto 0); v.app_layer_size := 0; else v.dmao.wdata(16 downto 0) := r.readbuf(16 downto 0); end if; end if; when nak => start := '1'; v.app_layer_size := 0; if dmain.ready = '1' then start := '0'; v.app_state := finished; end if; when app3 => start := '1'; if dmain.ready = '1' then start := '0'; v.app_state := app4; if r.dmao.write = '0' then v.readbuf := dmain.rdata; end if; end if; when app4 => if r.counter < 1 then v.app_state := app3; v.counter := r.counter + 1; v.dmao.address := r.baseadr(31 downto 6) & "110000"; v.dmao.write := '0'; v.dmao.size := "10"; v.app_write := r.readbuf(17); v.app_length := "00" & r.readbuf(16 downto 9); else v.app_addr := r.readbuf; v.app_state := app5; v.counter := 0; v.dmao.size := "10"; v.dmao.address := r.baseadr + 52; v.dmao.write := not r.app_write; v.dmao.burst := '1'; v.dmao_m.size := "10"; v.dmao_m.burst := '1'; v.dmao_m.address := v.app_addr; v.dmao_m.write := r.app_write; end if; v.m0counter := 0; v.m1counter := 0; v.fifo_count := "000"; when app5 => if r.m0counter >= unsigned(r.app_length) and r.m1counter >= unsigned(r.app_length) then v.app_state := finished; end if; when finished => if r.main_state /= app then v.app_state := idle; end if; when others => v.app_state := idle; end case; -------------------------------------------------------------------------------- --AHB BRIDGE-------------------------------------------------------------------------------- if r.app_state = app5 then if dmain.ready = '1' then v.m0counter := r.m0counter + 1; v.dmao.address := r.dmao.address + 4; end if; if dmain_m.ready = '1' then v.m1counter := r.m1counter + 1; v.dmao_m.address := r.dmao_m.address + 4; end if; start := '1'; mstart := '1'; if r.app_write = '1' then if dmain_m.ready = '1' then v.fifo_buf(0 to 2) := r.fifo_buf(1 to 3); v.fifo_count := v.fifo_count - 1; end if; if dmain.ready = '1' then v.fifo_buf(conv_integer(v.fifo_count)) := dmain.rdata; v.fifo_count := v.fifo_count + 1; end if; if unsigned(v.fifo_count) = 0 then mstart := '0'; end if; if unsigned(v.fifo_count) = 4 then start := '0'; end if; else if dmain.ready = '1' then v.fifo_buf(0 to 2) := r.fifo_buf(1 to 3); v.fifo_count := v.fifo_count - 1; end if; if dmain_m.ready = '1' then v.fifo_buf(conv_integer(v.fifo_count)) := dmain_m.rdata; v.fifo_count := v.fifo_count + 1; end if; if unsigned(v.fifo_count) = 4 then mstart := '0'; end if; if unsigned(v.fifo_count) = 0 then start := '0'; end if; end if; v.dmao.wdata := v.fifo_buf(0); v.dmao_m.wdata := v.fifo_buf(0); if dmain.ready = '1' and r.dmao.address(9 downto 0) = "1111111100" then start := '0'; end if; if dmain_m.ready = '1' and r.dmao_m.address(9 downto 0) = "1111111100" then mstart := '0'; end if; if r.m0counter = unsigned(r.app_length) - 1 and dmain.ready = '1' then start := '0'; end if; if r.m1counter = unsigned(r.app_length) - 1 and dmain_m.ready = '1' then mstart := '0'; end if; if r.m0counter >= unsigned(r.app_length) then start := '0'; end if; if r.m1counter >= unsigned(r.app_length) then mstart := '0'; end if; end if;-------------------------------------------------------------------------------- --UDP FSM-------------------------------------------------------------------------------- case r.udp_state is when idle => if r.main_state = udp then v.udp_state := udp1; v.dmao.address := r.baseadr(31 downto 6) & "101000"; v.dmao.write := '1'; v.dmao.size := "10"; v.dmao.wdata := X"00000000"; end if; when udp1 => start := '1'; if dmain.ready = '1' then start := '0'; v.udp_state := udp2; if r.dmao.write = '0' then v.readbuf := dmain.rdata; end if; end if; when udp2 => if r.counter < 4 then v.udp_state := udp1; v.counter := r.counter + 1; else v.udp_state := finished; v.counter := 0; end if; case r.counter is when 0 => v.dmao.address := r.baseadr(31 downto 6) & "100110"; v.dmao.size:="01"; v.dmao.write := '1'; v.dmao.wdata(15 downto 0):=conv_std_logic_vector(18+r.app_layer_size,16); when 1 => v.dmao.address := r.baseadr(31 downto 6) & "100010"; v.dmao.write := '0'; v.dmao.size:="01"; when 2 => v.dmao.address := r.baseadr(31 downto 6) & "100100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf(15 downto 0); when 3 => v.dmao.address := r.baseadr(31 downto 6) & "100010"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(15 downto 0) := port_nbr; when others => null; end case; when finished => if r.main_state /= udp then v.udp_state := idle; end if; end case; -------------------------------------------------------------------------------- --IP FSM -------------------------------------------------------------------------------- case r.ip_state is when idle => if r.main_state = ip then v.ip_state := ip1; v.dmao.address := r.baseadr(31 downto 6) & "010000"; v.dmao.write := '1'; v.dmao.size := "10"; v.dmao.wdata := conv_std_logic_vector(r.app_layer_size + 38, 16) & conv_std_logic_vector(r.ipid, 16); v.ipchksum:=r.ipchksum + conv_std_logic_vector(r.ipid, 16) + conv_std_logic_vector(r.app_layer_size + 38, 16); end if; when ip1 => start := '1'; if dmain.ready = '1' then start := '0'; v.ip_state := ip2; if r.dmao.write = '0' then v.readbuf2 := dmain.rdata; end if; end if; when ip2 => if r.counter2 < 11 then v.ip_state := ip1; v.counter2 := r.counter2 + 1; else v.ip_state := finished; v.counter2 := 0; v.ipchksum := iptemp1 + iptemp2 + iptemp3; v.ipid := r.ipid + 1; end if; case r.counter2 is when 0 => v.dmao.address := r.baseadr(31 downto 6) & "010110"; v.dmao.write := '1'; v.dmao.size := "00"; v.dmao.wdata(15 downto 8) := conv_std_logic_vector(64, 8); when 1 => v.dmao.address := r.baseadr(31 downto 6) & "010100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := X"0000"; when 2 => v.dmao.address := r.baseadr(31 downto 6) & "011010"; v.dmao.write := '0'; v.dmao.size := "01"; when 3 =>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?