alu: besseres geruest
[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                 ack : in std_logic;
17                 calc_done : out std_logic
18         );
19 end entity alu;
20
21 architecture beh of alu is
22         type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDONE);
23         signal state, state_next : ALU_STATE;
24         signal done_intern : std_logic;
25 begin
26         -- sync
27         process(sys_clk, sys_res_n)
28         begin
29                 if sys_res_n = '0' then
30                         state <= SIDLE;
31                 elsif rising_edge(sys_clk) then
32                         state <= state_next;
33                 end if;
34         end process;
35
36         -- next state
37         process(state, opcode, done_intern)
38         begin
39                 -- set a default value for next state
40                 state_next <= state;
41                 -- next state berechnen
42                 case state is
43                         when SIDLE =>
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                         when SADD =>
57                                 if done_intern = '1' then
58                                         state_next <= SDONE;
59                                 end if;
60                         when SSUB =>
61                                 if done_intern = '1' then
62                                         state_next <= SDONE;
63                                 end if;
64                         when SMUL =>
65                                 if done_intern = '1' then
66                                         state_next <= SDONE;
67                                 end if;
68                         when SDIV =>
69                                 if done_intern = '1' then
70                                         state_next <= SDONE;
71                                 end if;
72                         when SDONE =>
73                                 if ack = '1' then
74                                         state_next <= SIDLE;
75                                 end if;
76                 end case;
77         end process;
78
79         -- output
80         process(state)
81         begin
82                 op3 <= (others => '0');
83                 calc_done <= '0';
84
85                 case state is
86                         when SIDLE =>
87                                 done_intern <= '0';
88                         when SADD =>
89                                 op3 <= op1 + op2;
90                                 done_intern <= '1';
91                         when SSUB =>
92                                 op3 <= op1 - op2;
93                                 done_intern <= '1';
94                         when SMUL =>
95                                 op3 <= op1 * op2;
96                                 done_intern <= '1';
97                         when SDIV =>
98                                 op3 <= op1 / op2;
99                                 done_intern <= '1';
100                         when SDONE =>
101                                 done_intern <= '1';
102                                 calc_done <= '1';
103                 end case;
104         end process;
105 end architecture beh;