entity alu is
port
(
- sys_clk : in std_ulogic;
- sys_res_n : in std_ulogic;
+ sys_clk : in std_logic;
+ sys_res_n : in std_logic;
opcode : in alu_ops;
- op1 : in signed(31 downto 0);
- op2 : in signed(31 downto 0);
- op3 : out signed(31 downto 0);
- do_calc : in std_ulogic;
- calc_done : out std_ulogic
+ op1 : in csigned;
+ 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
- -- signal cnt_int, cnt_next : integer range 0 to CNT_MAX;
- signal op3_next : signed (31 downto 0);
+ type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
+ signal state, state_next : ALU_STATE;
+ signal done_intern : std_logic;
begin
+ -- sync
process(sys_clk, sys_res_n)
begin
if sys_res_n = '0' then
- op3 <= (others => '0');
+ state <= SIDLE;
elsif rising_edge(sys_clk) then
- op3 <= op3_next;
+ state <= state_next;
end if;
end process;
- process(do_calc, opcode, op1, op2)
+ -- next state
+ process(state, opcode, done_intern)
begin
- case opcode is
- when ADD => op3_next <= op1 + op2;
- when SUB => op3_next <= op1 - op2;
- when MUL => op3_next <= op1 * op2;
- when DIV => op3_next <= op1 / op2;
- when others => op3_next <= (others => '0');
+ -- 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;
+ when SADD =>
+ if done_intern = '1' then
+ state_next <= SDONE;
+ end if;
+ when SSUB =>
+ if done_intern = '1' then
+ state_next <= SDONE;
+ 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
+ state_next <= SIDLE;
+ end if;
+ end case;
+ end process;
+
+ -- output
+ process(state)
+ begin
+ op3 <= (others => '0');
+ calc_done <= '0';
+
+ case state is
+ when SIDLE =>
+ done_intern <= '0';
+ when SADD =>
+ op3 <= op1 + op2;
+ done_intern <= '1';
+ when SSUB =>
+ op3 <= op1 - op2;
+ done_intern <= '1';
+ when SMUL =>
+ op3 <= op1 * op2;
+ done_intern <= '1';
+ when SDIV =>
+ op3 <= op1 / op2;
+ done_intern <= '1';
+ when SDONE =>
+ done_intern <= '1';
+ calc_done <= '1';
end case;
- -- calc_done <= '1';
- --else
- -- calc_done <= '0';
- --end if;
end process;
end architecture beh;
sys_clk : in std_logic;
sys_res_n : in std_logic;
opcode : in alu_ops;
- op1 : in signed(31 downto 0);
- op2 : in signed(31 downto 0);
- op3 : out signed(31 downto 0);
+ op1 : in csigned;
+ op2 : in csigned;
+ op3 : out csigned;
do_calc : in std_logic;
+ ack : in std_logic;
calc_done : out std_logic
);
end component alu;
- signal sys_clk, sys_res_n, do_calc, calc_done : std_ulogic;
+ signal sys_clk, sys_res_n, do_calc, calc_done, ack : std_logic;
signal opcode : alu_ops;
- signal op1, op2, op3, optmp : signed(31 downto 0);
+ signal op1, op2, op3, optmp : csigned;
signal stop : boolean := false;
begin
bla : alu
sys_clk => sys_clk,
sys_res_n => sys_res_n,
do_calc => do_calc,
+ ack => ack,
calc_done => calc_done,
op1 => op1,
op2 => op2,
process
begin
sys_res_n <= '0';
- wait for 100 ns;
+ wait for 50 ns;
sys_res_n <= '1';
- wait for 200 ns;
+ wait for 100 ns;
op1(31 downto 0) <= (0 => '1', 1 => '1', 2 => '1', others => '0');
op2(31 downto 0) <= (0 => '1', 2 => '1', others => '0');
opcode <= ADD;
- wait for 30ns;
+
+ wait for 10 ns;
+ -- berechnung kann los gehen
do_calc <= '1';
- wait for 300ns;
- optmp <= op3;
- wait for 400ns;
+ ack <= '0';
+
+ -- warten auf die alu einheit
+ wait on calc_done;
+
+ -- ack it!
+ do_calc <= '0';
+ ack <= '1';
+
+ wait for 20 ns;
stop <= true;
wait;