library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gen_pkg.all; entity alu is port ( sys_clk : in std_logic; sys_res_n : in std_logic; opcode : in alu_ops; op1 : in csigned; op2 : in csigned; op3 : out csigned; do_calc : in std_logic; calc_done : out std_logic ); end entity alu; architecture beh of alu is type ALU_STATE is (SIDLE, SMUL, SDONE); signal state_int, state_next : ALU_STATE; signal done_intern : std_logic; signal op3_int, op3_next : csigned; signal calc_done_int, calc_done_next : std_logic; begin op3 <= op3_int; calc_done <= calc_done_int; -- sync process(sys_clk, sys_res_n) begin if sys_res_n = '0' then state_int <= SIDLE; op3_int <= (others => '0'); calc_done_int <= '0'; elsif rising_edge(sys_clk) then state_int <= state_next; op3_int <= op3_next; calc_done_int <= calc_done_next; end if; end process; -- next state process(state_int, opcode, done_intern, do_calc) begin -- set a default value for next state state_next <= state_int; -- next state berechnen case state_int is when SIDLE => if do_calc = '1' then case opcode is when ALU_MUL => state_next <= SMUL; when others => state_next <= SIDLE; end case; end if; when SMUL => if done_intern = '1' then state_next <= SDONE; end if; when SDONE => if do_calc = '0' then state_next <= SIDLE; end if; end case; end process; -- output process(state_int, op1, op2, op3_int) variable multmp : signed(((2*CBITS)-1) downto 0); begin done_intern <= '0'; calc_done_next <= '0'; op3_next <= (others => '0'); case state_int is when SIDLE => null; when SMUL => multmp := op1 * op2; op3_next(CBITS-1) <= multmp((2*CBITS)-1); op3_next((CBITS-2) downto 0) <= multmp((CBITS-2) downto 0); done_intern <= '1'; when SDONE => calc_done_next <= '1'; op3_next <= op3_int; end case; end process; end architecture beh;