op2 : in csigned;
op3 : out csigned;
do_calc : in std_logic;
- ack : in std_logic;
calc_done : out std_logic
);
end entity alu;
architecture beh of alu is
- type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
- signal state, state_next : ALU_STATE;
+ 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 <= SIDLE;
+ state_int <= SIDLE;
+ op3_int <= (others => '0');
+ calc_done_int <= '0';
elsif rising_edge(sys_clk) then
- state <= state_next;
+ state_int <= state_next;
+ op3_int <= op3_next;
+ calc_done_int <= calc_done_next;
end if;
end process;
-- next state
- process(state, opcode, done_intern)
+ process(state_int, opcode, done_intern, do_calc)
begin
-- set a default value for next state
- state_next <= state;
+ state_next <= state_int;
-- next state berechnen
- case state is
+ case state_int is
when SIDLE =>
- case opcode is
- when ADD =>
- state_next <= SADD;
- when SUB =>
- state_next <= SSUB;
- when MUL =>
- state_next <= SMUL;
- when DIV =>
- state_next <= SDIV;
- when others =>
- state_next <= SIDLE;
- end case;
- when SADD =>
- if done_intern = '1' then
- state_next <= SDONE;
- end if;
- when SSUB =>
- if done_intern = '1' then
- state_next <= SDONE;
+ 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 SDIV =>
- if done_intern = '1' then
- state_next <= SDONE;
- end if;
when SDONE =>
- if ack = '1' then
+ if do_calc = '0' then
state_next <= SIDLE;
end if;
end case;
end process;
-- output
- process(state)
+ process(state_int, op1, op2, op3_int)
+ variable multmp : signed(((2*CBITS)-1) downto 0);
begin
- op3 <= (others => '0');
- calc_done <= '0';
+ done_intern <= '0';
+ calc_done_next <= '0';
+ op3_next <= (others => '0');
- case state is
+ case state_int is
when SIDLE =>
- done_intern <= '0';
- when SADD =>
- op3 <= op1 + op2;
- done_intern <= '1';
- when SSUB =>
- op3 <= op1 - op2;
- done_intern <= '1';
+ null;
when SMUL =>
- op3 <= op1 * op2;
- done_intern <= '1';
- when SDIV =>
- op3 <= op1 / op2;
+ 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 =>
- done_intern <= '1';
- calc_done <= '1';
+ calc_done_next <= '1';
+ op3_next <= op3_int;
end case;
end process;
end architecture beh;
+