alu: fix fuer synthese
[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         signal op3_int, op3_next : csigned;
25         signal calc_done_int, calc_done_next : std_logic;
26 begin
27         op3 <= op3_int;
28         calc_done <= calc_done_int;
29
30         -- sync
31         process(sys_clk, sys_res_n)
32         begin
33                 if sys_res_n = '0' then
34                         state <= SIDLE;
35                 elsif rising_edge(sys_clk) then
36                         state <= state_next;
37                         op3_int <= op3_next;
38                         calc_done_int <= calc_done_next;
39                 end if;
40         end process;
41
42         -- next state
43         process(state, opcode, done_intern, do_calc)
44         begin
45                 -- set a default value for next state
46                 state_next <= state;
47                 -- next state berechnen
48                 case state is
49                         when SIDLE =>
50                                 if do_calc = '1' then
51                                         case opcode is
52                                                 when ADD =>
53                                                         state_next <= SADD;
54                                                 when SUB =>
55                                                         state_next <= SSUB;
56                                                 when MUL =>
57                                                         state_next <= SMUL;
58                                                 when DIV =>
59                                                         state_next <= SDIV;
60                                                 when others =>
61                                                         state_next <= SIDLE;
62                                         end case;
63                                 end if;
64                         when SADD =>
65                                 if done_intern = '1' then
66                                         state_next <= SDONE;
67                                 end if;
68                         when SSUB =>
69                                 if done_intern = '1' then
70                                         state_next <= SDONE;
71                                 end if;
72                         when SMUL =>
73                                 if done_intern = '1' then
74                                         state_next <= SDONE;
75                                 end if;
76                         when SDIV =>
77                                 if done_intern = '1' then
78                                         state_next <= SDONE;
79                                 end if;
80                         when SDONE =>
81                                 if do_calc = '0' then
82                                         state_next <= SIDLE;
83                                 end if;
84                 end case;
85         end process;
86
87         -- output
88         process(state, op1, op2)
89         variable tmperg : csigned;
90         variable multmp : signed(((2*CBITS)-1) downto 0);
91         begin
92                 op3_next <= (others => '0');
93                 calc_done_next <= '0';
94
95                 case state is
96                         when SIDLE =>
97                                 tmperg := (others => '0');
98                                 done_intern <= '0';
99                         when SADD =>
100                                 tmperg := op1 + op2;
101                                 done_intern <= '1';
102                         when SSUB =>
103                                 tmperg := op1 - op2;
104                                 done_intern <= '1';
105                         when SMUL =>
106                                 multmp := op1 * op2;
107                                 tmperg(CBITS-1) := multmp((2*CBITS)-1);
108                                 tmperg((CBITS-2) downto 0) := multmp((CBITS-2) downto 0);
109                                 done_intern <= '1';
110                         when SDIV =>
111                                 tmperg := op1 / op2;
112                                 done_intern <= '1';
113                         when SDONE =>
114                                 done_intern <= '1';
115                                 calc_done_next <= '1';
116                                 op3_next <= tmperg;
117                                 tmperg := (others => '0');
118                 end case;
119         end process;
120 end architecture beh;