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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_arith_pkg.vhd] - Rev 2

Compare with Previous | Blame | View Log

-----------------------------------------------------------------
--                                                             --
-----------------------------------------------------------------
--                                                             --
-- Copyright (C) 2015 Stefano Tonello                          --
--                                                             --
-- This source file may be used and distributed without        --
-- restriction provided that this copyright statement is not   --
-- removed from the file and that any derivative work contains --
-- the original copyright notice and the associated disclaimer.--
--                                                             --
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
-- POSSIBILITY OF SUCH DAMAGE.                                 --
--                                                             --
-----------------------------------------------------------------
 
---------------------------------------------------------------
-- Arithmetic operations macros and shifting functions
---------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all; 
use IEEE.numeric_std.all;
 
library WORK;
use WORK.RV01_CONSTS_PKG.all;
use WORK.RV01_TYPES_PKG.all;
use WORK.RV01_FUNCS_PKG.all;
 
package RV01_ARITH_PKG is
 
  ----------------------------------------------------
  -- ALU operation types
  ----------------------------------------------------
 
  -- addition operation type
  type ADD_CTRL is (
    AC_ADD,
    AC_SUB,
    AC_SLT,
    AC_NIL
  );
 
  -- multiplication operation type
  type MUL_CTRL is (
    MC_MUL,
    MC_MULH,
    MC_MULHSU,
    MC_MULHU,
    MC_NIL
  );
 
  -- division operation type
  type DIV_CTRL is (
    DC_DIV,
    DC_DIVU,
    DC_REM,
    DC_REMU,
    DC_NIL
  );
 
  -- shifting operation type
  type SHF_CTRL is (
    SC_SHL,
    SC_SHR,
    SC_NIL
  );
 
  -- logic (boolean) operation type
  type LOG_CTRL is (
    LC_AND,
    LC_OR,
    LC_XOR,
    LC_LUI,
    LC_NIL
  );
 
  ----------------------------------------------------
  -- shifting functions
  ----------------------------------------------------
 
  -- 32-bit left shift
  function shift_left32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T;
 
  -- 32-bit arithmetic right shift
  function shift_right32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T;
 
  -- 32-bit logical right shift
  function shift_right32(SI : SDWORDU_T;SHFT : SHORT_SHIFT_T) return SDWORDU_T;
 
  -- 64-bit left shift
  function shift_left64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T;
 
  -- 64-bit arithmetic right shift
  function shift_right64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T;
 
  ----------------------------------------------------
  -- Wrap-up sum
  ----------------------------------------------------
 
  function wrap_sum(A,B : unsigned(SDLEN-1 downto 0)) return unsigned;
 
  ----------------------------------------------------
  -- Sign-extension
  ----------------------------------------------------
 
  function EXTS32(V : std_logic_vector) return signed;
 
  function EXTS64(V : std_logic_vector) return signed;
 
 
end RV01_ARITH_PKG;
 
package body RV01_ARITH_PKG is
 
  ----------------------------------------------------
  -- shifting functions
  ----------------------------------------------------
 
  function shift_left32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T is
    variable SO : SDWORD_T;
  begin
    case SHFT is
      when  0 => SO := shift_left(SI, 0);
      when  1 => SO := shift_left(SI, 1);
      when  2 => SO := shift_left(SI, 2);
      when  3 => SO := shift_left(SI, 3);
      when  4 => SO := shift_left(SI, 4);
      when  5 => SO := shift_left(SI, 5);
      when  6 => SO := shift_left(SI, 6);
      when  7 => SO := shift_left(SI, 7);
      when  8 => SO := shift_left(SI, 8);
      when  9 => SO := shift_left(SI, 9);
      when 10 => SO := shift_left(SI,10);
      when 11 => SO := shift_left(SI,11);
      when 12 => SO := shift_left(SI,12);
      when 13 => SO := shift_left(SI,13);
      when 14 => SO := shift_left(SI,14);
      when 15 => SO := shift_left(SI,15);
      when 16 => SO := shift_left(SI,16);
      when 17 => SO := shift_left(SI,17);
      when 18 => SO := shift_left(SI,18);
      when 19 => SO := shift_left(SI,19);
      when 20 => SO := shift_left(SI,20);
      when 21 => SO := shift_left(SI,21);
      when 22 => SO := shift_left(SI,22);
      when 23 => SO := shift_left(SI,23);
      when 24 => SO := shift_left(SI,24);
      when 25 => SO := shift_left(SI,25);
      when 26 => SO := shift_left(SI,26);
      when 27 => SO := shift_left(SI,27);
      when 28 => SO := shift_left(SI,28);
      when 29 => SO := shift_left(SI,29);
      when 30 => SO := shift_left(SI,30);
      when others => SO := shift_left(SI,31);
    end case;
    return(SO);
  end function;
 
  function shift_right32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T is
    variable SO : SDWORD_T;
  begin
    case SHFT is
      when  0 => SO := shift_right(SI, 0);
      when  1 => SO := shift_right(SI, 1);
      when  2 => SO := shift_right(SI, 2);
      when  3 => SO := shift_right(SI, 3);
      when  4 => SO := shift_right(SI, 4);
      when  5 => SO := shift_right(SI, 5);
      when  6 => SO := shift_right(SI, 6);
      when  7 => SO := shift_right(SI, 7);
      when  8 => SO := shift_right(SI, 8);
      when  9 => SO := shift_right(SI, 9);
      when 10 => SO := shift_right(SI,10);
      when 11 => SO := shift_right(SI,11);
      when 12 => SO := shift_right(SI,12);
      when 13 => SO := shift_right(SI,13);
      when 14 => SO := shift_right(SI,14);
      when 15 => SO := shift_right(SI,15);
      when 16 => SO := shift_right(SI,16);
      when 17 => SO := shift_right(SI,17);
      when 18 => SO := shift_right(SI,18);
      when 19 => SO := shift_right(SI,19);
      when 20 => SO := shift_right(SI,20);
      when 21 => SO := shift_right(SI,21);
      when 22 => SO := shift_right(SI,22);
      when 23 => SO := shift_right(SI,23);
      when 24 => SO := shift_right(SI,24);
      when 25 => SO := shift_right(SI,25);
      when 26 => SO := shift_right(SI,26);
      when 27 => SO := shift_right(SI,27);
      when 28 => SO := shift_right(SI,28);
      when 29 => SO := shift_right(SI,29);
      when 30 => SO := shift_right(SI,30);
      when others => SO := shift_right(SI,31);
    end case;
    return(SO);
  end function;
 
  function shift_right32(SI : SDWORDU_T;SHFT : SHORT_SHIFT_T) return SDWORDU_T is
    variable SO : SDWORDU_T;
  begin
    case SHFT is
      when  0 => SO := shift_right(SI, 0);
      when  1 => SO := shift_right(SI, 1);
      when  2 => SO := shift_right(SI, 2);
      when  3 => SO := shift_right(SI, 3);
      when  4 => SO := shift_right(SI, 4);
      when  5 => SO := shift_right(SI, 5);
      when  6 => SO := shift_right(SI, 6);
      when  7 => SO := shift_right(SI, 7);
      when  8 => SO := shift_right(SI, 8);
      when  9 => SO := shift_right(SI, 9);
      when 10 => SO := shift_right(SI,10);
      when 11 => SO := shift_right(SI,11);
      when 12 => SO := shift_right(SI,12);
      when 13 => SO := shift_right(SI,13);
      when 14 => SO := shift_right(SI,14);
      when 15 => SO := shift_right(SI,15);
      when 16 => SO := shift_right(SI,16);
      when 17 => SO := shift_right(SI,17);
      when 18 => SO := shift_right(SI,18);
      when 19 => SO := shift_right(SI,19);
      when 20 => SO := shift_right(SI,20);
      when 21 => SO := shift_right(SI,21);
      when 22 => SO := shift_right(SI,22);
      when 23 => SO := shift_right(SI,23);
      when 24 => SO := shift_right(SI,24);
      when 25 => SO := shift_right(SI,25);
      when 26 => SO := shift_right(SI,26);
      when 27 => SO := shift_right(SI,27);
      when 28 => SO := shift_right(SI,28);
      when 29 => SO := shift_right(SI,29);
      when 30 => SO := shift_right(SI,30);
      when others => SO := shift_right(SI,31);
    end case;
    return(SO);
  end function;
 
  function shift_left64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T is
    variable SO : LDWORD_T;
  begin
    case SHFT is
      when  0 => SO := shift_left(SI, 0);
      when  1 => SO := shift_left(SI, 1);
      when  2 => SO := shift_left(SI, 2);
      when  3 => SO := shift_left(SI, 3);
      when  4 => SO := shift_left(SI, 4);
      when  5 => SO := shift_left(SI, 5);
      when  6 => SO := shift_left(SI, 6);
      when  7 => SO := shift_left(SI, 7);
      when  8 => SO := shift_left(SI, 8);
      when  9 => SO := shift_left(SI, 9);
      when 10 => SO := shift_left(SI,10);
      when 11 => SO := shift_left(SI,11);
      when 12 => SO := shift_left(SI,12);
      when 13 => SO := shift_left(SI,13);
      when 14 => SO := shift_left(SI,14);
      when 15 => SO := shift_left(SI,15);
      when 16 => SO := shift_left(SI,16);
      when 17 => SO := shift_left(SI,17);
      when 18 => SO := shift_left(SI,18);
      when 19 => SO := shift_left(SI,19);
      when 20 => SO := shift_left(SI,20);
      when 21 => SO := shift_left(SI,21);
      when 22 => SO := shift_left(SI,22);
      when 23 => SO := shift_left(SI,23);
      when 24 => SO := shift_left(SI,24);
      when 25 => SO := shift_left(SI,25);
      when 26 => SO := shift_left(SI,26);
      when 27 => SO := shift_left(SI,27);
      when 28 => SO := shift_left(SI,28);
      when 29 => SO := shift_left(SI,29);
      when 30 => SO := shift_left(SI,30);
      when 31 => SO := shift_left(SI,31);
      when 32 => SO := shift_left(SI,32);
      when 33 => SO := shift_left(SI,33);
      when 34 => SO := shift_left(SI,34);
      when 35 => SO := shift_left(SI,35);
      when 36 => SO := shift_left(SI,36);
      when 37 => SO := shift_left(SI,37);
      when 38 => SO := shift_left(SI,38);
      when 39 => SO := shift_left(SI,39);
      when 40 => SO := shift_left(SI,40);
      when 41 => SO := shift_left(SI,41);
      when 42 => SO := shift_left(SI,42);
      when 43 => SO := shift_left(SI,43);
      when 44 => SO := shift_left(SI,44);
      when 45 => SO := shift_left(SI,45);
      when 46 => SO := shift_left(SI,46);
      when 47 => SO := shift_left(SI,47);
      when 48 => SO := shift_left(SI,48);
      when 49 => SO := shift_left(SI,49);
      when 50 => SO := shift_left(SI,50);
      when 51 => SO := shift_left(SI,51);
      when 52 => SO := shift_left(SI,52);
      when 53 => SO := shift_left(SI,53);
      when 54 => SO := shift_left(SI,54);
      when 55 => SO := shift_left(SI,55);
      when 56 => SO := shift_left(SI,56);
      when 57 => SO := shift_left(SI,57);
      when 58 => SO := shift_left(SI,58);
      when 59 => SO := shift_left(SI,59);
      when 60 => SO := shift_left(SI,60);
      when 61 => SO := shift_left(SI,61);
      when 62 => SO := shift_left(SI,62);
      when others => SO := shift_left(SI,63);
    end case;
    return(SO);
  end function;
 
  function shift_right64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T is
    variable SO : LDWORD_T;
  begin
    case SHFT is
      when  0 => SO := shift_right(SI, 0);
      when  1 => SO := shift_right(SI, 1);
      when  2 => SO := shift_right(SI, 2);
      when  3 => SO := shift_right(SI, 3);
      when  4 => SO := shift_right(SI, 4);
      when  5 => SO := shift_right(SI, 5);
      when  6 => SO := shift_right(SI, 6);
      when  7 => SO := shift_right(SI, 7);
      when  8 => SO := shift_right(SI, 8);
      when  9 => SO := shift_right(SI, 9);
      when 10 => SO := shift_right(SI,10);
      when 11 => SO := shift_right(SI,11);
      when 12 => SO := shift_right(SI,12);
      when 13 => SO := shift_right(SI,13);
      when 14 => SO := shift_right(SI,14);
      when 15 => SO := shift_right(SI,15);
      when 16 => SO := shift_right(SI,16);
      when 17 => SO := shift_right(SI,17);
      when 18 => SO := shift_right(SI,18);
      when 19 => SO := shift_right(SI,19);
      when 20 => SO := shift_right(SI,20);
      when 21 => SO := shift_right(SI,21);
      when 22 => SO := shift_right(SI,22);
      when 23 => SO := shift_right(SI,23);
      when 24 => SO := shift_right(SI,24);
      when 25 => SO := shift_right(SI,25);
      when 26 => SO := shift_right(SI,26);
      when 27 => SO := shift_right(SI,27);
      when 28 => SO := shift_right(SI,28);
      when 29 => SO := shift_right(SI,29);
      when 30 => SO := shift_right(SI,30);
      when 31 => SO := shift_right(SI,31);
      when 32 => SO := shift_right(SI,32);
      when 33 => SO := shift_right(SI,33);
      when 34 => SO := shift_right(SI,34);
      when 35 => SO := shift_right(SI,35);
      when 36 => SO := shift_right(SI,36);
      when 37 => SO := shift_right(SI,37);
      when 38 => SO := shift_right(SI,38);
      when 39 => SO := shift_right(SI,39);
      when 40 => SO := shift_right(SI,40);
      when 41 => SO := shift_right(SI,41);
      when 42 => SO := shift_right(SI,42);
      when 43 => SO := shift_right(SI,43);
      when 44 => SO := shift_right(SI,44);
      when 45 => SO := shift_right(SI,45);
      when 46 => SO := shift_right(SI,46);
      when 47 => SO := shift_right(SI,47);
      when 48 => SO := shift_right(SI,48);
      when 49 => SO := shift_right(SI,49);
      when 50 => SO := shift_right(SI,50);
      when 51 => SO := shift_right(SI,51);
      when 52 => SO := shift_right(SI,52);
      when 53 => SO := shift_right(SI,53);
      when 54 => SO := shift_right(SI,54);
      when 55 => SO := shift_right(SI,55);
      when 56 => SO := shift_right(SI,56);
      when 57 => SO := shift_right(SI,57);
      when 58 => SO := shift_right(SI,58);
      when 59 => SO := shift_right(SI,59);
      when 60 => SO := shift_right(SI,60);
      when 61 => SO := shift_right(SI,61);
      when 62 => SO := shift_right(SI,62);
      when others => SO := shift_right(SI,63);
    end case;
    return(SO);
  end function;
 
  ----------------------------------------------------
  -- Wrap-up sum
  ----------------------------------------------------
 
  function wrap_sum(A,B : unsigned(SDLEN-1 downto 0)) return unsigned is
    variable TMP : unsigned(SDLEN downto 0);
  begin
    -- A is an unsigned value and thus is zero-extended
    -- B has to be instead treated as a signed value and thus is sign-extended
    TMP := ('0' & A) + (B(SDLEN-1) & B);
    -- result is TMP with MSb removed (wrap-up)
    return(TMP(SDLEN-1 downto 0));
  end function;
 
  ----------------------------------------------------
  -- Sign-extension
  ----------------------------------------------------
 
  function EXTS32(V : std_logic_vector) return signed is
    variable S : signed(SDLEN-1 downto 0);
  begin
    S(V'HIGH downto 0) := to_signed(V);
    S(SDLEN-1 downto V'HIGH+1) := (others => V(V'HIGH));
    return(S);
  end function;
 
  function EXTS64(V : std_logic_vector) return signed is
    variable S : signed(LDLEN-1 downto 0);
  begin
    S(V'HIGH downto 0) := to_signed(V);
    S(LDLEN-1 downto V'HIGH+1) := (others => V(V'HIGH));
    return(S);
  end function;
 
end RV01_ARITH_PKG;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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