library ieee; use work.ucore_package.all; use work.bus_package.all; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity ucore_execute is port ( -- global clk : in std_logic; reset : in std_logic; -- irq : in std_logic; -- in reg_data_b : in std_logic_vector(15 downto 0); reg_data_a : in std_logic_vector(15 downto 0); reg_rc : in std_logic_vector(2 downto 0); reg_rc_we : in std_logic; reg_opcode : in opcode_t; reg_simm : in std_logic_vector(15 downto 0); -- out alu_pc : out std_logic_vector(15 DOWNTO 0); alu_rc_we : out std_logic; alu_rc : out std_logic_vector(2 downto 0); alu_data_c : out std_logic_vector(15 downto 0); alu_stall : out std_logic; -- memory mem_address : out std_logic_vector(15 downto 0); mem_we : out std_logic; mem_data : out std_logic_vector(15 downto 0); mem_q : in std_logic_vector(15 downto 0); -- external -- send ext_send_data : out std_logic_vector(15 downto 0); ext_send_address : out std_logic_vector(31 downto 0); ext_send_we : out std_logic; ext_send_busy : in std_logic; ext_send_wrreq : out std_logic; -- recive ext_recive_data : in std_logic_vector(15 downto 0); ext_recive_busy : in std_logic; ext_recive_ack : out std_logic ); end entity; architecture rtl of ucore_execute is -- extended functions component ld2d is port ( -- global clk : in std_logic; reset : in std_logic; stall_in : in std_logic; -- param rsel : in integer range 0 to 15; wsel : in integer range 0 to 15; indata : in std_logic_vector(15 downto 0); inwe : in std_logic; outdata : out std_logic_vector(15 downto 0); -- activate en : in std_logic; -- dadr : out std_logic_vector(31 downto 0) ); end component; -- global signal ld2d_rsel : integer range 0 to 15 := 0; signal ld2d_wsel : integer range 0 to 15 := 0; signal ld2d_indata : std_logic_vector(15 downto 0) := (others => '0'); signal ld2d_inwe : std_logic := '0'; signal ld2d_outdata : std_logic_vector(15 downto 0) := (others => '0'); signal ld2d_en : std_logic := '0'; signal ld2d_dadr : std_logic_vector(31 downto 0) := (others => '0'); -- addsub component add_sub PORT ( add_sub : IN STD_LOGIC ; cin : IN STD_LOGIC ; dataa : IN STD_LOGIC_VECTOR (15 DOWNTO 0); datab : IN STD_LOGIC_VECTOR (15 DOWNTO 0); cout : OUT STD_LOGIC ; overflow : OUT STD_LOGIC ; result : OUT STD_LOGIC_VECTOR (15 DOWNTO 0) ); end component; signal cas_add_sub : std_logic := '0'; signal cas_cin : std_logic := '0'; signal cas_cout : std_logic := '0'; signal cas_overflow : std_logic := '0'; signal cas_result : std_logic_vector(15 downto 0) := (others =>'0'); -- multiply component multiply is port ( -- data in b : in std_logic_vector(15 downto 0); a : in std_logic_vector(15 downto 0); -- data out mul_res : out std_logic_vector(31 downto 0); muls_res : out std_logic_vector(31 downto 0) ); end component; signal mul_result : std_logic_vector(31 downto 0) := (others =>'0'); signal muls_result : std_logic_vector(31 downto 0) := (others =>'0'); -- shifts component shifts is port ( -- data in b : in std_logic_vector(15 downto 0); a : in std_logic_vector(15 downto 0); -- data out lsr_res : out std_logic_vector(15 downto 0); asr_res : out std_logic_vector(15 downto 0) ); end component; signal lsr_res : std_logic_vector(15 downto 0) := (others =>'0'); signal asr_res : std_logic_vector(15 downto 0) := (others =>'0'); -- logics component logics is port ( -- data in b : in std_logic_vector(15 downto 0); a : in std_logic_vector(15 downto 0); -- data out and_res : out std_logic_vector(15 downto 0); or_res : out std_logic_vector(15 downto 0); xor_res : out std_logic_vector(15 downto 0); bic_res : out std_logic_vector(15 downto 0) ); end component; signal and_res : std_logic_vector(15 downto 0) := (others =>'0'); signal or_res : std_logic_vector(15 downto 0) := (others =>'0'); signal xor_res : std_logic_vector(15 downto 0) := (others =>'0'); signal bic_res : std_logic_vector(15 downto 0) := (others =>'0'); -- bit field component bit_field is port ( -- data in b : in std_logic_vector(15 downto 0); a : in std_logic_vector(15 downto 0); -- data out bffo_res : out std_logic_vector(15 downto 0); bffo_t : out std_logic; bset_res : out std_logic_vector(15 downto 0); bclr_res : out std_logic_vector(15 downto 0); extr_t : out std_logic ); end component; signal bffo_res : std_logic_vector(15 downto 0) := (others =>'0'); signal bffo_t : std_logic := '0'; signal bset_res : std_logic_vector(15 downto 0) := (others =>'0'); signal bclr_res : std_logic_vector(15 downto 0) := (others =>'0'); signal extr_t : std_logic := '0'; -- compares component compares is port ( -- data in b : in std_logic_vector(15 downto 0); a : in std_logic_vector(15 downto 0); -- data out cmpeq_res : out std_logic; cmplo_res : out std_logic; cmplos_res : out std_logic; cmple_res : out std_logic; cmples_res : out std_logic ); end component; signal cmpeq_res : std_logic := '0'; signal cmplo_res : std_logic := '0'; signal cmplos_res : std_logic := '0'; signal cmple_res : std_logic := '0'; signal cmples_res : std_logic := '0'; -- udiv extension signal udiv_qoutient : std_logic_vector(31 DOWNTO 0) := (others => '0'); signal udiv_rest : std_logic_vector(31 DOWNTO 0) := (others => '0'); signal udiv_divident : std_logic_vector(31 DOWNTO 0) := (others => '0'); signal udiv_divisor : std_logic_vector(31 DOWNTO 0) := (others => '0'); signal udiv_counter : std_logic_vector(4 DOWNTO 0) := (others => '0'); ----------------------------------------------------------------------------------------------------------- -- constant ----------------------------------------------------------------------------------------------------------- constant reset_vector_default : std_logic_vector(15 downto 0) := x"0000"; -- RESET VECTOR constant irq_vector_default : std_logic_vector(15 downto 0) := x"0010"; -- IRQ VECTOR constant stack_address_default : std_logic_vector(15 downto 0) := x"8000"; -- STACK START -- signal irq_start_vector : std_logic_vector(15 downto 0) := irq_vector_default; signal ialu_t : std_logic := '0'; signal ialu_v : std_logic := '0'; signal ialu_stall : std_logic := '0'; signal iirq_enable : std_logic := '0'; signal ialu_pc : std_logic_vector(15 DOWNTO 0) := (others => '0'); signal ipc_stored : std_logic_vector(15 DOWNTO 0) := (others => '0'); signal it_stored : std_logic := '0'; signal iv_stored : std_logic := '0'; signal e_adr : std_logic_vector(31 DOWNTO 0) := (others => '0'); signal imulhi : std_logic_vector(15 DOWNTO 0) := (others => '0'); signal store_offset : std_logic_vector(5 DOWNTO 0) := (others => '0'); begin -- alu_stall <= ialu_stall; -- extensions (2d load) extension_ld2d : ld2d port map ( clk, reset, ialu_stall, ld2d_rsel, ld2d_wsel, ld2d_indata, ld2d_inwe, ld2d_outdata, ld2d_en, ld2d_dadr ); -- add subtype cas_add_sub <= '1' when reg_opcode = ope_rqld or -- add reg_opcode = ope_rqldi or reg_opcode = ope_add or reg_opcode = ope_addi or reg_opcode = ope_addt or reg_opcode = ope_addqi or reg_opcode = ope_addtqi else '0'; -- sub cas_cin <= ialu_t when reg_opcode = ope_addtqi or -- use t reg_opcode = ope_subtqi or reg_opcode = ope_addt or reg_opcode = ope_subt else '0' when reg_opcode = ope_rqld or -- no carry/ borrow reg_opcode = ope_rqldi or reg_opcode = ope_add or reg_opcode = ope_addi or reg_opcode = ope_addqi else '1'; addsub : add_sub port map ( cas_add_sub, cas_cin, reg_data_b, reg_data_a, cas_cout, cas_overflow, cas_result ); -- mul multiply_ops : multiply port map ( reg_data_b, reg_data_a, mul_result, muls_result ); -- shifts shifts_ops : shifts port map ( reg_data_b, reg_data_a, lsr_res, asr_res ); -- logics logics_ops : logics port map ( reg_data_b, reg_data_a, and_res, or_res, xor_res, bic_res ); -- bit field bit_field_ops : bit_field port map ( reg_data_b, reg_data_a, bffo_res, bffo_t, bset_res, bclr_res, extr_t ); -- compares compare_ops : compares port map ( reg_data_b, reg_data_a, cmpeq_res, cmplo_res, cmplos_res, cmple_res, cmples_res ); -- alu_pc <= ialu_pc; process(clk) variable stack_adr : std_logic_vector(15 downto 0) := stack_address_default; variable udiv_temp : std_logic_vector(31 downto 0) := (others => '0'); begin if rising_edge(clk) then if reset = '1' then alu_rc_we <= reg_rc_we; alu_rc <= reg_rc; alu_data_c <= (others => '0'); mem_address <= (others => '0'); mem_we <= '0'; mem_data <= (others => '0'); ext_send_data <= (others => '0'); ext_send_address <= (others => '0'); ext_send_we <= '0'; ext_send_wrreq <= '0'; ialu_t <= '0'; stack_adr := stack_address_default; imulhi <= (others => '0'); store_offset <= (others => '0'); e_adr <= (others => '0'); -- udiv extension udiv_qoutient <= (others => '0'); udiv_rest <= (others => '0'); udiv_divident <= (others => '0'); udiv_divisor <= (others => '0'); udiv_counter <= (others => '0'); -- else -- alu_rc_we <= reg_rc_we; alu_rc <= reg_rc; -- extension ld2d_en <= '0'; -- reg write alu_data_c <= (others => '0'); -- memory mem_we <= '0'; mem_data <= reg_data_a; -- write data ever reg a -- external mem (defaults) ext_send_data <= (others => '0'); ext_send_address <= e_adr; ext_send_we <= '0'; ext_send_wrreq <= '0'; -- nothing todo -- exec case reg_opcode is ----------------------------------------------------------------------------------------------------------- -- nop ----------------------------------------------------------------------------------------------------------- when ope_nop => ----------------------------------------------------------------------------------------------------------- -- moves / swaps / ext ----------------------------------------------------------------------------------------------------------- when ope_movei => alu_data_c <= reg_data_a(15 downto 0); when ope_moveih => alu_data_c <= reg_data_a(7 downto 0) & reg_data_b(7 downto 0); when ope_movets => if ialu_t = '1' then alu_data_c <= reg_data_b; else alu_data_c <= reg_data_a; end if; when ope_swp => alu_data_c <= reg_data_a(7 downto 0) & reg_data_a(15 downto 8); when ope_swptc => if ialu_t = '0' then alu_data_c <= reg_data_a(7 downto 0) & reg_data_a(15 downto 8); else alu_data_c <= reg_data_a; end if; when ope_extb => if reg_data_a(7) = '1' then alu_data_c <= x"ff" & reg_data_a(7 downto 0); else alu_data_c <= x"00" & reg_data_a(7 downto 0); end if; ----------------------------------------------------------------------------------------------------------- -- add / sub / neg ----------------------------------------------------------------------------------------------------------- when ope_addi | ope_add | ope_addt | ope_addqi | ope_addtqi => alu_data_c <= cas_result; ialu_t <= cas_cout; ialu_v <= cas_overflow; when ope_subi | ope_sub | ope_subt | ope_subqi | ope_subtqi => alu_data_c <= cas_result; ialu_t <= cas_cout; ialu_v <= cas_overflow; when ope_neg => alu_data_c <= x"0000" - reg_data_a; when ope_negts => if ialu_t = '1' then alu_data_c <= x"0000" - reg_data_a; else alu_data_c <= reg_data_a; end if; ----------------------------------------------------------------------------------------------------------- -- shifts ----------------------------------------------------------------------------------------------------------- when ope_lsri | ope_lsr | ope_lsrqi => alu_data_c <= lsr_res; when ope_lsrts => if ialu_t = '1' then alu_data_c <= lsr_res; else alu_data_c <= reg_data_b; end if; when ope_asri | ope_asr | ope_asrqi => alu_data_c <= asr_res; when ope_asrts => if ialu_t = '1' then alu_data_c <= asr_res; else alu_data_c <= reg_data_b; end if; ----------------------------------------------------------------------------------------------------------- -- mul / muls (remove for higher clock) ----------------------------------------------------------------------------------------------------------- when ope_muli | ope_mulqi | ope_mul => alu_data_c <= mul_result(15 downto 0); imulhi <= mul_result(31 downto 16); when ope_mults => if ialu_t = '1' then alu_data_c <= mul_result(15 downto 0); imulhi <= mul_result(31 downto 16); else alu_data_c <= reg_data_b; end if; when ope_muls => alu_data_c <= muls_result(15 downto 0); imulhi <= muls_result(31 downto 16); when ope_mulsts => if ialu_t = '1' then alu_data_c <= muls_result(15 downto 0); imulhi <= muls_result(31 downto 16); else alu_data_c <= reg_data_b; end if; when ope_gmulhi => alu_data_c <= imulhi; ----------------------------------------------------------------------------------------------------------- -- compares ----------------------------------------------------------------------------------------------------------- when ope_cmpeqi | ope_cmpeq => ialu_t <= cmpeq_res; when ope_cmploi | ope_cmplo => ialu_t <= cmplo_res; when ope_cmplosi | ope_cmplos => ialu_t <= cmplos_res; when ope_cmple => ialu_t <= cmple_res; when ope_cmples => ialu_t <= cmples_res; ----------------------------------------------------------------------------------------------------------- -- logic ----------------------------------------------------------------------------------------------------------- when ope_and => alu_data_c <= and_res; when ope_or => alu_data_c <= or_res; when ope_xor => alu_data_c <= xor_res; when ope_bic => alu_data_c <= bic_res; when ope_andts => if ialu_t = '1' then alu_data_c <= and_res; else alu_data_c <= reg_data_b; end if; when ope_orts => if ialu_t = '1' then alu_data_c <= or_res; else alu_data_c <= reg_data_b; end if; when ope_xorts => if ialu_t = '1' then alu_data_c <= xor_res; else alu_data_c <= reg_data_b; end if; when ope_bicts => if ialu_t = '1' then alu_data_c <= bic_res; else alu_data_c <= reg_data_b; end if; ----------------------------------------------------------------------------------------------------------- -- bit / bitfield ----------------------------------------------------------------------------------------------------------- when ope_bffo => ialu_t <= bffo_t; alu_data_c <= bffo_res; when ope_bset => alu_data_c <= bset_res; when ope_bclr => alu_data_c <= bclr_res; when ope_extri => ialu_t <= extr_t; ----------------------------------------------------------------------------------------------------------- -- imem ld/store push/pop etc ----------------------------------------------------------------------------------------------------------- when ope_rqldi | ope_rqld => mem_address <= cas_result; when ope_ld_pop => alu_data_c <= mem_q; when ope_st => mem_data <= reg_data_a; mem_address <= reg_data_b; mem_we <= '1'; when ope_stinc => mem_data <= reg_data_a; mem_address <= reg_data_b; mem_we <= '1'; alu_data_c <= reg_data_b + 1; when ope_stwo => mem_data <= reg_data_a; mem_address <= reg_data_b + store_offset; mem_we <= '1'; when ope_ssto => store_offset <= reg_data_a(5 downto 0); when ope_push => mem_data <= reg_data_b; stack_adr := stack_adr - 1; mem_address <= stack_adr; mem_we <= '1'; when ope_rqpop => mem_address <= stack_adr; stack_adr := stack_adr + 1; when ope_poparqp => alu_data_c <= mem_q; mem_address <= stack_adr; stack_adr := stack_adr + 1; when ope_epushsadrl => mem_data <= e_adr(15 downto 0); stack_adr := stack_adr - 1; mem_address <= stack_adr; mem_we <= '1'; when ope_epushsadrh => mem_data <= e_adr(31 downto 16); stack_adr := stack_adr - 1; mem_address <= stack_adr; mem_we <= '1'; when ope_epopsadrl => e_adr(15 downto 0) <= mem_q; when ope_epopsadrh => e_adr(31 downto 16) <= mem_q; ----------------------------------------------------------------------------------------------------------- -- pc / status / t modify ----------------------------------------------------------------------------------------------------------- when ope_gpci => alu_data_c <= ialu_pc + reg_data_a; when ope_rti => ialu_t <= it_stored; ialu_v <= iv_stored; when ope_getsp => alu_data_c <= stack_adr + reg_data_a; when ope_setsp => stack_adr := reg_data_a; when ope_tnt => ialu_t <= not ialu_t; when ope_vtt => ialu_t <= ialu_v; when ope_getssr => case reg_data_a(2 downto 0) is when "000" => alu_data_c <= x"00" & "0" & iv_stored & ext_send_busy & ext_recive_busy & "0" & irq & it_stored & iirq_enable; when "001" => alu_data_c <= ipc_stored; when "010" => alu_data_c <= irq_start_vector; when "011" => alu_data_c <= (others => '0'); -- extension when "110" => alu_data_c <= ld2d_outdata; when others => alu_data_c <= (others => '0'); end case; ----------------------------------------------------------------------------------------------------------- -- external memory access ----------------------------------------------------------------------------------------------------------- when ope_espage => e_adr <= reg_data_b & reg_data_a; when ope_est => ext_send_address <= e_adr + reg_data_a; ext_send_data <= reg_data_b; ext_send_we <= '1'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; when ope_estts => ext_send_address <= e_adr + reg_data_a; ext_send_data <= reg_data_b; ext_send_we <= '1'; if ialu_t = '1' then if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; end if; when ope_edrqldi => ext_send_address <= (reg_data_b & reg_data_a) + reg_simm; ext_send_we <= '0'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; when ope_erqldi | ope_erqld => ext_send_address <= e_adr + reg_data_a; ext_send_we <= '0'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; when ope_erqldb => ext_send_address <= e_adr + reg_data_a(15 downto 1); ext_send_we <= '0'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; when ope_eld => if ext_recive_busy = '0' then alu_data_c <= ext_recive_data; else alu_data_c <= (others => '0'); end if; ----------------------------------------------------------------------------------------------------------- -- udiv (remove for higher clock) ----------------------------------------------------------------------------------------------------------- when ope_udivinit => udiv_qoutient <= (others => '0'); udiv_rest <= (others => '0'); udiv_counter <= reg_data_a(4 downto 0); when ope_udivgq => alu_data_c <= udiv_qoutient(15 downto 0); when ope_udivgr => alu_data_c <= udiv_rest(15 downto 0); when ope_udivgqh => alu_data_c <= udiv_qoutient(31 downto 16); when ope_udivgrh => alu_data_c <= udiv_rest(31 downto 16); when ope_udivsdd => udiv_divident <= x"0000" & reg_data_a; when ope_udivsdv => udiv_divisor <= x"0000" & reg_data_a; when ope_udivsddh => udiv_divident(31 downto 16) <= reg_data_a; when ope_udivsdvh => udiv_divisor(31 downto 16) <= reg_data_a; when ope_udivstep => udiv_temp := udiv_rest(30 downto 0) & udiv_divident(conv_integer(udiv_counter)); if udiv_temp >= udiv_divisor then udiv_temp := udiv_temp - udiv_divisor; udiv_qoutient(conv_integer(udiv_counter)) <= '1'; end if; udiv_rest <= udiv_temp; udiv_counter <= udiv_counter - 1; ----------------------------------------------------------------------------------------------------------- -- extension load 2d (remove for higher clock) ----------------------------------------------------------------------------------------------------------- when ope_exl2den => ld2d_en <= '1'; when ope_exl2denerqld => ld2d_en <= '1'; ext_send_address <= ld2d_dadr; ext_send_we <= '0'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; when ope_exl2derqld => ext_send_address <= ld2d_dadr; ext_send_we <= '0'; if ext_send_busy = '0' then ext_send_wrreq <= '1'; end if; ----------------------------------------------------------------------------------------------------------- -- illegal ----------------------------------------------------------------------------------------------------------- when ope_illegal => when others => end case; end if; end if; end process; ----------------------------------------------------------------------------------------------------------- -- stall ctrl ----------------------------------------------------------------------------------------------------------- process(all) begin ialu_stall <= '0'; if reset = '0' then -- load (recive) stall if reg_opcode = ope_eld then -- there is an load if ext_recive_busy = '1' then -- and external port is busy ialu_stall <= '1'; -- so stall end if; end if; -- store / request load stall if reg_opcode = ope_est or reg_opcode = ope_erqldi or reg_opcode = ope_erqld or reg_opcode = ope_erqldb or reg_opcode = ope_edrqldi or reg_opcode = ope_exl2denerqld or reg_opcode = ope_exl2derqld or (reg_opcode = ope_estts and ialu_t = '1') then if ext_send_busy = '1' then -- stall if sender is busy ialu_stall <= '1'; end if; end if; end if; end process; ----------------------------------------------------------------------------------------------------------- -- load ack (reciver) ----------------------------------------------------------------------------------------------------------- ext_recive_ack <= '1' when reg_opcode = ope_eld and ext_recive_busy = '0' and reset = '0' -- on load and not busy ack else '0'; ----------------------------------------------------------------------------------------------------------- -- pc / irq releated ----------------------------------------------------------------------------------------------------------- process(clk) variable next_pc : std_logic_vector(15 downto 0) := reset_vector_default; begin if rising_edge(clk) then if reset = '1' then ialu_pc <= reset_vector_default; ipc_stored <= (others => '0'); irq_start_vector <= irq_vector_default; iirq_enable <= '0'; else -- default ld2d_inwe <= '0'; -- if ialu_stall = '0' then ----------------------------------------------------------------------------------------------------------- -- pc increment (standard if no branch) ----------------------------------------------------------------------------------------------------------- next_pc := ialu_pc + 1; -- exec case reg_opcode is ----------------------------------------------------------------------------------------------------------- -- branch / jump ----------------------------------------------------------------------------------------------------------- when ope_jmpi => next_pc := reg_data_b + reg_data_a; when ope_jmpts => if ialu_t = '1' then next_pc := reg_data_a; end if; when ope_jmptc => if ialu_t = '0' then next_pc := reg_data_a; end if; when ope_br => next_pc := ialu_pc + ( reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11 downto 0)); when ope_brts => if ialu_t = '1' then next_pc := ialu_pc + ( reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11 downto 0)); end if; when ope_brtc => if ialu_t = '0' then next_pc := ialu_pc + ( reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11) & reg_data_a(11 downto 0)); end if; when ope_rti => next_pc := ipc_stored; ----------------------------------------------------------------------------------------------------------- -- irq related ----------------------------------------------------------------------------------------------------------- when ope_setssr => case reg_data_a(2 downto 0) is when "000" => iirq_enable <= reg_data_b(0); when "001" => ipc_stored <= reg_data_b; when "010" => irq_start_vector <= reg_data_b; when "011" => -- extension when "100" => ld2d_rsel <= conv_integer(reg_data_b); when "101" => ld2d_wsel <= conv_integer(reg_data_b); when "110" => ld2d_indata <= reg_data_b; ld2d_inwe <= '1'; when others => end case; when ope_cli => iirq_enable <= '0'; when ope_sei => iirq_enable <= '1'; when others => end case; ----------------------------------------------------------------------------------------------------------- -- only jmp on these instructions if irq and enabled (branch injection) ----------------------------------------------------------------------------------------------------------- case reg_opcode is when ope_rti | ope_brtc | ope_brts | ope_br | ope_jmpi | ope_jmpts | ope_jmptc => if irq = '1' and iirq_enable = '1' then ipc_stored <= next_pc; -- store pc it_stored <= ialu_t; -- store t bit iv_stored <= ialu_v; -- store v bit next_pc := irq_start_vector; -- start at irq vector end if; when others => end case; ialu_pc <= next_pc; end if; end if; end if; end process; end rtl;