alu: bessere testbench
[hwmod.git] / src / alu.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity alu is
7         port
8         (
9                 sys_clk : in std_logic;
10                 sys_res_n : in std_logic;
11                 opcode : in alu_ops;
12                 op1 : in csigned;
13                 op2 : in csigned;
14                 op3 : out csigned;
15                 do_calc : in std_logic;
16                 calc_done : out std_logic
17         );
18 end entity alu;
19
20 architecture beh of alu is
21         type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
22         signal state, state_next : ALU_STATE;
23         signal done_intern : std_logic;
24 begin
25         -- sync
26         process(sys_clk, sys_res_n)
27         begin
28                 if sys_res_n = '0' then
29                         state <= SIDLE;
30                 elsif rising_edge(sys_clk) then
31                         state <= state_next;
32                 end if;
33         end process;
34
35         -- next state
36         process(state, opcode, done_intern, do_calc)
37         begin
38                 -- set a default value for next state
39                 state_next <= state;
40                 -- next state berechnen
41                 case state is
42                         when SIDLE =>
43                                 if do_calc = '1' then
44                                         case opcode is
45                                                 when ADD =>
46                                                         state_next <= SADD;
47                                                 when SUB =>
48                                                         state_next <= SSUB;
49                                                 when MUL =>
50                                                         state_next <= SMUL;
51                                                 when DIV =>
52                                                         state_next <= SDIV;
53                                                 when others =>
54                                                         state_next <= SIDLE;
55                                         end case;
56                                 end if;
57                         when SADD =>
58                                 if done_intern = '1' then
59                                         state_next <= SDONE;
60                                 end if;
61                         when SSUB =>
62                                 if done_intern = '1' then
63                                         state_next <= SDONE;
64                                 end if;
65                         when SMUL =>
66                                 if done_intern = '1' then
67                                         state_next <= SDONE;
68                                 end if;
69                         when SDIV =>
70                                 if done_intern = '1' then
71                                         state_next <= SDONE;
72                                 end if;
73                         when SDONE =>
74                                 if do_calc = '0' then
75                                         state_next <= SIDLE;
76                                 end if;
77                 end case;
78         end process;
79
80         -- output
81         process(state)
82         variable tmperg : csigned;
83         variable multmp : signed(((2*CBITS)-1) downto 0);
84         begin
85                 op3 <= (others => '0');
86                 calc_done <= '0';
87
88                 case state is
89                         when SIDLE =>
90                                 done_intern <= '0';
91                         when SADD =>
92                                 tmperg := op1 + op2;
93                                 done_intern <= '1';
94                         when SSUB =>
95                                 tmperg := op1 - op2;
96                                 done_intern <= '1';
97                         when SMUL =>
98                                 multmp := op1 * op2;
99                                 tmperg(CBITS-1) := multmp((2*CBITS)-1);
100                                 tmperg((CBITS-2) downto 0) := multmp((CBITS-2) downto 0);
101                                 done_intern <= '1';
102                         when SDIV =>
103                                 tmperg := op1 / op2;
104                                 done_intern <= '1';
105                         when SDONE =>
106                                 done_intern <= '1';
107                                 calc_done <= '1';
108                                 op3 <= tmperg;
109                 end case;
110         end process;
111 end architecture beh;