Skip to content

Commit

Permalink
Better unsigned handling.
Browse files Browse the repository at this point in the history
sltu, signed multiplication.
All the basic instructions should be covered.
  • Loading branch information
Themaister committed Mar 24, 2011
1 parent 62e6365 commit 0b66d17
Show file tree
Hide file tree
Showing 9 changed files with 482 additions and 113 deletions.
46 changes: 34 additions & 12 deletions alu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ieee.std_logic_unsigned.all;
entity alu is
port(clk: in std_logic; -- for mul/div reg
a, b: in std_logic_vector(31 downto 0);
f: in std_logic_vector(6 downto 0); --sll - 6 to 4 mul/div
f: in std_logic_vector(7 downto 0); --sll - 6 to 4 mul/div, 7 unsigned
shamt: in std_logic_vector(4 downto 0); --sll
alu_out: out std_logic_vector(31 downto 0);
zero: inout std_logic; --blez
Expand All @@ -37,7 +37,9 @@ architecture synth of alu is
signal we_hi, we_lo, read_hi_lo, read_mul_div_reg : std_logic;
signal alu_res : std_logic_vector(63 downto 0); -- mult :3
signal output_mul_div : std_logic_vector(31 downto 0);
signal divider_quot, divider_rem : std_logic_vector(31 downto 0);
signal divider_quot, divider_rem : std_logic_vector(31 downto 0);
signal mult_res : std_logic_vector(63 downto 0);
signal slt : std_logic;

component mul_div_reg is
port (
Expand Down Expand Up @@ -69,9 +71,18 @@ architecture synth of alu is
remainder : out std_logic_vector(31 downto 0);
use_unsigned : in std_logic
);
end component;
end component;

component mips_multiplier is
port (
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
output : out std_logic_vector(63 downto 0);
is_unsigned : in std_logic);
end component;
begin


-- HI/LO register for use with mul/div instructions, and the "never used"-mtlo,mthi.
muldivreg_1 : mul_div_reg
port map (clk, we_hi, we_lo,
alu_res(63 downto 32), alu_res(31 downto 0),
Expand All @@ -83,8 +94,12 @@ begin
read_mul_div_reg, alu_out
);

-- single cycle divider megafunction. This is our critical path.
divider_1 : divider
port map (a, b, divider_quot, divider_rem, '1');
port map (a, b, divider_quot, divider_rem, f(7));

-- single cycle multiplier megafunction. Does signed and unsigned.
multiplier_1 : mips_multiplier port map(a, b, mult_res, f(7));


bout <= (not b) when (f(3) = '1') else b;
Expand All @@ -93,7 +108,7 @@ begin

-- alu function
process (f, a, bout, s) begin
case f is
case f(6 downto 0) is
when "0000000" =>
alu_res <= x"00000000" & (a and bout);
when "0000001" =>
Expand All @@ -107,8 +122,7 @@ process (f, a, bout, s) begin
when "0000010" =>
alu_res <= x"00000000" & s;
when "0001011" =>
alu_res <=
(x"00000000" & "0000000000000000000000000000000" & s(31));
alu_res <= conv_std_logic_vector(0, 63) & slt; --slt/sltu

-- shifting
when "0000100" =>
Expand All @@ -132,11 +146,10 @@ process (f, a, bout, s) begin

-- end shifting
when "1100000" =>
alu_res <=
a * b;
alu_res <= mult_res; -- Multiplier

when "1110000" =>
alu_res <= divider_rem & divider_quot;
alu_res <= divider_rem & divider_quot; -- Divider


when "1000000" =>
Expand All @@ -163,7 +176,16 @@ end process;
read_hi_lo <= f(4);

write_reg <= (jump_reg and not can_link) nor mul_div_write_op;
ltez <= zero or s(31); -- blez/bgtz
ltez <= zero or s(31); -- blez/bgtz

-- Calculate SLT, if unsigned we have to do some additional checks.
process (s(31), f(7), a(31), b(31)) begin
if f(7) = '0' then
slt <= s(31);
else
slt <= ((not (a(31) xor b(31))) and s(31)) or (a(31) and (not b(31)));
end if;
end process;

end;

43 changes: 43 additions & 0 deletions mips_multiplier.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
library ieee;
use ieee.std_logic_1164.all;
entity mips_multiplier is
port (
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
output : out std_logic_vector(63 downto 0);
is_unsigned : in std_logic);
end;

architecture synth of mips_multiplier is
COMPONENT multiplier IS
PORT
(
dataa : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
);
END COMPONENT;

COMPONENT multiplier_signed IS
PORT
(
dataa : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
);
END COMPONENT;

component mux2 is -- two-input multiplexer
generic(width: integer);
port(d0, d1: in std_logic_vector(width-1 downto 0);
s: in std_logic;
y: out std_logic_vector(width-1 downto 0));
end component;

signal result_unsigned, result_signed : std_logic_vector(63 downto 0);

begin
mult1 : multiplier port map(a, b, result_unsigned);
mult2 : multiplier port map(a, b, result_signed);
mux : mux2 generic map(64) port map(result_signed, result_unsigned, is_unsigned, output);
end;
Loading

0 comments on commit 0b66d17

Please sign in to comment.