Line 139... |
Line 139... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- less than (x < y) --
|
-- less than (x < y) --
|
cmp_opx <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i;
|
cmp_opx <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i;
|
cmp_opy <= (opc(opc'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & opc;
|
cmp_opy <= (opc(opc'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & opc;
|
cmp_sub <= std_ulogic_vector(signed(cmp_opx) - signed(cmp_opy));
|
cmp_sub <= std_ulogic_vector(signed(cmp_opx) - signed(cmp_opy));
|
cmp_less <= cmp_sub(cmp_sub'left); -- carry (borrow) indicates a less
|
cmp_less <= cmp_sub(cmp_sub'left); -- carry (borrow) indicates a "less"
|
sub_res <= cmp_sub(data_width_c-1 downto 0); -- use the less-comparator also for SUB operations
|
sub_res <= cmp_sub(data_width_c-1 downto 0); -- use the less-comparator also for SUB operations
|
|
|
-- equal (x = y) --
|
-- equal (x = y) --
|
cmp_equal <= '1' when (rs1_i = opc) else '0';
|
cmp_equal <= '1' when (rs1_i = opc) else '0';
|
|
|
Line 168... |
Line 168... |
shift_cmd_ff <= '0';
|
shift_cmd_ff <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
shift_cmd_ff <= shift_cmd;
|
shift_cmd_ff <= shift_cmd;
|
if (shift_start = '1') then -- trigger new shift
|
if (shift_start = '1') then -- trigger new shift
|
shift_sreg <= opa; -- shift operand
|
shift_sreg <= opa; -- shift operand
|
shift_cnt <= opb(4 downto 0); -- shift amount
|
shift_cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
|
elsif (shift_run = '1') then -- running shift
|
elsif (shift_run = '1') then -- running shift
|
shift_cnt <= std_ulogic_vector(unsigned(shift_cnt) - 1);
|
shift_cnt <= std_ulogic_vector(unsigned(shift_cnt) - 1);
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
shift_sreg <= shift_sreg(shift_sreg'left-1 downto 0) & '0';
|
shift_sreg <= shift_sreg(shift_sreg'left-1 downto 0) & '0';
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
Line 185... |
Line 185... |
-- is shift operation? --
|
-- is shift operation? --
|
shift_cmd <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_shift_c) else '0';
|
shift_cmd <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_shift_c) else '0';
|
shift_start <= '1' when (shift_cmd = '1') and (shift_cmd_ff = '0') else '0';
|
shift_start <= '1' when (shift_cmd = '1') and (shift_cmd_ff = '0') else '0';
|
|
|
-- shift operation running? --
|
-- shift operation running? --
|
shift_run <= '1' when (shift_cnt /= "00000") or (shift_start = '1') else '0';
|
shift_run <= '1' when (or_all_f(shift_cnt) = '1') or (shift_start = '1') else '0';
|
|
|
|
|
-- Coprocessor Interface ------------------------------------------------------------------
|
-- Coprocessor Interface ------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
cp_interface: process(rstn_i, clk_i)
|
cp_interface: process(rstn_i, clk_i)
|
Line 198... |
Line 198... |
cp_cmd_ff <= '0';
|
cp_cmd_ff <= '0';
|
cp_busy <= '0';
|
cp_busy <= '0';
|
cp_rb_ff0 <= '0';
|
cp_rb_ff0 <= '0';
|
cp_rb_ff1 <= '0';
|
cp_rb_ff1 <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (ctrl_i(ctrl_sys_m_ext_en_c) = '1') then
|
if (ctrl_i(ctrl_sys_m_ext_en_c) = '1') then -- FIXME add second cp (floating point stuff?)
|
cp_cmd_ff <= ctrl_i(ctrl_cp_use_c);
|
cp_cmd_ff <= ctrl_i(ctrl_cp_use_c);
|
cp_rb_ff0 <= '0';
|
cp_rb_ff0 <= '0';
|
cp_rb_ff1 <= cp_rb_ff0;
|
cp_rb_ff1 <= cp_rb_ff0;
|
if (cp_start = '1') then
|
if (cp_start = '1') then
|
cp_busy <= '1';
|
cp_busy <= '1';
|
Line 229... |
Line 229... |
-- ALU Function Select --------------------------------------------------------------------
|
-- ALU Function Select --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shift_sreg)
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shift_sreg)
|
begin
|
begin
|
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
|
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
|
when alu_cmd_bitc_c => alu_res <= opa and (not opb); -- bit clear (for CSR modification only)
|
when alu_cmd_bitc_c => alu_res <= opa and (not opb); -- bit clear (for CSR modifications only)
|
when alu_cmd_sub_c => alu_res <= sub_res;
|
|
when alu_cmd_add_c => alu_res <= add_res;
|
|
when alu_cmd_xor_c => alu_res <= opa xor opb;
|
when alu_cmd_xor_c => alu_res <= opa xor opb;
|
when alu_cmd_or_c => alu_res <= opa or opb;
|
when alu_cmd_or_c => alu_res <= opa or opb;
|
when alu_cmd_and_c => alu_res <= opa and opb;
|
when alu_cmd_and_c => alu_res <= opa and opb;
|
|
when alu_cmd_sub_c => alu_res <= sub_res;
|
|
when alu_cmd_add_c => alu_res <= add_res;
|
when alu_cmd_shift_c => alu_res <= shift_sreg;
|
when alu_cmd_shift_c => alu_res <= shift_sreg;
|
when alu_cmd_slt_c => alu_res <= (others => '0'); alu_res(0) <= cmp_less;
|
when alu_cmd_slt_c => alu_res <= (others => '0'); alu_res(0) <= cmp_less;
|
when others => alu_res <= (others => '0'); -- undefined
|
when others => alu_res <= (others => '0'); -- undefined
|
end case;
|
end case;
|
end process alu_function_mux;
|
end process alu_function_mux;
|