⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float_pkg_c.vhdl

📁 something i got you may find this useful
💻 VHDL
📖 第 1 页 / 共 5 页
字号:
    variable Result       : STD_ULOGIC := '0';  -- In the case of a NULL range  begin    if (arg'length >= 1) then      BUS_int := to_ux01 (arg);      if (BUS_int'length = 1) then        Result := BUS_int (BUS_int'left);      elsif (BUS_int'length = 2) then        Result := BUS_int(BUS_int'right) xor BUS_int(BUS_int'left);      else        Half   := (BUS_int'length + 1) / 2 + BUS_int'right;        Upper  := xor_reduce (BUS_int (BUS_int'left downto Half));        Lower  := xor_reduce (BUS_int (Half - 1 downto BUS_int'right));        Result := Upper xor Lower;      end if;    end if;    return Result;  end function xor_reduce;  function nand_reduce(arg : std_ulogic_vector) return STD_ULOGIC is  begin    return not and_reduce (arg);  end function nand_reduce;  function nor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is  begin    return not or_reduce (arg);  end function nor_reduce;  function xnor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is  begin    return not xor_reduce (arg);  end function xnor_reduce;  function find_leftmost (ARG : UNSIGNED; Y : STD_ULOGIC)    return INTEGER is  begin    for INDEX in ARG'range loop      if ARG(INDEX) = Y then        return INDEX;      end if;    end loop;    return -1;  end function find_leftmost;  -- Match table, copied form new std_logic_1164  type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;  constant match_logic_table : stdlogic_table := (    -----------------------------------------------------    -- U    X    0    1    Z    W    L    H    -         |   |      -----------------------------------------------------    ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1'),  -- | U |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | X |    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'),  -- | 0 |    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'),  -- | 1 |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | Z |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | W |    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'),  -- | L |    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'),  -- | H |    ('1', '1', '1', '1', '1', '1', '1', '1', '1')   -- | - |    );  constant no_match_logic_table : stdlogic_table := (    -----------------------------------------------------    -- U    X    0    1    Z    W    L    H    -         |   |      -----------------------------------------------------    ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '0'),  -- | U |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | X |    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'),  -- | 0 |    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'),  -- | 1 |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | Z |    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | W |    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'),  -- | L |    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'),  -- | H |    ('0', '0', '0', '0', '0', '0', '0', '0', '0')   -- | - |    );  -------------------------------------------------------------------  -- ?= functions, Similar to "std_match", but returns "std_ulogic".  -------------------------------------------------------------------  -- %%% FUNCTION "?=" ( l, r : std_ulogic ) RETURN std_ulogic IS  function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC is  begin    return match_logic_table (l, r);  end function \?=\;  -- %%% END FUNCTION "?=";  -- %%% FUNCTION "?/=" ( l, r : std_ulogic ) RETURN std_ulogic is  function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC is  begin    return no_match_logic_table (l, r);  end function \?/=\;  -- %%% END FUNCTION "?/=";  function \?=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC is  begin    return \?=\ (ufixed(l), ufixed(r));  end function \?=\;  function Is_X ( s : UNSIGNED ) return BOOLEAN is  begin    return Is_X (STD_LOGIC_VECTOR (s));  end function Is_X;    function Is_X ( s : SIGNED ) return BOOLEAN is  begin    return Is_X (STD_LOGIC_VECTOR (s));  end function Is_X;-- %%% END replicated functions  -- Special version of "minimum" to do some boundary checking  function mine (L, R : INTEGER)    return INTEGER is  begin  -- function minimum    if (L = INTEGER'low or R = INTEGER'low) then      report float_pkg'instance_name        & " Unbounded number passed, was a literal used?"        severity error;      return 0;    end if;    return minimum (L, R);  end function mine;  -- Generates the base number for the exponent normalization offset.  function gen_expon_base (    constant exponent_width : NATURAL)    return SIGNED is    variable result : SIGNED (exponent_width-1 downto 0);  begin    result                    := (others => '1');    result (exponent_width-1) := '0';    return result;  end function gen_expon_base;  -- Integer version of the "log2" command (contributed by Peter Ashenden)  function log2 (A : NATURAL) return NATURAL is    variable quotient : NATURAL;    variable result   : NATURAL := 0;  begin    quotient := A / 2;    while quotient > 0 loop      quotient := quotient / 2;      result   := result + 1;    end loop;    return result;  end function log2;  -- Function similar to the ILOGB function in MATH_REAL  function log2 (A : REAL) return INTEGER is    variable Y : REAL;    variable N : INTEGER := 0;  begin    if (A = 1.0 or A = 0.0) then      return 0;    end if;    Y := A;    if(A > 1.0) then      while Y >= 2.0 loop        Y := Y / 2.0;        N := N + 1;      end loop;      return N;    end if;    -- O < Y < 1    while Y < 1.0 loop      Y := Y * 2.0;      N := N - 1;    end loop;    return N;  end function log2;  -- purpose: Test the boundary conditions of a Real number  procedure test_boundary (    arg                     : in REAL;     -- Input, converted to real    constant fraction_width : in NATURAL;  -- length of FP output fraction    constant exponent_width : in NATURAL;  -- length of FP exponent    constant denormalize    : in BOOLEAN := true;  -- Use IEEE extended FP    variable btype : out boundary_type;    variable log2i : out INTEGER    ) is    constant expon_base : SIGNED (exponent_width-1 downto 0) :=      gen_expon_base(exponent_width);   -- exponent offset    constant exp_min : SIGNED (12 downto 0) :=      -(resize(expon_base, 13)) + 1;    -- Minimum normal exponent    constant exp_ext_min : SIGNED (12 downto 0) :=      exp_min - fraction_width;         -- Minimum for denormal exponent    variable log2arg : INTEGER;         -- log2 of argument  begin  -- function test_boundary    -- Check to see if the exponent is big enough    -- Note that the argument is always an absolute value at this point.    log2arg := log2(arg);    if arg = 0.0 then      btype := zero;    elsif exponent_width > 11 then      -- Exponent for Real is 11 (64 bit)      btype := normal;    else      if log2arg < to_integer(exp_min) then        if denormalize then          if log2arg < to_integer(exp_ext_min) then            btype := zero;          else            btype := denormal;          end if;        else          if log2arg < to_integer(exp_min)-1 then            btype := zero;          else            btype := normal;              -- Can still represent this number          end if;        end if;      elsif exponent_width < 11 then        if log2arg > to_integer(expon_base)+1 then          btype := infinity;        else          btype := normal;        end if;      else        btype := normal;      end if;    end if;    log2i := log2arg;  end procedure test_boundary;  -- purpose: Rounds depending on the state of the "round_style"  -- Logic taken from  -- "What Every Computer Scientist Should Know About Floating Point Arithmetic"  -- by David Goldberg (1991)  function check_round (    fract_in             : STD_ULOGIC;  -- input fraction    sign                 : STD_ULOGIC;  -- sign bit    remainder            : UNSIGNED;    -- remainder to round from    sticky               : STD_ULOGIC := '0';      -- Sticky bit    constant round_style : round_type)  -- rounding type    return BOOLEAN is    variable result     : BOOLEAN;    variable or_reduced : STD_ULOGIC;  begin  -- function check_round    result := false;    if (remainder'length > 0) then      -- if remainder in a null array      or_reduced := or_reduce (remainder & sticky);      rounding_case : case round_style is        when round_nearest =>           -- Round Nearest, default mode          if remainder(remainder'high) = '1' then  -- round            if (remainder'length > 1) then              if ((or_reduce (remainder(remainder'high-1                                 downto remainder'low)) = '1'                   or sticky = '1')                  or fract_in = '1') then                -- Make the bottom bit zero if possible if we are at 1/2                result := true;              end if;            else              result := (fract_in = '1' or sticky = '1');            end if;          end if;        when round_inf =>               -- round up if positive, else truncate.          if or_reduced = '1' and sign = '0' then            result := true;          end if;        when round_neginf =>        -- round down if negative, else truncate.          if or_reduced = '1' and sign = '1' then            result := true;          end if;        when round_zero =>              -- round toward 0   Truncate          null;      end case rounding_case;    end if;    return result;  end function check_round;  -- purpose: Rounds depending on the state of the "round_style"  -- unsigned version  procedure fp_round (    fract_in  : in  UNSIGNED;           -- input fraction    expon_in  : in  SIGNED;             -- input exponent    fract_out : out UNSIGNED;           -- output fraction    expon_out : out SIGNED) is          -- output exponent  begin  -- procedure fp_round    if and_reduce (fract_in) = '1' then        -- Fraction is all "1"      expon_out := expon_in + 1;      fract_out := to_unsigned(0, fract_out'h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -