ctrlunit.vhd
来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 844 行 · 第 1/3 页
VHD
844 行
-------------------------------------------------------------------------------- Entity: ctrlunit -- File: ctrlunit.vhd-- Author: Marko Isomaki-- Description: control unit for the ethernet debug interface------------------------------------------------------------------------------library ieee;library grlib;library gaisler;use ieee.std_logic_1164.all;use grlib.amba.all;use ieee.numeric_std.all;use gaisler.misc.all;use gaisler.devices.all;use gaisler.net.all;use grlib.stdlib.all;entity ctrlunit is generic ( ahbndx : integer := 0; ahbndx2 : integer := 1; ahbndx3 : integer := 3; memndx : integer := 1; memaddr : integer := 16#2000#; macaddrh : integer := 16#00007A#; macaddrl : integer := 16#000000#; ipaddrh : integer := 16#C0A8#; ipaddrl : integer := 16#0032#; udpport : integer := 10000; extip : integer := 0; fullduplex : integer := 0; mdioenabled: integer := 0; autoneg : integer := 0; speed : integer := 0; phyrstcls : integer := 100000; phyadr : integer := 0; sim : integer := 0); port( rst : in std_logic; clk : in std_logic; edcli : in edcl_in_type; ahbmi : in ahb_mst_in_type; ahbmo : out ahb_mst_out_type; ahbmi_m : in ahb_mst_in_type; ahbmo_m : out ahb_mst_out_type; ahbmi_rt : in ahb_mst_in_type; ahbmo_rt : out ahb_mst_out_type );end;architecture rtl of ctrlunit istype buffer_def is array (0 to 13) of natural;type FIFO_buf_type is array (0 to 3) of std_logic_vector(31 downto 0);constant win_block : buffer_def := (4, 256, 4, 512, 8, 512, 8, 1024, 16, 1024, 32, 1024, 64, 1024); constant win_size : natural := win_block(2 * memndx);constant block_size : natural := win_block(2 * memndx + 1);type buf_type is array (0 to win_size - 1) of std_logic_vector(2 downto 0); type initmac_state_type is (idle, initrxbd, initrxbd2, waitphy, addrSel, addrSel2, finished, setphy, setphy2, readdata, pollstat);type arp_state_type is (idle, arp_1, arp_2, arp_3, finished);type main_state_type is (idle, clr_int, clr_int2, wr_eth_adr, wr_eth_adr2, check_type, arp, check_ip, check_seq, app, udp, ip, set_txbd, set_txbd2, upd_tx_offset, no_snd);type ip_state_type is (idle, ip1, ip2, finished);type udp_state_type is (idle, udp1, udp2, finished);type app_state_type is (idle, app1, app2, app3, app4, app5, nak, finished);type rx_tx_state_type is (init, idle, clrintw, clrintw2, clrintr, readint, updrxbd, updrxbd2);type reg_type is record rx_offset : natural range 0 to win_size - 1; rx2_offset : natural range 0 to win_size - 1; tx_offset : natural range 0 to win_size - 1; tx2_offset : natural range 0 to win_size - 1; tx3_offset : natural range 0 to win_size - 1; baseadr : std_logic_vector(31 downto 0); readbuf : std_logic_vector(31 downto 0); readbuf2 : std_logic_vector(31 downto 0); readbuf3 : std_logic_vector(3 downto 0); ipid : natural range 0 to 65535; ipchksum : std_logic_vector(19 downto 0); counter : natural range 0 to 127; counter2 : natural range 0 to 127; rcv_nxt : std_logic_vector(13 downto 0); read_stat : std_logic_vector(win_size - 1 downto 0); write_stat : std_logic_vector(win_size - 1 downto 0); no_snd : std_logic_vector(win_size - 1 downto 0); read_error : std_logic_vector(win_size - 1 downto 0); app_layer_size: natural range 0 to 1024; arp_state : arp_state_type; app_addr : std_logic_vector(31 downto 0); app_length : std_logic_vector(9 downto 0); arp_bad_ip : std_logic; arp : std_logic; nak : std_logic; main_state : main_state_type; rx_tx_state : rx_tx_state_type; initmacstate : initmac_state_type; ip_state : ip_state_type; udp_state : udp_state_type; app_state : app_state_type; app_write : std_logic; dmao : ahb_dma_in_type; dmao_m : ahb_dma_in_type; dmao_rt : ahb_dma_in_type; fifo_buf : FIFO_buf_type; fifo_count : std_logic_vector(2 downto 0); m0counter : natural range 0 to 255; m1counter : natural range 0 to 255; laddr2 : std_logic_vector(15 downto 0); resetcounter : std_logic_vector(31 downto 0);end record;constant ethadr : std_logic_vector(47 downto 0) := conv_std_logic_vector(macaddrh, 24) & conv_std_logic_vector(macaddrl, 24);constant ipadr : std_logic_vector(31 downto 0) := conv_std_logic_vector(ipaddrh, 16) & conv_std_logic_vector(ipaddrl, 16);constant ram_addr : std_logic_vector(31 downto 0) := conv_std_logic_vector(memaddr, 16) & "0000000000000000"; constant port_nbr : std_logic_vector(15 downto 0) := conv_std_logic_vector(udpport, 16); signal ip_adr : std_logic_vector(31 downto 0); signal eth_adr : std_logic_vector(47 downto 0);signal iptemp1 : std_logic_vector(19 downto 0);signal iptemp2 : std_logic_vector(19 downto 0);constant iptemp3 : std_logic_vector(19 downto 0):="00000100010100000000";signal r,rin : reg_type;signal dmaout : ahb_dma_in_type;signal dmain : ahb_dma_out_type;signal dmaout_m : ahb_dma_in_type;signal dmain_m : ahb_dma_out_type;signal dmain_rt : ahb_dma_out_type;signal dmaout_rt : ahb_dma_in_type;begin eip0 : if extip /= 0 generate ip_adr <= ipadr(31 downto 4) & edcli.lsbip; eth_adr <= ethadr(47 downto 4) & edcli.lsbip; end generate; eip1 : if extip = 0 generate ip_adr <= ipadr; eth_adr <= ethadr; end generate; iptemp1 <= "0000" & ip_adr(31 downto 16); iptemp2 <= "0000" & ip_adr(15 downto 0); a0 : ahbmst generic map (hindex => ahbndx, venid => VENDOR_GAISLER, devid => GAISLER_DSUCTRL, incaddr => 1) port map(rst => rst, clk => clk, dmai => dmaout, dmao => dmain, ahbi => ahbmi,ahbo => ahbmo); a1 : ahbmst generic map(hindex => ahbndx2, venid => VENDOR_GAISLER, devid => GAISLER_DSUCTRL, incaddr => 1) port map(rst => rst,clk => clk, dmai => dmaout_m, dmao => dmain_m, ahbi => ahbmi_m, ahbo => ahbmo_m); a2 : ahbmst generic map(hindex => ahbndx3, venid => VENDOR_GAISLER, devid => GAISLER_DSUCTRL, incaddr => 1) port map(rst => rst, clk => clk, dmai => dmaout_rt, dmao => dmain_rt, ahbi => ahbmi_rt, ahbo => ahbmo_rt); comb : process(r, dmain, ahbmi, dmain_m, ahbmi_rt, dmain_rt, rst, ip_adr, eth_adr, iptemp1, iptemp2) variable v : reg_type; variable start : std_logic; variable mstart : std_logic; variable rtstart : std_logic; variable haddr, laddr : std_logic_vector(15 downto 0); begin v := r; start := '0'; mstart := '0'; rtstart := '0';-------------------------------------------------------------------------------- --MAIN FSM-------------------------------------------------------------------------------- case r.main_state is when idle => if r.read_stat(r.tx_offset) = '1' then v.read_stat(r.tx_offset) := '0'; v.dmao.address := r.baseadr(31 downto 6) & "001100"; v.dmao.size := "01"; v.dmao.write := '0'; if r.read_error(r.tx_offset) = '1' then v.read_error(r.tx_offset) := '0'; v.main_state := no_snd; else v.main_state := check_type; end if; end if; v.nak := '0'; v.arp := '0'; v.arp_bad_ip := '0'; when check_type => start := '1'; if dmain.ready = '1' then start := '0'; if dmain.rdata(23 downto 16) = X"06" then v.main_state := arp; else v.main_state := check_ip; end if; end if; when arp => if r.arp_state = finished then v.arp := '1'; if r.arp_bad_ip = '1' then v.main_state := no_snd; else v.main_state := wr_eth_adr; end if; end if; when check_ip => case r.counter is when 0 => v.dmao.address := r.baseadr(31 downto 6) & "011110"; v.counter := r.counter + 1; when 1 => start := '1'; if dmain.ready = '1' then start := '0'; v.readbuf(31 downto 16) := dmain.rdata(15 downto 0); v.dmao.address := r.baseadr(31 downto 6) & "100000"; v.counter := r.counter + 1; end if; when 2 => start := '1'; if dmain.ready = '1' then start := '0'; v.counter := 0; v.readbuf(15 downto 0) := dmain.rdata(31 downto 16); if v.readbuf = ip_adr then v.main_state := check_seq; v.dmao.size := "10"; v.dmao.address := r.baseadr(31 downto 6) & "101100"; else v.main_state:=no_snd; end if; end if; when others => null; end case; when check_seq => start := '1'; if dmain.ready = '1' then start := '0'; if dmain.rdata(31 downto 18) /= r.rcv_nxt then v.nak := '1'; else v.rcv_nxt := r.rcv_nxt + 1; end if; v.main_state := app; end if; when app => if r.app_state = finished then v.main_state := udp; end if; when udp => if r.udp_state = finished then v.main_state := ip; end if; when ip => if r.ip_state = finished then v.main_state := wr_eth_adr; end if; when wr_eth_adr => if r.counter < 7 then case r.counter is when 0 => v.dmao.address := r.baseadr(31 downto 6) & "001000"; v.dmao.write := '0'; v.dmao.size := "10"; when 1 => v.dmao.address := r.baseadr(31 downto 6) & "000100"; v.dmao.write := '1'; v.dmao.size := "01"; v.dmao.wdata(31 downto 16) := r.readbuf(15 downto 0); when 2 => v.dmao.address := r.baseadr(31 downto 6) & "000010"; v.dmao.wdata(15 downto 0) := r.readbuf(31 downto 16); when 3 => v.dmao.address := r.baseadr(31 downto 6) & "000110"; v.dmao.write := '0'; when 4 => v.dmao.address := r.baseadr; v.dmao.write := '1'; v.dmao.wdata(31 downto 16) := r.readbuf(15 downto 0); when 5 => v.dmao.address := r.baseadr(31 downto 6) & "000110"; v.dmao.wdata(15 downto 0) := eth_adr(47 downto 32); when 6 => v.dmao.address := r.baseadr(31 downto 6) & "001000"; v.dmao.size := "10"; v.dmao.wdata := eth_adr(31 downto 0); when others => null; end case; v.main_state := wr_eth_adr2; else v.counter := 0; v.main_state := set_txbd; v.no_snd(r.tx_offset) := '0'; v.dmao.address := X"FFF01404" + r.tx2_offset * 8; v.dmao.wdata := r.baseadr; end if; when wr_eth_adr2 =>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?