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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_alu.vhd] - Diff between revs 3 and 6

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

Rev 3 Rev 6
Line 40... Line 40...
 
 
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 (
 
    CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
 
    CPU_EXTENSION_RISCV_M : boolean := false  -- implement mul/div extension?
 
  );
 
  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
    ctrl_i      : in  std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
    ctrl_i      : in  std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
    -- 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
    pc_i        : in  std_ulogic_vector(data_width_c-1 downto 0); -- current PC
 
    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
    csr_i       : in  std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
    -- data output --
    -- data output --
    cmp_o       : out std_ulogic_vector(1 downto 0); -- comparator status
    cmp_o       : out std_ulogic_vector(1 downto 0); -- comparator status
Line 73... Line 68...
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
 
 
  -- operands --
  -- operands --
  signal opa, opb, opc, pc_inc : std_ulogic_vector(data_width_c-1 downto 0);
  signal opa, opb, opc : std_ulogic_vector(data_width_c-1 downto 0);
 
 
  -- results --
  -- results --
  signal add_res : std_ulogic_vector(data_width_c-1 downto 0);
  signal add_res : std_ulogic_vector(data_width_c-1 downto 0);
  signal alu_res : std_ulogic_vector(data_width_c-1 downto 0);
  signal alu_res : std_ulogic_vector(data_width_c-1 downto 0);
 
 
Line 107... Line 102...
 
 
begin
begin
 
 
  -- Operand Mux ----------------------------------------------------------------------------
  -- Operand Mux ----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  input_op_mux: process(ctrl_i, csr_i, pc2_i, pc_i, rs1_i, rs2_i, imm_i, pc_inc)
  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) --
    case ctrl_i(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) is
    if (ctrl_i(ctrl_alu_opa_mux_msb_c) = '0') then
      when "00"   => opa <= rs1_i;
      if (ctrl_i(ctrl_alu_opa_mux_lsb_c) = '0') then
      when "01"   => opa <= pc2_i;
        opa <= rs1_i;
      when "10"   => opa <= csr_i;
      else
      when others => opa <= pc_i;
        opa <= pc2_i;
    end case;
      end if;
 
    else
 
      opa <= csr_i;
 
    end if;
    -- opb (second ALU input operand) --
    -- opb (second ALU input operand) --
    case ctrl_i(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) is
    if (ctrl_i(ctrl_alu_opb_mux_msb_c) = '0') then
      when "00"   => opb <= rs2_i;
      if (ctrl_i(ctrl_alu_opb_mux_lsb_c) = '0') then
      when "01"   => opb <= imm_i;
        opb <= rs2_i;
      when "10"   => opb <= rs1_i;
      else
      when others => opb <= pc_inc;
        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;
    end if;
    end if;
  end process input_op_mux;
  end process input_op_mux;
 
 
  -- PC increment --
 
  pc_inc <= x"00000002" when (CPU_EXTENSION_RISCV_C = true) else x"00000004";
 
 
 
 
 
  -- Comparator Unit ------------------------------------------------------------------------
  -- Comparator Unit ------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- less than (x < y) --
  -- less than (x < y) --
  cmp_opx  <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i;
  cmp_opx  <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i;
Line 200... Line 198...
      cp_cmd_ff <= '0';
      cp_cmd_ff <= '0';
      cp_busy   <= '0';
      cp_busy   <= '0';
      cp_rb_ff0 <= '0';
      cp_rb_ff0 <= '0';
      cp_rb_ff1 <= '0';
      cp_rb_ff1 <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (CPU_EXTENSION_RISCV_M = true) then
      if (ctrl_i(ctrl_sys_m_ext_en_c) = '1') then
        cp_cmd_ff <= ctrl_i(ctrl_cp_use_c);
        cp_cmd_ff <= ctrl_i(ctrl_cp_use_c);
        cp_rb_ff0 <= '0';
        cp_rb_ff0 <= '0';
        cp_rb_ff1 <= cp_rb_ff0;
        cp_rb_ff1 <= cp_rb_ff0;
        if (cp_start = '1') then
        if (cp_start = '1') then
          cp_busy <= '1';
          cp_busy <= '1';

powered by: WebSVN 2.1.0

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