Skip to content
Snippets Groups Projects

fixed divider functionality and verified through simulations

Merged Snijder, T. (Taya, Student M-EMSYS) requested to merge taya_branch into main
1 file
+ 52
38
Compare changes
  • Side-by-side
  • Inline
+ 52
38
@@ -19,23 +19,24 @@ entity divider is
reset: in std_logic;
trigger: in std_logic;
done: out std_logic;
do_modulo: in std_logic;
divider: in std_logic_vector(word_length-1 downto 0);
divisor: in std_logic_vector(word_length-1 downto 0);
denominator: in std_logic_vector(word_length-1 downto 0);
numerator: in std_logic_vector(word_length-1 downto 0);
div_output: out std_logic_vector(word_length-1 downto 0)
);
end divider;
architecture div of divider is
-- outputs
signal loop_counter, loop_counter_nxt: integer range 0 to word_length-1;
signal loop_counter, loop_counter_nxt: integer range -1 to word_length-1;
signal remainder, quotient: std_logic_vector(31 downto 0);
signal remainder_nxt, quotient_nxt: std_logic_vector(31 downto 0);
signal triggered, modulo_flag, done: std_logic;
signal triggered_nxt, modulo_flag_nxt, done_nxt: std_logic;
signal triggered, modulo_flag, done_s: std_logic;
signal triggered_nxt, modulo_flag_nxt, done_s_nxt: std_logic;
begin
-- fully combinational process for calculating the output.
@@ -46,92 +47,105 @@ begin
loop_counter <= 31;
remainder <= (others => '0');
quotient <= (others => '0');
done <= '0';
done_s <= '0';
triggered <= '0';
modulo_flag <= '0'
elsif rising_edge(clk)
then
modulo_flag <= '0';
elsif rising_edge(clk)
then
loop_counter <= loop_counter_nxt;
remainder <= remainder_nxt;
quotient <= quotient_nxt;
triggered <= triggered_nxt;
modulo_flag <= modulo_flag_nxt;
done <= done_nxt;
done_s <= done_s_nxt;
-- TODO: move some of the control signals to here if possible
end if;
end process seq;
comb: process(done, triggered, quotient, remainder, loop_counter)
comb: process(trigger, done_s, triggered, quotient, remainder, loop_counter)
variable temp: std_logic_vector(31 downto 0);
begin
-- looking for new instructions
if done = '0' and triggered = '0'
if done_s = '0' and triggered = '0'
then
-- look for new trigger signals
if trigger '1'
if trigger = '1'
then
modulo_flag_nxt <= do_modulo;
triggered_nxt <= '1';
else:
quotient_nxt <= (others => '0');
remainder_nxt <= (others => '0');
else
modulo_flag_nxt <= modulo_flag;
triggered_nxt <= '0';
quotient_nxt <= quotient;
remainder_nxt <= remainder;
end if;
quotient_nxt <= quotient;
remainder_nxt <= remainder;
loop_counter_nxt <= 31;
done_nxt <= '0';
done_s_nxt <= '0';
-- main calculation
elsif done = '0' and triggered = '1'
elsif done_s = '0' and triggered = '1'
then
-- calculate remainder going in to this iteration
-- shift 1 left and add the next bit to the LSB
temp := (remainder << 1) + divisor(loop_counter)
if remainder >= divider
then
-- append '1' to the quotient and set remainder to the difference
quotient_nxt(loop_counter) := '1';
remainder_nxt <= temp - divider;
else
-- append '0' to the quotient
quotient_nxt(loop_counter) := '0';
remainder_nxt <= temp;
end if;
if loop_counter = 0
if remainder >= denominator
then
-- append '1' to the quotient and set remainder to the difference
quotient_nxt <= quotient(30 downto 0) & '1';
temp := std_logic_vector(signed(remainder) - signed(denominator));
else
-- append '0' to the quotient
quotient_nxt <= quotient(30 downto 0) & '0';
end if;
if loop_counter = -1
then
-- we're done with this calculation, set the done flag to '1' and reset the counter
loop_counter_nxt <= 31;
done_nxt <= '1'
done_s_nxt <= '1';
else
if remainder >= denominator
then
remainder_nxt <= temp(30 downto 0) & numerator(loop_counter);
else
remainder_nxt <= remainder(30 downto 0) & numerator(loop_counter);
end if;
-- not done yet, keep decrementing the loop counter
loop_counter_nxt <= loop_counter - 1;
done_nxt <= '0';
done_s_nxt <= '0';
end if;
triggered_nxt <= '1';
modulo_flag_nxt <= modulo_flag;
-- when done with the calculation
else:
else
triggered_nxt <= '0';
done_nxt <= '0';
done_s_nxt <= '0';
quotient_nxt <= quotient;
remainder_nxt <= remainder;
loop_counter_nxt <= 31;
if modulo_flag = '1'
then
div_output <= remainder
div_output <= remainder;
else
div_output <= quotient
div_output <= quotient;
end if;
end if;
end process comb;
done <= done_s;
end div;
Loading