Library of reusable VHDL components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
8.3 KiB

  1. --
  2. -- File Name: RandomBasePkg.vhd
  3. -- Design Unit Name: RandomBasePkg
  4. -- Revision: STANDARD VERSION, revision 2013.05
  5. --
  6. -- Maintainer: Jim Lewis email: jim@synthworks.com
  7. -- Contributor(s):
  8. -- Jim Lewis jim@synthworks.com
  9. --
  10. --
  11. -- Description:
  12. -- Defines Base randomization, seed definition, seed generation,
  13. -- and seed IO functionality for RandomPkg.vhd
  14. -- Defines:
  15. -- Procedure Uniform - baseline randomization
  16. -- Type RandomSeedType - the seed as a single object
  17. -- function GenRandSeed from integer_vector, integer, or string
  18. -- IO function to_string, & procedures write, read
  19. --
  20. -- In revision 2.0 these types and functions are included by package reference.
  21. -- Long term these will be passed as generics to RandomGenericPkg
  22. --
  23. --
  24. -- Developed for:
  25. -- SynthWorks Design Inc.
  26. -- VHDL Training Classes
  27. -- 11898 SW 128th Ave. Tigard, Or 97223
  28. -- http://www.SynthWorks.com
  29. --
  30. -- Revision History:
  31. -- Date Version Description
  32. -- 01/2008: 0.1 Initial revision
  33. -- Numerous revisions for VHDL Testbenches and Verification
  34. -- 02/2009: 1.0 First Public Released Version
  35. -- 02/25/2009 1.1 Replaced reference to std_2008 with a reference
  36. -- to ieee_proposed.standard_additions.all ;
  37. -- 03/01/2011 2.0 STANDARD VERSION
  38. -- Fixed abstraction by moving RandomParmType to RandomPkg.vhd
  39. -- 4/2013 2013.04 No Changes
  40. -- 5/2013 2013.05 No Changes
  41. --
  42. --
  43. -- Copyright (c) 2008 - 2013 by SynthWorks Design Inc. All rights reserved.
  44. --
  45. -- Verbatim copies of this source file may be used and
  46. -- distributed without restriction.
  47. --
  48. -- This source file is free software; you can redistribute it
  49. -- and/or modify it under the terms of the ARTISTIC License
  50. -- as published by The Perl Foundation; either version 2.0 of
  51. -- the License, or (at your option) any later version.
  52. --
  53. -- This source is distributed in the hope that it will be
  54. -- useful, but WITHOUT ANY WARRANTY; without even the implied
  55. -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  56. -- PURPOSE. See the Artistic License for details.
  57. --
  58. -- You should have received a copy of the license with this source.
  59. -- If not download it from,
  60. -- http://www.perlfoundation.org/artistic_license_2_0
  61. --
  62. library ieee ;
  63. use ieee.math_real.all ;
  64. use std.textio.all ;
  65. -- comment out following 2 lines with VHDL-2008. Leave in for VHDL-2002
  66. -- library ieee_proposed ; -- remove with VHDL-2008
  67. -- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008
  68. package RandomBasePkg is
  69. -- RandomSeedType and Uniform can be replaced by any procedure that
  70. -- produces a uniform distribution with 0 <= Value < 1 or 0 < Value < 1
  71. -- and maintains the same call interface
  72. type RandomSeedType is array (1 to 2) of integer ;
  73. procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
  74. -- Translate from integer_vector, integer, or string to RandomSeedType
  75. -- Required by RandomPkg.InitSeed
  76. -- GenRandSeed makes sure all values are in a valid range
  77. function GenRandSeed(IV : integer_vector) return RandomSeedType ;
  78. function GenRandSeed(I : integer) return RandomSeedType ;
  79. function GenRandSeed(S : string) return RandomSeedType ;
  80. -- IO for RandomSeedType. If use subtype, then create aliases here
  81. -- in a similar fashion VHDL-2008 std_logic_textio.
  82. -- Not required by RandomPkg
  83. function to_string(A : RandomSeedType) return string ;
  84. procedure write(variable L: inout line ; A : RandomSeedType ) ;
  85. procedure read (variable L: inout line ; A : out RandomSeedType ; good : out boolean ) ;
  86. procedure read (variable L: inout line ; A : out RandomSeedType ) ;
  87. end RandomBasePkg ;
  88. -----------------------------------------------------------------
  89. -----------------------------------------------------------------
  90. package body RandomBasePkg is
  91. -----------------------------------------------------------------
  92. -- Uniform
  93. -- Generate a random number with a Uniform distribution
  94. -- Required by RandomPkg. All randomization is derived from here.
  95. -- Value produced must be either:
  96. -- 0 <= Value < 1 or 0 < Value < 1
  97. --
  98. -- Current version uses ieee.math_real.Uniform
  99. -- This abstraction allows higher precision version
  100. -- of a uniform distribution to be used provided
  101. --
  102. procedure Uniform (
  103. Result : out real ;
  104. Seed : inout RandomSeedType
  105. ) is
  106. begin
  107. ieee.math_real.Uniform (Seed(Seed'left), Seed(Seed'right), Result) ;
  108. end procedure Uniform ;
  109. -----------------------------------------------------------------
  110. -- GenRandSeed
  111. -- Convert integer_vector to RandomSeedType
  112. -- Uniform requires two seed values of the form:
  113. -- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
  114. --
  115. -- if 2 seed values are passed to GenRandSeed and they are
  116. -- in the above range, then they must remain unmodified.
  117. --
  118. function GenRandSeed(IV : integer_vector) return RandomSeedType is
  119. alias iIV : integer_vector(1 to IV'length) is IV ;
  120. variable Seed1 : integer ;
  121. variable Seed2 : integer ;
  122. constant SEED1_MAX : integer := 2147483562 ;
  123. constant SEED2_MAX : integer := 2147483398 ;
  124. begin
  125. if iIV'Length <= 0 then -- no seed
  126. report "%%FATAL: GenRandSeed received NULL integer_vector" severity failure ;
  127. return (3, 17) ; -- if continue seed = (3, 17)
  128. elsif iIV'Length = 1 then -- one seed value
  129. -- inefficient handling, but condition is unlikely
  130. return GenRandSeed(iIV(1)) ; -- generate a seed
  131. else -- only use the left two values
  132. -- 1 <= SEED1 <= 2147483562
  133. -- mod returns 0 to MAX-1, the -1 adjusts legal values, +1 adjusts them back
  134. Seed1 := ((iIV(1)-1) mod SEED1_MAX) + 1 ;
  135. -- 1 <= SEED2 <= 2147483398
  136. Seed2 := ((iIV(2)-1) mod SEED2_MAX) + 1 ;
  137. return (Seed1, Seed2) ;
  138. end if ;
  139. end function GenRandSeed ;
  140. -----------------------------------------------------------------
  141. -- GenRandSeed
  142. -- transform a single integer into the internal seed
  143. --
  144. function GenRandSeed(I : integer) return RandomSeedType is
  145. variable result : integer_vector(1 to 2) ;
  146. begin
  147. result(1) := I ;
  148. result(2) := I/3 + 1 ;
  149. return GenRandSeed(result) ; -- make value ranges legal
  150. end function GenRandSeed ;
  151. -----------------------------------------------------------------
  152. -- GenRandSeed
  153. -- transform a string value into the internal seed
  154. -- usage: RV.GenRandSeed(RV'instance_path));
  155. --
  156. function GenRandSeed(S : string) return RandomSeedType is
  157. constant LEN : integer := S'length ;
  158. constant HALF_LEN : integer := LEN/2 ;
  159. alias revS : string(LEN downto 1) is S ;
  160. variable result : integer_vector(1 to 2) ;
  161. variable temp : integer := 0 ;
  162. begin
  163. for i in 1 to HALF_LEN loop
  164. temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
  165. end loop ;
  166. result(1) := temp ;
  167. for i in HALF_LEN + 1 to LEN loop
  168. temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
  169. end loop ;
  170. result(2) := temp ;
  171. return GenRandSeed(result) ; -- make value ranges legal
  172. end function GenRandSeed ;
  173. -----------------------------------------------------------------
  174. function to_string(A : RandomSeedType) return string is
  175. begin
  176. return to_string(A(A'left)) & " " & to_string(A(A'right)) ;
  177. end function to_string ;
  178. -----------------------------------------------------------------
  179. procedure write(variable L: inout line ; A : RandomSeedType ) is
  180. begin
  181. write(L, to_string(A)) ;
  182. end procedure ;
  183. -----------------------------------------------------------------
  184. procedure read(variable L: inout line ; A : out RandomSeedType ; good : out boolean ) is
  185. variable iGood : boolean ;
  186. begin
  187. for i in A'range loop
  188. read(L, A(i), iGood) ;
  189. exit when not iGood ;
  190. end loop ;
  191. good := iGood ;
  192. end procedure read ;
  193. -----------------------------------------------------------------
  194. procedure read(variable L: inout line ; A : out RandomSeedType ) is
  195. variable good : boolean ;
  196. begin
  197. read(L, A, good) ;
  198. assert good report "read[line, RandomSeedType] failed" severity error ;
  199. end procedure read ;
  200. end RandomBasePkg ;