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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_alu.vhd] - Diff between revs 11 and 12

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

Rev 11 Rev 12
Line 86... Line 86...
  signal sub_res   : std_ulogic_vector(data_width_c-1 downto 0);
  signal sub_res   : std_ulogic_vector(data_width_c-1 downto 0);
  signal cmp_equal : std_ulogic;
  signal cmp_equal : std_ulogic;
  signal cmp_less  : std_ulogic;
  signal cmp_less  : std_ulogic;
 
 
  -- shifter --
  -- shifter --
  signal shift_cmd    : std_ulogic;
  type shifter_t is record
  signal shift_cmd_ff : std_ulogic;
    cmd    : std_ulogic;
  signal shift_start  : std_ulogic;
    cmd_ff : std_ulogic;
  signal shift_run    : std_ulogic;
    start  : std_ulogic;
  signal shift_cnt    : std_ulogic_vector(4 downto 0);
    run    : std_ulogic;
  signal shift_sreg   : std_ulogic_vector(data_width_c-1 downto 0);
    cnt    : std_ulogic_vector(4 downto 0);
 
    sreg   : std_ulogic_vector(data_width_c-1 downto 0);
 
  end record;
 
  signal shifter : shifter_t;
 
 
  -- co-processor interface --
  -- co-processor interface --
  signal cp_cmd_ff : std_ulogic;
  signal cp_cmd_ff : std_ulogic;
  signal cp_run    : std_ulogic;
  signal cp_run    : std_ulogic;
  signal cp_start  : std_ulogic;
  signal cp_start  : std_ulogic;
Line 108... Line 111...
  -- Operand Mux ----------------------------------------------------------------------------
  -- Operand Mux ----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i)
  input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i)
  begin
  begin
    -- opa (first ALU input operand) --
    -- opa (first ALU input operand) --
    if (ctrl_i(ctrl_alu_opa_mux_msb_c) = '0') then
    case ctrl_i(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) is
      if (ctrl_i(ctrl_alu_opa_mux_lsb_c) = '0') then
      when "00"   => opa <= rs1_i;
        opa <= rs1_i;
      when "01"   => opa <= pc2_i;
      else
      when others => opa <= csr_i;
        opa <= pc2_i;
    end case;
      end if;
 
    else
 
      opa <= csr_i;
 
    end if;
 
    -- opb (second ALU input operand) --
    -- opb (second ALU input operand) --
    if (ctrl_i(ctrl_alu_opb_mux_msb_c) = '0') then
    case ctrl_i(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) is
      if (ctrl_i(ctrl_alu_opb_mux_lsb_c) = '0') then
      when "00"   => opb <= rs2_i;
        opb <= rs2_i;
      when "01"   => opb <= imm_i;
      else
      when others => opb <= rs1_i;
        opb <= imm_i;
    end case;
      end if;
 
    else
 
      opb <= rs1_i;
 
    end if;
 
    -- opc (second operand for comparison (and SUB)) --
    -- opc (second operand for comparison (and SUB)) --
    if (ctrl_i(ctrl_alu_opc_mux_c) = '0') then
    if (ctrl_i(ctrl_alu_opc_mux_c) = '0') then
      opc <= imm_i;
      opc <= imm_i;
    else
    else
      opc <= rs2_i;
      opc <= rs2_i;
Line 164... Line 159...
  -- Iterative Shifter Unit -----------------------------------------------------------------
  -- Iterative Shifter Unit -----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  shifter_unit: process(rstn_i, clk_i)
  shifter_unit: process(rstn_i, clk_i)
  begin
  begin
    if (rstn_i = '0') then
    if (rstn_i = '0') then
      shift_sreg   <= (others => '0');
      shifter.sreg   <= (others => '0');
      shift_cnt    <= (others => '0');
      shifter.cnt    <= (others => '0');
      shift_cmd_ff <= '0';
      shifter.cmd_ff <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      shift_cmd_ff <= shift_cmd;
      shifter.cmd_ff <= shifter.cmd;
      if (shift_start = '1') then -- trigger new shift
      if (shifter.start = '1') then -- trigger new shift
        shift_sreg <= opa; -- shift operand
        shifter.sreg <= opa; -- shift operand
        shift_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 (shift_run = '1') then -- running shift
      elsif (shifter.run = '1') then -- running shift
        shift_cnt <= std_ulogic_vector(unsigned(shift_cnt) - 1);
        -- coarse shift -> multiples of 4 --
 
        if (or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
 
          shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4);
        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';
            shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000";
        else -- SRL: shift right logical / SRA: shift right arithmetical
        else -- SRL: shift right logical / SRA: shift right arithmetical
          shift_sreg <= (shift_sreg(shift_sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shift_sreg(shift_sreg'left downto 1);
            shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
 
                            (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
 
                            (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
 
                            (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4);
 
          end if;
 
        -- fine shift -> 0..3 --
 
        else
 
          shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
 
          if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
 
            shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
 
          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);
 
          end if;
        end if;
        end if;
      end if;
      end if;
    end if;
    end if;
  end process shifter_unit;
  end process shifter_unit;
 
 
  -- 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';
  shifter.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';
  shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0';
 
 
  -- shift operation running? --
  -- shift operation running? --
  shift_run <= '1' when (or_all_f(shift_cnt) = '1') or (shift_start = '1') else '0';
  shifter.run <= '1' when (or_all_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
 
 
 
 
  -- Coprocessor Interface ------------------------------------------------------------------
  -- Coprocessor Interface ------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  cp_interface: process(rstn_i, clk_i)
  cp_interface: process(rstn_i, clk_i)
Line 229... Line 238...
  cp_run <= cp_busy or cp_start;
  cp_run <= cp_busy or cp_start;
 
 
 
 
  -- 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, shifter)
  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 modifications only)
      when alu_cmd_bitc_c  => alu_res <= opa and (not opb); -- bit clear (for CSR modifications only)
      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_sub_c   => alu_res <= sub_res;
      when alu_cmd_add_c   => alu_res <= add_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 <= shifter.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;
 
 
 
 
  -- ALU Result -----------------------------------------------------------------------------
  -- ALU Result -----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  wait_o <= shift_run or cp_run; -- wait until iterative units have completed
  wait_o <= shifter.run or cp_run; -- wait until iterative units have completed
  res_o  <= (cp0_data_i or cp1_data_i) when (cp_rb_ff1 = '1') else alu_res; -- FIXME
  res_o  <= (cp0_data_i or cp1_data_i) when (cp_rb_ff1 = '1') else alu_res; -- FIXME
 
 
 
 
end neorv32_cpu_cpu_rtl;
end neorv32_cpu_cpu_rtl;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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