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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_alu.vhd] - Diff between revs 29 and 34

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 29 Rev 34
Line 42... Line 42...
library neorv32;
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_package.all;
 
 
entity neorv32_cpu_alu is
entity neorv32_cpu_alu is
  generic (
  generic (
    CPU_EXTENSION_RISCV_M : boolean := true -- implement muld/div extension?
    CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
 
    FAST_SHIFT_EN         : boolean := false -- use barrel shifter for shift operations
  );
  );
  port (
  port (
    -- global control --
    -- global control --
    clk_i       : in  std_ulogic; -- global clock, rising edge
    clk_i       : in  std_ulogic; -- global clock, rising edge
    rstn_i      : in  std_ulogic; -- global reset, low-active, async
    rstn_i      : in  std_ulogic; -- global reset, low-active, async
Line 93... Line 94...
    start  : std_ulogic;
    start  : std_ulogic;
    run    : std_ulogic;
    run    : std_ulogic;
    halt   : std_ulogic;
    halt   : std_ulogic;
    cnt    : std_ulogic_vector(4 downto 0);
    cnt    : std_ulogic_vector(4 downto 0);
    sreg   : std_ulogic_vector(data_width_c-1 downto 0);
    sreg   : std_ulogic_vector(data_width_c-1 downto 0);
 
    -- for barrel shifter only --
 
    bs_a_in : std_ulogic_vector(4 downto 0);
 
    bs_d_in : std_ulogic_vector(data_width_c-1 downto 0);
  end record;
  end record;
  signal shifter : shifter_t;
  signal shifter : shifter_t;
 
 
  -- co-processor arbiter and interface --
  -- co-processor arbiter and interface --
  type cp_ctrl_t is record
  type cp_ctrl_t is record
Line 156... Line 160...
    addsub_res  <= res_v(31 downto 0);
    addsub_res  <= res_v(31 downto 0);
    addsub_res  <= res_v(31 downto 0);
    addsub_res  <= res_v(31 downto 0);
  end process binary_arithmetic_core;
  end process binary_arithmetic_core;
 
 
 
 
  -- Iterative Shifter Unit -----------------------------------------------------------------
  -- Shifter Unit ---------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  shifter_unit: process(rstn_i, clk_i)
  shifter_unit: process(rstn_i, clk_i)
 
    variable bs_input_v   : std_ulogic_vector(data_width_c-1 downto 0);
 
    variable bs_level_4_v : std_ulogic_vector(data_width_c-1 downto 0);
 
    variable bs_level_3_v : std_ulogic_vector(data_width_c-1 downto 0);
 
    variable bs_level_2_v : std_ulogic_vector(data_width_c-1 downto 0);
 
    variable bs_level_1_v : std_ulogic_vector(data_width_c-1 downto 0);
 
    variable bs_level_0_v : std_ulogic_vector(data_width_c-1 downto 0);
  begin
  begin
    if (rstn_i = '0') then
    if (rstn_i = '0') then
      shifter.sreg   <= (others => '0');
      shifter.sreg   <= (others => '0');
      shifter.cnt    <= (others => '0');
      shifter.cnt    <= (others => '0');
      shifter.cmd_ff <= '0';
      shifter.cmd_ff <= '0';
 
      if (FAST_SHIFT_EN = true) then
 
        shifter.bs_d_in <= (others => '0');
 
        shifter.bs_a_in <= (others => '0');
 
      end if;
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      shifter.cmd_ff <= shifter.cmd;
      shifter.cmd_ff <= shifter.cmd;
 
 
 
      -- --------------------------------------------------------------------------------
 
      -- Iterative shifter (small but slow) (default)
 
      -- --------------------------------------------------------------------------------
 
      if (FAST_SHIFT_EN = false) then
 
 
      if (shifter.start = '1') then -- trigger new shift
      if (shifter.start = '1') then -- trigger new shift
        shifter.sreg <= opa; -- shift operand
        shifter.sreg <= opa; -- shift operand
        shifter.cnt  <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
        shifter.cnt  <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
      elsif (shifter.run = '1') then -- running shift
      elsif (shifter.run = '1') then -- running shift
        -- coarse shift: multiples of 4 --
        -- coarse shift: multiples of 4 --
Line 191... Line 211...
          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_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 1);
          end if;
          end if;
        end if;
        end if;
      end if;
      end if;
 
 
 
      -- --------------------------------------------------------------------------------
 
      -- Barrel shifter (huge but fast)
 
      -- --------------------------------------------------------------------------------
 
      else
 
 
 
        -- operands and cycle control --
 
        if (shifter.start = '1') then -- trigger new shift
 
          shifter.bs_d_in <= opa; -- shift data
 
          shifter.bs_a_in <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
 
          shifter.cnt     <= (others => '0');
 
        end if;
 
 
 
        -- convert left shifts to right shifts --
 
        if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- is left shift?
 
          bs_input_v := bit_rev_f(shifter.bs_d_in); -- reverse bit order of input operand
 
        else
 
          bs_input_v := shifter.bs_d_in;
 
        end if;
 
        -- shift >> 16 --
 
        if (shifter.bs_a_in(4) = '1') then
 
          bs_level_4_v(31 downto 16) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c)));
 
          bs_level_4_v(15 downto 00) := (bs_input_v(31 downto 16));
 
        else
 
          bs_level_4_v := bs_input_v;
 
        end if;
 
        -- shift >> 8 --
 
        if (shifter.bs_a_in(3) = '1') then
 
          bs_level_3_v(31 downto 24) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c)));
 
          bs_level_3_v(23 downto 00) := (bs_level_4_v(31 downto 8));
 
        else
 
          bs_level_3_v := bs_level_4_v;
 
        end if;
 
        -- shift >> 4 --
 
        if (shifter.bs_a_in(2) = '1') then
 
          bs_level_2_v(31 downto 28) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c)));
 
          bs_level_2_v(27 downto 00) := (bs_level_3_v(31 downto 4));
 
        else
 
          bs_level_2_v := bs_level_3_v;
 
        end if;
 
        -- shift >> 2 --
 
        if (shifter.bs_a_in(1) = '1') then
 
          bs_level_1_v(31 downto 30) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c)));
 
          bs_level_1_v(29 downto 00) := (bs_level_2_v(31 downto 2));
 
        else
 
          bs_level_1_v := bs_level_2_v;
 
        end if;
 
        -- shift >> 1 --
 
        if (shifter.bs_a_in(0) = '1') then
 
          bs_level_0_v(31 downto 31) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c)));
 
          bs_level_0_v(30 downto 00) := (bs_level_1_v(31 downto 1));
 
        else
 
          bs_level_0_v := bs_level_1_v;
 
        end if;
 
        -- re-convert original left shifts --
 
        if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then
 
          shifter.sreg <= bit_rev_f(bs_level_0_v);
 
        else
 
          shifter.sreg <= bs_level_0_v;
 
        end if;
 
      end if;
    end if;
    end if;
  end process shifter_unit;
  end process shifter_unit;
 
 
  -- is shift operation? --
  -- is shift operation? --
  shifter.cmd   <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_shift_c) else '0';
  shifter.cmd   <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_shift_c) else '0';

powered by: WebSVN 2.1.0

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