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