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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_alu.vhd] - Diff between revs 36 and 39

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

Rev 36 Rev 39
Line 84... Line 84...
  -- operands --
  -- operands --
  signal opa, opb : std_ulogic_vector(data_width_c-1 downto 0);
  signal opa, opb : std_ulogic_vector(data_width_c-1 downto 0);
 
 
  -- results --
  -- results --
  signal addsub_res : std_ulogic_vector(data_width_c downto 0);
  signal addsub_res : std_ulogic_vector(data_width_c downto 0);
 
  --
  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 logic_res  : std_ulogic_vector(data_width_c-1 downto 0);
 
 
  -- comparator --
  -- comparator --
  signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
  signal cmp_sub : std_ulogic_vector(data_width_c downto 0);
  signal cmp_sub : std_ulogic_vector(data_width_c downto 0);
Line 165... Line 168...
  end process binary_arithmetic_core;
  end process binary_arithmetic_core;
 
 
  -- direct output of address result --
  -- direct output of address result --
  add_o <= addsub_res(data_width_c-1 downto 0);
  add_o <= addsub_res(data_width_c-1 downto 0);
 
 
 
  -- ALU arithmetic logic core --
 
  arithmetic_core: process(ctrl_i, addsub_res)
 
  begin
 
    if (ctrl_i(ctrl_alu_arith_c) = alu_arith_cmd_addsub_c) then -- ADD/SUB
 
      arith_res <= addsub_res(data_width_c-1 downto 0);
 
    else -- SLT
 
      arith_res <= (others => '0');
 
      arith_res(0) <= addsub_res(addsub_res'left); -- => carry/borrow
 
    end if;
 
  end process arithmetic_core;
 
 
 
 
  -- Shifter Unit ---------------------------------------------------------------------------
  -- Shifter Unit ---------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  shifter_unit: process(clk_i)
  shifter_unit: process(clk_i)
    variable bs_input_v   : std_ulogic_vector(data_width_c-1 downto 0);
    variable bs_input_v   : std_ulogic_vector(data_width_c-1 downto 0);
Line 274... Line 288...
      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_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';
  shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0';
 
 
  -- shift operation running? --
  -- shift operation running? --
  shifter.run  <= '1' when (or_all_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
  shifter.run  <= '1' when (or_all_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
  shifter.halt <= '1' when (or_all_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0';
  shifter.halt <= '1' when (or_all_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0';
Line 292... Line 306...
      cp_ctrl.cmd_ff <= '0';
      cp_ctrl.cmd_ff <= '0';
      cp_ctrl.busy   <= '0';
      cp_ctrl.busy   <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (CPU_EXTENSION_RISCV_M = true) then
      if (CPU_EXTENSION_RISCV_M = true) then
        cp_ctrl.cmd_ff <= cp_ctrl.cmd;
        cp_ctrl.cmd_ff <= cp_ctrl.cmd;
        if (cp_ctrl.start = '1') then
        if ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
          cp_ctrl.busy <= '1';
 
        elsif ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
 
          cp_ctrl.busy <= '0';
          cp_ctrl.busy <= '0';
 
        elsif (cp_ctrl.start = '1') then
 
          cp_ctrl.busy <= '1';
        end if;
        end if;
      else -- no co-processor(s) implemented
      else -- no co-processor(s) implemented
        cp_ctrl.cmd_ff <= '0';
        cp_ctrl.cmd_ff <= '0';
        cp_ctrl.busy   <= '0';
        cp_ctrl.busy   <= '0';
      end if;
      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_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_cp_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';
  cp0_start_o   <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0'; -- CP0: MULDIV CP
 
  cp1_start_o   <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0'; -- CP1: not implemented yet
 
  cp2_start_o   <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0'; -- CP2: not implemented yet
 
  cp3_start_o   <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0'; -- CP3: not implemented yet
 
 
 
  -- co-processor operation running? --
  -- co-processor select --
  cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
  cp0_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0';
 
  cp1_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0';
 
  cp2_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0';
 
  cp3_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0';
 
 
 
  -- co-processor operation (still) running? --
 
  cp_ctrl.halt <= (cp_ctrl.busy and (not (cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i))) or cp_ctrl.start;
 
 
  -- co-processor result --
  -- co-processor result --
 
  cp_read_back: process(clk_i)
 
  begin
 
    if rising_edge(clk_i) then
  cp_res <= cp0_data_i or cp1_data_i or cp2_data_i or cp3_data_i; -- only the *actually selected* co-processor may output data != 0
  cp_res <= cp0_data_i or cp1_data_i or cp2_data_i or cp3_data_i; -- only the *actually selected* co-processor may output data != 0
 
    end if;
 
  end process cp_read_back;
 
 
 
 
 
  -- ALU Logic Core -------------------------------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  alu_logic_core: process(ctrl_i, rs1_i, opb)
 
  begin
 
    case ctrl_i(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) is
 
      when alu_logic_cmd_movb_c => logic_res <= opb; -- (default)
 
      when alu_logic_cmd_xor_c  => logic_res <= rs1_i xor opb; -- only rs1 required for logic ops (opa would also contain pc)
 
      when alu_logic_cmd_or_c   => logic_res <= rs1_i or  opb;
 
      when alu_logic_cmd_and_c  => logic_res <= rs1_i and opb;
 
      when others               => logic_res <= opb; -- undefined
 
    end case;
 
  end process alu_logic_core;
 
 
 
 
  -- ALU Function Select --------------------------------------------------------------------
  -- ALU Function Select --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  alu_function_mux: process(ctrl_i, rs1_i, opb, addsub_res, cp_res, shifter.sreg)
  alu_function_mux: process(ctrl_i, arith_res, logic_res, shifter.sreg, cp_res)
  begin
  begin
    case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
    case ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) is
      when alu_cmd_xor_c    => res_o <= rs1_i xor opb; -- only rs1 required for logic ops (opa would also contain pc)
      when alu_func_cmd_arith_c => res_o <= arith_res; -- (default)
      when alu_cmd_or_c     => res_o <= rs1_i or  opb;
      when alu_func_cmd_logic_c => res_o <= logic_res;
      when alu_cmd_and_c    => res_o <= rs1_i and opb;
      when alu_func_cmd_shift_c => res_o <= shifter.sreg;
      when alu_cmd_movb_c   => res_o <= opb;
      when alu_func_cmd_copro_c => res_o <= cp_res;
      when alu_cmd_addsub_c => res_o <= addsub_res(data_width_c-1 downto 0);
      when others               => res_o <= arith_res; -- undefined
      when alu_cmd_cp_c     => res_o <= cp_res;
 
      when alu_cmd_shift_c  => res_o <= shifter.sreg;
 
      when alu_cmd_slt_c    => res_o <= (others => '0'); res_o(0) <= addsub_res(addsub_res'left); -- => carry/borrow
 
      when others           => res_o <= opb; -- undefined
 
    end case;
    end case;
  end process alu_function_mux;
  end process alu_function_mux;
 
 
 
 
  -- ALU Busy -------------------------------------------------------------------------------
  -- ALU Busy -------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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