Files
vhdl/lib/fixed_ja/fixed_ja_body.vhd
T
jens af8fb3b865 - bounds check failure with GHDL
git-svn-id: http://moon:8086/svn/vhdl/trunk@1438 cc03376c-175c-47c8-b038-4cd826a8556b
2021-03-21 17:20:23 +00:00

1922 lines
51 KiB
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.textio.all;
package body fixed_ja is
-------------------------------------------------------------
-- Local Procedures
-------------------------------------------------------------
-- adds 1 to the LSB of the number
procedure round_up
(
src : in ufixed_t;
result : out ufixed_t;
overflowx : out BOOLEAN ) is
variable srcuns, resuns : UNSIGNED (src'high-src'low+1 downto 0) := (others => '0');
begin -- round_up
srcuns (srcuns'high-1 downto 0) := to_unsigned (src);
resuns := srcuns + 1;
result := to_ufixed(resuns(src'high-src'low downto 0), src);
overflowx := (resuns(resuns'high) = '1');
end procedure round_up;
-------------------------------------------------------------
-- adds 1 to the LSB of the number
procedure round_up
(
src : in sfixed_t;
result : out sfixed_t;
overflowx : out BOOLEAN ) is
variable srcs, ress : SIGNED (src'high-src'low+1 downto 0);
begin -- round_up
srcs (srcs'high-1 downto 0) := to_signed (src);
srcs(srcs'high) := src(src'high); -- sign extend
ress := srcs + 1;
result := to_sfixed(ress (ress'high-1 downto 0), src);
overflowx := ((src(src'high) /= ress(ress'high-1)) and (or_red (sfixed_t(ress)) /= '0'));
end procedure round_up;
-------------------------------------------------------------
-- Local functions
-------------------------------------------------------------
-- round_fixed()
-- function round_fixed
-- (
-- src : ufixed_t;
-- remainder : ufixed_t;
-- rnd_mode : round_mode_t := default_round_mode
-- ) return ufixed_t is
-- variable res : ufixed_t(src'range);
-- begin
-- return res;
--
-- end round_fixed;
-------------------------------------------------------------
-- function round_fixed
-- (
-- src : sfixed_t;
-- remainder : sfixed_t;
-- rnd_mode : round_mode_t := default_round_mode
-- ) return sfixed_t is
-- variable res : to_signed(src'length-1 downto 0);
-- begin
-- return src;
--
-- end round_fixed;
-------------------------------------------------------------
function reshape
(
src : ufixed_t;
proto : ufixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
variable RemainLow : ufixed_t (proto'low-1 downto src'low) := (others => '0');
variable RemainHigh : ufixed_t (src'high downto proto'high+1) := (others => '0');
variable dst, tmp : ufixed_t (proto'high downto proto'low) := (others => '0');
variable ovf, isTruncLo, isTruncHi : boolean := false;
begin
if proto'high < -1 then
assert false report "U: reshape: Bad dual point (Upper bound < (-1))" severity error;
end if;
-- Check for high and low truncation
isTruncLo := (src'low < dst'low);
isTruncHi := (src'high > dst'high);
-- Reshape
dst := (others => '0');
dst(min(src'high, dst'high) downto max(src'low, dst'low)) := src(min(src'high, dst'high) downto max(src'low, dst'low));
tmp := dst;
-- Get low remainder
if isTruncLo then
RemainLow := src(RemainLow'range);
end if;
-- Get high remainder
if isTruncHi then
RemainHigh := src(RemainHigh'range);
end if;
ovf := false;
-- Rounding
if isTruncLo then
case rnd_mode is
-- Round to positive infinity (round ceiling)
when round_pos_infinity =>
if or_red(RemainLow) = '1' then
round_up(tmp, dst, ovf);
end if;
-- Round Half-up
-- Round nearest
when round_half_up | round_nearest =>
if (RemainLow(RemainLow'high) = '1') then
round_up(tmp, dst, ovf);
end if;
-- Round convergent
when round_convergent =>
if RemainLow(RemainLow'high) = '1' then
if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then
round_up(tmp, dst, ovf);
elsif tmp(dst'low) = '1' then
round_up(tmp, dst, ovf);
end if;
end if;
-- Round to zero
when round_to_zero | none => null;
when others =>
assert false report "Reshape(U): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error;
end case;
end if;
-- Saturating
if sat_mode = saturate then
-- Check overflow
if isTruncHi then
ovf := ovf or or_red(RemainHigh) = '1';
end if;
-- Saturate
if ovf then
dst := (others => '1');
end if;
end if;
return dst;
end reshape;
-------------------------------------------------------------
function reshape
(
src : ufixed_t;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
begin
return reshape(src, uproto(nbits, nbits_int), rnd_mode, sat_mode);
end reshape;
-------------------------------------------------------------
function reshape
(
src : sfixed_t;
proto : sfixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
variable RemainLow : sfixed_t (proto'low-1 downto src'low) := (others => '0');
variable RemainHigh : sfixed_t (src'high-1 downto proto'high) := (others => '0');
variable dst, tmp : sfixed_t (proto'high downto proto'low) := (others => '0');
variable ovf, isTruncLo, isTruncHi : boolean := false;
variable sign : std_logic;
begin
if proto'high < 0 then
assert false report "Reshape(S): Bad dual point (Upper bound < (0))" severity error;
end if;
-- Check for high and low truncation
isTruncLo := (src'low < dst'low);
isTruncHi := (src'high > dst'high);
-- Reshape
sign := src(src'high);
dst := (others => '0');
dst(dst'high downto max(src'low, dst'low)) := (dst'high downto min(src'high, dst'high) => sign) & src(min(src'high, dst'high)-1 downto max(src'low, dst'low));
tmp := dst;
-- Get low remainder
if isTruncLo then
RemainLow := src(RemainLow'range);
end if;
-- Get high remainder
if isTruncHi then
RemainHigh := src(RemainHigh'range);
end if;
ovf := false;
-- Rounding
if isTruncLo then
case rnd_mode is
-- Round to positive infinity (round ceiling)
when round_pos_infinity =>
round_up(tmp, dst, ovf);
if ovf then
dst(dst'high) := '0';
end if;
-- Round Half-up
when round_half_up =>
if RemainLow(RemainLow'high) = '1' then
round_up(tmp, dst, ovf);
end if;
-- Round nearest
when round_nearest =>
if RemainLow(RemainLow'high) = '1' then
if RemainLow'length = 1 then
if sign = '0' then
round_up(tmp, dst, ovf);
end if;
elsif sign = '0' or (sign and or_red(RemainLow(RemainLow'high-1 downto RemainLow'low))) = '1' then
round_up(tmp, dst, ovf);
end if;
end if;
-- Round convergent
when round_convergent =>
if RemainLow(RemainLow'high) = '1' then
if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then
round_up(tmp, dst, ovf);
elsif tmp(dst'low) = '1' then
round_up(tmp, dst, ovf);
end if;
end if;
-- Round to zero
when round_to_zero =>
if (or_red(RemainLow) = '1' and sign = '1') then
round_up(tmp, dst, ovf);
end if;
-- No Round
when none =>
-- Same as RoundToZero but overflow detection is omitted
dst := tmp + (or_red(RemainLow) and sign);
when others =>
assert false report "Reshape(S): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error;
end case;
-- Check negative zero
if dst(dst'high) = '1' then
if or_red(dst(dst'high-1 downto dst'low)) = '0' then
dst(dst'high) := '0';
-- assert false report "Reshape(S): -0 detected" severity note;
end if;
end if;
end if;
-- Saturating
if sat_mode = saturate then
-- Check overflow
if isTruncHi then
ovf := ovf or
(sign = '1' and src(dst'high) = '0' and or_red(tmp(dst'high-1 downto dst'low)) = '1') or
(sign = '1' and src(dst'high) = '1' and or_red(tmp(dst'high-1 downto dst'low)) = '0') or
(sign = '0' and or_red(RemainHigh) = '1');
end if;
-- Saturate
if ovf then
if (sign = '1') then
dst := '1' & (dst'high-1 downto dst'low+1 => '0') & '1';
else
dst := '0' & (dst'high-1 downto dst'low => '1');
end if;
end if;
end if;
return dst;
end reshape;
-------------------------------------------------------------
function reshape
(
src : sfixed_t;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
begin
return reshape(src, sproto(nbits, nbits_int), rnd_mode, sat_mode);
end reshape;
-------------------------------------------------------------
-- Constuctor helpers
-------------------------------------------------------------
function uproto (nbits : integer; nbits_int : integer) return ufixed_t is
constant result : ufixed_t (nbits_int-1 downto nbits_int-nbits) := (others => '0');
begin
return result(nbits_int-1 downto nbits_int-nbits);
end uproto;
-------------------------------------------------------------
function sproto (nbits : integer; nbits_int : integer) return sfixed_t is
constant result : sfixed_t (nbits_int downto nbits_int-nbits+1) := (others => '0');
begin
return result(nbits_int downto nbits_int-nbits+1);
end sproto;
-------------------------------------------------------------
function uproto (a : ufixed_t; op : character; b : ufixed_t) return ufixed_t is
constant result : ufixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0');
variable hi, lo : integer := 0;
begin
case op is
when '+' =>
hi := max(a'high, b'high);
if a'high = b'high then
hi := hi + 1;
end if;
lo := min(a'low, b'low);
when '-' =>
hi := max(a'high, b'high);
lo := min(a'low, b'low);
when '*' =>
hi := a'high + b'high + 1;
if (a'high < 0 or b'high < 0) then
if (hi > -1) then
hi := hi-1;
end if;
end if;
lo := hi - a'length - b'length + 1;
when others => null;
end case;
return result(hi downto lo);
end uproto;
-------------------------------------------------------------
function sproto (a : sfixed_t; op : character; b : sfixed_t) return sfixed_t is
constant result : sfixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0');
variable hi, lo : integer := 0;
begin
case op is
when '+' =>
hi := max(a'high, b'high);
if a'high = b'high then
hi := hi + 1;
end if;
lo := min(a'low, b'low);
when '-' =>
hi := max(a'high, b'high);
lo := min(a'low, b'low);
when '*' =>
hi := a'high + b'high;
if (a'high = 0 or b'high = 0) then
if (hi > 0) then
hi := hi-1;
end if;
end if;
lo := hi - a'length - b'length + 1;
when others => null;
end case;
return result(hi downto lo);
end sproto;
-------------------------------------------------------------
-- Type conversions
-------------------------------------------------------------
-- ufixed <= ufixed
function to_ufixed(src : ufixed_t) return ufixed_t is
begin
return to_ufixed(src, src);
end to_ufixed;
-------------------------------------------------------------
-- ufixed <= sfixed
function to_ufixed(src : sfixed_t) return ufixed_t is
variable dst : ufixed_t(src'range) := (others => '0');
begin
dst := ufixed_t(abs(src));
return dst(src'high-1 downto src'low);
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= sfixed
function to_sfixed(src : sfixed_t) return sfixed_t is
begin
return src;
end to_sfixed;
-------------------------------------------------------------
-- sfixed <= ufixed
function to_sfixed(src : ufixed_t) return sfixed_t is
variable dst : sfixed_t(src'high+1 downto src'low) := (others => '0');
begin
dst(src'range) := sfixed_t(src);
return dst;
end to_sfixed;
-------------------------------------------------------------
-- ufixed <= ufixed
function to_ufixed
(
src : ufixed_t;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
begin
return reshape(src, nbits, nbits_int, rnd_mode, sat_mode);
end to_ufixed;
-------------------------------------------------------------
-- ufixed <= ufixed
function to_ufixed
(
src : ufixed_t;
proto : ufixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
begin
return reshape(src, proto, rnd_mode, sat_mode);
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= sfixed
function to_sfixed
(
src : sfixed_t;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
begin
return reshape(src, nbits, nbits_int, rnd_mode, sat_mode);
end to_sfixed;
-------------------------------------------------------------
-- sfixed <= sfixed
function to_sfixed
(
src : sfixed_t;
proto : sfixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
begin
return reshape(src, proto, rnd_mode, sat_mode);
end to_sfixed;
-------------------------------------------------------------
-- ufixed <= integer
function to_ufixed (src : integer; nbits : integer; nbits_int : integer) return ufixed_t is
begin
return to_ufixed(src, uproto(nbits, nbits_int));
end to_ufixed;
function to_ufixed (src : integer; proto : ufixed_t) return ufixed_t is
begin
return to_ufixed(to_unsigned(src, proto'length), proto);
end to_ufixed;
-------------------------------------------------------------
-- ufixed <= unsigned
function to_ufixed (src : unsigned; nbits : integer; nbits_int : integer) return ufixed_t is
begin
return to_ufixed(src, uproto(nbits, nbits_int));
end to_ufixed;
-------------------------------------------------------------
-- ufixed <= unsigned
function to_ufixed(src : unsigned; proto : ufixed_t) return ufixed_t is
variable dst : ufixed_t(proto'high downto proto'low) := (others => '0');
begin
dst(dst'low + min(dst'length, src'length)-1 downto dst'low) := ufixed_t(src(min(dst'length, src'length)-1 downto 0));
return dst;
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= integer
function to_sfixed (src : integer; nbits : integer; nbits_int : integer) return sfixed_t is
begin
return to_sfixed(src, sproto(nbits, nbits_int));
end to_sfixed;
function to_sfixed (src : integer; proto : sfixed_t) return sfixed_t is
begin
return to_sfixed(to_signed(src, proto'length), proto);
end to_sfixed;
-------------------------------------------------------------
-- sfixed <= signed
function to_sfixed (src : signed; nbits : integer; nbits_int : integer) return sfixed_t is
begin
return to_sfixed(src, sproto(nbits, nbits_int));
end to_sfixed;
-------------------------------------------------------------
-- sfixed <= signed
function to_sfixed(src : signed; proto : sfixed_t) return sfixed_t is
variable dst : sfixed_t(proto'high downto proto'low) := (others => '0');
begin
dst(dst'low + min(dst'length, src'length)-2 downto dst'low) := sfixed_t(src(min(dst'length, src'length)-2 downto 0));
dst(dst'high) := src(src'high);
return dst;
end to_sfixed;
-------------------------------------------------------------
function to_ufixed (src : STD_LOGIC_VECTOR; proto : ufixed_t) return ufixed_t is
variable result : ufixed_t (proto'left downto proto'right);
begin
if (result'length < 1) then
return result;
else
result := to_ufixed (unsigned(src), proto);
return result;
end if;
end function to_ufixed;
-------------------------------------------------------------
function to_ufixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return ufixed_t is
begin
return to_ufixed(src, uproto(nbits, nbits_int));
end function to_ufixed;
-------------------------------------------------------------
function to_sfixed (src : STD_LOGIC_VECTOR; proto : sfixed_t) return sfixed_t is
variable result : sfixed_t (proto'left downto proto'right);
begin
if (result'length < 1) then
return result;
else
result := to_sfixed (signed(src), proto);
return result;
end if;
end function to_sfixed;
-------------------------------------------------------------
function to_sfixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return sfixed_t is
begin
return to_sfixed(src, sproto(nbits, nbits_int));
end to_sfixed;
-------------------------------------------------------------
-- ufixed <= real
function to_ufixed
(
src : real;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
constant nbits_ext : integer := nbits + 1;
constant fix_hi : integer := nbits_int - 1;
constant fix_lo : integer := nbits_int - nbits_ext;
variable dst : ufixed_t (fix_hi downto fix_lo) := (others => '0');
variable i : integer := 0;
variable remain : real := 0.0;
begin
if (nbits_int < 0) then
assert false report "to_ufixed: Bad dual point (N integer bits < 0)" severity error;
end if;
if ((2.0**nbits_int - 1.0) < ipart(abs(src))) then
-- assert ASSERT_NO_WARN report "to_ufixed: Overflow (" & REAL'image(src) & ") " severity warning;
-- print_info(dst, "dst: ");
end if;
remain := abs(src);
for i in dst'range loop
if remain >= 2.0**i then
dst(i) := '1';
remain := remain - 2.0**i;
else
dst(i) := '0';
end if;
end loop;
return to_ufixed(dst, nbits, nbits_int, rnd_mode, sat_mode);
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= real
function to_sfixed
(
src : real;
proto : sfixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
variable utmp : ufixed_t(proto'high-1 downto proto'low) := (others => '0');
variable dst : sfixed_t(proto'high downto proto'low) := (others => '0');
begin
utmp := to_ufixed(src, utmp, rnd_mode, sat_mode);
if (src < 0.0) then
dst := -to_sfixed(utmp);
else
dst := to_sfixed(utmp);
end if;
return dst;
end to_sfixed;
-------------------------------------------------------------
-- ufixed <= real
function to_ufixed
(
src : real;
proto : ufixed_t;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return ufixed_t is
begin
return to_ufixed(src, proto'length, proto'high+1, rnd_mode, sat_mode);
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= real
function to_sfixed
(
src : real;
nbits : integer;
nbits_int : integer;
rnd_mode : round_mode_t := default_round_mode;
sat_mode : saturate_mode_t := default_saturate_mode
) return sfixed_t is
begin
return to_sfixed(src, sproto(nbits, nbits_int), rnd_mode, sat_mode);
end to_sfixed;
-------------------------------------------------------------------------------
-- ufixed <= ufixed_array(i)
function to_ufixed(src : ufixed_array_t; index : integer) return ufixed_t is
variable dst : ufixed_t(src'range(2));
begin
for j in src'range(2) loop
dst(j) := src(index, j);
end loop;
return dst;
end to_ufixed;
-------------------------------------------------------------------------------
-- sfixed <= sfixed_array(i)
function to_sfixed(src : sfixed_array_t; index : integer) return sfixed_t is
variable dst : sfixed_t(src'range(2));
begin
for j in src'range(2) loop
dst(j) := src(index, j);
end loop;
return dst;
end to_sfixed;
-------------------------------------------------------------
-- ufixed <= string
function to_ufixed (src : string) return ufixed_t is
variable i, j, nbits, nbits_int, nbits_frac : integer := 0;
variable dst : unsigned(src'length downto 0) := (others => '0');
variable dp_found : boolean := false;
begin
for i in src'reverse_range loop
case src(i) is
when '.' =>
if dp_found then
assert false report "More than one DP not found." severity error;
else
dp_found := true;
nbits_frac := j;
end if;
when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1;
when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1;
when others =>
assert false report "Illegal character in binary string." severity error;
end case;
end loop ;
if not dp_found then
assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning;
end if;
nbits_int := nbits - nbits_frac;
return to_ufixed(dst(nbits-1 downto 0), nbits, nbits_int);
end to_ufixed;
-------------------------------------------------------------
-- sfixed <= string
function to_sfixed (src : string) return sfixed_t is
variable i, j, nbits, nbits_int, nbits_frac : integer := 0;
variable dst : signed(src'length downto 0) := (others => '0');
variable dp_found : boolean := false;
variable is_neg : boolean := false;
begin
is_neg := src(src'left) = '-';
for i in src'reverse_range loop
case src(i) is
when '-' => null;
when '+' => null;
when '.' =>
if dp_found then
assert false report "More than one DP not found." severity error;
else
dp_found := true;
nbits_frac := j;
end if;
when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1;
when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1;
when others =>
assert false report "Illegal character in binary string." severity error;
end case;
end loop ;
nbits := nbits + 1;
if not dp_found then
assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning;
end if;
nbits_int := nbits - nbits_frac-1;
if is_neg then
dst(nbits-1 downto 0) := -dst(nbits-1 downto 0);
end if;
return to_sfixed(dst(nbits-1 downto 0), nbits, nbits_int);
end to_sfixed;
-------------------------------------------------------------
function to_unsigned (src : ufixed_t) return UNSIGNED is
subtype t is UNSIGNED(src'high - src'low downto 0);
variable slv : t;
begin
slv := t(src);
return UNSIGNED(to_X01(std_logic_vector(slv)));
end function to_unsigned;
-------------------------------------------------------------
function to_signed (src : sfixed_t) return SIGNED is
subtype t is SIGNED(src'high - src'low downto 0);
variable slv : t;
begin
slv := t(src);
return SIGNED(to_X01(std_logic_vector(slv)));
end function to_signed;
-------------------------------------------------------------
-- integer <= ufixed
function to_integer (src : ufixed_t) return integer is
begin
return to_integer(to_unsigned(src));
end to_integer;
-------------------------------------------------------------
-- integer <= sfixed
function to_integer (src : sfixed_t) return integer is
begin
return to_integer(to_signed(src));
end to_integer;
-------------------------------------------------------------
-- to_real
function to_real(src : ufixed_t) return real is
variable dst : real := 0.0;
begin
for i in src'range loop
if (src(i) = '1') then
dst := dst + real(2.0**i);
end if;
end loop;
return dst;
end to_real;
-------------------------------------------------------------
function to_real(src : sfixed_t) return real is
variable dst : real := 0.0;
begin
dst := to_real(to_ufixed(src));
if (src(src'high) = '1') then
dst := -dst;
end if;
return dst;
end to_real;
-------------------------------------------------------------
-- to_slv
function to_slv (src : ufixed_t) return STD_LOGIC_VECTOR is
subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0);
variable slv : t;
begin
if src'length < 1 then
return NSLV;
end if;
slv := t (src);
return slv;
end function to_slv;
-------------------------------------------------------------
-- to_slv
function to_slv (src : sfixed_t) return STD_LOGIC_VECTOR is
subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0);
variable slv : t;
begin
if src'length < 1 then
return NSLV;
end if;
slv := t (src);
return slv;
end function to_slv;
-------------------------------------------------------------
function to_string(src : ufixed_t) return string is
variable str : string(src'length+1 downto 1) := (others => '0');
variable i, j : integer := 0;
begin
j := src'length+1;
for i in src'high downto 0 loop
if (src(i) = '1') then
str(j) := '1';
end if;
j := j - 1;
end loop;
str(j) := '.';
j := j - 1;
for i in -1 downto src'low loop
if (src(i) = '1') then
str(j) := '1';
end if;
j := j - 1;
end loop;
return str;
end to_string;
-------------------------------------------------------------
function to_string(src : sfixed_t) return string is
variable str : string(src'length+1 downto 1) := (others => '0');
variable i, j, start : integer := 0;
variable strlen : integer := 0;
variable src_abs : sfixed_t(src'range) := (others => '0');
begin
if (src'high < 0) then
assert false report "Illegal signed fix point number" severity error;
end if;
start := src'high;
strlen := src'length;
j := src'length+1;
if (src(start) = '1') then
str(j) := '-';
j := j - 1;
start := start - 1;
strlen := strlen + 1;
end if;
src_abs := abs(src);
for i in start downto 0 loop
if (src_abs(i) = '1') then
str(j) := '1';
end if;
j := j - 1;
end loop;
str(j) := '.';
j := j - 1;
for i in -1 downto src'low loop
if (src_abs(i) = '1') then
str(j) := '1';
end if;
j := j - 1;
end loop;
return str(strlen downto 1);
end to_string;
-------------------------------------------------------------
function to_string(src : std_logic_vector) return string is
variable str : string(src'length downto 1) := (others => '0');
variable i : integer := 0;
begin
for i in src'range loop
if (src(i) = '1') then
str(i+1) := '1';
end if;
end loop;
return str;
end to_string;
-------------------------------------------------------------
-- Binary Operators
-------------------------------------------------------------
function "sla" (src : ufixed_t; count : integer) return ufixed_t is
variable result : ufixed_t (src'high downto src'low) := (others => '0');
begin
if (count = 0) then
result := src;
elsif (count < 0) then
result := src sra -count;
elsif (count < src'length) then
result(src'high downto src'low) := src(src'high-count downto src'low) & (count-1 downto 0 => '0');
end if;
return result;
end "sla";
-------------------------------------------------------------
function "sla" (src : sfixed_t; count : integer) return sfixed_t is
variable result : sfixed_t (src'high downto src'low) := (others => '0');
variable sign : std_logic := '0';
begin
sign := src(src'high);
if (count = 0) then
result := src;
elsif (count < 0) then
result := src sra -count;
elsif (count < src'length-1) then
result(src'high downto src'low) := sign & src(src'high-count-1 downto src'low) & (count-1 downto 0 => '0');
end if;
return result;
end "sla";
-------------------------------------------------------------
function "sra" (src : ufixed_t; count : integer) return ufixed_t is
variable result : ufixed_t (src'high downto src'low) := (others => '0');
begin
if (count = 0) then
result := src;
elsif (count < 0) then
result := src sla -count;
elsif (count < src'length) then
result(src'high downto src'low) := (count-1 downto 0 => '0') & src(src'high downto src'low + count);
end if;
return result;
end "sra";
-------------------------------------------------------------
function "sra" (src : sfixed_t; count : integer) return sfixed_t is
variable result : sfixed_t (src'high downto src'low) := (others => '0');
variable res_slv, src_slv : signed (src'length-1 downto 0) := (others => '0');
variable sign, do_sub : std_logic := '0';
begin
src_slv := to_signed(src);
sign := src(src'high);
do_sub := src(src'high) and src(src'low);
if (count = 0) then
result := src;
elsif (count < 0) then
result := src sla -count;
elsif (count < src'length-1) then
res_slv := (count downto 0 => sign) & src_slv(src'length-2 downto count);
if (do_sub = '1') then
result(src'high downto src'low) := to_sfixed(res_slv+1, result);
else
result(src'high downto src'low) := to_sfixed(res_slv, result);
end if;
end if;
return result;
end "sra";
-------------------------------------------------------------
function "*" (a : ufixed_t; b : ufixed_t) return ufixed_t is
variable result : ufixed_t (uproto(a,'*',b)'high downto uproto(a,'*',b)'low);
begin
if (a'high < 0 and b'high >= 0) or (a'high >= 0 and b'high < 0) then
result := to_ufixed(to_unsigned(a) * to_unsigned(b), result) sla 1;
else
result := to_ufixed(to_unsigned(a) * to_unsigned(b), result);
end if;
return result;
end "*";
-------------------------------------------------------------
function "*" (a : sfixed_t; b : sfixed_t) return sfixed_t is
variable result : sfixed_t (sproto(a,'*',b)'high downto sproto(a,'*',b)'low);
begin
if (a'high = 0 and b'high > 0) or (a'high > 0 and b'high = 0) then
result := to_sfixed(to_signed(a) * to_signed(b), result) sla 2;
else
result := to_sfixed(to_signed(a) * to_signed(b), result) sla 1;
end if;
return result;
end "*";
-------------------------------------------------------------
function "*" (a : ufixed_t; b : sfixed_t) return sfixed_t is
begin
return to_sfixed(a) * b;
end "*";
-------------------------------------------------------------
function "*" (a : sfixed_t; b : ufixed_t) return sfixed_t is
begin
return b * a;
end "*";
-------------------------------------------------------------
function "+" (a : ufixed_t; b : ufixed_t) return ufixed_t is
variable result : ufixed_t (uproto(a,'+',b)'high downto uproto(a,'+',b)'low);
begin
result := ufixed_t(to_unsigned(reshape(a, result)) + to_unsigned(reshape(b, result)));
return result;
end "+";
-------------------------------------------------------------
function "+" (a : sfixed_t; b : sfixed_t) return sfixed_t is
variable result : sfixed_t (sproto(a,'+',b)'high downto sproto(a,'+',b)'low);
begin
result := to_sfixed(to_signed(reshape(a,result)) + to_signed(reshape(b,result)), result);
-- result := to_sfixed(to_signed(a) + to_signed(b), result);
return result;
end "+";
-------------------------------------------------------------
function "+" (a : ufixed_t; b : sfixed_t) return sfixed_t is
begin
return to_sfixed(a) + b;
end "+";
-------------------------------------------------------------
function "+" (a : sfixed_t; b : ufixed_t) return sfixed_t is
begin
return b + a;
end "+";
-------------------------------------------------------------
function "+" (a : ufixed_t; b : unsigned) return ufixed_t is
begin
return ufixed_t(to_unsigned(a) + b);
end "+";
-------------------------------------------------------------
function "+" (a : sfixed_t; b : signed) return sfixed_t is
begin
return sfixed_t(to_signed(a) + b);
end "+";
-------------------------------------------------------------
function "+" (a : ufixed_t; b : integer) return ufixed_t is
begin
return ufixed_t(to_unsigned(a) + to_unsigned(b, a'length));
end "+";
-------------------------------------------------------------
function "+" (a : sfixed_t; b : integer) return sfixed_t is
begin
return sfixed_t(to_signed(a) + to_signed(b, a'length));
end "+";
-------------------------------------------------------------
function "+" (a : ufixed_t; b : std_logic) return ufixed_t is
variable result : ufixed_t (a'high downto a'low);
variable buns : unsigned(a'length-1 downto 0);
begin
buns := (a'length-1 downto 1 => '0') & b;
result := ufixed_t(to_unsigned(a) + buns);
return result;
end "+";
-------------------------------------------------------------
function "+" (a : sfixed_t; b : std_logic) return sfixed_t is
variable result : sfixed_t (a'high downto a'low);
variable bs : signed(a'length-1 downto 0);
begin
bs := (a'length-1 downto 1 => '0') & b;
result := sfixed_t(to_signed(a) + bs);
return result;
end "+";
-------------------------------------------------------------
function "-" (a : ufixed_t; b : ufixed_t) return ufixed_t is
variable result : ufixed_t (uproto(a,'-',b)'high downto uproto(a,'-',b)'low);
begin
result := to_ufixed(to_sfixed(a) - to_sfixed(b));
return result;
end "-";
-------------------------------------------------------------
function "-" (a : sfixed_t; b : sfixed_t) return sfixed_t is
variable result : sfixed_t (sproto(a,'-',b)'high downto sproto(a,'-',b)'low);
begin
result := to_sfixed(to_signed(reshape(a,result)) - to_signed(reshape(b,result)), result);
return result;
end "-";
-------------------------------------------------------------
function "-" (a : ufixed_t; b : sfixed_t) return sfixed_t is
begin
return to_sfixed(a) - b;
end "-";
-------------------------------------------------------------
function "-" (a : sfixed_t; b : ufixed_t) return sfixed_t is
begin
return a - to_sfixed(b);
end "-";
-------------------------------------------------------------
function "-" (a : ufixed_t; b : unsigned) return ufixed_t is
begin
return ufixed_t(to_unsigned(a) - b);
end "-";
-------------------------------------------------------------
function "-" (a : sfixed_t; b : signed) return sfixed_t is
begin
return sfixed_t(to_signed(a) - b);
end "-";
-------------------------------------------------------------
function "-" (a : ufixed_t; b : integer) return ufixed_t is
begin
return ufixed_t(to_unsigned(a) - to_unsigned(b, a'length));
end "-";
-------------------------------------------------------------
function "-" (a : sfixed_t; b : integer) return sfixed_t is
begin
return sfixed_t(to_signed(a) - to_signed(b, a'length));
end "-";
-------------------------------------------------------------
function "-" (a : ufixed_t; b : std_logic) return ufixed_t is
variable result : ufixed_t (a'high downto a'low);
variable buns : unsigned(a'length-1 downto 0);
begin
buns := (a'length-1 downto 1 => '0') & b;
result := ufixed_t(to_unsigned(a) - buns);
return result;
end "-";
-------------------------------------------------------------
function "-" (a : sfixed_t; b : std_logic) return sfixed_t is
variable result : sfixed_t (a'high downto a'low);
variable bs : signed(a'length-1 downto 0);
begin
bs := (a'length-1 downto 1 => '0') & b;
result := sfixed_t(to_signed(a) - bs);
return result;
end "-";
-------------------------------------------------------------
-- Unary Operators
-------------------------------------------------------------
function "abs" (src : sfixed_t) return sfixed_t is
begin
return to_sfixed(abs(to_signed(src)), src);
end "abs";
-------------------------------------------------------------
function "-" (src : ufixed_t) return sfixed_t is
begin
return -to_sfixed(src);
end "-";
-------------------------------------------------------------
function "-" (src : sfixed_t) return sfixed_t is
begin
return to_sfixed(-to_signed(src), src);
end "-";
-------------------------------------------------------------
-- Binary Equality
-------------------------------------------------------------
function "=" (a : ufixed_t; b : ufixed_t) return boolean is
variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_ufixed(a, ta);
tb := to_ufixed(b, tb);
return to_unsigned(ta) = to_unsigned(tb);
end "=";
-------------------------------------------------------------
function "=" (a : sfixed_t; b : sfixed_t) return boolean is
variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_sfixed(a, ta);
tb := to_sfixed(b, tb);
return to_signed(ta) = to_signed(tb);
end "=";
-------------------------------------------------------------
function "=" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return to_sfixed(a) = b;
end "=";
-------------------------------------------------------------
function "=" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return b = a;
end "=";
-------------------------------------------------------------
-- Binary Inequality
-------------------------------------------------------------
function "/=" (a : ufixed_t; b : ufixed_t) return boolean is
begin
return not (a = b);
end "/=";
-------------------------------------------------------------
function "/=" (a : sfixed_t; b : sfixed_t) return boolean is
begin
return not (a = b);
end "/=";
-------------------------------------------------------------
function "/=" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return not (a = b);
end "/=";
-------------------------------------------------------------
function "/=" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return not (a = b);
end "/=";
-------------------------------------------------------------
-- Binary less than
-------------------------------------------------------------
function "<" (a : ufixed_t; b : ufixed_t) return boolean is
variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_ufixed(a, ta);
tb := to_ufixed(b, tb);
return to_unsigned(ta) < to_unsigned(tb);
end "<";
-------------------------------------------------------------
function "<" (a : sfixed_t; b : sfixed_t) return boolean is
variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_sfixed(a, ta);
tb := to_sfixed(b, tb);
return to_signed(ta) < to_signed(tb);
end "<";
-------------------------------------------------------------
function "<" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return to_sfixed(a) < b;
end "<";
-------------------------------------------------------------
function "<" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return a < to_sfixed(b);
end "<";
-------------------------------------------------------------
-- Binary greater than
-------------------------------------------------------------
function ">" (a : ufixed_t; b : ufixed_t) return boolean is
variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_ufixed(a, ta);
tb := to_ufixed(b, tb);
return to_unsigned(ta) > to_unsigned(tb);
end ">";
-------------------------------------------------------------
function ">" (a : sfixed_t; b : sfixed_t) return boolean is
variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low));
begin
ta := (others => '0');
tb := (others => '0');
ta := to_sfixed(a, ta);
tb := to_sfixed(b, tb);
return to_signed(ta) > to_signed(tb);
end ">";
-------------------------------------------------------------
function ">" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return to_sfixed(a) > b;
end ">";
-------------------------------------------------------------
function ">" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return a > to_sfixed(b);
end ">";
-------------------------------------------------------------
-- Binary less equal than
-------------------------------------------------------------
function "<=" (a : ufixed_t; b : ufixed_t) return boolean is
begin
return not (a > b);
end "<=";
function "<=" (a : sfixed_t; b : sfixed_t) return boolean is
begin
return not (a > b);
end "<=";
function "<=" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return not (a > b);
end "<=";
function "<=" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return not (a > b);
end "<=";
-------------------------------------------------------------
-- Binary greater or equal than
-------------------------------------------------------------
function ">=" (a : ufixed_t; b : ufixed_t) return boolean is
begin
return not (a < b);
end ">=";
function ">=" (a : sfixed_t; b : sfixed_t) return boolean is
begin
return not (a < b);
end ">=";
function ">=" (a : ufixed_t; b : sfixed_t) return boolean is
begin
return not (a < b);
end ">=";
function ">=" (a : sfixed_t; b : ufixed_t) return boolean is
begin
return not (a < b);
end ">=";
-------------------------------------------------------------
-- Misc. Operators
-------------------------------------------------------------
function ipart (src : ufixed_t) return ufixed_t is
begin
return src(src'high downto 0);
end ipart;
function fpart (src : ufixed_t) return ufixed_t is
begin
return src(-1 downto src'low);
end fpart;
function ipart (src : sfixed_t) return sfixed_t is
begin
return src(src'high-1 downto 0);
end ipart;
function fpart (src : sfixed_t) return sfixed_t is
begin
return src(-1 downto src'low);
end fpart;
-------------------------------------------------------------
-- Print functions
-------------------------------------------------------------
procedure print_info(src : in ufixed_t; prefix : in string) is
variable L : line;
begin
write (L, prefix & "'length = ");write (L, src'length);
writeline (output, L);
write (L, prefix & "'high(left) = ");
write (L, src'high);
write (L, '(');
write (L, src'left);
write (L, ')');
writeline (output, L);
write (L, prefix & "'low(right) = ");
write (L, src'low);
write (L, '(');
write (L, src'right);
write (L, ')');
writeline (output, L);
write (L, prefix & "'value = B");write (L, to_string(src));
writeline (output, L);
write (L, prefix & "'value = ");write (L, to_real(src));
writeline (output, L);
-- write (L, prefix & "'cmsb = ");write (L, cmsb(src));
-- writeline (output, L);
-- write (L, prefix & "'clsb = ");write (L, clsb(src));
-- writeline (output, L);
writeline (output, L);
end print_info;
-------------------------------------------------------------
procedure print_info(src : in sfixed_t; prefix : in string) is
variable L : line;
begin
write (L, prefix & "'length = ");write (L, src'length);
writeline (output, L);
write (L, prefix & "'high(left) = ");
write (L, src'high);
write (L, '(');
write (L, src'left);
write (L, ')');
writeline (output, L);
write (L, prefix & "'low(right) = ");
write (L, src'low);
write (L, '(');
write (L, src'right);
write (L, ')');
writeline (output, L);
write (L, prefix & "'value = B");write (L, to_string(src));
writeline (output, L);
write (L, prefix & "'value = ");write (L, to_real(src));
writeline (output, L);
-- write (L, prefix & "'cmsb = ");write (L, cmsb(src));
-- writeline (output, L);
-- write (L, prefix & "'clsb = ");write (L, clsb(src));
-- writeline (output, L);
writeline (output, L);
end print_info;
-------------------------------------------------------------
procedure print_info(src : in string; prefix : in string) is
variable L : line;
begin
write (L, prefix & "'length = ");write (L, src'length);
writeline (output, L);
write (L, prefix & "'high(left) = ");
write (L, src'high);
write (L, '(');
write (L, src'left);
write (L, ')');
writeline (output, L);
write (L, prefix & "'low(right) = ");
write (L, src'low);
write (L, '(');
write (L, src'right);
write (L, ')');
writeline (output, L);
writeline (output, L);
end print_info;
-------------------------------------------------------------
-- Helpers
-------------------------------------------------------------
-- Count significant bits for integer part
function cmsb(src : ufixed_t) return integer is
variable j, i : integer := src'high;
begin
for i in src'range loop
if src(i) = '1' then
exit;
end if;
j := j - 1;
end loop;
-- LRM nachlesen: hier is i=src'high re-initialisert
return j;
end cmsb;
-------------------------------------------------------------
-- Count significant bits for fractional part
function clsb(src : ufixed_t) return integer is
variable j, i : integer := src'low;
begin
for i in src'reverse_range loop
if src(i) = '1' then
exit;
end if;
j := j + 1;
end loop;
-- LRM nachlesen: hier is i=src'low re-initialisert
return j;
end clsb;
-------------------------------------------------------------
function MIN (X, Y: INTEGER) return INTEGER is
variable res : integer := X;
begin
if Y < X then
res := Y;
end if;
return res;
end MIN;
-------------------------------------------------------------
function MAX (X, Y: INTEGER) return INTEGER is
variable res : integer := X;
begin
if Y > X then
res := Y;
end if;
return res;
end MAX;
-------------------------------------------------------------
function "MOD" (X, Y: in REAL ) return REAL is
-- Description:
-- See function declaration in IEEE Std 1076.2-1996
-- Notes:
-- a) Returns 0.0 on error
variable XNEGATIVE : BOOLEAN := X < 0.0;
variable YNEGATIVE : BOOLEAN := Y < 0.0;
variable VALUE : REAL;
begin
-- Check validity of input arguments
if (Y = 0.0) then
assert FALSE
report "MOD(X, 0.0) is undefined"
severity ERROR;
return 0.0;
end if;
-- Compute value
if ( XNEGATIVE ) then
if ( YNEGATIVE ) then
VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
else
VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
end if;
else
if ( YNEGATIVE ) then
VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
else
VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
end if;
end if;
return VALUE;
end "MOD";
-------------------------------------------------------------
-- misc. conversion
function ipart(src : real) return real is
begin
return floor(src);
end ipart;
-------------------------------------------------------------
function fpart(src : real) return real is
begin
return src - floor(src);
end fpart;
-------------------------------------------------------------
function or_red (arg : STD_LOGIC_VECTOR)
return STD_LOGIC is
variable Upper, Lower : STD_LOGIC;
variable Half : INTEGER;
variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0);
variable Result : STD_LOGIC;
begin
if (arg'length < 1) then -- In the case of a NULL range
Result := '0';
else
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) or BUS_int (BUS_int'left);
else
Half := (BUS_int'length + 1) / 2 + BUS_int'right;
Upper := or_red (BUS_int (BUS_int'left downto Half));
Lower := or_red (BUS_int (Half - 1 downto BUS_int'right));
Result := Upper or Lower;
end if;
end if;
return Result;
end function or_red;
-------------------------------------------------------------
function and_red (arg : STD_LOGIC_VECTOR)
return STD_LOGIC is
variable Upper, Lower : STD_LOGIC;
variable Half : INTEGER;
variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0);
variable Result : STD_LOGIC;
begin
if (arg'length < 1) then -- In the case of a NULL range
Result := '1';
else
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) and BUS_int (BUS_int'left);
else
Half := (BUS_int'length + 1) / 2 + BUS_int'right;
Upper := and_red (BUS_int (BUS_int'left downto Half));
Lower := and_red (BUS_int (Half - 1 downto BUS_int'right));
Result := Upper and Lower;
end if;
end if;
return Result;
end function and_red;
-------------------------------------------------------------
function xor_red (arg : STD_LOGIC_VECTOR) return STD_ULOGIC is
variable Upper, Lower : STD_ULOGIC;
variable Half : INTEGER;
variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0);
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_red (BUS_int (BUS_int'left downto Half));
Lower := xor_red (BUS_int (Half - 1 downto BUS_int'right));
Result := Upper xor Lower;
end if;
end if;
return Result;
end function xor_red;
-------------------------------------------------------------
-- Reduction operators, same as numeric_std functions
function and_red(arg : ufixed_t) return STD_ULOGIC is
begin
return and_red (to_slv(arg));
end function and_red;
function nand_red(arg : ufixed_t) return STD_ULOGIC is
begin
return not and_red (to_slv(arg));
end function nand_red;
function or_red(arg : ufixed_t) return STD_ULOGIC is
begin
return or_red (to_slv(arg));
end function or_red;
function nor_red(arg : ufixed_t) return STD_ULOGIC is
begin
return not or_red (to_slv(arg));
end function nor_red;
function xor_red(arg : ufixed_t) return STD_ULOGIC is
begin
return xor_red (to_slv(arg));
end function xor_red;
function xnor_red(arg : ufixed_t) return STD_ULOGIC is
begin
return not xor_red (to_slv(arg));
end function xnor_red;
function and_red(arg : sfixed_t) return STD_ULOGIC is
begin
return and_red (to_slv(arg));
end function and_red;
function nand_red(arg : sfixed_t) return STD_ULOGIC is
begin
return not and_red (to_slv(arg));
end function nand_red;
function or_red(arg : sfixed_t) return STD_ULOGIC is
begin
return or_red (to_slv(arg));
end function or_red;
function nor_red(arg : sfixed_t) return STD_ULOGIC is
begin
return not or_red (to_slv(arg));
end function nor_red;
function xor_red(arg : sfixed_t) return STD_ULOGIC is
begin
return xor_red (to_slv(arg));
end function xor_red;
function xnor_red(arg : sfixed_t) return STD_ULOGIC is
begin
return not xor_red (to_slv(arg));
end function xnor_red;
-------------------------------------------------------------
end; -- package body fixed_ja;