-- ********************************************************************** -- * This Software Package was developed for internal use within * -- * McDonnell Douglas Corporation (MDC). MDC and the authors or * -- * distributers of this code are not responsible for correctnes or * -- * accuracy of the procedures/functions in this package. This code * -- * may not be distributed for commercial purposes. IN NO EVENT SHALL * -- * MDC BE LIABLE FOR ANY INCIDENTAL, INDIRECT , SPECIAL, OR * -- * CONSEQUENTIAL DAMAGES WHATSOEVER ARISING OUT OF OR RELATING TO * -- * THE USE OF THE INFORMATION/SOFTWARE PROVIDED IN THIS PACKAGE. * -- ********************************************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; --use IEEE.std_logic_unsigned.all; Package rnd2 Is Use STD.TEXTIO.ALL; -- Other VHDL Tolls Require This Instead Type rnd_seed_t Is Array (3 downto 0) of Integer; Type integer_array is Array (Positive Range<>) of Integer; Type rnd_rec_t Is Record rnd: Real; seed: rnd_seed_t; mean, std_dev: Real; bound_l, bound_h: Real; trials: Integer; p_success: Real; End Record; Type rnd_seed_vector_t Is Array (Positive Range <>) of rnd_seed_t; Procedure uniform_d(rnd_rec: InOut rnd_rec_t); Function Mult(rnd_lcg_b : rnd_seed_t) return rnd_seed_t; Function Add(x : rnd_seed_t) return rnd_seed_t; Procedure rnd48(rnd: Out Real; seed: InOut rnd_seed_t); Function Floor (X:Real) return Real; End rnd2; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; --use IEEE.std_logic_unsigned.all; Package Body rnd2 Is Constant rnd_lcg_a: rnd_seed_t := (1, 1502, 3790, 1645); Constant rnd_lcg_c: rnd_seed_t := (1, 1, 1, 11); Constant rnd_lcg_m: Integer := 2**12; -- ---------------------------------------------------------------------- -- Body of Math Functions within VHDL! -- VHDL CODING OF MATH FUNCTIONS. WE RECOMMEND THE USE OF A MATH LIBRARY -- IF ONE IS AVAILABLE Function Mult(rnd_lcg_b : rnd_seed_t) return rnd_seed_t is Variable temp : rnd_seed_t; Variable i, j : integer; Begin for i in 0 to 3 loop temp(i) := 0; end loop; for i in 0 to 3 loop for j in 0 to (3 - i) loop temp(i + j) := temp(i + j) + (rnd_lcg_a(i) * rnd_lcg_b(j)); end loop; end loop; for i in 0 to 2 loop if temp(i) >= rnd_lcg_m then temp(i + 1) := temp(i + 1) + ( temp(i) / rnd_lcg_m); temp(i) := temp(i) mod rnd_lcg_m; end if; end loop; temp(3) := temp(3) mod rnd_lcg_m; return temp; End Mult; Function Add(x : rnd_seed_t) return rnd_seed_t is Variable tempa : rnd_seed_t; Variable i : integer; Begin for i in 0 to 3 loop tempa(i) := x(i) + rnd_lcg_c(i); end loop; for i in 0 to 2 loop if tempa(i) >= rnd_lcg_m then tempa(i +1) := tempa(i +1) + (tempa(i) / rnd_lcg_m); tempa(i) := tempa(i) mod rnd_lcg_m; end if; end loop; tempa(3) := x(3) mod rnd_lcg_m; return tempa; End Add; -- Floor Function Function Floor (X:Real) return Real Is Variable A: Real:=0.0; -- TEMP for Evaluation begin for n in -32767 to 32767 loop if Real(X)= rnd_lcg_m then Assert False Report "The seed element must be less than the 4096" Severity Warning; seed(i) := seed(i) mod rnd_lcg_m; Elsif Seed(i) < 0 then Assert False Report "The seed must be a positive number" Severity Warning; seed(i) := (-seed(i)) mod rnd_lcg_m; End if; End loop; seed := add(mult(seed)); rnd := ((((Real(seed(0)) / Real(rnd_lcg_m) + Real(seed(1))) / Real(rnd_lcg_m) + Real(seed(2))) / Real(rnd_lcg_m) + Real(seed(3))) / Real(rnd_lcg_m)); End rnd48; Procedure uniform_d(rnd_rec: InOut rnd_rec_t) Is ----------------------------------------------------------------- --uniform_d : Generate a uniformly distributed integer -- -- random number in the range [bound_l, bound_h). -- -- -- --Used Fields : seed, bound_l, bound_h. -- -- -- --Changed Fields : rnd, seed. -- ----------------------------------------------------------------- Variable tmp : real; Begin If (rnd_rec.bound_l > rnd_rec.bound_h) then Assert False Report "Lower bound is greater than the upper bound." Severity Warning; rnd_rec.rnd := rnd_rec.bound_h; Elsif (rnd_rec.bound_l /= real(integer(rnd_rec.bound_l))) or (rnd_rec.bound_h /= real(integer(rnd_rec.bound_h))) then Assert False Report "The lower and upper bounds are not integer numbers" Severity Warning; rnd_rec.rnd := floor(rnd_rec.bound_h); Else rnd48(tmp, rnd_rec.seed); rnd_rec.rnd := rnd_rec.bound_l + floor -- ((rnd_rec.bound_h + 1.0 - rnd_rec.bound_l) * tmp); ((rnd_rec.bound_h - rnd_rec.bound_l) * tmp); End if; End uniform_d; End rnd2;