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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_alu.vhd] - Diff between revs 60 and 61

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

Rev 60 Rev 61
Line 41... Line 41...
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?
    -- RISC-V CPU Extensions --
    FAST_SHIFT_EN         : boolean := false; -- use barrel shifter for shift operations
    CPU_EXTENSION_RISCV_M     : boolean := false; -- implement mul/div extension?
    TINY_SHIFT_EN         : boolean := false  -- use tiny (single-bit) shifter for shift operations
    CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
 
    CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
 
    -- Extension Options --
 
    FAST_MUL_EN               : boolean := false; -- use DSPs for M extension's multiplier
 
    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 55... Line 59...
    -- data input --
    -- data input --
    rs1_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
    rs1_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
    rs2_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
    rs2_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
    pc2_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC
    pc2_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC
    imm_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- immediate
    imm_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- immediate
 
    csr_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data
 
    cmp_i       : in  std_ulogic_vector(1 downto 0); -- comparator status
    -- data output --
    -- data output --
    res_o       : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result
    res_o       : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result
    add_o       : out std_ulogic_vector(data_width_c-1 downto 0); -- address computation result
    add_o       : out std_ulogic_vector(data_width_c-1 downto 0); -- address computation result
    -- co-processor interface --
    fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags
    cp_start_o  : out std_ulogic_vector(7 downto 0); -- trigger co-processor i
 
    cp_valid_i  : in  std_ulogic_vector(7 downto 0); -- co-processor i done
 
    cp_result_i : in  cp_data_if_t; -- co-processor result
 
    -- status --
    -- status --
    wait_o      : out std_ulogic -- busy due to iterative processing units
    idone_o     : out std_ulogic -- iterative processing units done?
  );
  );
end neorv32_cpu_alu;
end neorv32_cpu_alu;
 
 
architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is
architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is
 
 
Line 79... Line 82...
  --
  --
  signal cp_res     : std_ulogic_vector(data_width_c-1 downto 0);
  signal cp_res     : std_ulogic_vector(data_width_c-1 downto 0);
  signal arith_res  : std_ulogic_vector(data_width_c-1 downto 0);
  signal arith_res  : std_ulogic_vector(data_width_c-1 downto 0);
  signal logic_res  : std_ulogic_vector(data_width_c-1 downto 0);
  signal logic_res  : std_ulogic_vector(data_width_c-1 downto 0);
 
 
  -- shifter --
 
  type shifter_t is record
 
    cmd     : std_ulogic;
 
    cmd_ff  : std_ulogic;
 
    start   : std_ulogic;
 
    run     : std_ulogic;
 
    halt    : std_ulogic;
 
    cnt     : std_ulogic_vector(4 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;
 
  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
    cmd     : std_ulogic;
    cmd     : std_ulogic;
    cmd_ff  : std_ulogic;
    cmd_ff  : std_ulogic;
    busy    : std_ulogic;
 
    start   : std_ulogic;
    start   : std_ulogic;
    halt    : std_ulogic;
    busy    : std_ulogic;
    timeout : std_ulogic_vector(9 downto 0);
    timeout : std_ulogic_vector(9 downto 0);
  end record;
  end record;
  signal cp_ctrl : cp_ctrl_t;
  signal cp_ctrl : cp_ctrl_t;
 
 
 
  -- co-processor interface --
 
  signal cp_start  : std_ulogic_vector(3 downto 0); -- trigger co-processor i
 
  signal cp_valid  : std_ulogic_vector(3 downto 0); -- co-processor i done
 
  signal cp_result : cp_data_if_t; -- co-processor result
 
 
begin
begin
 
 
  -- Operand Mux ----------------------------------------------------------------------------
  -- Operand Mux ----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  opa <= pc2_i when (ctrl_i(ctrl_alu_opa_mux_c) = '1') else rs1_i; -- operand a (first ALU input operand), only required for arithmetic ops
  opa <= pc2_i when (ctrl_i(ctrl_alu_opa_mux_c) = '1') else rs1_i; -- operand a (first ALU input operand), only required for arithmetic ops
  opb <= imm_i when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else rs2_i; -- operand b (second ALU input operand)
  opb <= imm_i when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else rs2_i; -- operand b (second ALU input operand)
 
 
 
 
  -- Binary Adder/Subtractor ----------------------------------------------------------------
  -- Binary Adder/Subtracter ----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  binary_arithmetic_core: process(ctrl_i, opa, opb)
  binary_arithmetic_core: process(ctrl_i, opa, opb)
    variable cin_v  : std_ulogic_vector(0 downto 0);
    variable cin_v  : std_ulogic_vector(0 downto 0);
    variable op_a_v : std_ulogic_vector(data_width_c downto 0);
    variable op_a_v : std_ulogic_vector(data_width_c downto 0);
    variable op_b_v : std_ulogic_vector(data_width_c downto 0);
    variable op_b_v : std_ulogic_vector(data_width_c downto 0);
Line 152... Line 144...
      arith_res(0) <= addsub_res(addsub_res'left); -- => carry/borrow
      arith_res(0) <= addsub_res(addsub_res'left); -- => carry/borrow
    end if;
    end if;
  end process arithmetic_core;
  end process arithmetic_core;
 
 
 
 
  -- Shifter Unit ---------------------------------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  shifter_unit: process(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
 
    if rising_edge(clk_i) then
 
      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
 
          shifter.sreg <= rs1_i; -- shift operand (can only be rs1; opa would also contain pc)
 
          shifter.cnt  <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
 
        elsif (shifter.run = '1') then -- running shift
 
          -- coarse shift: multiples of 4 --
 
          if (TINY_SHIFT_EN = false) and -- use coarse shifts first if TINY SHIFT option is NOT enabled
 
             (or_reduce_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
 
              shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000";
 
            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) 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: single shifts, 0..3 times; use ONLY single-bit shifts if TINY_SHIFT_EN is enabled (even smaller than the default approach) --
 
          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;
 
 
 
      -- --------------------------------------------------------------------------------
 
      -- Barrel shifter (huge but fast)
 
      -- --------------------------------------------------------------------------------
 
      else
 
        -- operands and cycle control --
 
        if (shifter.start = '1') then -- trigger new shift
 
          shifter.bs_d_in <= rs1_i; -- shift operand (can only be rs1; opa would also contain pc)
 
          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 process shifter_unit;
 
 
 
  -- is shift operation? --
 
  shifter.cmd   <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_shift_c) else '0';
 
  shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0';
 
 
 
  -- shift operation running? --
 
  shifter.run  <= '1' when (or_reduce_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
 
  shifter.halt <= '1' when (or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0';
 
 
 
 
 
  -- Co-Processor Arbiter -------------------------------------------------------------------
  -- Co-Processor Arbiter -------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- Interface:
  -- Interface:
  -- Co-processor "valid" signal has to be asserted (for one cycle) one cycle before asserting output data
  -- Co-processor "valid" signal has to be asserted (for one cycle) one cycle before asserting output data
  -- Co-processor "output data" has to be always zero unless co-processor was explicitly triggered
  -- Co-processor "output data" has to be always zero unless co-processor was explicitly triggered
Line 281... Line 157...
      cp_ctrl.cmd_ff  <= '0';
      cp_ctrl.cmd_ff  <= '0';
      cp_ctrl.busy    <= '0';
      cp_ctrl.busy    <= '0';
      cp_ctrl.timeout <= (others => '0');
      cp_ctrl.timeout <= (others => '0');
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      cp_ctrl.cmd_ff <= cp_ctrl.cmd;
      cp_ctrl.cmd_ff <= cp_ctrl.cmd;
      if (or_reduce_f(cp_valid_i) = '1') then -- cp computation done?
      -- timeout counter --
        cp_ctrl.busy <= '0';
      if (cp_ctrl.start = '1') then
      elsif (cp_ctrl.timeout(cp_ctrl.timeout'left) = '1') and (cp_timeout_en_c = true) then -- timeout
 
        assert false report "NEORV32 CPU CO-PROCESSOR TIMEOUT ERROR!" severity warning;
 
        cp_ctrl.busy <= '0';
 
      elsif (cp_ctrl.start = '1') then
 
        cp_ctrl.busy <= '1';
        cp_ctrl.busy <= '1';
 
      elsif (or_reduce_f(cp_valid) = '1') then
 
        cp_ctrl.busy <= '0';
      end if;
      end if;
      -- timeout counter --
 
      if (cp_ctrl.busy = '1') and (cp_timeout_en_c = true) then
      if (cp_ctrl.busy = '1') and (cp_timeout_en_c = true) then
        cp_ctrl.timeout <= std_ulogic_vector(unsigned(cp_ctrl.timeout) + 1);
        cp_ctrl.timeout <= std_ulogic_vector(unsigned(cp_ctrl.timeout) + 1);
      else
      else
        cp_ctrl.timeout <= (others => '0');
        cp_ctrl.timeout <= (others => '0');
      end if;
      end if;
 
      if (cp_ctrl.timeout(cp_ctrl.timeout'left) = '1') and (cp_timeout_en_c = true) then -- timeout
 
        assert false report "NEORV32 CPU CO-PROCESSOR TIMEOUT ERROR!" severity warning;
 
      end if;
    end if;
    end if;
  end process cp_arbiter;
  end process cp_arbiter;
 
 
  -- is co-processor operation? --
  -- is co-processor operation? --
  cp_ctrl.cmd   <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_copro_c) else '0';
  cp_ctrl.cmd   <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_copro_c) else '0';
  cp_ctrl.start <= '1' when (cp_ctrl.cmd = '1') and (cp_ctrl.cmd_ff = '0') else '0';
  cp_ctrl.start <= '1' when (cp_ctrl.cmd = '1') and (cp_ctrl.cmd_ff = '0') else '0';
 
 
  -- co-processor select --
  -- co-processor select / star trigger --
  cp_operation_trigger: process(cp_ctrl, ctrl_i)
  cp_start(0) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0';
  begin
  cp_start(1) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0';
    for i in 0 to 7 loop
  cp_start(2) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0';
      if (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = std_ulogic_vector(to_unsigned(i, 3))) then
  cp_start(3) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0';
        cp_start_o(i) <= '1';
 
      else
 
        cp_start_o(i) <= '0';
 
      end if;
 
    end loop; -- i
 
  end process;
 
 
 
  -- co-processor operation (still) running? --
  -- co-processor operation done? --
  cp_ctrl.halt <= (cp_ctrl.busy and (not or_reduce_f(cp_valid_i))) or cp_ctrl.start;
  idone_o <= or_reduce_f(cp_valid);
 
 
  -- co-processor result - only the *actually selected* co-processor may output data != 0 --
  -- co-processor result - only the *actually selected* co-processor may output data != 0 --
  cp_res <= cp_result_i(0) or cp_result_i(1) or cp_result_i(2) or cp_result_i(3) or
  cp_res <= cp_result(0) or cp_result(1) or cp_result(2) or cp_result(3);
            cp_result_i(4) or cp_result_i(5) or cp_result_i(6) or cp_result_i(7);
 
 
 
 
 
  -- ALU Logic Core -------------------------------------------------------------------------
  -- ALU Logic Core -------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  alu_logic_core: process(ctrl_i, rs1_i, opb)
  alu_logic_core: process(ctrl_i, rs1_i, opb)
Line 338... Line 207...
  end process alu_logic_core;
  end process alu_logic_core;
 
 
 
 
  -- ALU Function Select --------------------------------------------------------------------
  -- ALU Function Select --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  alu_function_mux: process(ctrl_i, arith_res, logic_res, shifter.sreg, cp_res)
  alu_function_mux: process(ctrl_i, arith_res, logic_res, csr_i, cp_res)
  begin
  begin
    case ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) is
    case ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) is
      when alu_func_cmd_arith_c => res_o <= arith_res; -- (default)
      when alu_func_cmd_arith_c => res_o <= arith_res; -- (default)
      when alu_func_cmd_logic_c => res_o <= logic_res;
      when alu_func_cmd_logic_c => res_o <= logic_res;
      when alu_func_cmd_shift_c => res_o <= shifter.sreg;
      when alu_func_cmd_csrr_c  => res_o <= csr_i;
      when alu_func_cmd_copro_c => res_o <= cp_res;
      when alu_func_cmd_copro_c => res_o <= cp_res;
      when others               => res_o <= arith_res; -- undefined
      when others               => res_o <= arith_res; -- undefined
    end case;
    end case;
  end process alu_function_mux;
  end process alu_function_mux;
 
 
 
 
  -- ALU Busy -------------------------------------------------------------------------------
  -- **************************************************************************************************************************
 
  -- Co-Processors
 
  -- **************************************************************************************************************************
 
 
 
  -- Co-Processor 0: Shifter (CPU Core ISA) --------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
    neorv32_cpu_cp_shifter_inst: neorv32_cpu_cp_shifter
 
    generic map (
 
      FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations
 
    )
 
    port map (
 
      -- global control --
 
      clk_i   => clk_i,           -- global clock, rising edge
 
      rstn_i  => rstn_i,          -- global reset, low-active, async
 
      ctrl_i  => ctrl_i,          -- main control bus
 
      start_i => cp_start(0),     -- trigger operation
 
      -- data input --
 
      rs1_i   => rs1_i,           -- rf source 1
 
      rs2_i   => rs2_i,           -- rf source 2
 
      imm_i   => imm_i,           -- immediate
 
      -- result and status --
 
      res_o   => cp_result(0),    -- operation result
 
      valid_o => cp_valid(0)      -- data output valid
 
    );
 
 
 
 
 
  -- Co-Processor 1: Integer Multiplication/Division ('M' Extension) ------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  neorv32_cpu_cp_muldiv_inst_true:
 
  if (CPU_EXTENSION_RISCV_M = true) or (CPU_EXTENSION_RISCV_Zmmul = true) generate
 
    neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv
 
    generic map (
 
      FAST_MUL_EN => FAST_MUL_EN,          -- use DSPs for faster multiplication
 
      DIVISION_EN => CPU_EXTENSION_RISCV_M -- implement divider hardware
 
    )
 
    port map (
 
      -- global control --
 
      clk_i   => clk_i,           -- global clock, rising edge
 
      rstn_i  => rstn_i,          -- global reset, low-active, async
 
      ctrl_i  => ctrl_i,          -- main control bus
 
      start_i => cp_start(1),     -- trigger operation
 
      -- data input --
 
      rs1_i   => rs1_i,           -- rf source 1
 
      rs2_i   => rs2_i,           -- rf source 2
 
      -- result and status --
 
      res_o   => cp_result(1),    -- operation result
 
      valid_o => cp_valid(1)      -- data output valid
 
    );
 
  end generate;
 
 
 
  neorv32_cpu_cp_muldiv_inst_false:
 
  if (CPU_EXTENSION_RISCV_M = false) and (CPU_EXTENSION_RISCV_Zmmul = false) generate
 
    cp_result(1) <= (others => '0');
 
    cp_valid(1)  <= cp_start(1); -- to make sure CPU does not get stalled if there is an accidental access
 
  end generate;
 
 
 
 
 
  -- Co-Processor 2: reserved ---------------------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  cp_result(2) <= (others => '0');
 
  cp_valid(2)  <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access
 
 
 
 
 
  -- Co-Processor 3: Single-Precision Floating-Point Unit ('Zfinx' Extension) ---------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  wait_o <= shifter.halt or cp_ctrl.halt; -- wait until iterative units have completed
  neorv32_cpu_cp_fpu_inst_true:
 
  if (CPU_EXTENSION_RISCV_Zfinx = true) generate
 
    neorv32_cpu_cp_fpu_inst: neorv32_cpu_cp_fpu
 
    port map (
 
      -- global control --
 
      clk_i    => clk_i,        -- global clock, rising edge
 
      rstn_i   => rstn_i,       -- global reset, low-active, async
 
      ctrl_i   => ctrl_i,       -- main control bus
 
      start_i  => cp_start(3),  -- trigger operation
 
      -- data input --
 
      cmp_i    => cmp_i,        -- comparator status
 
      rs1_i    => rs1_i,        -- rf source 1
 
      rs2_i    => rs2_i,        -- rf source 2
 
      -- result and status --
 
      res_o    => cp_result(3), -- operation result
 
      fflags_o => fpu_flags_o,  -- exception flags
 
      valid_o  => cp_valid(3)   -- data output valid
 
    );
 
  end generate;
 
 
 
  neorv32_cpu_cp_fpu_inst_false:
 
  if (CPU_EXTENSION_RISCV_Zfinx = false) generate
 
    cp_result(3) <= (others => '0');
 
    fpu_flags_o  <= (others => '0');
 
    cp_valid(3)  <= cp_start(3); -- to make sure CPU does not get stalled if there is an accidental access
 
  end generate;
 
 
 
 
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.