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 + -
显示快捷键?