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.

223 lines
8.2 KiB

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