Line 29... |
Line 29... |
cmd_div_i: in std_logic;
|
cmd_div_i: in std_logic;
|
cmd_div_mod_i: in std_logic;
|
cmd_div_mod_i: in std_logic;
|
cmd_cmp_i: in std_logic;
|
cmd_cmp_i: in std_logic;
|
cmd_negate_op2_i: in std_logic;
|
cmd_negate_op2_i: in std_logic;
|
cmd_and_i: in std_logic;
|
cmd_and_i: in std_logic;
|
cmd_or_i: in std_logic;
|
|
cmd_xor_i: in std_logic;
|
cmd_xor_i: in std_logic;
|
cmd_shift_i: in std_logic;
|
cmd_shift_i: in std_logic;
|
cmd_shift_right_i: in std_logic;
|
cmd_shift_right_i: in std_logic;
|
|
|
op1_i: in std_logic_vector(31 downto 0);
|
op1_i: in std_logic_vector(31 downto 0);
|
Line 60... |
Line 59... |
signal cmp_eq: std_logic;
|
signal cmp_eq: std_logic;
|
signal cmp_carry: std_logic;
|
signal cmp_carry: std_logic;
|
signal cmp_s1: std_logic;
|
signal cmp_s1: std_logic;
|
signal cmp_s2: std_logic;
|
signal cmp_s2: std_logic;
|
|
|
signal and_result: std_logic_vector(31 downto 0);
|
signal logic_result: std_logic_vector(31 downto 0);
|
signal and_we: std_logic;
|
signal logic_we: std_logic;
|
signal or_result: std_logic_vector(31 downto 0);
|
|
signal or_we: std_logic;
|
|
signal xor_result: std_logic_vector(31 downto 0);
|
|
signal xor_we: std_logic;
|
|
|
|
signal mul_result: std_logic_vector(31 downto 0);
|
signal mul_result: std_logic_vector(31 downto 0);
|
signal mul_ce: std_logic;
|
signal mul_ce: std_logic;
|
signal mul_we: std_logic;
|
signal mul_we: std_logic;
|
|
|
signal div_quotient: std_logic_vector(31 downto 0);
|
signal div_result: std_logic_vector(31 downto 0);
|
signal div_remainder: std_logic_vector(31 downto 0);
|
|
signal div_ce: std_logic;
|
signal div_ce: std_logic;
|
signal div_we: std_logic;
|
signal div_we: std_logic;
|
signal div_select_remainder: std_logic;
|
|
|
|
signal shift_result: std_logic_vector(31 downto 0);
|
signal shift_result: std_logic_vector(31 downto 0);
|
signal shift_ce: std_logic;
|
signal shift_ce: std_logic;
|
signal shift_we: std_logic;
|
signal shift_we: std_logic;
|
|
|
Line 95... |
Line 88... |
severity failure;
|
severity failure;
|
|
|
-- Add/subtract
|
-- Add/subtract
|
|
|
addend1<=unsigned(op1_i);
|
addend1<=unsigned(op1_i);
|
addend2<=unsigned(op2_i) when cmd_negate_op2_i='0' else not unsigned(op2_i);
|
|
|
addend2_gen: for i in addend2'range generate
|
|
addend2(i)<=op2_i(i) xor cmd_negate_op2_i;
|
|
end generate;
|
|
|
adder_result<=("0"&addend1)+("0"&addend2)+(to_unsigned(0,adder_result'length-1)&cmd_negate_op2_i);
|
adder_result<=("0"&addend1)+("0"&addend2)+(to_unsigned(0,adder_result'length-1)&cmd_negate_op2_i);
|
adder_we<=cmd_addsub_i and valid_i;
|
adder_we<=cmd_addsub_i and valid_i;
|
|
|
-- Comparator (needs cmd_negate_op2_i to work correctly)
|
-- Comparator (needs cmd_negate_op2_i to work correctly)
|
|
|
Line 124... |
Line 121... |
cmp_ug_o<=cmp_carry and not cmp_eq;
|
cmp_ug_o<=cmp_carry and not cmp_eq;
|
cmp_sg_o<=((cmp_s1 and cmp_s2 and cmp_carry) or
|
cmp_sg_o<=((cmp_s1 and cmp_s2 and cmp_carry) or
|
(not cmp_s1 and not cmp_s2 and cmp_carry) or
|
(not cmp_s1 and not cmp_s2 and cmp_carry) or
|
(not cmp_s1 and cmp_s2)) and not cmp_eq;
|
(not cmp_s1 and cmp_s2)) and not cmp_eq;
|
|
|
-- Logical functions
|
-- Bitwise operations (and, or, xor)
|
|
-- Note: (a or b) = (a and b) or (a xor b)
|
|
|
|
logic_result_gen: for i in logic_result'range generate
|
|
logic_result(i)<=((op1_i(i) and op2_i(i)) and cmd_and_i) or
|
|
((op1_i(i) xor op2_i(i)) and cmd_xor_i);
|
|
end generate;
|
|
|
and_result<=op1_i and op2_i;
|
logic_we<=(cmd_and_i or cmd_xor_i) and valid_i;
|
and_we<=cmd_and_i and valid_i;
|
|
or_result<=op1_i or op2_i;
|
|
or_we<=cmd_or_i and valid_i;
|
|
xor_result<=op1_i xor op2_i;
|
|
xor_we<=cmd_xor_i and valid_i;
|
|
|
|
-- Multiplier
|
-- Multiplier
|
|
|
mul_ce<=cmd_mul_i and valid_i;
|
mul_ce<=cmd_mul_i and valid_i;
|
|
|
Line 189... |
Line 187... |
rst_i=>rst_i,
|
rst_i=>rst_i,
|
ce_i=>div_ce,
|
ce_i=>div_ce,
|
op1_i=>op1_i,
|
op1_i=>op1_i,
|
op2_i=>op2_i,
|
op2_i=>op2_i,
|
signed_i=>cmd_signed_i,
|
signed_i=>cmd_signed_i,
|
|
rem_i=>cmd_div_mod_i,
|
ce_o=>div_we,
|
ce_o=>div_we,
|
quotient_o=>div_quotient,
|
result_o=>div_result
|
remainder_o=>div_remainder
|
|
);
|
);
|
end generate;
|
end generate;
|
|
|
gen_no_divider: if not DIVIDER_EN generate
|
gen_no_divider: if not DIVIDER_EN generate
|
div_we<=div_ce;
|
div_we<=div_ce;
|
div_quotient<=(others=>'0');
|
div_result<=(others=>'0');
|
div_remainder<=(others=>'0');
|
|
end generate;
|
end generate;
|
|
|
process (clk_i) is
|
|
begin
|
|
if rising_edge(clk_i) then
|
|
if div_ce='1' then
|
|
div_select_remainder<=cmd_div_mod_i;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Shifter
|
-- Shifter
|
|
|
shift_ce<=cmd_shift_i and valid_i;
|
shift_ce<=cmd_shift_i and valid_i;
|
|
|
shifter_inst: entity work.lxp32_shifter(rtl)
|
shifter_inst: entity work.lxp32_shifter(rtl)
|
Line 231... |
Line 219... |
|
|
-- Result multiplexer
|
-- Result multiplexer
|
|
|
result_mux_gen: for i in result_mux'range generate
|
result_mux_gen: for i in result_mux'range generate
|
result_mux(i)<=(adder_result(i) and adder_we) or
|
result_mux(i)<=(adder_result(i) and adder_we) or
|
(and_result(i) and and_we) or
|
(logic_result(i) and logic_we) or
|
(or_result(i) and or_we) or
|
|
(xor_result(i) and xor_we) or
|
|
(mul_result(i) and mul_we) or
|
(mul_result(i) and mul_we) or
|
(div_quotient(i) and div_we and not div_select_remainder) or
|
(div_result(i) and div_we) or
|
(div_remainder(i) and div_we and div_select_remainder) or
|
|
(shift_result(i) and shift_we);
|
(shift_result(i) and shift_we);
|
end generate;
|
end generate;
|
|
|
result_o<=result_mux;
|
result_o<=result_mux;
|
|
|
result_we<=adder_we or and_we or or_we or xor_we or mul_we or div_we or shift_we;
|
result_we<=adder_we or logic_we or mul_we or div_we or shift_we;
|
we_o<=result_we;
|
we_o<=result_we;
|
|
|
-- Pipeline control
|
-- Pipeline control
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if rst_i='1' then
|
if rst_i='1' or result_we='1' then
|
busy<='0';
|
busy<='0';
|
else
|
elsif shift_ce='1' or mul_ce='1' or div_ce='1' then
|
if shift_ce='1' or mul_ce='1' or div_ce='1' then
|
|
busy<='1';
|
busy<='1';
|
end if;
|
end if;
|
if result_we='1' then
|
|
busy<='0';
|
|
end if;
|
|
end if;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
busy_o<=busy;
|
busy_o<=busy;
|
|
|