op2 : in csigned;
op3 : out csigned;
do_calc : in std_logic;
- ack : in std_logic;
calc_done : out std_logic
);
end entity alu;
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;
-- output
process(state)
+ variable tmperg : csigned;
+ variable multmp : signed(((2*CBITS)-1) downto 0);
begin
op3 <= (others => '0');
calc_done <= '0';
when SIDLE =>
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';
+ op3 <= tmperg;
end case;
end process;
end architecture beh;
use work.gen_pkg.all;
entity alu_tb is
- end entity alu_tb;
+end entity alu_tb;
architecture sim of alu_tb is
component alu is
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, ack : std_logic;
+ signal sys_clk, sys_res_n, do_calc, calc_done : std_logic;
signal opcode : alu_ops;
- signal op1, op2, op3, optmp : csigned;
+ signal op1, op2, op3 : 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,
sys_clk <= '0';
wait for 15 ns;
sys_clk <= '1';
+ wait for 15 ns;
if stop = true then
wait;
end if;
- wait for 15 ns;
end process;
process
+ type alu_testv is record
+ o1 : cinteger;
+ o : alu_ops;
+ o2 : cinteger;
+ expected : cinteger;
+ end record alu_testv;
+
+ -- ggf. groesse des arrays erhoehen
+ type alu_testv_array is array (natural range 0 to 20) of alu_testv;
+
+ variable testmatrix : alu_testv_array :=
+ ( 0 => (7, ADD, 3, 10),
+ 1 => (7, SUB, 1, 6),
+ 2 => (7, DIV, 1, 7),
+ 3 => (7, DIV, 2, 3),
+ 4 => (7, ADD, 1, 8),
+ 5 => (7, MUL, 3, 21),
+ 6 => (-7, MUL, 3, -21),
+ 7 => (268435456, MUL, -2, -536870912),
+ 8 => (268435456, MUL, 2**5, 0), -- um fuenf nach links shiften
+ 9 => (268435456 + 5, MUL, 2**5, 160), -- = 5 * (2^5)
+ others => (0, ADD, 0, 0)
+ );
+
begin
sys_res_n <= '0';
wait for 50 ns;
sys_res_n <= '1';
- 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;
+ for i in testmatrix'range loop
+ wait for 100 ns;
+ op1 <= to_signed(testmatrix(i).o1,CBITS);
+ opcode <= testmatrix(i).o;
+ op2 <= to_signed(testmatrix(i).o2,CBITS);
- wait for 10 ns;
- -- berechnung kann los gehen
- do_calc <= '1';
- ack <= '0';
+ -- berechnung kann los gehen
+ do_calc <= '1';
- -- warten auf die alu einheit
- wait on calc_done;
+ -- warten auf die alu einheit
+ wait on calc_done;
- -- ack it!
- do_calc <= '0';
- ack <= '1';
+ assert op3 = to_signed(testmatrix(i).expected,CBITS)
+ report "" & cinteger'image(testmatrix(i).o1) &
+ " " & alu_ops'image(opcode) &
+ " " & cinteger'image(testmatrix(i).o2) &
+ "/= " & integer'image(to_integer(op3)) &
+ " -- erwartet: " & cinteger'image(testmatrix(i).expected);
- wait for 20 ns;
+ wait for 5 ns;
+ -- ack it!
+ do_calc <= '0';
+ end loop;
+ assert false
+ report "alle testfaelle der ALU waren erfolgreich!";
stop <= true;
wait;
end process;