PACKAGE fun_pkg IS
FUNCTION NextGray(G1:std_logic_vector)
return std_logic_vector;
--this function implements
a length independent gray counter.
--No arithmatic operators are
used.
FUNCTION bin2gray(B1:std_logic_vector)
return std_logic_vector;
--this function converts a
binary count to gray count
FUNCTION gray2bin(G1:std_logic_vector)
return std_logic_vector;
--this function converts a
gray count to binary count
FUNCTION crr(s1:std_logic_vector;index:integer)
return std_logic_vector;
--crr=CircularRotateRight
--this function Circular Rotates Right 's1' by 'index'
FUNCTION crl(s1:std_logic_vector;index:integer)
return std_logic_vector;
--crl=CircularRotateLeft
--this function Circular Rotates Right 's1' by 'index'
FUNCTION incr_vec(s1:std_logic_vector;en:std_logic)
return std_logic_vector;
--This function increments
an std_logic_vector type by '1', without
--using any arithmatic
FUNCTION dcr_vec(s1:std_logic_vector;en:std_logic)
return std_logic_vector;
--This function decrements
an std_logic_vector type by '1', without
--using any arithmatic
FUNCTION all_ones(s1:std_logic_vector)
return std_logic;
--This function returns if
the input vector has all ones and no zeros
FUNCTION all_zeros(s1:std_logic_vector)
return std_logic;
--This function returns if
the input vector has all zeros and no ones
FUNCTION mux1(a0:std_logic;a1:std_logic;sel:std_logic)
return std_logic;
--one bit mux, handy to be
used in combinational assignmets
FUNCTION mux_vec(a0:std_logic_vector;a1:std_logic_vector;sel:std_logic)
return std_logic_vector;
--multi bit mux, handy to be
used in combinational assignmets
FUNCTION if_eq(s1:std_logic_vector;s2:std_logic_vector)
return std_logic;
--returns a '1' iff s1=s2(s1
and s2 MUST be of equal no of bits
FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic)
return std_logic_vector;
--retruns a 1's compilment
of s1, if en is '1' otherwise s1 as such is returned
FUNCTION inv(s1:std_logic_vector)
return std_logic_vector;
--retruns a 1's compilment
of s1 i.e invert of s1;
FUNCTION myabs(s1:std_logic_vector)
return std_logic_vector;
--this function returns an absolute value of a vector
FUNCTION twos_comp(s1:std_logic_vector)
return std_logic_vector;
--returns a twos compliment
of s1
--To make things more clear:
It returns s1 itself if s1(s1'high) = '0'. Since
--if s1(s1'high) i.e msb of
s1 is '0', then the input no is +ive and hence
--no processing is done on
s1. On the other hand, if s1(s1'high) is -ive
--then each bit in s1 is inverted
and then s1 is inremented by '1'
FUNCTION tc(s1:std_logic_vector)
return std_logic_vector;
--returns a twos compliment
of a s1.
--No matter if the input is
-ive or +ive. It will return a
--twos compliment of the input
vector.
--IE if the input number is
-ive, output will be +ive number
--if the input number is +ive,
the output will be a -ive number
--
FUNCTION sshr(s1:std_logic_vector)
return std_logic_vector;
-- Signed Shift right
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for signed;
FUNCTION zshr(s1:std_logic_vector)
return std_logic_vector;
-- UnSigned Shift right
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for unsigned;
FUNCTION shl(s1:std_logic_vector)
return std_logic_vector;
-- performes shift left i.e
<< i.e x 2, lsb = 0;
FUNCTION csshr(s1:std_logic_vector;s2:std_logic)
return std_logic_vector;
-- Conditional Signed Shift
right, if s2= 1, shift, otherwise return original
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for signed;
FUNCTION czshr(s1:std_logic_vector;s2:std_logic)
return std_logic_vector;
-- Conditional UnSigned Shift
right;shift when s2 = '1'
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for unsigned;
FUNCTION zshrn(s1:std_logic_vector;n:integer)
return std_logic_vector;
-- UnSigned Shift right by
n bits
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for unsigned;
FUNCTION sshrn(s1:std_logic_vector;nn:integer)
return std_logic_vector;
-- Signed Shift right by n
bits
-- performes shift right i.e
>> i.e / 2, msb = 0, suitable for signed;
FUNCTION sext(s1:std_logic_vector;nn:integer)
return std_logic_vector;
-- sign extend an std_logic_vector
by nn bits
-- Example s1 = 10101010, nn
= 3, return = 11110101010
FUNCTION shln(s1:std_logic_vector;nn:integer)
return std_logic_vector;
-- shift left by nn bits, add
nn 0s to LSBs
-- Example s1 = 11111101, nn
= 3, return = 11101000
FUNCTION ccitt_crc_16(s1:std_logic_vector;ser_in:std_logic)
return std_logic_vector;
--Calculates the next CRC value
as per ccitt_crc_16
--X^16 + X^12 + X^5 + 1
FUNCTION bit_reverse(s1:std_logic_vector)
return std_logic_vector;
--It reverses the bits of std_logic_vector
--ie LSB becomes MSB and vice-versa
--Example 01100000 becomes
00000110
END fun_pkg;
PACKAGE body fun_pkg IS
--Function Declaration Section
FUNCTION bin2gray(B1:std_logic_vector)
return std_logic_vector is
VARIABLE G1 : std_logic_vector(B1'high
downto B1'low) ;
BEGIN
G1(G1'high):=B1(B1'high);
for i in B1'high-1
downto B1'low loop
G1(i)
:= B1(i+1) XOR B1(i);
end loop;
return G1;
end bin2gray; --
end function
FUNCTION gray2bin(G1:std_logic_vector)
return std_logic_vector is
VARIABLE B1 : std_logic_vector(G1'high
downto G1'low) ;
BEGIN
B1(G1'high):=G1(B1'high);
for i in G1'high-1
downto G1'low loop
B1(i)
:= B1(i+1) XOR G1(i);
end loop;
return B1;
end gray2bin; --
end function
FUNCTION crr(s1:std_logic_vector;index:integer)
return std_logic_vector is
--crr=CircularRotateRight
--this function Circular Rotates Right 's1' by 'index'
variable z : std_logic_vector(s1'high
downto s1'low);
begin
--pragma translate_off
--pragma coverage_off
if(index >= s1'length)
then
assert false
report
"crr: rotate index is greater than variable length can't rotate" severity
error;
end if;
if(index < 0)
then
assert false
report
"crr: rotate index is negative,can't rotate" severity error;
end if;
--pragma coverage_on
--pragma translate_on
if(index = 0) then
z:=s1;
else
for
jj in 1 to s1'high loop
z:= s1(jj-1 downto 0) & s1(s1'high downto jj);
if(jj = index) then
exit;
end if;
end
loop;
end if;
return z;
end crr; -- end function
function crl(s1:std_logic_vector;index:integer)
return std_logic_vector is
--crl=CircularRotateLeft
--this function Circular Rotates Right 's1' by 'index'
variable z : std_logic_vector(s1'high
downto s1'low);
begin
--pragma translate_off
--pragma coverage_off
if(index >= s1'length)
then
assert false
report
"crl: rotate index is greater than variable length can't rotate" severity
error;
end if;
if(index < 0)
then
assert false
report
"crl: rotate index is negative,can't rotate" severity error;
end if;
--pragma coverage_on
--pragma translate_on
if(index = 0) then
z:=s1;
else
for
jj in 1 to s1'high loop
z:= s1(s1'high-jj downto 0) & s1(s1'high downto s1'high-jj+1);
if(jj = index) then
exit;
end if;
end
loop;
end if;
return z;
end crl; -- end function
FUNCTION incr_vec(s1:std_logic_vector;en:std_logic)
return std_logic_vector is
--this function increments a std_logic_vector type by '1'
VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
VARIABLE tb : std_logic_vector(s1'high downto s1'low);
BEGIN
tb(s1'low) := en;
V := s1;
for i in (V'low + 1) to V'high loop
tb(i) := V(i - 1) and tb(i -1);
end loop;
for i in V'low to V'high loop
if(tb(i) = '1') then
V(i) := not(V(i));
end if;
end loop;
return V;
end incr_vec; -- end function
FUNCTION dcr_vec(s1:std_logic_vector;en:std_logic)
return std_logic_vector is
--this function decrements a std_logic_vector type by '1'
VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
VARIABLE tb : std_logic_vector(s1'high downto s1'low);
BEGIN
tb(s1'low) := not(en);
V := s1;
for i in (V'low + 1) to V'high loop
tb(i) := V(i - 1) or tb(i -1);
end loop;
for i in V'low to V'high loop
if(tb(i) = '0') then
V(i) := not(V(i));
end if;
end loop;
return V;
end dcr_vec; -- end function
FUNCTION all_ones(s1:std_logic_vector)
return std_logic is
--this function tells if all bits of a vector are '1'
--return value Z is '1', then vector has all 1 bits
--VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
VARIABLE Z : std_logic;
BEGIN
Z := s1(s1'low);
FOR i IN (s1'low+1) to s1'high LOOP
Z := Z AND s1(i);
END LOOP;
RETURN Z;
END all_ones; -- end function
FUNCTION all_zeros(s1:std_logic_vector)
return std_logic is
--this function tells if all bits of a vector are '0'
--return value Z if '1', then vector has all 0 bits
--VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
VARIABLE Z : std_logic;
BEGIN
Z := '0';
FOR i IN (s1'low) to s1'high LOOP
Z := Z OR s1(i);
END LOOP;
RETURN not(Z);
END all_zeros; -- end function
FUNCTION mux1(a0:std_logic;a1:std_logic;sel:std_logic)
return std_logic is
--a 1 bit mux, handy to be used combinational assignments.
--output = a0, if sel = 0,
--output = a1,if sel = 1.
VARIABLE Z: std_logic;
BEGIN
IF(sel = '0') THEN
Z := a0;
ELSE
Z := a1;
END IF;
RETURN Z;
END mux1; -- end function
FUNCTION mux_vec(a0:std_logic_vector;a1:std_logic_vector;sel:std_logic)
return std_logic_vector is
--a vectored mux, handy to be used combinational assignments.
--output = a0, if sel = 0,
--output = a1,if sel = 1.
VARIABLE Z: std_logic_vector(a0'high downto a0'low);
BEGIN
IF(sel = '0') THEN
Z := a0;
ELSE
Z := a1;
END IF;
RETURN Z;
END mux_vec; -- end function
FUNCTION if_eq(s1:std_logic_vector;s2:std_logic_vector)
return std_logic is
--this function returns a value of '1' if the passed
--input1 vector is equal to the input2 value
--Usage:
-- mybit = if_eq(sig1,const1);
-- where sig1 and const1 are equal in widths
-- This function works only with 'constant' types
-- The function must be passed a 'constant' type
-- for its variable 'const1', otherwise potential problems may
-- arise
VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
VARIABLE Z : std_logic;
BEGIN
FOR i IN (s1'high) downto (s1'low) LOOP
V(i) := s1(i) XOR s2(i);
END LOOP;
Z := all_zeros(V);
RETURN Z;
END if_eq; -- end function
FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic)
return std_logic_vector is
--this function inverts all the bits of a vector if
--'en' is '1'.
VARIABLE Z : std_logic_vector(s1'high downto s1'low);
BEGIN
FOR i IN (s1'low) to s1'high LOOP
Z(i) := en XOR s1(i);
END LOOP;
RETURN Z;
END inv_if_one; -- end function
FUNCTION inv(s1:std_logic_vector) return
std_logic_vector is
--this function inverts all the bits of input vector
VARIABLE Z : std_logic_vector(s1'high downto s1'low);
BEGIN
FOR i IN (s1'low) to s1'high LOOP
Z(i) := NOT(s1(i));
END LOOP;
RETURN Z;
END inv; -- end function
FUNCTION twos_comp(s1:std_logic_vector)
return std_logic_vector is
VARIABLE Z : std_logic_vector(s1'high downto s1'low);
--Finds twos compliment of an std_logic_vector type.
--will do nothing to +ive numbers.(which have their msb='0'
BEGIN
Z := inv_if_one(s1,s1(s1'high));
Z := incr_vec(Z,s1(s1'high));
RETURN Z;
END twos_comp; -- end function
FUNCTION tc(s1:std_logic_vector) return
std_logic_vector is
VARIABLE Z : std_logic_vector(s1'high downto s1'low);
--Finds twos compliment of an std_logic_vector type.
--No matter input is -ive or +ive, it will always return
--output = NOT(input) + 1;
BEGIN
Z := inv(s1);
Z := incr_vec(Z,'1');
RETURN Z;
END tc; -- end function
FUNCTION myabs(s1:std_logic_vector)
return std_logic_vector is
--this function returns an absolute value of a vector
--This is same as the function 'twos_comp' above
VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
BEGIN
for i in V'low to V'high loop
V(i) := s1(i) XOR s1(s1'high);
end loop;
V := incr_vec(V,s1(s1'high));
return V;
end myabs; -- end function
FUNCTION NextGray(G1:std_logic_vector)
return std_logic_vector is
VARIABLE G2 : std_logic_vector(G1'high
downto G1'low) ;
VARIABLE B1 : std_logic_vector(G1'high
downto G1'low) ;
VARIABLE tb : std_logic_vector(G1'high
downto G1'low);
BEGIN
if(G1'length <=
2) then
assert false
report
"NextGray: Min Vector Length in Function is 3" severity error;
end if;
if(all_zeros(not(G1(G1'high))
& G1(G1'high-1 downto G1'low)) = '1') then
G2
:= (others => '0');
return
G2;
end if;
B1 := gray2bin(G1);
tb(G1'low) := not(B1(B1'low));
tb(G1'low + 1) := G1(G1'low) and B1(B1'low);
for i in (G1'low
+ 2) to G1'high loop
tb(i)
:= all_zeros( not(G1(i-1)) & G1(i-2 downto G1'low) & not(B1(B1'low))
);
end loop;
G2:=G1;
for i in G1'low
to G1'high loop
if(tb(i)
= '1') then
G2(i) := not(G2(i));
end if;
end loop;
return G2;
end NextGray; --
end function
FUNCTION sshr(s1:std_logic_vector)
return std_logic_vector is
variable r : std_logic_vector(s1'high
downto s1'low);
begin
r(r'high) := s1(s1'high);
r(r'high -1 downto
0) := s1(s1'high downto 1);
return r;
end sshr;
FUNCTION csshr(s1:std_logic_vector;s2:std_logic)
return std_logic_vector is
variable r : std_logic_vector(s1'high
downto s1'low);
begin
if(s2 = '1') then
r(r'high)
:= s1(s1'high);
r(r'high
-1 downto 0) := s1(s1'high downto 1);
else
r :=
s1;
end if;
return r;
end csshr;
FUNCTION zshr(s1:std_logic_vector)
return std_logic_vector is
variable r : std_logic_vector(s1'high
downto s1'low);
begin
r(r'high) := '0';
r(r'high -1 downto
0) := s1(s1'high downto 1);
return r;
end zshr;
FUNCTION czshr(s1:std_logic_vector;s2:std_logic)
return std_logic_vector is
variable r : std_logic_vector(s1'high
downto s1'low);
begin
if(s2 = '1') then
r(r'high)
:= '0';
r(r'high
-1 downto 0) := s1(s1'high downto 1);
else
r :=
s1;
end if;
return r;
end czshr;
--------------------------------------------------------------------------------
--IMP NOTE: the following function
zshrn is not synthesizeable at the moment
--------------------------------------------------------------------------------
FUNCTION zshrn(s1:std_logic_vector;n:integer)
return std_logic_vector is
--------------------------------------------------------------------------------
variable r : std_logic_vector(s1'high
downto s1'low);
begin
--pragma translate_off
--pragma coverage_off
if(n < 0) then
assert false
report
"zshrn: shift index is negative,can't rotate" severity error;
end if;
--pragma translate_on
--pragma coverage_on
r := s1;
if(n = 0) then
return
r;
end if;
r(r'high downto
r'high-(n-1)) := (others => '0');
r(r'high -n downto
0) := s1(s1'high downto n);
return r;
end zshrn;
FUNCTION sshrn(s1:std_logic_vector;nn:integer)
return std_logic_vector is
variable rr : std_logic_vector(s1'high
downto s1'low);
begin
--pragma translate_off
--pragma coverage_off
if(nn < 0) then
assert false
report
"sshrn: shift index is negative,can't rotate" severity error;
end if;
--pragma translate_on
--pragma coverage_on
if(nn = 0) then
rr
:= s1;
else
rr
:= (others => s1(s1'high));
for
ii in s1'high downto 0 loop
rr(ii-nn) := s1(ii);
if(ii = nn) then
exit;
end if;
end
loop;
end if;
return rr;
end sshrn;
FUNCTION shl(s1:std_logic_vector)
return std_logic_vector is
variable r : std_logic_vector(s1'high
downto s1'low);
begin
r(r'low) := '0';
r(r'high downto
1) := s1(s1'high-1 downto 0);
return r;
end shl;
FUNCTION ccitt_crc_16(s1:std_logic_vector;ser_in:std_logic)
return std_logic_vector is
--Calculates the next CRC value
as per ccitt_crc_16
--X^16 + X^12 + X^5 + 1
variable r : std_logic_vector(s1'high
downto s1'low);
begin
r(15)
:= s1(14);
r(14)
:= s1(13);
r(13)
:= s1(12);
r(12)
:= s1(11) xor s1(15) xor ser_in;
r(11)
:= s1(10);
r(10)
:= s1(9);
r(9)
:= s1(8);
r(8)
:= s1(7);
r(7)
:= s1(6);
r(6)
:= s1(5);
r(5)
:= s1(4) xor s1(15) xor ser_in;
r(4)
:= s1(3);
r(3)
:= s1(2);
r(2)
:= s1(1);
r(1)
:= s1(0);
r(0)
:= s1(15) xor ser_in;
return r;
end ccitt_crc_16;
FUNCTION sext(s1:std_logic_vector;nn:integer)
return std_logic_vector is
variable rr : std_logic_vector(s1'high+nn
downto s1'low);
begin
if(nn < 0) then
assert false
report
"sext: index nn is negative,can't sign extend" severity error;
end if;
rr(s1'high downto
s1'low) := s1;
for ii in s1'high+nn
downto s1'high+1 loop
rr(ii)
:= s1(s1'high);
end loop;
return rr;
END sext;
FUNCTION shln(s1:std_logic_vector;nn:integer)
return std_logic_vector is
-- shift left by nn bits, add
nn 0s to LSBs
-- Example s1 = 11111101, nn
= 3, return = 11101000
--It is in effect unsigned
multiplication by 2^nn
variable rr : std_logic_vector(s1'high
downto s1'low);
begin
if(nn < 0) then
assert false
report
"shln: shift index nn is negative,can't shift" severity error;
end if;
if(nn = 0) then
rr
:= s1;
else
rr
:= (others => '0');
for
ii in s1'high downto s1'low+1 loop
rr(ii) := s1(ii-nn);
if(ii = nn) then
exit;
end if;
end
loop;
end if;
return rr;
end shln;
FUNCTION bit_reverse(s1:std_logic_vector)
return std_logic_vector is
variable
rr : std_logic_vector(s1'high downto s1'low);
begin
for ii in s1'high
downto s1'low loop
rr(ii)
:= s1(s1'high-ii);
end loop;
return rr;
end bit_reverse;
--Function Declaration Section Ends
END fun_pkg;