![]() |
|
|
|
#1 |
|
------------------------------------------------------------------------------ -- -- 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 |
|
|
![]() |
| Thread Tools | Search this Thread |
|
|
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 |