|
|
- --
- -- File Name: RandomBasePkg.vhd
- -- Design Unit Name: RandomBasePkg
- -- Revision: STANDARD VERSION, revision 2.0, VHDL-2008
- --
- -- Maintainer: Jim Lewis email: jim@synthworks.com
- -- Contributor(s):
- -- Jim Lewis jim@synthworks.com
- --
- --
- -- Description:
- -- Defines Base randomization, seed definition, seed generation,
- -- and seed IO functionality for RandomPkg.vhd
- -- Defines:
- -- Procedure Uniform - baseline randomization
- -- Type RandomSeedType - the seed as a single object
- -- function GenRandSeed from integer_vector, integer, or string
- -- IO function to_string, & procedures write, read
- --
- -- In revision 2.0 these types and functions are included by package reference.
- -- Long term these will be passed as generics to RandomGenericPkg
- --
- --
- -- Developed for:
- -- SynthWorks Design Inc.
- -- VHDL Training Classes
- -- 11898 SW 128th Ave. Tigard, Or 97223
- -- http://www.SynthWorks.com
- --
- -- Revision History:
- -- Date Version Description
- -- 01/2008: 0.1 Initial revision
- -- Numerous revisions for VHDL Testbenches and Verification
- -- 02/2009: 1.0 First Public Released Version
- -- 02/25/2009 1.1 Replaced reference to std_2008 with a reference
- -- to ieee_proposed.standard_additions.all ;
- -- 03/01/2011 2.0 STANDARD VERSION
- -- Fixed abstraction by moving RandomParmType to RandomPkg.vhd
- --
- --
- -- Copyright (c) 2008, 2009, 2010, 2011 by SynthWorks Design Inc. All rights reserved.
- --
- -- Verbatim copies of this source file may be used and
- -- distributed without restriction.
- --
- -- This source file is free software; you can redistribute it
- -- and/or modify it under the terms of the ARTISTIC License
- -- as published by The Perl Foundation; either version 2.0 of
- -- the License, or (at your option) any later version.
- --
- -- This source is distributed in the hope that it will be
- -- useful, but WITHOUT ANY WARRANTY; without even the implied
- -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- -- PURPOSE. See the Artistic License for details.
- --
- -- You should have received a copy of the license with this source.
- -- If not download it from,
- -- http://www.perlfoundation.org/artistic_license_2_0
- --
-
- library ieee ;
- use ieee.math_real.all ;
- use std.textio.all ;
-
- -- comment out following 2 lines with VHDL-2008. Leave in for VHDL-2002
- library ieee_proposed ; -- remove with VHDL-2008
- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008
-
-
- package RandomBasePkg is
-
- -- RandomSeedType and Uniform can be replaced by any procedure that
- -- produces a uniform distribution with 0 <= Value < 1 or 0 < Value < 1
- -- and maintains the same call interface
- type RandomSeedType is array (1 to 2) of integer ;
- procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
-
- -- Translate from integer_vector, integer, or string to RandomSeedType
- -- Required by RandomPkg.InitSeed
- -- GenRandSeed makes sure all values are in a valid range
- function GenRandSeed(IV : integer_vector) return RandomSeedType ;
- function GenRandSeed(I : integer) return RandomSeedType ;
- function GenRandSeed(S : string) return RandomSeedType ;
-
- -- IO for RandomSeedType. If use subtype, then create aliases here
- -- in a similar fashion VHDL-2008 std_logic_textio.
- -- Not required by RandomPkg
- function to_string(A : RandomSeedType) return string ;
- procedure write(variable L: inout line ; A : RandomSeedType ) ;
- procedure read (variable L: inout line ; A : out RandomSeedType ; good : out boolean ) ;
- procedure read (variable L: inout line ; A : out RandomSeedType ) ;
-
- end RandomBasePkg ;
- -----------------------------------------------------------------
- -----------------------------------------------------------------
- package body RandomBasePkg is
-
- -----------------------------------------------------------------
- -- Uniform
- -- Generate a random number with a Uniform distribution
- -- Required by RandomPkg. All randomization is derived from here.
- -- Value produced must be either:
- -- 0 <= Value < 1 or 0 < Value < 1
- --
- -- Current version uses ieee.math_real.Uniform
- -- This abstraction allows higher precision version
- -- of a uniform distribution to be used provided
- --
- procedure Uniform (
- Result : out real ;
- Seed : inout RandomSeedType
- ) is
- begin
- ieee.math_real.Uniform (Seed(Seed'left), Seed(Seed'right), Result) ;
- end procedure Uniform ;
-
-
- -----------------------------------------------------------------
- -- GenRandSeed
- -- Convert integer_vector to RandomSeedType
- -- Uniform requires two seed values of the form:
- -- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
- --
- -- if 2 seed values are passed to GenRandSeed and they are
- -- in the above range, then they must remain unmodified.
- --
- function GenRandSeed(IV : integer_vector) return RandomSeedType is
- alias iIV : integer_vector(1 to IV'length) is IV ;
- variable Seed1 : integer ;
- variable Seed2 : integer ;
- constant SEED1_MAX : integer := 2147483562 ;
- constant SEED2_MAX : integer := 2147483398 ;
- begin
- if iIV'Length <= 0 then -- no seed
- report "%%FATAL: GenRandSeed received NULL integer_vector" severity failure ;
- return (3, 17) ; -- if continue seed = (3, 17)
-
- elsif iIV'Length = 1 then -- one seed value
- -- inefficient handling, but condition is unlikely
- return GenRandSeed(iIV(1)) ; -- generate a seed
-
- else -- only use the left two values
- -- 1 <= SEED1 <= 2147483562
- -- mod returns 0 to MAX-1, the -1 adjusts legal values, +1 adjusts them back
- Seed1 := ((iIV(1)-1) mod SEED1_MAX) + 1 ;
- -- 1 <= SEED2 <= 2147483398
- Seed2 := ((iIV(2)-1) mod SEED2_MAX) + 1 ;
- return (Seed1, Seed2) ;
- end if ;
- end function GenRandSeed ;
-
-
- -----------------------------------------------------------------
- -- GenRandSeed
- -- transform a single integer into the internal seed
- --
- function GenRandSeed(I : integer) return RandomSeedType is
- variable result : integer_vector(1 to 2) ;
- begin
- result(1) := I ;
- result(2) := I/3 + 1 ;
- return GenRandSeed(result) ; -- make value ranges legal
- end function GenRandSeed ;
-
-
- -----------------------------------------------------------------
- -- GenRandSeed
- -- transform a string value into the internal seed
- -- usage: RV.GenRandSeed(RV'instance_path));
- --
- function GenRandSeed(S : string) return RandomSeedType is
- constant LEN : integer := S'length ;
- constant HALF_LEN : integer := LEN/2 ;
- alias revS : string(LEN downto 1) is S ;
- variable result : integer_vector(1 to 2) ;
- variable temp : integer := 0 ;
- begin
- for i in 1 to HALF_LEN loop
- temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
- end loop ;
- result(1) := temp ;
- for i in HALF_LEN + 1 to LEN loop
- temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
- end loop ;
- result(2) := temp ;
- return GenRandSeed(result) ; -- make value ranges legal
- end function GenRandSeed ;
-
-
- -----------------------------------------------------------------
- function to_string(A : RandomSeedType) return string is
- begin
- return to_string(A(A'left)) & " " & to_string(A(A'right)) ;
- end function to_string ;
-
-
- -----------------------------------------------------------------
- procedure write(variable L: inout line ; A : RandomSeedType ) is
- begin
- write(L, to_string(A)) ;
- end procedure ;
-
-
- -----------------------------------------------------------------
- procedure read(variable L: inout line ; A : out RandomSeedType ; good : out boolean ) is
- variable iGood : boolean ;
- begin
- for i in A'range loop
- read(L, A(i), iGood) ;
- exit when not iGood ;
- end loop ;
- good := iGood ;
- end procedure read ;
-
-
- -----------------------------------------------------------------
- procedure read(variable L: inout line ; A : out RandomSeedType ) is
- variable good : boolean ;
- begin
- read(L, A, good) ;
- assert good report "read[line, RandomSeedType] failed" severity error ;
- end procedure read ;
-
- end RandomBasePkg ;
|