2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
9 sys_clk : in std_logic;
10 sys_res_n : in std_logic;
15 do_calc : in std_logic;
16 calc_done : out std_logic
20 architecture beh of alu is
21 type ALU_STATE is (SIDLE, SADD, SSUB, SMUL, SDIV, SDIV_CALC, SDIV_DONE, SDONE);
22 signal state, state_next : ALU_STATE;
23 signal done_intern, div_calc_done, div_go_calc : std_logic;
24 signal op3_int, op3_next : csigned;
25 signal calc_done_int, calc_done_next : std_logic;
26 -- signale fuer division
27 signal dividend_msb, dividend_msb_next, laengediv, laengediv_next : natural;
28 signal quo, quo_next, aktdiv, aktdiv_next, op1_int, op1_next, op2_int, op2_next : csigned;
29 signal sign, sign_next : std_logic;
32 calc_done <= calc_done_int;
35 process(sys_clk, sys_res_n)
37 if sys_res_n = '0' then
39 elsif rising_edge(sys_clk) then
42 calc_done_int <= calc_done_next;
44 dividend_msb <= dividend_msb_next;
45 laengediv <= laengediv_next;
47 aktdiv <= aktdiv_next;
55 process(state, opcode, done_intern, do_calc, div_calc_done, div_go_calc)
57 -- set a default value for next state
59 -- next state berechnen
77 if done_intern = '1' then
81 if done_intern = '1' then
85 if done_intern = '1' then
89 if div_go_calc = '1' then
90 state_next <= SDIV_CALC;
93 if div_calc_done = '1' then
94 state_next <= SDIV_DONE;
97 if done_intern = '1' then
101 if do_calc = '0' then
108 process(state, op1, op2, dividend_msb, laengediv, quo, aktdiv, sign, op1_int, op2_int)
109 variable tmperg : csigned;
110 variable multmp : signed(((2*CBITS)-1) downto 0);
112 variable laengediv_var, dividend_msb_var : natural;
113 variable aktdiv_var, quo_var, op1_var, op2_var : csigned;
115 op3_next <= (others => '0');
116 calc_done_next <= '0';
117 div_calc_done <= '0';
121 dividend_msb_next <= 0;
123 quo_next <= (others => '0');
124 aktdiv_next <= (others => '0');
125 op1_next <= (others => '0');
126 op2_next <= (others => '0');
131 tmperg := (others => '0');
140 tmperg(CBITS-1) := multmp((2*CBITS)-1);
141 tmperg((CBITS-2) downto 0) := multmp((CBITS-2) downto 0);
144 -- division implementiert nach ~hwmod/doc/division.pdf
145 tmperg := (others => '0');
146 if op2 = to_signed(0,CBITS) then
147 -- TODO: err out signal
153 if op1(CBITS-1) = '1' then
154 op1_var := not (op1_var + 1);
156 if op2(CBITS-1) = '1' then
157 op2_var := not (op2_var + 1);
160 dividend_msb_var := find_msb(op1_var)-1;
161 laengediv_var := find_msb(op2_var)-1;
163 aktdiv_next <= op1_var srl (dividend_msb_var - laengediv_var + 1);
166 dividend_msb_next <= dividend_msb_var;
167 laengediv_next <= laengediv_var;
168 quo_next <= (others => '0');
171 sign_next <= op1(CBITS-1) xor op2(CBITS-1);
174 tmperg := (others => '0');
176 if (dividend_msb - laengediv + 1) > 0 then
177 aktdiv_var := aktdiv sll 1;
178 aktdiv_var(0) := op1_int(dividend_msb - laengediv);
180 quo_var := quo sll 1;
181 if aktdiv_var >= op2_int then
183 aktdiv_var := aktdiv_var - op2_int;
187 aktdiv_next <= aktdiv_var;
188 dividend_msb_next <= dividend_msb;
189 laengediv_next <= laengediv + 1;
195 quo_next <= (not quo) + 1;
199 div_calc_done <= '1';
206 calc_done_next <= '1';
208 tmperg := (others => '0');
211 end architecture beh;