Go Back   Velocity Reviews > Newsgroups > VHDL
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

VHDL - extension pack

 
Thread Tools Search this Thread
Old 05-06-2005, 07:21 AM   #1
Default extension pack



------------------------------------------------------------------------------
--
-- author : Michael Bills ()
--
-- description : This package has functions and procedures
-- for testbenching and assisting in RTL design
-- creation. It consists mostly of conversion functions.
--
--
-- Copyright (c) 2005 by Michael Bills
--
-- Permission to use, copy, modify, distribute, and sell this source code
-- for any purpose is hereby granted without fee, provided that
-- the above copyright notices and this permission notice appear
-- in all copies of this source code.
--
-- THIS SOURCE CODE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION,
-- ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
--
-- THE USER OF THIS SOURCE CODE ASSUMES ALL LIABILITY FOR THEIR USE
-- OF THIS SOURCE CODE.
--
-- IN NO EVENT SHALL MICHAEL BILLS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
-- INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
-- RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER OR NOT ADVISED OF
-- THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING
-- OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
--
------------------------------------------------------------------------------


-- 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 "*"(MultiplicandVal : integer;
MultiplierVal : std_logic_vector) return std_logic_vector;

function "*"(MultiplicandVal : std_logic_vector;
MultiplierVal : integer) return std_logic_vector;

--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 "/"(DividendVal : std_logic_vector;
DivisorVal : integer) return std_logic_vector;

function "/"(DividendVal : string;
DivisorVal : integer) 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 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 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 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_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

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(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_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_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 strh(stringVal : string) return integer;

-- 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 bool is boolean;
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 multiplies an integer by a std_logic_vector
--
-- NOTES :
--
------------------------------------------------------------------------------
function "*"(MultiplicandVal : integer;
MultiplierVal : std_logic_vector) return std_logic_vector is
begin
return int_to_slv(MultiplicandVal)*MultiplierVal;
end "*";


------------------------------------------------------------------------------
--
-- FUNCTION NAME : "*"
--
-- DESCRIPTION : This function multiplies a std_logic_vector by an integer
--
-- NOTES :
--
------------------------------------------------------------------------------
function "*"(MultiplicandVal : std_logic_vector;
MultiplierVal : integer) return std_logic_vector is
begin
return MultiplicandVal*int_to_slv(MultiplierVal);
end "*";


------------------------------------------------------------------------------
--
-- 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'len gth downto 0);
variable DivisorVar : std_logic_vector(DivisorVal'length downto 0);
variable InterimVar : std_logic_vector(DivisorVal'length downto 0);
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;
-- round to the nearest digit
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 : "/"
--
-- DESCRIPTION : This function divides an string value
-- by integer value
--
-- NOTES :
--
------------------------------------------------------------------------------
function "/"(DividendVal : std_logic_vector;
DivisorVal : integer) return std_logic_vector is
begin
return DividendVal/int_to_slv(DivisorVal);
end "/";


------------------------------------------------------------------------------
--
-- FUNCTION NAME : "/"
--
-- DESCRIPTION : This function divides an string value
-- by integer value
--
-- NOTES :
--
------------------------------------------------------------------------------
function "/"(DividendVal : string;
DivisorVal : integer) return std_logic_vector is
begin
return str_to_slv(DividendVal)/int_to_slv(DivisorVal);
end "/";


------------------------------------------------------------------------------
--
-- FUNCTION NAME : bcd_to_led
--
-- DESCRIPTION : This function converts a packed BCD vector or a hex value
-- 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 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 "1010" => resultVar(7*loopVar+6 downto 7*loopvar) := "0001000"; -- A
when "1011" => resultVar(7*loopVar+6 downto 7*loopvar) := "1100000"; -- b
when "1100" => resultVar(7*loopVar+6 downto 7*loopvar) := "0110001"; -- C
when "1101" => resultVar(7*loopVar+6 downto 7*loopvar) := "1000010"; -- d
when "1110" => resultVar(7*loopVar+6 downto 7*loopvar) := "0110000"; -- E
when "1111" => resultVar(7*loopVar+6 downto 7*loopvar) := "0111000"; -- F
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 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 negVar : boolean;
begin
if (intVal < 0) then
intVar := -intVal;
negVar := true;
else
intVar := intVal;
negVar := false;
end if;
for LoopVar in 1 to MAX_VECT_SIZE loop
if (intVar = 0) then
return 1;
elsif (intVar < 10 and intVar >= 1) then
if (negVar) then
return loopVar + 1; -- allow for the '-' character
else
return loopVar;
end if;
else
intVar := intVar/10;
end if;
end loop;
end cfi;


------------------------------------------------------------------------------
--
-- 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(freqStrV al,CFT_BASE_SIZE) downto 0);
variable timeVar : std_logic_vector(str_to_slv_var_base_high(timeStrV al,CFT_BASE_SIZE) downto 0);
begin
freqStrVar := str_to_slv(freqStrVal,CFT_BASE_SIZE);
timeVar := str_to_slv(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(freqStrV al,CFT_BASE_SIZE) downto 0);
variable timeVar : std_logic_vector(str_to_slv_var_base_high(timeStrV al,CFT_BASE_SIZE) downto 0);
begin
freqStrVar := str_to_slv(freqStrVal,CFT_BASE_SIZE);
timeVar := str_to_slv(timeStrVal,CFT_BASE_SIZE);
return reduce_high(timeVar/freqStrVar);
end cfth;


------------------------------------------------------------------------------
--
-- 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 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'leng th)/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-3);
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 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'leng th)/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-3);
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 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'leng th)/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-3);
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 : 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;
else
intVar := intVal;
end if;
for CountVar in 1 to MAX_VECT_SIZE loop
if (intVal = 0) then
return 1;
elsif (intVar < 10 and intVar >= 1) then
return CountVar;
else
intVar := intVar/10;
end if;
end loop;
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 realVar : real;
variable ResultVar : natural;
begin
if (realVal < 0.0) then
realVar := -realVal;
else
realVar := realVal;
end if;
for loopVar in 1 to MAX_VECT_SIZE loop
if (realVal = 0.0) then
return 1;
elsif (realVar < 10.0 and realVar >= 1.0) then
return loopVar;
else
realVar := realVar/10.0;
end if;
end loop;
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 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 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 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(1 to stringVal'length);
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 negVar : std_logic;
variable multiplicandVar : std_logic_vector(Multiplicand'length-1 downto 0);
variable multiplierVar : std_logic_vector(Multiplier'length+Multiplicand'le ngth-1 downto 0);
variable resultVar : std_logic_vector(Multiplier'length+Multiplicand'le ngth-1 downto 0);
begin
multiplicandVar := abs(multiplicand);
multiplierVar := ext(abs(Multiplier),multiplierVar'length);
negVar := multiplier(multiplier'left) xor multiplicand(multiplicand'left);
resultVar := (others => '0');
for loopVar in multiplicandVar'reverse_range 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 multiplicandVar : std_logic_vector(Multiplicand'length-1 downto 0);
variable multiplierVar : std_logic_vector(Multiplier'length+Multiplicand'le ngth-1 downto 0);
variable resultVar : std_logic_vector(Multiplier'length+Multiplicand'le ngth-1 downto 0);
begin
multiplicandVar := multiplicand;
multiplierVar := ext(Multiplier,multiplierVar'length);
resultVar := (others => '0');
for loopVar in multiplicandVar'reverse_range 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 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 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 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 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 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 '.' =>
if (negVar) then -- ignore everything after a decimal point
return -resultVar;
else
return resultVar;
end if;
when others => resultVar := resultVar;
end case;
end loop;
if (negVar) then -- ignore everything after a decimal point
return -resultVar;
else
return resultVar;
end if;
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 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(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
--
-- 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(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 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 scndTimeFndVar : boolean; -- used to indicate a second time value was found
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');
scndTimeFndVar := false;
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 loopVar in stringVar'range loop
vectorParseVar := stringVar(loopVar);
if (scndTimeFndVar) then
resultVar := resultVar;
else
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(stringVar(loopVar to stringVar'length),baseVar),result2Var'length); -- pass the rest of the string to the next instance of the function
scndTimeFndVar := true;
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(loopVar to stringVal'length)); -- and capture its value
end if;
when '.' => decPntFndVar := true; -- mark the position of the decimal point
when 'y' | 'Y' => -- yoctosecond 10^-24
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-24 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'z' | 'Z' => -- zeptosecond 10^-21
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-21 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'a' | 'A' => -- attosecond 10^-18
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-18 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'f' | 'F' => -- femtosecond 10^-15
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-15 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'p' | 'P' => -- picosecond 10^-12
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-12 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'n' | 'N' => -- nanosecond 10^-9
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-9 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'u' | 'U' => -- microsecond 10^-6
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar in 1 to baseVar-6 loop
resultVar := mult_us(resultVar(MAX_VECT_SIZE+12 downto 0), \10\);
end loop;
end if;
when 'm' | 'M' => -- millisecond 10^-3
if (not freqUnitFndVar and not timeUnitFndVar and
((stringVar(loopVar+1) = 's') or
(stringVar(loopVar+1) = 'S')))
then
timeUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "in")) or
(seq(stringVar(loopVar+1 to loopVar+2), "iN")) or
(seq(stringVar(loopVar+1 to loopVar+2), "In")) or
(seq(stringVar(loopVar+1 to loopVar+2), "IN"))))
then
timeUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "hZ")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "HZ"))))
then
freqUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "ec")) or
(seq(stringVar(loopVar+1 to loopVar+2), "eC")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Ec")) or
(seq(stringVar(loopVar+1 to loopVar+2), "EC"))))
then
timeUnitFndVar := true;
for loopVar 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(loopVar+1) = 'r') or
(stringVar(loopVar+1) = 'R')))
then
timeUnitFndVar := true;
for loopVar 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(loopVar+1) = 'z') or
(stringVar(loopVar+1) = 'Z')))
then
freqUnitFndVar := true;
end if;
when 'd' | 'D' =>
if (not freqUnitFndVar and not timeUnitFndVar and
((seq(stringVar(loopVar+1 to loopVar+2), "ay")) or
(seq(stringVar(loopVar+1 to loopVar+2), "aY")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Ay")) or
(seq(stringVar(loopVar+1 to loopVar+2), "AY"))))
then
timeUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "hZ")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "HZ"))))
then
freqUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "hZ")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "HZ"))))
then
freqUnitFndVar := true;
for loopVar 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(loopVar+1 to loopVar+2), "hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "hZ")) or
(seq(stringVar(loopVar+1 to loopVar+2), "Hz")) or
(seq(stringVar(loopVar+1 to loopVar+2), "HZ"))))
then
freqUnitFndVar := true;
for loopVar 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 if;
end loop;
if (expVar >= 0) then -- if it's a positive exponent then perform a multiplication loop
for loopVar 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 loopVar 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 loopVar 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;


------------------------------------------------------------------------------
--
-- 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(stringVal,intVal));
end str_to_slv_var_base_high;


------------------------------------------------------------------------------
--
-- FUNCTION NAME : strh
--
-- DESCRIPTION : This function returns the high value of a sring vector
--
--
-- NOTES
--
--
------------------------------------------------------------------------------
function strh(stringVal : string) return integer is
begin
return stringVal'high;
end strh;


------------------------------------------------------------------------------
--
-- 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 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 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
return loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
end if;
end loop;
elsif (intVal = 0) then -- '0' has no value and, therefore, needs no sign bit
return 1;
elsif (intVal = -1) then -- '-1' is a special case which contains no zeros so the following algorithm would fail.
return 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
return loopVar + 1; -- this is the minimum number of bits needed to represent the absolute value. And then add one for the sign bit
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 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;
return 0;
elsif (natVal > 0) then
for loopVar in slvVar'range loop
if (slvVar(loopVar) = '1') then
return loopVar;
end if;
end loop;
else
return 1;
end if;
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 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 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;


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


My Name
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Tremors Attack Pack, all 16x9 ? WanderinRoy DVD Video 0 09-08-2007 08:57 PM
Re: Microsoft Action Pack Adam Leinss A+ Certification 0 02-16-2005 01:17 AM
New Releases: Spider-Man 2, Fox 3 Packs: Updated complete downloadable R1 DVD DB & info lists Doug MacLean DVD Video 5 08-28-2004 02:55 AM
New Releases: More Universal 2 pack, 21 Grams, Honey: Updated complete downloadable R1 DVD DB & info lists Doug MacLean DVD Video 1 01-22-2004 08:35 PM
New releases: Fox two pack blitz, WB 3 packs: Updated complete downloadable R1 DVD DB & info lists Doug MacLean DVD Video 0 08-19-2003 05:39 AM




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46