extension package

M

My Name

Here's a package I've been tinkering with for a while in my spare time.
It was called "handy_pack" by I've decided to rename it.




------------------------------------------------------------------------------
--
-- author : Michael Bills ([email protected])
--
-- description : This package has functions and procedures
-- for testbenching and assisting in RTL design
-- creation. It consists mostly of conversion functions.
--
------------------------------------------------------------------------------


-- LIBRARY STATEMENT
library ieee, extension_lib;

-- PACKAGE STATEMENT
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed."abs";
use ieee.std_logic_unsigned.all;
use ieee.std_logic_textio.all;
use std.textio.all;


------------------------------------------------------------------------------
package extension_pack is
------------------------------------------------------------------------------


------------------------------------------------------------------------------
-- Type Declarations
------------------------------------------------------------------------------
type hexchar is ('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');

type hex is array (positive range <>) of hexchar;

type LED_Char is (' ', '"', ''', '-', '.', '/', '0', '1',
'2', '3', '4', '5', '6', '7', '8', '9',
'=', '?', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'O', 'P',
'S', 'T', 'U', 'Y', 'Z', '\', ']', '^',
'_', 'b', 'c', 'd', 'h', 'g', 'j', 'l',
'n', 'o', 'r', 'u', '¬', '­', '¯', '°',
'·');

type SevenSegLED is array (positive range <>) of LED_Char;


type frequency is range -1 to 2_147_483_647
units
Hz;
daHz = 10 Hz; -- dekahertz 10E+1
hHz = 10 daHz; -- hectohertz 10E+2
kHz = 10 hHz; -- kilohertz 10E+3
MHz = 1000 kHz; -- megahertz 10E+6
GHz = 1000 MHz; -- gigahertz 10E+9
end units;


------------------------------------------------------------------------------
-- Subtype Declarations
------------------------------------------------------------------------------
--subtype bv is bit_vector;
--subtype char is character;
---- synopsys translate_off
--subtype fok is file_open_kind;
--subtype fos is file_open_status;
--subtype freq is frequency;
---- synopsys translate_on
--subtype int is integer;
--subtype nat is natural;
--subtype pos is positive;
--subtype sl is std_logic;
--subtype slv is std_logic_vector;
--subtype str is string;
--subtype sul is std_ulogic;
--subtype sulv is std_ulogic_vector;
--subtype uns is unsigned;


------------------------------------------------------------------------------
-- Constant Declarations
------------------------------------------------------------------------------
-- count_for_time base size (60 means the timebase = 10E-60 seconds)
-- this value should be increased if round off error occurs
-- in a value computed by the function "count_for_time" or if
-- array length errors similar to this occur:
-- # ** Fatal: (vsim-3420) Array lengths do not match. Left is (96 downto 0). Right is (97 downto 0).
--
-- This value must be smaller than MAX_VECT_SIZE by a factor of 4 for
-- logic vectors 2 bits long and it must be smaller by a factor of 3.5 for
-- logic vectors longer than 2 bits

constant CFT_BASE_SIZE : natural := 30;


-- this value represents the largest size a logic vector may be for certain
-- functions and procedures in this package. It is used to set upper loop
-- limits for non-deterministic values thus avoiding the use of access
-- types and enabling the functions to be used for synthesizeable code.
--
-- This value may be increased (as high as natural'high will allow)
-- if a larger value needs to be represented, or it may be decreased
-- if compile time is excessive by modifying the CFT_BASE_SIZE constant

constant MAX_VECT_SIZE : natural := CFT_BASE_SIZE*4;


------------------------------------------------------------------------------
-- Function Declarations
------------------------------------------------------------------------------

--function "/"(Dividend : std_logic_vector;
-- Divisor : std_logic_vector) return std_logic_vector; -- synthesizeable version

function "/"(DividendVal : std_logic_vector;
DivisorVal : std_logic_vector) return std_logic_vector;

function bcd_to_led(slvVal : std_logic_vector ;
CAVal : boolean) return std_logic_vector; -- binary coded decimal to seven segment LED conversion

function bcd_to_slv(vectorVal : std_logic_vector) return std_logic_vector; -- returns a packed BCD number in std_logic_vector form from the std_logic_vector passed to it using enough BCD digits to represent the largest value possible in the range of the vector passed

function bcd_to_slv_pipe(BCD_RVal : std_logic_vector;
BCD_DigitsVal : integer) return std_logic_vector; -- returns a packed BCD number in std_logic_vector form from the std_logic_vector passed to it using the number of BCD digits specified. For pipelined operation. function must be called N times where N is the number of bits in the passed value

function bv_to_slv(bitVectVal : bit_vector) return std_logic_vector; -- repackaging of "To_StdLogicVector" function

function ceil(RealVal : in real ) return real; -- rounds a real value up the the next highest real integer

function cfi(intVal : integer) return natural;

function conv_to_hex(vectorVal : bit_vector) return string; -- bit_vector to hexadecimal conversion
function conv_to_hex(vectorVal : std_logic_vector) return string; -- std_logic_vector to hexadecimal conversion
function conv_to_hex(vectorVal : std_ulogic_vector) return string; -- std_ulogic_vector to hexadecimal conversion

function cft(timeStrVal : string;
freqStrVal : string) return std_logic_vector; -- count for the time specified using the frequency (or period) value passed as a reference
function cfth(timeStrVal : string;
freqStrVal : string) return integer; -- returns the high value to be used in the range declaration of a vector used to represent the time specified using the frequency (or period) value passed as a reference

function cslv(int1Val : integer;
int2Val : integer) return std_logic_vector; -- repackaging of "conv_std_logic_vector"
function cslv(sigVal : signed;
intVal : integer) return std_logic_vector; -- repackaging of "conv_std_logic_vector"
function cslv(usgVal : unsigned;
intVal : integer) return std_logic_vector; -- repackaging of "conv_std_logic_vector"

function dpfi(intVal : integer) return natural; -- returns the number of decimal places for an integer value
function dpfr(realVal : real) return natural; -- returns the number of decimal places to the left of the decimal point for a real value

function dpfslvr(vectorVal : std_logic_vector) return natural; -- returns the number of decimal places needed to represent the full range of the std_logic_vector passed
function dpfslvv(vectorVal : std_logic_vector) return natural; -- returns the number of decimal places needed to represent the value of the std_logic_vector passed

function flip(vectorVal : bit_vector) return bit_vector; -- returns a bit_vector with all the bits in the reverse order
function flip(vectorVal : std_logic_vector) return std_logic_vector; -- returns a std_logic_vector with all the bits in the reverse order
function flip(vectorVal : std_ulogic_vector) return std_ulogic_vector; -- returns a std_ulogic_vector with all the bits in the reverse order

function hex_to_slv(stringVal : string) return std_logic_vector; -- converts a Hexadeximal string to a standard logic vector

function int_to_slv(intVal : integer) return std_logic_vector; -- returns a std_logic_vector value just large enough to represent the integer value passed

function mult_s(Multiplier : std_logic_vector;
Multiplicand : std_logic_vector) return std_logic_vector; -- signed multiply
function mult_us(Multiplier : std_logic_vector;
Multiplicand : std_logic_vector) return std_logic_vector; -- unsigned multiply

function nat_to_slv(natVal : natural) return std_logic_vector; -- returns a std_logic_vector value just large enough to represent the natural value passed

function neg(VectorVal : std_logic_vector) return std_logic_vector; -- returns the negated value

function reduce(vectorVal : std_logic_vector) return std_logic_vector; -- returns a std_logic_vector value just large enough to represent the standard logic vector value passed
function reduce_high(vectorVal : std_logic_vector) return integer; -- returns a std_logic_vector value just large enough to represent the standard logic vector value passed

function seq(str1Val : string;
str2Val : string) return boolean;

function shl(vectorVal : std_logic_vector;
natVal : natural) return std_logic_vector;

function slv_to_bcd(vectorVal : std_logic_vector;
BCD_DigitsVal : integer) return std_logic_vector; -- returns a packed BCD number in std_logic_vector form from the std_logic_vector passed to it using the number of BCD digits specified
function slv_to_bcd(vectorVal : std_logic_vector) return std_logic_vector; -- returns a packed BCD number in std_logic_vector form from the std_logic_vector passed to it using enough BCD digits to represent the largest value possible in the range of the vector passed

function slv_to_bcd_pipe(BCD_RVal : std_logic_vector;
MSB_Val : std_logic;
BCD_DigitsVal : integer) return std_logic_vector; -- returns a packed BCD number in std_logic_vector form from the std_logic_vector passed to it using the number of BCD digits specified. For pipelined operation. function must be called N times where N is the number of bits in the passed value

function str_to_int(stringVal : string) return integer; -- converts an Integer string to an integer

function str_to_slv(stringVal : string) return std_logic_vector; -- converts an Integer, in string form, of any length to a std_logic_vector
function str_to_slv_high(stringVal : string) return integer; -- returns an integer representing the length of a vector needed to represent the intever value (in string form) passed
function str_to_slv_var_base(stringVal : string;
intVal : integer) return std_logic_vector; -- converts an Integer, in string form, of any length to a std_logic_vector using the time base passed
function str_to_slv_var_base_high(stringVal : string;
intVal : integer) return integer; -- returns an integer representing the length of a vector needed to represent the intever value (in string form) passed using the timebase value



function str_to_led(stringVal : string;
CAVal : boolean) return std_logic_vector; -- converts a Hexadecimal string of any length to a std_logic_vector for seven segment LEDs

-- synopsys translate_off
function time_to_slv(timeVal : time;
clkFreqVal : frequency) return std_logic_vector;
-- synopsys translate_on

function to_int(vectorVal : std_logic_vector) return integer; -- repackaging of "conv_integer" function

function to_period(freqVal : frequency) return time; -- returns a one cycle period value for a given frequency

-- synopsys translate_off
function to_string(intVal : integer) return string; -- returns a string value for an integer value passed
function to_string(realVal : real) return string; -- returns a string value for an real value passed
function to_string(vectorVal : std_logic_vector) return string;
-- synopsys translate_on

function vhfi(intVal : integer) return natural; -- returns the high value to be used in the range declaration of a vector used to represent the integer value passed. This assumes the rest of the range declaration of the vector will be "downto 0"
function vhfn(natVal : natural) return natural; -- returns the high value to be used in the range declaration of a vector used to represent the natural value passed. This assumes the rest of the range declaration of the vector will be "downto 0"

function vlfi(intVal : integer) return natural; -- returns an integer representing the length of a vector needed to represent the integer value passed
function vlfn(natVal : natural) return natural; -- returns an integer representing the length of a vector needed to represent the natural value passed

function vrfi(intVal : integer) return std_logic_vector; -- returns a std_logic_vector with a range just large enough to represent the integer value passed

function vrfn(natVal : natural) return std_logic_vector; -- returns a std_logic_vector with a range just large enough to represent the natural value passed

------------------------------------------------------------------------------
-- Procedure Declarations
------------------------------------------------------------------------------
-- synopsys translate_off
procedure clkgen(
constant clkFreqSig : in frequency;
signal clkSig : out std_logic);

procedure clkgen(
signal clkEnSig : in boolean;
signal clkFreqSig : in frequency;
signal clkSig : out std_logic);

procedure clkgen(
signal clkEnSig : in boolean;
signal clkPeriodSig : in time;
constant clkDutySig : in real;
signal clkResetSig : in boolean;
signal clkSig : inout std_logic);

procedure clkgen(
signal clkEnSig : in boolean;
signal clkFreqSig : in frequency;
constant clkDutySig : in real;
signal clkResetSig : in boolean;
signal clkSig : inout std_logic);
-- synopsys translate_on

procedure FF(
signal Clk : in std_logic;
signal Rst : in std_logic;
signal D : in std_logic_vector;
signal Q : out std_logic_vector);

procedure slv_to_bcd(
signal BCD_RIn : in std_logic_vector;
signal BinIn : in std_logic_vector;
signal BinFBIn : in std_logic_vector;
signal ClkIn : in std_logic;
constant BCD_DigitsVal : in integer;
signal EnIn : in std_logic;
signal RstLowIn : in std_logic;
signal BCD_ROut : out std_logic_vector;
signal Bin_ROut : out std_logic_vector;
signal DoneOut : out std_logic);


------------------------------------------------------------------------------
-- Aliases
------------------------------------------------------------------------------
alias bv is bit_vector;
-- synthesis translate_off
--alias cft is count_for_time[string,string return std_logic_vector]; -- synplify doesn't like "[" or "]"
--alias cfth is count_for_time_high[string,string return integer];
-- synthesis translate_on
alias char is character;
-- synopsys translate_off
alias fok is file_open_kind;
alias fos is file_open_status;
alias freq is frequency;
-- synopsys translate_on
alias int is integer;
alias nat is natural;
alias pos is positive;
alias sl is std_logic;
alias slv is std_logic_vector;
alias str is string;
alias sul is std_ulogic;
alias sulv is std_ulogic_vector;
alias uns is unsigned;


------------------------------------------------------------------------------
end extension_pack;
------------------------------------------------------------------------------


------------------------------------------------------------------------------
package body extension_pack is
------------------------------------------------------------------------------


------------------------------------------------------------------------------
--
-- Functions
--
------------------------------------------------------------------------------


------------------------------------------------------------------------------
--
-- FUNCTION NAME : "/"
--
-- DESCRIPTION : This function divides an unsigned std_logic vector value
-- by another unsigned std_logic_vector value
--
-- NOTES : the algorithm used in this function
-- is the standard long division algorithm.
-- it rounds to the nearest value
--
------------------------------------------------------------------------------
function "/"(DividendVal : std_logic_vector;
DivisorVal : std_logic_vector) return std_logic_vector is
variable DividendVar : std_logic_vector(DividendVal'length+DivisorVal'length downto 0);
variable DivisorVar : std_logic_vector(DivisorVal'length downto 0);
variable InterimVar : std_logic_vector(DivisorVal'length downto 0);
variable loopVar : integer;
variable ResultVar : std_logic_vector(DividendVal'length downto 0);
begin
DividendVar := ext(DividendVal & '0',DividendVar'length);
DivisorVar := '0' & DivisorVal;
InterimVar := '0' & DividendVar(DividendVar'high downto DividendVar'high-(DivisorVar'length-2));
ResultVar := (others => '0');
for loopVar in ResultVar'range loop
if (InterimVar >= DivisorVar) then
InterimVar := InterimVar - DivisorVar;
InterimVar := InterimVar(InterimVar'high-1 downto 0) & DividendVar(loopVar);
ResultVar(loopVar) := '1';
else
InterimVar := InterimVar(InterimVar'high-1 downto 0) & DividendVar(loopVar);
ResultVar(loopVar) := '0';
end if;
end loop;
if (InterimVar >= DivisorVal) then -- it the remainder is at least 1/2 of the Divisor (it was effectively multiplied by two during the final pass through the loop)
ResultVar := ResultVar + '1'; -- then round up to the next value
end if;
return ResultVar(ResultVar'length-2 downto 0);
end "/";


------------------------------------------------------------------------------
--
-- FUNCTION NAME : "/"
--
-- DESCRIPTION : This function divides a std_logic vector value by
-- another std_logic_vector value
--
--
-- NOTES : this function is synthesizable
--
------------------------------------------------------------------------------
--function "/"(DividendVal : STD_LOGIC_VECTOR;
-- DivisorVal : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
--
--variable B : STD_LOGIC_VECTOR(DivisorVal'length - 1 downto 0);
--variable A : STD_LOGIC_VECTOR(DividendVal'length - 1 downto 0);
--variable QUOTIENT, REMAINDER : STD_LOGIC_VECTOR(DivisorVal'length - 1 downto 0);
--variable VECT : STD_LOGIC_VECTOR(DividendVal'length downto 0);
--variable QI : STD_LOGIC_VECTOR(0 downto 0);
--variable OVFL : STD_LOGIC;
--
--function div(A: STD_LOGIC_VECTOR;
-- B: STD_LOGIC_VECTOR;
-- Q: STD_LOGIC_VECTOR;
-- EXT: STD_LOGIC) return STD_LOGIC_VECTOR is
--
--variable R : STD_LOGIC_VECTOR(A'length - 2 downto 0);
--variable RESIDUAL : STD_LOGIC_VECTOR(A'length - 1 downto 0);
--variable QN : STD_LOGIC_VECTOR(Q'length downto 0);
--variable S : STD_LOGIC_VECTOR(B'length + Q'length downto 0);
--
--function div1(A: STD_LOGIC_VECTOR;
-- B: STD_LOGIC_VECTOR;
-- Q: STD_LOGIC_VECTOR;
-- EXT: STD_LOGIC) return STD_LOGIC_VECTOR is
--variable S : STD_LOGIC_VECTOR(A'length downto 0);
--variable REST : STD_LOGIC_VECTOR(A'length - 1 downto 0);
--variable QN : STD_LOGIC_VECTOR(Q'length downto 0);
--
--begin
-- S := EXT & A - B;
--
-- QN := Q & (not S(S'high));
-- if S(S'high) = '1' then
-- REST := A;
-- else
-- REST := S(S'high - 1 downto 0);
-- end if;
-- return QN & REST;
--end div1;
--
--begin
-- S := div1(A(A'high downto A'high - B'high), B, Q, EXT);
-- QN := S(S'high downto B'high + 1);
--
-- if A'length > B'length then
-- R := S(B'high - 1 downto 0) & A(A'high - B'high - 1 downto 0);
-- return DIV(R, B, QN, S(B'high)); -- save MSB '1' in the rest for future sum
-- else
-- RESIDUAL := S(B'high downto 0);
-- return QN(QN'high - 1 downto 0) & RESIDUAL; -- delete initial '0'
-- end if;
--end div;
--
--begin
-- A := DividendVal; -- it is necessary to avoid errors during synthesis!!!!
-- B := DivisorVal;
-- QI := (others =>'0');
--
-- VECT := div(A, B, QI, '0');
--
-- QUOTIENT := VECT(VECT'high - 1 downto B'high + 1);
-- REMAINDER := VECT(B'high downto 0);
-- OVFL := VECT(VECT'high );
-- return OVFL & QUOTIENT & REMAINDER;
---- return VECT;
--
--end "/";



------------------------------------------------------------------------------
--
-- FUNCTION NAME : bcd_to_led
--
-- DESCRIPTION : This function converts a packed BCD vector into a seven
-- segment LED output
--
-- NOTES if the CAVal boolean input is true the output will
-- be for a Common Anode (1=off) display, otherwise it will
-- be for a Common Cathode (1=on)display.
-- _____
-- | a |
-- f| |b
-- |_____|
-- | g |
-- e| |c
-- |_____|
-- d
--
-- "width mismatch" errors are due to improper sizing of the vector
-- that this function is assigned to
--
------------------------------------------------------------------------------
function bcd_to_led(slvVal : std_logic_vector ; CAVal : boolean) return std_logic_vector is
variable loopVar : integer;
variable resultVar : std_logic_vector(7*slvVal'length/4-1 downto 0);
variable vectorParseVar : std_logic_vector(3 downto 0);
variable vectorVar : std_logic_vector(slvVal'length-1 downto 0);
begin
vectorVar := slvVal; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
for loopVar in 0 to slvVal'length/4-1 loop
vectorParseVar := vectorVar(4*loopVar+3 downto 4*loopVar);
case vectorParseVar is
-- Illuminated
-- vector Segment
-- value abcdefg
when "0000" => resultVar(7*loopVar+6 downto 7*loopvar) := "1111110"; -- 0
when "0001" => resultVar(7*loopVar+6 downto 7*loopvar) := "0110000"; -- 1
when "0010" => resultVar(7*loopVar+6 downto 7*loopvar) := "1101101"; -- 2
when "0011" => resultVar(7*loopVar+6 downto 7*loopvar) := "1111001"; -- 3
when "0100" => resultVar(7*loopVar+6 downto 7*loopvar) := "0110011"; -- 4
when "0101" => resultVar(7*loopVar+6 downto 7*loopvar) := "1011011"; -- 5
when "0110" => resultVar(7*loopVar+6 downto 7*loopvar) := "1011111"; -- 6
when "0111" => resultVar(7*loopVar+6 downto 7*loopvar) := "1110010"; -- 7
when "1000" => resultVar(7*loopVar+6 downto 7*loopvar) := "1111111"; -- 8
when "1001" => resultVar(7*loopVar+6 downto 7*loopvar) := "1110011"; -- 9
when others =>
end case;
end loop;
if (CAVal) then
return not resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
else
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end if;
end bcd_to_led;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : bcd_to_slv
--
-- DESCRIPTION : This function converts a packed binary coded decimal (BCD)
-- in standard logic vector for and returns an unsigned,
-- decending range, binary value
--
-- NOTES
--
-- "width mismatch" errors are due to improper sizing of the vector
-- that this function is assigned to
------------------------------------------------------------------------------
function bcd_to_slv(vectorVal : std_logic_vector) return std_logic_vector is
type BCDArrayType is array(vectorVal'length downto 0) -- array depth is 1 level more than the input vector
of std_logic_vector(vectorVal'length-1 downto 0); --
variable CarryVar : std_logic_vector
(vectorVal'length/4 downto 0); -- the # of carry bits is determined by the number of BCD digits
variable BCD_WoCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if no carry to the next BCD Digit is needed
variable BCD_WiCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if carry to the next BCD Digit is needed
variable InnrLoopVar : integer := 0; -- inner loop index variable
variable OutrLoopVar : integer := 0; -- outer loop index variable
variable BCDVar : BCDArrayType; -- BCD value array
variable ResultVar : std_logic_vector(vectorVal'length-1 downto 0);
begin
BCDVar(0) := vectorVal; -- set the initial entry in the array to the input vector
for OutrLoopVar in 1 to vectorVal'length loop --
CarryVar(CarryVar'high) := '0';
for InnrLoopVar in CarryVar'high-1 downto 0 loop -- start at the MSB of the BCD vector
BCD_WoCarVar := '0' & BCDVar(OutrLoopVar-1) -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
(4*InnrLoopVar+3 downto 4*InnrLoopVar+1); -- read the results of the previous calculation
BCD_WiCarVar := BCD_WoCarVar + "0101"; -- compute the result for the current BCD digit if carry is needed
CarryVar(InnrLoopVar) := BCDVar(OutrLoopVar-1)(4*InnrLoopVar); -- read in the next bit of the LSB of the previous BCD digit input into the lowest carry bit
if (CarryVar(InnrLoopVar+1) = '1') then -- if the the previous digit has a carry bit then then the result of the binary shift right is greater by 5
BCDVar(OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar) := BCD_WiCarVar;
else -- otherwise
BCDVar(OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar) := BCD_WoCarVar; -- we shift the bits right by 1 space
end if;
end loop;
ResultVar(OutrLoopVar-1) := BCDVar(OutrLoopVar-1)(0);
end loop;
return ResultVar;
end bcd_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : bcd_to_slv_pipe
--
-- DESCRIPTION : This function converts a packed binary coded decimal (BCD)
-- into an unsigned, decending range,
-- binary value into a standard logic vector and returns the result in
-- the number BCD digits required to represent the maximum
-- unsigned value possible in the vector passed to it.
-- it is for use in pipelined implementations where
-- the binary coded decimal output is registered
-- and passed back to the function along with the binary
-- vector input to be shifted out of its MSB
-- register and into the function as a new bit.
--
--
-- NOTES
-- BCD_DigitsVal -> dpfslvr(vectorVal)
------------------------------------------------------------------------------
function bcd_to_slv_pipe(
BCD_RVal : std_logic_vector; -- registered output of this function fed back in
BCD_DigitsVal : integer) return std_logic_vector is -- binary coded decimal arithmetic shift right
variable BCDVar : std_logic_vector(BCD_RVal'length-1 downto 0);
variable CarryVar : std_logic_vector(BCD_DigitsVal downto 0) := (others => '0'); -- the # of carry bits is determined by the number of BCD digits
variable BCD_WoCarVar : std_logic_vector(3 downto 0);
variable BCD_WiCarVar : std_logic_vector(3 downto 0);
variable ResultVar : std_logic_vector(4*BCD_DigitsVal-1 downto 0);
begin
BCDVar := BCD_RVal;
CarryVar(CarryVar'high) := '0';
for loopVar in BCD_DigitsVal-1 downto 0 loop
BCD_WoCarVar := '0' & BCDVar(4*loopVar+3 downto 4*loopVar+1);
BCD_WiCarVar := BCD_WoCarVar + "0101";
CarryVar(loopVar) := BCDVar(4*loopVar);
if (CarryVar(loopVar+1) = '1') then
ResultVar(4*loopVar+3 downto 4*loopVar) := BCD_WiCarVar;
else
ResultVar(4*loopVar+3 downto 4*loopVar) := BCD_WoCarVar;
end if;
end loop;
return ResultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end bcd_to_slv_pipe;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : bv_to_slv (convert integer to std_logic_vector)
--
-- DESCRIPTION : This function converts an integer (int1Val)
-- to a std logic vector of length int2Val.
--
-- NOTES
--
------------------------------------------------------------------------------
function bv_to_slv(bitVectVal : bit_vector) return std_logic_vector is
begin
return To_StdLogicVector(bitVectVal);
end bv_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : ceil (convert integer to std_logic_vector)
--
-- DESCRIPTION : This function rounds a real value up to the next
-- real integer
--
-- NOTES
--
------------------------------------------------------------------------------
function ceil (RealVal : in real) return real is
constant integerMaxVal : real := real(2_147_483_647);
variable RoundVar : real;
variable ResultVar : real;
begin
RoundVar := real(integer(RealVal));
if (abs(RealVal) >= integerMaxVal) then
ResultVar := RealVal;
elsif (RoundVar = RealVal) then
ResultVar := RoundVar;
elsif (RealVal > 0.0) then
if (RoundVar >= RealVal) then
ResultVar := RoundVar;
else
ResultVar := RoundVar + 1.0;
end if;
elsif (RealVal = 0.0) then
ResultVar := 0.0;
else
if (RoundVar <= RealVal) then
ResultVar := RoundVar + 1.0;
else
ResultVar := RoundVar;
end if;
end if;
return ResultVar;
end ceil;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cfi (characters for integer)
--
-- DESCRIPTION : This function returns a natural representing the
-- number of characters required to reprsent an
-- integer value. It is essentially
-- an integer'length function for the characters.
--
-- NOTES :
--
------------------------------------------------------------------------------
function cfi(intVal : integer) return natural is
variable intVar : integer;
variable CountVar : natural := 1;
variable ResultVar : natural;
begin
if (intVal < 0) then
intVar := intVal * (-1);
else
intVar := intVal;
end if;
for CountVar in 1 to MAX_VECT_SIZE loop
if (intVal = 0) then
ResultVar := 1;
exit;
elsif (intVar < 10 and intVar >= 1) then
ResultVar := CountVar;
exit;
else
intVar := intVar/10;
end if;
end loop;
if (intVal < 0) then
ResultVar := ResultVar + 1; -- allow for the '-' character
else
ResultVar := ResultVar;
end if;
return ResultVar;
end cfi;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : conv_to_hex
--
-- DESCRIPTION : This function converts a bit vector of any length to a
-- string representing the Hexadecimal value of that vector
-- NOTES
--
------------------------------------------------------------------------------
function conv_to_hex(vectorVal : bit_vector) return string is
variable loopVar : integer;
variable resultVar : string(integer(ceil(real(vectorVal'length)/4.0)) downto 1);
variable vectorParseVar : std_logic_vector(4 downto 1);
variable vectorStretchVar : std_logic_vector((integer(ceil(real(vectorVal'length)/4.0)))*4 downto 1);
variable VectorVar : bit_vector(vectorVal'length-1 downto 0);
begin
VectorVar := vectorVal;
vectorStretchVar := ext(to_stdlogicvector(VectorVar),vectorStretchVar'length);
for loopVar in resultVar'range loop
vectorParseVar := vectorStretchVar(loopVar*4 downto loopVar*4-4);
case vectorParseVar(4 downto 1) is
when "0000" => resultVar(loopVar) := '0';
when "0001" => resultVar(loopVar) := '1';
when "0010" => resultVar(loopVar) := '2';
when "0011" => resultVar(loopVar) := '3';
when "0100" => resultVar(loopVar) := '4';
when "0101" => resultVar(loopVar) := '5';
when "0110" => resultVar(loopVar) := '6';
when "0111" => resultVar(loopVar) := '7';
when "1000" => resultVar(loopVar) := '8';
when "1001" => resultVar(loopVar) := '9';
when "1010" => resultVar(loopVar) := 'A';
when "1011" => resultVar(loopVar) := 'B';
when "1100" => resultVar(loopVar) := 'C';
when "1101" => resultVar(loopVar) := 'D';
when "1110" => resultVar(loopVar) := 'E';
when "1111" => resultVar(loopVar) := 'F';
when others =>
end case;
end loop;
return resultVar;
end conv_to_hex;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : conv_to_hex
--
-- DESCRIPTION : This function converts a logic vector of any length to a
-- string representing the Hexadecimal value of that vector
-- NOTES
--
------------------------------------------------------------------------------
function conv_to_hex(vectorVal : std_logic_vector) return string is
variable loopVar : integer;
variable resultVar : string(integer(ceil(real(vectorVal'length)/4.0)) downto 1);
variable vectorParseVar : std_logic_vector(4 downto 1);
variable vectorStretchVar : std_logic_vector((integer(ceil(real(vectorVal'length)/4.0)))*4 downto 1);
variable VectorVar : std_logic_vector(vectorVal'length-1 downto 0);
begin
VectorVar := vectorVal;
vectorStretchVar := ext(VectorVar,vectorStretchVar'length);
for loopVar in resultVar'range loop
vectorParseVar := vectorStretchVar(loopVar*4 downto loopVar*4-4);
case vectorParseVar(4 downto 1) is
when "0000" => resultVar(loopVar) := '0';
when "0001" => resultVar(loopVar) := '1';
when "0010" => resultVar(loopVar) := '2';
when "0011" => resultVar(loopVar) := '3';
when "0100" => resultVar(loopVar) := '4';
when "0101" => resultVar(loopVar) := '5';
when "0110" => resultVar(loopVar) := '6';
when "0111" => resultVar(loopVar) := '7';
when "1000" => resultVar(loopVar) := '8';
when "1001" => resultVar(loopVar) := '9';
when "1010" => resultVar(loopVar) := 'A';
when "1011" => resultVar(loopVar) := 'B';
when "1100" => resultVar(loopVar) := 'C';
when "1101" => resultVar(loopVar) := 'D';
when "1110" => resultVar(loopVar) := 'E';
when "1111" => resultVar(loopVar) := 'F';
when others =>
end case;
end loop;
return resultVar;
end conv_to_hex;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : conv_to_hex
--
-- DESCRIPTION : This function converts a ulogic vector of any length to a
-- string representing the Hexadecimal value of that vector
-- NOTES
--
------------------------------------------------------------------------------
function conv_to_hex(vectorVal : std_ulogic_vector) return string is
variable loopVar : integer;
variable resultVar : string(integer(ceil(real(vectorVal'length)/4.0)) downto 1);
variable vectorParseVar : std_logic_vector(4 downto 1);
variable vectorStretchVar : std_logic_vector((integer(ceil(real(vectorVal'length)/4.0)))*4 downto 1);
variable VectorVar : std_ulogic_vector(vectorVal'length-1 downto 0);
begin
VectorVar := vectorVal;
vectorStretchVar := ext(to_stdlogicvector(VectorVar),vectorStretchVar'length);
for loopVar in resultVar'range loop
vectorParseVar := vectorStretchVar(loopVar*4 downto loopVar*4-4);
case vectorParseVar(4 downto 1) is
when "0000" => resultVar(loopVar) := '0';
when "0001" => resultVar(loopVar) := '1';
when "0010" => resultVar(loopVar) := '2';
when "0011" => resultVar(loopVar) := '3';
when "0100" => resultVar(loopVar) := '4';
when "0101" => resultVar(loopVar) := '5';
when "0110" => resultVar(loopVar) := '6';
when "0111" => resultVar(loopVar) := '7';
when "1000" => resultVar(loopVar) := '8';
when "1001" => resultVar(loopVar) := '9';
when "1010" => resultVar(loopVar) := 'A';
when "1011" => resultVar(loopVar) := 'B';
when "1100" => resultVar(loopVar) := 'C';
when "1101" => resultVar(loopVar) := 'D';
when "1110" => resultVar(loopVar) := 'E';
when "1111" => resultVar(loopVar) := 'F';
when others =>
end case;
end loop;
return resultVar;
end conv_to_hex;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cft (count_for_time)
--
-- DESCRIPTION : This function takes a string based time value and
-- converts it to a std_logic_vector value using
-- a string based frequency value, as a reference
-- NOTES
--
------------------------------------------------------------------------------
function cft(timeStrVal : string;
freqStrVal : string) return std_logic_vector is
variable freqStrVar : std_logic_vector(str_to_slv_var_base_high(freqStrVal,CFT_BASE_SIZE) downto 0);
variable timeVar : std_logic_vector(str_to_slv_var_base_high(timeStrVal,CFT_BASE_SIZE) downto 0);
begin
freqStrVar := str_to_slv_var_base(freqStrVal,CFT_BASE_SIZE);
timeVar := str_to_slv_var_base(timeStrVal,CFT_BASE_SIZE);
return reduce(timeVar/freqStrVar);
end cft;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cfth (count_for_time_high)
--
-- DESCRIPTION : This function takes a string based time value and
-- converts it to a std_logic_vector value using
-- the a string based period value, as a reference
-- NOTES
--
------------------------------------------------------------------------------
function cfth(timeStrVal : string;
freqStrVal : string) return integer is
variable freqStrVar : std_logic_vector(str_to_slv_var_base_high(freqStrVal,CFT_BASE_SIZE) downto 0);
variable timeVar : std_logic_vector(str_to_slv_var_base_high(timeStrVal,CFT_BASE_SIZE) downto 0);
begin
freqStrVar := str_to_slv_var_base(freqStrVal,CFT_BASE_SIZE);
timeVar := str_to_slv_var_base(timeStrVal,CFT_BASE_SIZE);
return reduce_high(timeVar/freqStrVar);
end cfth;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cslv (convert integer to std_logic_vector)
--
-- DESCRIPTION : This function converts an integer (int1Val)
-- to a std logic vector of length int2Val.
--
-- NOTES
--
------------------------------------------------------------------------------
function cslv(int1Val : integer; int2Val : integer) return std_logic_vector is
begin
return conv_std_logic_vector(int1Val,int2Val);
end cslv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cslv (convert signed to std_logic_vector)
--
-- DESCRIPTION : This function converts an signed value
-- to a std logic vector of length intVal.
--
-- NOTES
--
------------------------------------------------------------------------------
function cslv(sigVal : signed; intVal : integer) return std_logic_vector is
begin
return conv_std_logic_vector(sigVal,intVal);
end cslv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : cslv (convert integer to std_logic_vector)
--
-- DESCRIPTION : This function converts an unsigned value
-- to a std logic vector of length intVal.
--
-- NOTES
--
------------------------------------------------------------------------------
function cslv(usgVal : unsigned; intVal : integer) return std_logic_vector is
begin
return conv_std_logic_vector(usgVal,intVal);
end cslv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : dpfi (decimal places for integer)
--
-- DESCRIPTION : This function returns a natural representing the
-- number of digits in an integer value. It is essentially
-- an integer'length function.
--
-- NOTES :
--
------------------------------------------------------------------------------
function dpfi(intVal : integer) return natural is
variable intVar : integer;
variable CountVar : natural := 1;
variable ResultVar : natural;
begin
if (intVal < 0) then
intVar := intVal * (-1);
else
intVar := intVal;
end if;
for CountVar in 1 to MAX_VECT_SIZE loop
if (intVal = 0) then
ResultVar := 1;
exit;
elsif (intVar < 10 and intVar >= 1) then
ResultVar := CountVar;
exit;
else
intVar := intVar/10;
end if;
end loop;
return ResultVar;
end dpfi;



-- synthesizable version
--function dpfi(intVal : integer) return natural is
-- variable resultVar : natural;
--begin
-- if (intVal <= -1_000_000_000 or intVal >= 1_000_000_000) then
-- resultVar := 10;
-- elsif (intVal <= -100_000_000 or intVal >= 100_000_000) then
-- resultVar := 9;
-- elsif (intVal <= -10_000_000 or intVal >= 10_000_000) then
-- resultVar := 8;
-- elsif (intVal <= -1_000_000 or intVal >= 1_000_000) then
-- resultVar := 7;
-- elsif (intVal <= -100_000 or intVal >= 100_000) then
-- resultVar := 6;
-- elsif (intVal <= -10_000 or intVal >= 10_000) then
-- resultVar := 5;
-- elsif (intVal <= -1_000 or intVal >= 1_000) then
-- resultVar := 4;
-- elsif (intVal <= -100 or intVal >= 100) then
-- resultVar := 3;
-- elsif (intVal <= -10 or intVal >= 10) then
-- resultVar := 2;
-- else
-- resultVar := 1;
-- end if;
-- return resultVar;
--end dpfi;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : dpfr (decimal places for real)
--
-- DESCRIPTION : This function returns an natural representing the
-- number of digits to the left of the decimal
-- in a real value.
--
-- NOTES :
--
------------------------------------------------------------------------------
function dpfr(realVal : real) return natural is
variable CountVar : natural := 1;
variable realVar : real;
variable ResultVar : natural;
begin
if (realVal < 0.0) then
realVar := realVal * (-1.0);
else
realVar := realVal;
end if;
for CountVar in 1 to MAX_VECT_SIZE loop
if (realVal = 0.0) then
ResultVar := 1;
exit;
elsif (realVar < 10.0 and realVar >= 1.0) then
ResultVar := CountVar;
exit;
else
realVar := realVar/10.0;
end if;
end loop;
return ResultVar;
end dpfr;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : dpfslvr (decimal places for slv range)
--
-- DESCRIPTION : This function returns a natural representing the
-- number of decimal places the largest integer value that
-- can be represented by a vector will occupy.
--
-- NOTES :
--
------------------------------------------------------------------------------
function dpfslvr(vectorVal : std_logic_vector) return natural is
variable returnVar : std_logic_vector(vectorVal'length-1 downto 0) := (others => '1');
begin
return dpfi(conv_integer(returnVar));
end dpfslvr;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : dpfslvv (decimal places for slv value)
--
-- DESCRIPTION : This function returns a natural representing the
-- number of decimal places the integer value represented
-- by a vector will occupy.
--
-- NOTES :
--
------------------------------------------------------------------------------
function dpfslvv(vectorVal : std_logic_vector) return natural is
begin
return dpfi(conv_integer(vectorVal));
end dpfslvv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : flip
--
-- DESCRIPTION : This function returns a vector with all the bits
-- in the vector flipped.
-- i.e. if vectorval = 00011001
-- flip(vectorval) returns 10011000
-- NOTES
--
------------------------------------------------------------------------------
function flip(vectorVal : bit_vector) return bit_vector is
variable loopVar : integer;
variable resultVar : bit_vector(vectorVal'range);
begin
for loopVar in vectorVal'range loop
resultVar(resultVar'high-loopVar) := vectorVal(loopVar);
end loop;
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end flip;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : flip
--
-- DESCRIPTION : This function returns a vector with all the bits
-- in the vector flipped.
-- i.e. if vectorval = 00011001
-- flip(vectorval) returns 10011000
-- NOTES
--
------------------------------------------------------------------------------
function flip(vectorVal : std_logic_vector) return std_logic_vector is
variable loopVar : integer;
variable resultVar : std_logic_vector(vectorVal'range);
begin
for loopVar in vectorVal'range loop
resultVar(resultVar'high-loopVar) := vectorVal(loopVar);
end loop;
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end flip;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : flip
--
-- DESCRIPTION : This function returns a vector with all the bits
-- in the vector flipped.
-- i.e. if vectorval = 00011001
-- flip(vectorval) returns 10011000
-- NOTES
--
------------------------------------------------------------------------------
function flip(vectorVal : std_ulogic_vector) return std_ulogic_vector is
variable loopVar : integer;
variable resultVar : std_ulogic_vector(vectorVal'range);
begin
for loopVar in vectorVal'range loop
resultVar(resultVar'high-loopVar) := vectorVal(loopVar);
end loop;
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end flip;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : hex_to_slv
--
-- DESCRIPTION : This function converts a Hexadecimal value string
-- of any length to a std_logic_vector
--
-- NOTES
--
-- "width mismatch" errors are due to improper sizing of the vector
-- that this function is assigned to
------------------------------------------------------------------------------
function hex_to_slv(stringVal : string) return std_logic_vector is
variable stringVar : string(stringVal'length downto 1);
variable loopVar : integer;
variable resultVar : std_logic_vector(4*stringVal'length downto 1);
variable vectorParseVar : character;
begin
stringVar := stringVal;
for loopVar in stringVar'range loop
vectorParseVar := stringVar(loopVar);
case vectorParseVar is
when '0' => resultVar(4*loopVar downto 4*loopvar-3) := "0000";
when '1' => resultVar(4*loopVar downto 4*loopvar-3) := "0001";
when '2' => resultVar(4*loopVar downto 4*loopvar-3) := "0010";
when '3' => resultVar(4*loopVar downto 4*loopvar-3) := "0011";
when '4' => resultVar(4*loopVar downto 4*loopvar-3) := "0100";
when '5' => resultVar(4*loopVar downto 4*loopvar-3) := "0101";
when '6' => resultVar(4*loopVar downto 4*loopvar-3) := "0110";
when '7' => resultVar(4*loopVar downto 4*loopvar-3) := "0111";
when '8' => resultVar(4*loopVar downto 4*loopvar-3) := "1000";
when '9' => resultVar(4*loopVar downto 4*loopvar-3) := "1001";
when 'a' | 'A' => resultVar(4*loopVar downto 4*loopvar-3) := "1010";
when 'b' | 'B' => resultVar(4*loopVar downto 4*loopvar-3) := "1011";
when 'c' | 'C' => resultVar(4*loopVar downto 4*loopvar-3) := "1100";
when 'd' | 'D' => resultVar(4*loopVar downto 4*loopvar-3) := "1101";
when 'e' | 'E' => resultVar(4*loopVar downto 4*loopvar-3) := "1110";
when 'f' | 'F' => resultVar(4*loopVar downto 4*loopvar-3) := "1111";
when others =>
end case;
end loop;
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end hex_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : int_to_slv (convert integer to std_logic_vector)
--
-- DESCRIPTION : This function converts an integer value to a
-- std_logic_vector with a range just large enough
-- to represent it
--
-- NOTES
--
------------------------------------------------------------------------------
function int_to_slv(intVal : integer) return std_logic_vector is
begin
return conv_std_logic_vector(intVal,vlfi(intVal)); -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end int_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : mult_s
--
-- DESCRIPTION : This function multiplies an signed std_logic vector
-- value by another signed std_logic_vector value
--
-- NOTES : This function is provided for in std_logic_arith
------------------------------------------------------------------------------
function mult_s(Multiplier : std_logic_vector;
Multiplicand : std_logic_vector) return std_logic_vector is
variable loopVar : integer;
variable negVar : std_logic;
variable multiplicandVar : std_logic_vector(Multiplicand'length-1 downto 0);
variable multiplierVar : std_logic_vector(Multiplier'length+Multiplicand'length-1 downto 0);
variable resultVar : std_logic_vector(Multiplier'length+Multiplicand'length-1 downto 0);
begin
loopVar := 0;
multiplicandVar := abs(multiplicand);
multiplierVar := ext(abs(Multiplier),multiplierVar'length);
negVar := multiplier(multiplier'left) xor multiplicand(multiplicand'left);
resultVar := (others => '0');
for loopVar in 0 to multiplicandVar'length-1 loop
if (multiplicandVar(loopVar) = '1') then
resultVar := resultVar + multiplierVar;
end if;
multiplierVar := multiplierVar(multiplierVar'high-1 downto 0) & '0';
end loop;
if (negVar = '1') then
return neg(resultVar);
else
return resultVar;
end if;
end mult_s;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : mult_us
--
-- DESCRIPTION : This function multiplies an unsigned std_logic vector
-- value by another unsigned std_logic_vector value
--
-- NOTES : This function is provided for in std_logic_arith
------------------------------------------------------------------------------
function mult_us(Multiplier : std_logic_vector;
Multiplicand : std_logic_vector) return std_logic_vector is
variable loopVar : integer;
variable multiplicandVar : std_logic_vector(Multiplicand'length-1 downto 0);
variable multiplierVar : std_logic_vector(Multiplier'length+Multiplicand'length-1 downto 0);
variable resultVar : std_logic_vector(Multiplier'length+Multiplicand'length-1 downto 0);
begin
loopVar := 0;
multiplicandVar := multiplicand;
multiplierVar := ext(Multiplier,multiplierVar'length);
resultVar := (others => '0');
for loopVar in 0 to multiplicandVar'length-1 loop
if (multiplicandVar(loopVar) = '1') then
resultVar := resultVar + multiplierVar;
end if;
multiplierVar := multiplierVar(multiplierVar'high-1 downto 0) & '0';
end loop;
return resultVar;
end mult_us;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : nat_to_slv (convert natural to std_logic_vector)
--
-- DESCRIPTION : This function converts a natural value to a
-- std_logic_vector with a range just large enough
-- to represent it
--
-- NOTES
--
------------------------------------------------------------------------------
function nat_to_slv(natVal : natural) return std_logic_vector is
begin
return conv_std_logic_vector(natVal,vlfn(natVal));
end nat_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : neg
--
-- DESCRIPTION : This function toggles the sign of the value passed
--
-- NOTES :
--
------------------------------------------------------------------------------
function neg(VectorVal : std_logic_vector) return std_logic_vector is
variable oneFndVar : boolean;
variable loopVar : integer;
variable resultVar : std_logic_vector(VectorVal'length-1 downto 0);
begin
oneFndVar := false;
resultVar := VectorVal;
resultVar := not resultVar; -- invert all bits
resultVar := resultVar + '1'; -- then add one
return ResultVar;
end neg;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : reduce
--
-- DESCRIPTION : This function returns a vector with the extra sign
-- bits removed
--
-- NOTES :
--
------------------------------------------------------------------------------
function reduce(vectorVal : std_logic_vector) return std_logic_vector is
variable loopVar : integer;
variable lengthVar : integer;
variable MSBFound : boolean;
variable resultVar : std_logic_vector(vectorVal'length-1 downto 0);
begin
resultVar := vectorVal;
lengthVar := 0;
MSBFound := False;
for loopVar in resultVar'range loop -- start at the MSB of the vector and index down
if (((resultVar(resultVar'high) = '0' and resultVar(loopVar) = '1') or -- if it's a positive value then look for a bit to be '1'
(resultVar(resultVar'high) = '1' and resultVar(loopVar) = '0')) and -- or if it's a negative value look for a bit to be '0'
(MSBFound = False)) -- and the MSB hasn't been found yet
then -- and if a bit is asserted then
lengthVar := loopVar; -- this is the minimum number of bits needed to represent the absolute value.
MSBFound := True;
end if;
end loop;
lengthVar := lengthVar + 1; -- Add one for the sign bit
return resultVar(lengthVar downto 0); -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end reduce;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : reduce_high
--
-- DESCRIPTION : This function returns an integer value representing
-- the length of a sign bit reduced vector
--
-- NOTES :
--
------------------------------------------------------------------------------
function reduce_high(vectorVal : std_logic_vector) return integer is
variable interimVar : std_logic_vector(vectorVal'length-1 downto 0);
variable loopVar : integer;
variable lengthVar : integer;
variable MSBFound : boolean;
variable resultVar : std_logic_vector(MAX_VECT_SIZE downto 0);
begin
interimVar := vectorVal;
lengthVar := 0;
MSBFound := False;
resultVar := sxt(interimVar,resultVar'length); -- sign extend the value passed to the size of the slv variable
for loopVar in resultVar'range loop -- start at the MSB of the vector and index down
if (((resultVar(resultVar'high) = '0' and resultVar(loopVar) = '1') or -- if it's a positive value then look for a bit to be '1'
(resultVar(resultVar'high) = '1' and resultVar(loopVar) = '0')) and -- or if it's a negative value look for a bit to be '0'
(MSBFound = False)) -- and the MSB hasn't been found yet
then -- and if a bit is asserted then
lengthVar := loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
MSBFound := True;
end if;
end loop;
return lengthVar;
end reduce_high;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : seq (string equality function)
--
-- DESCRIPTION : This function returns true if both string values passed
-- are identical
--
-- NOTES : This function was added because the the synthesis tool
-- didn't support a boolean string equality operation test.
-- Also, adding a new overloaded operator "=" caused problems
-- with the simulator
--
------------------------------------------------------------------------------
function seq(str1Val : string;
str2Val : string) return boolean is
variable char1Var : character;
variable char2Var : character;
variable loopVar : integer;
variable resultVar : boolean;
variable str1Var : string(1 to str1Val'length);
variable str2Var : string(1 to str2Val'length);
begin
resultVar := true;
str1Var := str1Val;
str2Var := str2Val;
for loopVar in str1Var'range loop
if (str1Var(loopVar) /= str2Var(loopVar)) then
resultVar := false;
end if;
end loop;
return resultVar;
end seq;


--------------------------------------------------------------------------------
----
---- FUNCTION NAME : shift
----
---- DESCRIPTION : This function returns a std_logic_vector shifted
---- by the number of integer places specified. This provides
---- an easy way to multiply or divide by 2^(natVal)
----
----
---- NOTES
----
--------------------------------------------------------------------------------
--function shift(vectorVal : std_logic_vector;
-- intVal : integer) return std_logic_vector is
-- variable resultVar : std_logic_vector(vectorVal'length-1 downto 0);
--begin
-- resultVar := vectorVal;
-- resultVar := (others => '0');
-- resultVar(resultVar'high downto resultVar'high-vectorVal'length+1) := resultVar;
-- return resultVar;
--end shl;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : shl (shift left)
--
-- DESCRIPTION : This function returns a std_logic_vector shifted left
-- by the number of binary places specified. This provides
-- an easy way to multiply by 2^(natVal)
--
--
-- NOTES
--
------------------------------------------------------------------------------
function shl(vectorVal : std_logic_vector;
natVal : natural) return std_logic_vector is
variable interimVar : std_logic_vector(vectorVal'length-1 downto 0);
variable resultVar : std_logic_vector(vectorVal'length+natVal-1 downto 0);
begin
interimVar := vectorVal;
resultVar := (others => '0');
resultVar(resultVar'high downto resultVar'high-vectorVal'length+1) := interimVar;
return resultVar;
end shl;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : slv_to_bcd
--
-- DESCRIPTION : This function converts an unsigned, decending range,
-- std logic vector value into a
-- packed binary coded decimal (BCD)
-- standard logic vector and returns the result in
-- the number of BCD digits passed to the function.
--
-- NOTES
--
-- "width mismatch" errors are due to improper sizing of the vector
-- that this function is assigned to
--
------------------------------------------------------------------------------
function slv_to_bcd(vectorVal : std_logic_vector; BCD_DigitsVal : integer)
return std_logic_vector is
type resultArrayType is array(vectorVal'length downto 0) -- array depth is 1 level more than the input vector
of std_logic_vector(4*BCD_DigitsVal-1 downto 0); -- array width is determined by the number of BCD digits to output
variable CarryVar : std_logic_vector(BCD_DigitsVal downto 0); -- the # of carry bits is determined by the number of BCD digits
variable BCD_WoCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if the next BCD Digit is computed without carry from the current BCD value
variable BCD_WiCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if the next BCD Digit is computed with carry from the current BCD value
variable InnrLoopVar : integer := 0; -- inner loop index variable
variable OutrLoopVar : integer := 0; -- outer loop index variable
variable ResultVar : resultArrayType; -- BCD value result variable
variable VectorVar : std_logic_vector(vectorVal'length-1 downto 0);
begin
VectorVar := vectorVal;
ResultVar(0) := (others => '0'); -- set the initial entry in the results array to zero
for OutrLoopVar in VectorVar'high downto 0 loop -- start at the MSB of the std logic vector input and work down
CarryVar(0) := VectorVar(OutrLoopVar); -- read in the next bit of the slv input into the lowest carry bit
for InnrLoopVar in 0 to BCD_DigitsVal-1 loop -- start at the LSB of the BCD output
BCD_WoCarVar := ResultVar(VectorVar'length - OutrLoopVar -1) -- read the results of the previous calculation
(4*InnrLoopVar+3 downto 4*InnrLoopVar);
BCD_WiCarVar := BCD_WoCarVar - "0101"; -- compute the result for the current BCD digit if a carry to the next digit will be needed
if (BCD_WoCarVar > "0100") then -- if the digit is 5 or greater ("0101") then the result of the binary shift left "10100" = decimal 16, which is to great to represent in one BCD digit so then
CarryVar(InnrLoopVar+1) := '1'; -- we carry a digit to the next BCD digit
ResultVar(VectorVar'length - OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar)
:= BCD_WiCarVar(2 downto 0) & CarryVar(InnrLoopVar); -- and we use the lesser value for the current digit along with the carry value from the previous BCD digit
else -- otherwise the digit is small enough to be represented in one BCD digit when a binary shift in is performed
CarryVar(InnrLoopVar+1) := '0';
ResultVar(VectorVar'length - OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar)
:= BCD_WoCarVar(2 downto 0) & CarryVar(InnrLoopVar); -- so we write the value to the result variable along with any carry value from a previous BCD digit
end if;
end loop;
end loop;
return ResultVar(VectorVar'high+1); -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end slv_to_bcd;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : slv_to_bcd
--
-- DESCRIPTION : This function converts an unsigned, decending range,
-- binary value into a packed binary coded decimal (BCD)
-- standard logic vector and returns the result in
-- the number BCD digits required to represent the maximum
-- unsigned value possible in the vector passed to it
--
-- NOTES
-- BCD_DigitsVal -> dpfslvr(vectorVal)
--
-- "width mismatch" errors are due to improper sizing of the vector
-- that this function is assigned to
------------------------------------------------------------------------------
function slv_to_bcd(vectorVal : std_logic_vector) return std_logic_vector is
type resultArrayType is array(vectorVal'length downto 0) -- array depth is 1 level more than the input vector
of std_logic_vector(4*dpfslvr(vectorVal)-1 downto 0); -- array width is determined by the number of BCD digits to output
variable CarryVar : std_logic_vector
(dpfslvr(vectorVal) downto 0); -- the # of carry bits is determined by the number of BCD digits
variable BCD_WoCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if no carry to the next BCD Digit is needed
variable BCD_WiCarVar : std_logic_vector(3 downto 0); -- BCD digit variable used by the inner loop if carry to the next BCD Digit is needed
variable InnrLoopVar : integer := 0; -- inner loop index variable
variable OutrLoopVar : integer := 0; -- outer loop index variable
variable ResultVar : resultArrayType; -- BCD value result variable
variable VectorVar : std_logic_vector(vectorVal'length-1 downto 0);
begin
VectorVar := vectorVal;
ResultVar(0) := (others => '0'); -- set the initial entry in the results array to zero
for OutrLoopVar in VectorVar'high downto 0 loop -- start at the MSB of the std logic vector input and work down
CarryVar(0) := VectorVar(OutrLoopVar); -- read in the next bit of the slv input into the lowest carry bit
for InnrLoopVar in 0 to CarryVar'high-1 loop -- start at the LSB of the BCD output
BCD_WoCarVar := ResultVar(VectorVar'length - OutrLoopVar -1) -- read the results of the previous calculation
(4*InnrLoopVar+3 downto 4*InnrLoopVar);
BCD_WiCarVar := BCD_WoCarVar - "0101"; -- compute the result for the current BCD digit if a carry to the next digit will be needed
if (BCD_WoCarVar > "0100") then -- if the digit is 5 or greater ("0101") then the result of the binary shift left "10100" = decimal 16, which is to great to represent in one BCD digit so then
CarryVar(InnrLoopVar+1) := '1'; -- we carry a digit to the next BCD digit
ResultVar(VectorVar'length - OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar)
:= BCD_WiCarVar(2 downto 0) & CarryVar(InnrLoopVar); -- and we use the lesser value for the current digit along with the carry value from the previous BCD digit
else -- otherwise the digit is small enough to be represented in one BCD digit when a binary shift in is performed
CarryVar(InnrLoopVar+1) := '0';
ResultVar(VectorVar'length - OutrLoopVar)
(4*InnrLoopVar+3 downto 4*InnrLoopVar)
:= BCD_WoCarVar(2 downto 0) & CarryVar(InnrLoopVar); -- so we write the value to the result variable along with any carry value from a previous BCD digit
end if;
end loop;
end loop;
return ResultVar(VectorVar'high+1); -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end slv_to_bcd;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : slv_to_bcd_pipe
--
-- DESCRIPTION : This function converts an unsigned, decending range,
-- binary value into a packed binary coded decimal (BCD)
-- standard logic vector and returns the result in
-- the number BCD digits required to represent the maximum
-- unsigned value possible in the vector passed to it.
-- it is for use in pipelined implementations where
-- the binary coded decimal output is registered
-- and passed back to the function along with the binary
-- vector input to be shifted out of its MSB
-- register and into the function as a new bit.
--
--
-- NOTES
-- BCD_DigitsVal -> dpfslvr(vectorVal)
--
-- "width mismatch" errors here are due to improper sizing of the vector
-- that this function is assigned to
------------------------------------------------------------------------------
function slv_to_bcd_pipe(
BCD_RVal : std_logic_vector; -- registered output of this function fed back in
MSB_Val : std_logic; -- msb of binary value being shifted in
BCD_DigitsVal : integer) return std_logic_vector is -- binary coded decimal arithmetic shift left
variable BCDVar : std_logic_vector(BCD_RVal'length-1 downto 0);
variable CarryVar : std_logic_vector(BCD_DigitsVal downto 0); -- the # of carry bits is determined by the number of BCD digits
variable BCD_WoCarVar : std_logic_vector(3 downto 0);
variable BCD_WiCarVar : std_logic_vector(3 downto 0);
variable ResultVar : std_logic_vector(4*BCD_DigitsVal-1 downto 0);
begin
BCDVar := BCD_RVal;
for loopVar in 0 to BCD_DigitsVal-1 loop
CarryVar(0) := MSB_Val;
BCD_WoCarVar := BCDVar(4*loopVar+3 downto 4*loopVar);
BCD_WiCarVar := BCD_WoCarVar - "0101";
if (BCD_WoCarVar > "0100") then
CarryVar(loopVar+1) := '1';
ResultVar(4*loopVar+3 downto 4*loopVar)
:= BCD_WiCarVar(2 downto 0) & CarryVar(loopVar);
else
CarryVar(loopVar+1) := '0';
ResultVar(4*loopVar+3 downto 4*loopVar)
:= BCD_WoCarVar(2 downto 0) & CarryVar(loopVar);
end if;
end loop;
return ResultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end slv_to_bcd_pipe;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_int
--
-- DESCRIPTION : This function converts a string to an integer
--
-- NOTES :
--
------------------------------------------------------------------------------
function str_to_int(stringVal : string) return integer is
variable decPlace : integer := 1;
variable stringVar : string(1 to stringVal'length);
variable loopVar : integer;
variable negVar : boolean; -- used to indicate whether or not the string represents a negative number
variable resultVar : integer;
variable vectorParseVar : character;
begin
negVar := false;
resultVar := 0;
stringVar := stringVal;
for loopVar in stringVar'range loop
vectorParseVar := stringVar(loopVar);
case vectorParseVar is
when '-' => negVar := true;
when '0' => resultVar := (resultVar * 10) + 0;
when '1' => resultVar := (resultVar * 10) + 1;
when '2' => resultVar := (resultVar * 10) + 2;
when '3' => resultVar := (resultVar * 10) + 3;
when '4' => resultVar := (resultVar * 10) + 4;
when '5' => resultVar := (resultVar * 10) + 5;
when '6' => resultVar := (resultVar * 10) + 6;
when '7' => resultVar := (resultVar * 10) + 7;
when '8' => resultVar := (resultVar * 10) + 8;
when '9' => resultVar := (resultVar * 10) + 9;
when '.' => exit; -- ignore everything after a decimal point
when others => resultVar := resultVar;
end case;
end loop;
if (negVar) then
resultVar := -resultVar;
end if;
return resultVar;
end str_to_int;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_led
--
-- DESCRIPTION : This function converts a Seven Segment LED
-- string of any length to a std_logic_vector
--
-- NOTES : if the CAVal boolean input is true the output will
-- be for a Common Anode (1=off) display, otherwise it will
-- be for a Common Cathode (1=on)display.
--
-- _____
-- | a |
-- f| |b
-- |_____|
-- | g |
-- e| |c
-- |_____|
-- d
--
-- "width mismatch" errors here are due to improper sizing of the vector
-- that this function is assigned to
------------------------------------------------------------------------------
function str_to_led(stringVal : string;
CAVal : boolean) return std_logic_vector is
variable stringVar : string(stringVal'length downto 1);
variable loopVar : integer;
variable resultVar : std_logic_vector(7*StringVal'length downto 1);
variable vectorParseVar : character;
begin
stringVar := stringVal;
for loopVar in StringVar'range loop
vectorParseVar := StringVar(loopVar);
case vectorParseVar is
-- Illuminated
-- character Segment
-- shown abcdefg
when ' ' => resultVar(7*loopVar downto 7*loopVar-6) := "0000000";
when '"' => resultVar(7*loopVar downto 7*loopVar-6) := "0100010";
when ''' => resultVar(7*loopVar downto 7*loopVar-6) := "0100000";
when '-' => resultVar(7*loopVar downto 7*loopVar-6) := "0000001";
when '/' => resultVar(7*loopVar downto 7*loopVar-6) := "0100101";
when '0' | 'D' => resultVar(7*loopVar downto 7*loopVar-6) := "1111110";
when '1' => resultVar(7*loopVar downto 7*loopVar-6) := "0110000";
when '2' => resultVar(7*loopVar downto 7*loopVar-6) := "1101101";
when '3' => resultVar(7*loopVar downto 7*loopVar-6) := "1111001";
when '4' => resultVar(7*loopVar downto 7*loopVar-6) := "0110011";
when '5' | 'S' => resultVar(7*loopVar downto 7*loopVar-6) := "1011011";
when '6' => resultVar(7*loopVar downto 7*loopVar-6) := "1011111";
when '7' => resultVar(7*loopVar downto 7*loopVar-6) := "1110010";
when '8' | 'B' => resultVar(7*loopVar downto 7*loopVar-6) := "1111111";
when '9' => resultVar(7*loopVar downto 7*loopVar-6) := "1110011";
when '=' => resultVar(7*loopVar downto 7*loopVar-6) := "0001001";
when '?' => resultVar(7*loopVar downto 7*loopVar-6) := "1100101";
when 'A' => resultVar(7*loopVar downto 7*loopVar-6) := "1110111";
when 'C' => resultVar(7*loopVar downto 7*loopVar-6) := "1001110";
when 'E' => resultVar(7*loopVar downto 7*loopVar-6) := "1001111";
when 'F' => resultVar(7*loopVar downto 7*loopVar-6) := "1000111";
when 'G' => resultVar(7*loopVar downto 7*loopVar-6) := "1011110";
when 'H' => resultVar(7*loopVar downto 7*loopVar-6) := "0110111";
when 'I' => resultVar(7*loopVar downto 7*loopVar-6) := "0000110";
when 'J' => resultVar(7*loopVar downto 7*loopVar-6) := "1111100";
when 'L' => resultVar(7*loopVar downto 7*loopVar-6) := "0001110";
when 'O' => resultVar(7*loopVar downto 7*loopVar-6) := "1111110";
when 'P' => resultVar(7*loopVar downto 7*loopVar-6) := "1100111";
when 'T' => resultVar(7*loopVar downto 7*loopVar-6) := "1000110";
when 'U' => resultVar(7*loopVar downto 7*loopVar-6) := "0111110";
when 'Y' => resultVar(7*loopVar downto 7*loopVar-6) := "0100111";
when 'Z' => resultVar(7*loopVar downto 7*loopVar-6) := "1101101";
when '\' => resultVar(7*loopVar downto 7*loopVar-6) := "0010011";
when ']' => resultVar(7*loopVar downto 7*loopVar-6) := "1111000";
when '^' => resultVar(7*loopVar downto 7*loopVar-6) := "1100010";
when '_' => resultVar(7*loopVar downto 7*loopVar-6) := "0001000";
when 'b' => resultVar(7*loopVar downto 7*loopVar-6) := "0011111";
when 'c' => resultVar(7*loopVar downto 7*loopVar-6) := "0001101";
when 'd' => resultVar(7*loopVar downto 7*loopVar-6) := "0111101";
when 'g' => resultVar(7*loopVar downto 7*loopVar-6) := "1111011";
when 'h' => resultVar(7*loopVar downto 7*loopVar-6) := "0010111";
when 'j' => resultVar(7*loopVar downto 7*loopVar-6) := "0111100";
when 'l' => resultVar(7*loopVar downto 7*loopVar-6) := "0111000";
when 'n' => resultVar(7*loopVar downto 7*loopVar-6) := "0010101";
when 'o' => resultVar(7*loopVar downto 7*loopVar-6) := "0011101";
when 'r' => resultVar(7*loopVar downto 7*loopVar-6) := "0000101";
when 'u' => resultVar(7*loopVar downto 7*loopVar-6) := "0011100";
when '¬' => resultVar(7*loopVar downto 7*loopVar-6) := "0010001";
when '¯' => resultVar(7*loopVar downto 7*loopVar-6) := "1000000";
when '°' => resultVar(7*loopVar downto 7*loopVar-6) := "1100011";
when others =>
end case;
end loop;
if (CAVal) then
return not resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
else
return resultVar; -- "width mismatch" errors here are due to improper sizing of the vector that this function is assigned to
end if;
end str_to_led;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_slv
--
-- DESCRIPTION : This function converts an integer value string
-- of any length to a std_logic_vector
--
-- NOTES :
--
--
------------------------------------------------------------------------------
function str_to_slv(stringVal : string) return std_logic_vector is
begin
return str_to_slv_var_base(stringVal,15); -- default to 1fs time base
end str_to_slv;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_slv_high
--
-- DESCRIPTION : This function converts an integer value string
-- of any length to a std_logic_vector
--
-- NOTES
--
--
------------------------------------------------------------------------------
function str_to_slv_high(stringVal : string) return integer is
begin
return reduce_high(str_to_slv(stringVal));
end str_to_slv_high;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_slv_var_base
--
-- DESCRIPTION : This function converts an integer value string
-- of any length to a std_logic_vector
--
-- NOTES : This function supports both positive and negative numbers
-- as well as positive and negative exponents. It supports
-- multiple time unit per string as long as there are no
-- exponents used.
--
-- EXAMPLE "1 day, 3 hrs, 15.298 seconds"
-- "66,000,000 Hz" "66,000,000.000 Hz" "66 MHz" "66E6 Hz" "66E+6 Hz" "66.000E+6 Hz"
-- "66,000,000 us" "66,000,000.000 us" "66 us" "66E6 us" "66E+6 us" "66.000E+6 us"
--
--
------------------------------------------------------------------------------
function str_to_slv_var_base(stringVal : string;
intVal : integer) return std_logic_vector is
constant \10\ : std_logic_vector(3 downto 0) := "1010"; -- 10
constant \60\ : std_logic_vector(5 downto 0) := "111100"; -- 60
constant \3600\ : std_logic_vector(11 downto 0) := "111000010000"; -- 3600
constant \86400\ : std_logic_vector(16 downto 0) := "10101000110000000"; -- 86,400 (solar day)
variable baseVar : integer; -- exponent of the timebase i.e. 1fs = 1E-15 seconds so the timebase = 15
variable decPlacesVar : integer; -- used to count how many numbers are after the decimal point
variable decPntFndVar : boolean; -- used to flag whether or not a decimal point was found in the string
variable expFndVar : boolean; -- used to flag that the exponent has been reached so that the rest of the string value will not be interpreted as part of the base value
variable expVar : integer; -- used to indicated the exponent value
variable freqUnitFndVar : boolean; -- used to flag whether or not the string represents a frequency
variable loop1Var : integer; -- main string parse loop variable
variable loop2Var : integer; -- used to raise the result to whichever power of 'E' is passed
variable loop3Var : integer; -- used to scale the result based on a time unit
variable loop4Var : integer; -- used to scale the result based on how many digits were found after the decimal point
variable negVar : boolean; -- used to flag whether or not the string represents a negative number
variable resultVar : std_logic_vector(MAX_VECT_SIZE+16 downto 0);
variable result2Var : std_logic_vector(MAX_VECT_SIZE+16 downto 0); -- used to store a result from a secondary value such as would be encounter when a value such as "1 hr 10 mins" is passed to the function
variable stringVar : string(1 to stringVal'length+4); -- slightly larger because string is addessed beyond the current loop to test for units
variable timeBaseVar : std_logic_vector(MAX_VECT_SIZE+16 downto 0);
variable timeUnitFndVar : boolean; -- used to flag that a time unit was found (days, hrs, mins, secs)
variable vectorParseVar : character; -- character currently under test
begin
baseVar := intVal;
decPntFndVar := false;
decPlacesVar := 0;
expFndVar := false;
expVar := 0;
freqUnitFndVar := false;
negVar := false;
resultVar := (others => '0');
result2Var := (others => '0');
stringVar := stringVal & " "; -- tack on few extra spaces for padding so that it is possible to address beyond the current loop variable
timeUnitFndVar := false;
timeBaseVar := ext("01",timeBaseVar'length);
for loopVar in 1 to baseVar loop
timeBaseVar := mult_us(timeBaseVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
for loop1Var in stringVar'range loop
vectorParseVar := stringVar(loop1Var);
case vectorParseVar is
when '-' =>
if (not decPntFndvar and not expFndVar and not freqUnitFndVar and not timeUnitFndVar) then -- expect the sign to be near the front of the string
negVar := true;
end if;
when '0' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then -- if the decimal point was found and we're not reading an exponent then
decPlacesVar := decPlacesVar + 1; -- consider this to be a number after the decimal point
end if;
if (not expFndVar) then -- if we are not reading the exponent then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 0; -- factor in the next digit
end if;
end if;
when '1' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 1;
end if;
end if;
when '2' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 2;
end if;
end if;
when '3' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 3;
end if;
end if;
when '4' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 4;
end if;
end if;
when '5' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 5;
end if;
end if;
when '6' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 6;
end if;
end if;
when '7' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 7;
end if;
end if;
when '8' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 8;
end if;
end if;
when '9' =>
if (freqUnitFndVar) then
resultVar := resultVar; -- do nothing
elsif (timeUnitFndVar) then -- if we've already found a time unit then this must be a second time value
result2Var := ext(str_to_slv_var_base(stringVar(loop1Var to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
exit;
else
if (decPntFndVar and not expFndVar) then
decPlacesVar := decPlacesVar + 1;
end if;
if (not expFndVar) then
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\) + 9;
end if;
end if;
when 'e' | 'E' => -- exponent
if (not expFndVar and not freqUnitFndVar and not timeUnitFndVar) -- if we haven't already found an exponent, frequency unit, or time unit
then
expFndVar := true; -- mark that we've found it
expVar := str_to_int(stringVar(loop1Var to stringVal'length)); -- and capture its value
end if;
when '.' => decPntFndVar := true; -- mark the position of the decimal point
when 'p' | 'P' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 's') or
(stringVar(loop1Var+1) = 'S')))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar-12 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'n' | 'N' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 's') or
(stringVar(loop1Var+1) = 'S')))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar-9 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'u' | 'U' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 's') or
(stringVar(loop1Var+1) = 'S')))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar-6 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'm' | 'M' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 's') or
(stringVar(loop1Var+1) = 'S')))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar-3 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
elsif (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "in")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "iN")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "In")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "IN"))))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
resultVar := mult_us(resultVar(MAX_VECT_SIZE+10 downto 0), \60\);
elsif (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "hZ")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "HZ"))))
then
freqUnitFndVar := true;
for loop3Var in 1 to 6 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 's' | 'S' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "ec")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "eC")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Ec")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "EC"))))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'h' | 'H' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 'r') or
(stringVar(loop1Var+1) = 'R')))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
resultVar := mult_us(resultVar(MAX_VECT_SIZE+4 downto 0), \3600\);
elsif (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loop1Var+1) = 'z') or
(stringVar(loop1Var+1) = 'Z')))
then
freqUnitFndVar := true;
end if;
when 'd' | 'D' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "ay")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "aY")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Ay")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "AY"))))
then
timeUnitFndVar := true;
for loop3Var in 1 to baseVar loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
resultVar := mult_us(resultVar(MAX_VECT_SIZE-1 downto 0), \86400\);
end if;
when 'g' | 'G' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "hZ")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "HZ"))))
then
freqUnitFndVar := true;
for loop3Var in 1 to 9 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'k' | 'K' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "hZ")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "HZ"))))
then
freqUnitFndVar := true;
for loop3Var in 1 to 3 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 't' | 'T' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loop1Var+1 to loop1Var+2), "hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "hZ")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "Hz")) or
(seq(stringVar(loop1Var+1 to loop1Var+2), "HZ"))))
then
freqUnitFndVar := true;
for loop3Var in 1 to 12 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when others =>
end case;
end loop;
if (expVar >= 0) then -- if it's a positive exponent then perform a multiplication loop
for loop2Var in 1 to expVar loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
else -- if it's a negative exponent then perform a division loop
for loop2Var in 1 to (-expVar) loop
resultVar := resultVar / \10\;
end loop;
end if;
if (decPntFndVar) then -- if a decimal point was present in the value then
for loop4Var in 1 to decPlacesVar loop -- scale the output accordingly
resultVar := resultVar / \10\;
end loop;
end if;
resultVar := resultVar + result2Var; -- add on any secondary value
if (freqUnitFndVar) then -- the the string is a frequency value then
resultVar := timeBaseVar / resultVar; -- invert it to convert it to a period value before returning
end if;
if (negVar and not timeUnitFndVar) then -- the the string is a negative value and its not a time value then
resultVar := neg(resultVar); -- negate the result
end if;
return reduce(resultVar);
end str_to_slv_var_base;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : str_to_slv_var_base_high
--
-- DESCRIPTION : This function converts an integer value string
-- of any length to a std_logic_vector
--
-- NOTES
--
--
------------------------------------------------------------------------------
function str_to_slv_var_base_high(stringVal : string;
intVal : integer) return integer is
begin
return reduce_high(str_to_slv_var_base(stringVal,intVal));
end str_to_slv_var_base_high;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : time_to_slv (convert time to slv)
--
-- DESCRIPTION : converts a time value referenced to a clock frequency
-- to a standard logic vector value large enough to
-- represent it as a signed integer value
--
-- NOTES
-- This function does not work with Synplify
------------------------------------------------------------------------------
-- synopsys translate_off
function time_to_slv(timeVal : time;
clkFreqVal : frequency) return std_logic_vector is
variable resultVar : std_logic_vector(int_to_slv(timeVal/to_period(clkFreqVal))'range);
begin
resultVar := int_to_slv(timeVal/to_period(clkFreqVal));
return resultVar;
end time_to_slv;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : to_int
--
-- DESCRIPTION : conv_integer function repackaged
--
-- NOTES
--
------------------------------------------------------------------------------
function to_int(vectorVal : std_logic_vector) return integer is
begin
return conv_integer(vectorVal);
end to_int;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : to_period
--
-- DESCRIPTION : This function returns a one cycle period value for
-- a given frequency
--
-- NOTES timeVar must be larger than the simulator resolution
-- and is limited by the integer that can be created from
-- time'pos of it's value
--
-- the funtion does not work with Synplify 7.7
------------------------------------------------------------------------------
--function to_period(freqVal : frequency) return time is
-- variable resultVar : time;
--begin
-- resultVar := 1E9/frequency'pos(freqVal) * 1 ns; -- max of 2147.483647 ns for Precision Synthesis
-- return resultVar;
--end to_period;


--synopsys translate_on
function to_period(freqVal : frequency) return time is
variable resultVar : time;
variable timeVar : time := 1 ms;
variable divVar : real := real(1 sec/timeVar);
begin
if (frequency'pos(freqVal) > 2_147_483_647) then
assert FALSE
report "Frequency value passed to function is greater than 2,147,483,647 when converted to base units."
severity warning;
end if;
resultVar := divVar/real(frequency'pos(freqVal)) * timeVar; -- see "NOTES"
return resultVar;
end to_period;
--synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : to_string (integer)
--
-- DESCRIPTION : This function returns a string value representing the
-- integer value passed to it.
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
function to_string(intVal : integer) return string is
variable lineVar : line;
variable resultVar : string(1 to cfi(intVal));
begin
--Std.TextIO.Write(lineVar, intVal);
Write(lineVar, intVal);
resultVar(lineVar.all'range) := lineVar.all;
deallocate(lineVar);
return resultVar;
end to_string;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : to_string (real)
--
-- DESCRIPTION : This function returns a string value representing the
-- integer value passed to it.
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
function to_string(realVal : real) return string is
variable lengthVar : natural;
variable lineVar : line;
-- variable resultVar : string(1 to cfr(realVal));
variable resultVar : string(1 to 50);
begin
--Std.TextIO.Write(lineVar, intVal);
Write(lineVar, realVal);
lengthVar := lineVar.all'length;
resultVar(lineVar.all'range) := lineVar.all;
deallocate(lineVar);
return resultVar(1 to lengthVar);
end to_string;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : to_string (vector)
--
-- DESCRIPTION : This function returns a string value representing the
-- vector value passed to it.
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
function to_string(vectorVal : std_logic_vector) return string is
variable lineVar : line;
variable resultVar : string(1 to vectorVal'length);
begin
--Std.TextIO.Write(lineVar, vectorVal);
Write(lineVar, vectorVal);
resultVar(lineVar.all'range) := lineVar.all;
deallocate(lineVar);
return resultVar;
end to_string;
-- synopsys translate_on


--------------------------------------------------------------------------------
----
---- PROCEDURE NAME : transpose
----
---- DESCRIPTION : This procedure returns the transpose of an array
----
---- NOTES : column 1 -> row 1
---- column 2 -> row 2
----
--------------------------------------------------------------------------------
--procedure( transpose(arrayVal : array_type) return array_type is
-- variable loopVar : natural;
-- variable resultVar : std_ulogic_vector(vectorVal'range);
--begin
-- for loopVar in vectorVal'low to vectorVal'high loop
-- resultVar(resultVar'high-loopVar) := vectorVal(loopVar);
-- end loop;
-- return resultVar;
--end transpose;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vhfi (vector high for integer)
--
-- DESCRIPTION : This function returns the 'high value to be used
-- in the range declaration of a vector used to
-- represent the integer value passed to it.
--
-- WARNING: This function assumes the rest of the
-- range declaration of the vector
-- will be "downto 0"
--
-- NOTES : see vlfi for more information
--
-- EXAMPLE :
------------------------------------------------------------------------------
function vhfi(intVal : integer) return natural is
begin
return vlfi(intVal) - 1;
end vhfi;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vhfn (vector high for natural)
--
-- DESCRIPTION : This function returns the 'high value to be used
-- in the range declaration of a vector used to
-- represent the natural value passed to it.
--
-- WARNING: This function assumes the rest of the
-- range declaration of the vector
-- will be "downto 0"
--
-- NOTES : see vlfn for more information
--
-- EXAMPLE :
------------------------------------------------------------------------------
function vhfn(natVal : natural) return natural is
begin
return vlfn(natVal) - 1;
end vhfn;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vlfi (vector length for integer)
--
-- DESCRIPTION : This function returns an integer representing the
-- length of the vector required to represent
-- the integer value passed to it. This includes
-- the sign bit; hence the "resultVar := loopVar + 1;"
--
-- NOTES : type integer is range -2147483648 to 2147483647;
-- This function can be used in code intended for synthesis
-- Using a 31 bit variable strips off the sign bit that
-- the conversion function generates. This allows us
-- to place the sign bit in the new location at the top
-- of the vector.
--
-- EXAMPLE : -2147483648 passed, convertion to logic vector gives
-- 0000000000000000000000000000000. Bit 31 is '0' and
-- a sign bit is needed so 31 + 1 = 32 bits are needed to
-- represent this value
--
-- given intVal = 32
-- slvVar is assigned 0000000000000000000000000100000
-- "if" condition becomes true for loopVar = 6
-- result is 7 (6 bits to represent 32, plus the sign bit)
------------------------------------------------------------------------------
function vlfi(intVal : integer) return natural is
variable loopVar : natural;
variable resultVar : natural;
variable slvVar : std_logic_vector(31 downto 1); -- range of 31 downto 1 used because the numbering is correct for the positional location of the bits
begin
slvVar := conv_std_logic_vector(intVal,slvVar'length); -- convert the integer passed to the function to a 31 bit logic vector
if (intVal > 0) then -- if the integer is positive then
for loopVar in slvVar'range loop -- start at the top of the vector and index down
if (slvVar(loopVar) = '1') then -- and if a bit is asserted then
resultVar := loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
exit;
end if;
end loop;
elsif (intVal = 0) then -- '0' has no value and, therefore, needs no sign bit
resultVar := 1;
elsif (intVal = -1) then -- '-1' is a special case which contains no zeros so the following algorithm would fail.
resultVar := 2;
elsif (intVal < -1) then -- if the integer is negative then
for loopVar in slvVar'range loop -- start at the top of the vector and index down
if (slvVar(loopVar) = '0') then -- and if a bit is asserted then
resultVar := loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
exit;
end if;
end loop;
end if;
return resultVar;
end vlfi;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vlfn (vector length for natural)
--
-- DESCRIPTION : This function returns an integer representing the
-- length of the vector required to represent
-- the natural value passed to it. There is no
-- sign bit needed so "resultVar := loopVar;"
--
-- NOTES : subtype natural is integer range 0 to 2_147_483_647;
-- This function can be used in code intended for synthesis
--
-- EXAMPLE : given natVal = 32
-- slvVar is assigned 0000000000000000000000000100000
-- "if" condition becomes true for loopVar = 6
-- result is 6 (6 bits to represent 32, no sign bit needed)
------------------------------------------------------------------------------
function vlfn(natVal : natural) return natural is
variable loopVar : natural;
variable resultVar : natural;
variable slvVar : std_logic_vector(31 downto 1);
begin
slvVar := conv_std_logic_vector(natVal,slvVar'length);
if (natVal > 2_147_483_647) then
assert false
report "value exceeds 2,147,483,647"
severity warning;
elsif (natVal > 0) then
for loopVar in slvVar'range loop
if (slvVar(loopVar) = '1') then
resultVar := loopVar;
exit;
end if;
end loop;
else
resultVar := 1;
end if;
return resultVar;
end vlfn;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vrfi (vector range for integer)
--
-- DESCRIPTION : This function returns a std_logic_vector of the same range
-- required to represent the integer value passed to it.
-- This includes the sign bit;
--
-- NOTES : subtype natural is integer range 0 to 2_147_483_647;
-- This function can be used in code intended for synthesis
--
------------------------------------------------------------------------------
function vrfi(intVal : integer) return std_logic_vector is
variable slvVar : std_logic_vector(vhfi(intVal) downto 0);
attribute slv_high : natural;
attribute slv_low : natural;
attribute slv_range : natural;
attribute slv_high of slvVar : variable is slvVar'high;
attribute slv_low of slvVar : variable is slvVar'low;
--attribute slv_range of slvVar : variable is slvVar'range;
begin
return slvVar;
end vrfi;


--------------------------------------------------------------------------------
----
---- FUNCTION NAME : vrfi (vector range for integer)
----
---- DESCRIPTION : This function returns a std_logic_vector of the same range
---- required to represent the integer value passed to it.
---- This includes the sign bit;
---- hence the "resultVar := loopVar + 1;"
----
---- NOTES : subtype natural is integer range 0 to 2_147_483_647;
---- This function cannot be used in code intended for synthesis
----
--------------------------------------------------------------------------------
---- synopsys translate_off
--function vrfi(intVal : integer) return std_logic_vector is
-- type slv_ptr is access std_logic_vector;
-- variable size : slv_ptr;
-- variable loopVar : natural;
-- variable resultVar : natural;
-- variable slvVar : std_logic_vector(31 downto 1);
--begin
-- slvVar := conv_std_logic_vector(intVal,slvVar'length); -- convert the integer passed to the function to a 31 bit logic vector
-- if (intVal > 0) then -- if the integer is positive then
-- for loopVar in slvVar'range loop -- start at the top of the vector and index down
-- if (slvVar(loopVar) = '1') then -- and if a bit is asserted then
-- resultVar := loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
-- exit;
-- end if;
-- end loop;
-- elsif (intVal = 0) then -- '0' has no value and, therefore, needs no sign bit
-- resultVar := 1;
-- elsif (intVal = -1) then -- '-1' is a special case which contains no zeros so the following algorithm would fail.
-- resultVar := 2;
-- elsif (intVal < -1) then -- if the integer is negative then
-- for loopVar in slvVar'range loop -- start at the top of the vector and index down
-- if (slvVar(loopVar) = '0') then -- and if a bit is asserted then
-- resultVar := loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
-- exit;
-- end if;
-- end loop;
-- end if;
-- size := new std_logic_vector(resultVar-1 downto 0);
---- return size.all'range;
-- return size.all;
-- deallocate(size);
--end vrfi;
---- synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : vrfn (vector range for natural)
--
-- DESCRIPTION : This function returns an std_logic_vector representing the
-- length of the vector required to represent
-- the natural value passed to it.
--
-- NOTES : subtype natural is integer range 0 to 2_147_483_647;
-- This function can be used in code intended for synthesis
--
------------------------------------------------------------------------------
function vrfn(natVal : natural) return std_logic_vector is
variable slvVar : std_logic_vector(vhfn(natVal) downto 0);
attribute slv_high : natural;
attribute slv_low : natural;
attribute slv_range : natural;
attribute slv_high of slvVar : variable is slvVar'high;
attribute slv_low of slvVar : variable is slvVar'low;
--attribute slv_range of slvVar : variable is slvVar'range;
begin
return slvVar;
end vrfn;


--------------------------------------------------------------------------------
----
---- FUNCTION NAME : vrfn (vector range for natural)
----
---- DESCRIPTION : This function returns an std_logic_vector representing the
---- length of the vector required to represent
---- the natural value passed to it.
----
---- NOTES : subtype natural is integer range 0 to 2_147_483_647;
---- This function cannot be used in code intended for synthesis
----
--------------------------------------------------------------------------------
---- synopsys translate_off
--function vrfn(natVal : natural) return std_logic_vector is
-- type slv_ptr is access std_logic_vector;
-- variable size : slv_ptr;
-- variable loopVar : natural;
-- variable resultVar : natural;
-- variable slvVar : std_logic_vector(31 downto 1);
--begin
-- slvVar := conv_std_logic_vector(natVal,slvVar'length);
-- if (natVal > 0) then
-- for loopVar in slvVar'range loop
-- if (slvVar(loopVar) = '1') then
-- resultVar := loopVar;
-- exit;
-- end if;
-- end loop;
-- else
-- resultVar := 1;
-- end if;
-- size := new std_logic_vector(resultVar-1 downto 0);
-- return size.all;
-- deallocate(size);
--end vrfn;
---- synopsys translate_on










------------------------------------------------------------------------------
--
-- Procedures
--
------------------------------------------------------------------------------


------------------------------------------------------------------------------
--
-- PROCEDURE NAME : clock_gen
--
-- DESCRIPTION : generate a 50% duty cycle clock with the specified
--
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
procedure clkgen(
constant clkFreqSig : in frequency;
signal clkSig : out std_logic
) is
variable posPeriodVar : time := (to_period(clkFreqSig) * 50.0) / 100;
variable negPeriodVar : time := to_period(clkFreqSig) - posPeriodVar;
begin
while true loop
clkSig <= '1';
wait for posPeriodVar;
clkSig <= '0';
wait for negPeriodVar;
end loop;
end clkgen;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- PROCEDURE NAME : clock_gen
--
-- DESCRIPTION : generate a 50% duty cycle clock with the specified
--
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
procedure clkgen(
signal clkEnSig : in boolean;
signal clkFreqSig : in frequency;
signal clkSig : out std_logic
) is
variable posPeriodVar : time := (to_period(clkFreqSig) * 50.0) / 100;
variable negPeriodVar : time := to_period(clkFreqSig) - posPeriodVar;
begin
while clkEnSig loop
clkSig <= '1';
wait for posPeriodVar;
clkSig <= '0';
wait for negPeriodVar;
end loop;
end clkgen;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- PROCEDURE NAME : clock_gen
--
-- DESCRIPTION : generate a clock
--
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
procedure clkgen(
signal clkEnSig : in boolean;
signal clkPeriodSig : in time;
constant clkDutySig : in real;
signal clkResetSig : in boolean;
signal clkSig : inout std_logic
) is
variable posPeriodVar : time;
variable negPeriodVar : time;
begin
posPeriodVar := (clkPeriodSig * clkDutySig) / 100;
negPeriodVar := clkPeriodSig - posPeriodVar;
if (clkResetSig)
then
clkSig <= '1';
elsif (clkEnSig)
then
if (clkSig = '1')
then
clkSig <= '0' after posPeriodVar;
else
clkSig <= '1' after negPeriodVar;
end if;
end if;
end clkgen;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- PROCEDURE NAME : clock_gen
--
-- DESCRIPTION : generate a clock
--
-- NOTES
--
------------------------------------------------------------------------------
-- synopsys translate_off
procedure clkgen(
signal clkEnSig : in boolean;
signal clkFreqSig : in frequency;
constant clkDutySig : in real;
signal clkResetSig : in boolean;
signal clkSig : inout std_logic
) is
variable posPeriodVar : time;
variable negPeriodVar : time;
begin
posPeriodVar := (to_period(clkFreqSig) * clkDutySig) / 100;
negPeriodVar := to_period(clkFreqSig) - posPeriodVar;
if (clkResetSig)
then
clkSig <= '1';
elsif (clkEnSig)
then
if (clkSig = '1')
then
clkSig <= '0' after posPeriodVar;
else
clkSig <= '1' after negPeriodVar;
end if;
end if;
end clkgen;
-- synopsys translate_on


------------------------------------------------------------------------------
--
-- FUNCTION NAME : FF
--
-- DESCRIPTION : simple flip flop procedure
--
-- NOTES : synthesizeable
--
------------------------------------------------------------------------------
procedure FF
(
signal Clk : in std_logic;
signal Rst : in std_logic;
signal D : in std_logic_vector;
signal Q : out std_logic_vector
) is
variable zeros : std_logic_vector(Q'range) := (others => '0');
begin
if (Rst = '1') then
Q <= zeros;
elsif Rising_Edge(Clk) then
Q <= D;
end if;
end FF;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : slv_to_bcd
--
-- DESCRIPTION : This function converts an unsigned, decending range,
-- binary value into a packed binary coded decimal (BCD)
-- standard logic vector and returns the result in
-- the number BCD digits required to represent the maximum
-- unsigned value possible in the vector passed to it.
-- it is for use in pipelined implementations where
-- the binary coded decimal output is registered
-- and passed back to the function along with the binary
-- vector input to be shifted out of its MSB
-- register and into the function as a new bit.
--
--
-- NOTES
-- BCD_DigitsVal -> dpfslvr(vectorVal)
------------------------------------------------------------------------------
procedure slv_to_bcd(
signal BCD_RIn : in std_logic_vector;
signal BinIn : in std_logic_vector;
signal BinFBIn : in std_logic_vector;
signal ClkIn : in std_logic;
constant BCD_DigitsVal : in integer;
signal EnIn : in std_logic;
signal RstLowIn : in std_logic;
signal BCD_ROut : out std_logic_vector;
signal Bin_ROut : out std_logic_vector; -- registed, shifted version of BinIn
signal DoneOut : out std_logic) is
constant BCD_ZEROS : std_logic_vector(BCD_ROut'range) := (others => '0');
constant BIN_ZEROS : std_logic_vector(BinIn'range) := (others => '0');
variable BCD_Var : std_logic_vector(BCD_ROut'range);
variable BCD_RVar : std_logic_vector(BCD_ROut'range);
begin
if (RstLowIn = '0' or EnIn = '0') then
BCD_ROut <= BCD_ZEROS;
BCD_RVar := BIN_ZEROS;
Bin_ROut <= BinIn;
DoneOut <= '0';
elsif rising_edge(ClkIn) then
Bin_ROut <= BinFBIn(BinFBIn'high-1 downto BinFBIn'low) & '0';
if (BinFBIn = BIN_ZEROS) then
BCD_ROut <= BCD_RIn;
DoneOut <= '1';
else
BCD_ROut <= slv_to_bcd_pipe(BCD_RIn,BinFBIn(BinFBIn'high),BCD_DigitsVal);
DoneOut <= '0';
end if;
end if;
end slv_to_bcd;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top