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