Line 104... |
Line 104... |
if (start_i = '1') then -- trigger new shift
|
if (start_i = '1') then -- trigger new shift
|
shifter.sreg <= rs1_i; -- shift operand
|
shifter.sreg <= rs1_i; -- shift operand
|
shifter.cnt <= shamt_i; -- shift amount
|
shifter.cnt <= shamt_i; -- shift amount
|
elsif (or_reduce_f(shifter.cnt) = '1') then -- running shift (cnt != 0)
|
elsif (or_reduce_f(shifter.cnt) = '1') then -- running shift (cnt != 0)
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then -- SLL: shift left logical
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 1);
|
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_ir_funct12_10_c)) & shifter.sreg(shifter.sreg'left downto 1);
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process shifter_unit_sync;
|
end process shifter_unit_sync;
|
end generate;
|
end generate;
|
|
|
-- shift control/output --
|
-- shift control/output --
|
serial_shifter_ctrl:
|
serial_shifter_ctrl:
|
if (FAST_SHIFT_EN = false) generate
|
if (FAST_SHIFT_EN = false) generate
|
shifter.done <= not or_reduce_f(shifter.cnt(shifter.cnt'left downto 1));
|
shifter.done <= '1' when (or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)) = '0') else '0';
|
valid_o <= shifter.busy and shifter.done;
|
valid_o <= shifter.busy and shifter.done;
|
res_o <= shifter.sreg when (shifter.busy = '0') and (shifter.busy_ff = '1') else (others => '0');
|
res_o <= shifter.sreg when (shifter.busy = '0') and (shifter.busy_ff = '1') else (others => '0');
|
end generate;
|
end generate;
|
|
|
|
|
Line 130... |
Line 130... |
barrel_shifter_async:
|
barrel_shifter_async:
|
if (FAST_SHIFT_EN = true) generate
|
if (FAST_SHIFT_EN = true) generate
|
shifter_unit_async: process(rs1_i, shamt_i, ctrl_i, bs_level)
|
shifter_unit_async: process(rs1_i, shamt_i, ctrl_i, bs_level)
|
begin
|
begin
|
-- input level: convert left shifts to right shifts --
|
-- input level: convert left shifts to right shifts --
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- is left shift?
|
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then -- is left shift?
|
bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_i); -- reverse bit order of input operand
|
bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_i); -- reverse bit order of input operand
|
else
|
else
|
bs_level(index_size_f(data_width_c)) <= rs1_i;
|
bs_level(index_size_f(data_width_c)) <= rs1_i;
|
end if;
|
end if;
|
|
|
-- shifter array --
|
-- shifter array --
|
for i in index_size_f(data_width_c)-1 downto 0 loop
|
for i in index_size_f(data_width_c)-1 downto 0 loop
|
if (shamt_i(i) = '1') then
|
if (shamt_i(i) = '1') then
|
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= (others => (bs_level(i+1)(data_width_c-1) and ctrl_i(ctrl_alu_shift_ar_c)));
|
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= (others => (bs_level(i+1)(data_width_c-1) and ctrl_i(ctrl_ir_funct12_10_c)));
|
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
|
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
|
else
|
else
|
bs_level(i) <= bs_level(i+1);
|
bs_level(i) <= bs_level(i+1);
|
end if;
|
end if;
|
end loop;
|
end loop;
|
|
|
-- re-convert original left shifts --
|
-- re-convert original left shifts --
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then
|
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then
|
bs_result <= bit_rev_f(bs_level(0));
|
bs_result <= bit_rev_f(bs_level(0));
|
else
|
else
|
bs_result <= bs_level(0);
|
bs_result <= bs_level(0);
|
end if;
|
end if;
|
end process shifter_unit_async;
|
end process shifter_unit_async;
|