mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-05-05 15:54:17 +00:00
Add a divider unit and a testbench for it
This adds a divider unit, connected to the core in much the same way that the multiplier unit is connected. The division algorithm is very simple-minded, taking 64 clock cycles for any division (even 32-bit division instructions). The decoding is simplified by making use of regularities in the instruction encoding for div* and mod* instructions. Instead of having PPC_* encodings from the first-stage decoder for each of the different div* and mod* instructions, we now just have PPC_DIV and PPC_MOD, and the inputs to the divider that indicate what sort of division operation to do are derived from instruction word bits. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
@@ -12,6 +12,7 @@ entity writeback is
|
||||
e_in : in Execute2ToWritebackType;
|
||||
l_in : in Loadstore2ToWritebackType;
|
||||
m_in : in MultiplyToWritebackType;
|
||||
d_in : in DividerToWritebackType;
|
||||
|
||||
w_out : out WritebackToRegisterFileType;
|
||||
c_out : out WritebackToCrFileType;
|
||||
@@ -26,24 +27,30 @@ begin
|
||||
variable x : std_ulogic_vector(0 downto 0);
|
||||
variable y : std_ulogic_vector(0 downto 0);
|
||||
variable z : std_ulogic_vector(0 downto 0);
|
||||
variable w : std_ulogic_vector(0 downto 0);
|
||||
begin
|
||||
x := "" & e_in.valid;
|
||||
y := "" & l_in.valid;
|
||||
z := "" & m_in.valid;
|
||||
assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
|
||||
w := "" & d_in.valid;
|
||||
assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z)) + to_integer(unsigned(w))) <= 1 severity failure;
|
||||
|
||||
x := "" & e_in.write_enable;
|
||||
y := "" & l_in.write_enable;
|
||||
z := "" & m_in.write_reg_enable;
|
||||
assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
|
||||
w := "" & d_in.write_reg_enable;
|
||||
assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z)) + to_integer(unsigned(w))) <= 1 severity failure;
|
||||
|
||||
assert not(e_in.write_cr_enable = '1' and m_in.write_cr_enable = '1');
|
||||
x := "" & e_in.write_cr_enable;
|
||||
y := "" & m_in.write_cr_enable;
|
||||
z := "" & d_in.write_cr_enable;
|
||||
assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
|
||||
|
||||
w_out <= WritebackToRegisterFileInit;
|
||||
c_out <= WritebackToCrFileInit;
|
||||
|
||||
complete_out <= '0';
|
||||
if e_in.valid = '1' or l_in.valid = '1' or m_in.valid = '1' then
|
||||
if e_in.valid = '1' or l_in.valid = '1' or m_in.valid = '1' or d_in.valid = '1' then
|
||||
complete_out <= '1';
|
||||
end if;
|
||||
|
||||
@@ -76,5 +83,17 @@ begin
|
||||
c_out.write_cr_mask <= m_in.write_cr_mask;
|
||||
c_out.write_cr_data <= m_in.write_cr_data;
|
||||
end if;
|
||||
|
||||
if d_in.write_reg_enable = '1' then
|
||||
w_out.write_enable <= '1';
|
||||
w_out.write_reg <= d_in.write_reg_nr;
|
||||
w_out.write_data <= d_in.write_reg_data;
|
||||
end if;
|
||||
|
||||
if d_in.write_cr_enable = '1' then
|
||||
c_out.write_cr_enable <= '1';
|
||||
c_out.write_cr_mask <= d_in.write_cr_mask;
|
||||
c_out.write_cr_data <= d_in.write_cr_data;
|
||||
end if;
|
||||
end process;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user