OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_cp_shifter.vhd] - Diff between revs 71 and 74

Show entire file | Details | Blame | View Log

Rev 71 Rev 74
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;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.