H
hepmehepme
Sorry if this has been covered already. I am developing a testbench
for a design and I want the behavioral models for external devices to
use random parameters within the constraints of the data sheets. I
figured out how to start up a sim with a seed variable in Modelsim,
but now I'm confused about how to use that seed. Say I have two
processes, each controlling one aspect of an ADC. Does each process
have its own random number stream or do they share some global random
number stream? In other words, does each process access a global seed
or do they each maintain their own seeds. I was thinking that a global
seed may be dangerous because it may change in a non-deterministic
fashion. Here is an example with local seeds. The first process
controls the ADC convert to busy timing, the second process controls
the prop delay through a mux. Each takes the initial value for the
seed from the generic for the testbench and then keeps a local copy of
the seed. Is this the right way to do this?
procedure rand_time(
variable seed1, seed2 : inout positive;
min, max : in integer;
result : out time
) is
variable rand : real;
begin
uniform(seed1, seed2, rand);
result := (integer(real(min) + (rand * (real(max)-real(min)) ) ))* 1
ps;
end procedure;
-- ADC busy timing
convert : process
variable s1 : integer;
variable s2 : integer;
variable t6 : time;
variable tconv : time;
variable init : std_logic;
begin
-- Init seeds from generic if not already initialized
if(init /= '1')then
s1 := gSEED;
s2 := s1/2 + 50;
init := '1';
end if;
busy_n <= '1';
wait until falling_edge(convst_n);
if(cs_n = '0')and(shtdn_n = '1')then
rand_time(s1, s2, MIN_T6, MAX_T6, t6);
rand_time(s1, s2, MIN_TCONV, MAX_TCONV, tconv);
busy_n <= '0' after t6;
wait for (tconv - t6);
busy_n <= '1';
dtemp <= din;
end if;
end process convert;
-- mux timing
mux : process (en_n, mux_sel)
variable s1: integer;
variable s2: integer;
variable p : time;
variable init : std_logic;
begin
-- Init seeds from generic if not already initialized
if(init /= '1')then
s1 := gSEED;
s2 := s1/2 + 50;
init := '1';
end if;
rand_time(s1, s2, MIN_DELAY, MAX_DELAY, p);
if(en_n = '1') then
dout <= (others => 'Z') after p;
else
dout(15 downto 12) <= mux_sel after p;
dout(11 downto 0) <= (others => '0') after p;
end if;
end process mux;
for a design and I want the behavioral models for external devices to
use random parameters within the constraints of the data sheets. I
figured out how to start up a sim with a seed variable in Modelsim,
but now I'm confused about how to use that seed. Say I have two
processes, each controlling one aspect of an ADC. Does each process
have its own random number stream or do they share some global random
number stream? In other words, does each process access a global seed
or do they each maintain their own seeds. I was thinking that a global
seed may be dangerous because it may change in a non-deterministic
fashion. Here is an example with local seeds. The first process
controls the ADC convert to busy timing, the second process controls
the prop delay through a mux. Each takes the initial value for the
seed from the generic for the testbench and then keeps a local copy of
the seed. Is this the right way to do this?
procedure rand_time(
variable seed1, seed2 : inout positive;
min, max : in integer;
result : out time
) is
variable rand : real;
begin
uniform(seed1, seed2, rand);
result := (integer(real(min) + (rand * (real(max)-real(min)) ) ))* 1
ps;
end procedure;
-- ADC busy timing
convert : process
variable s1 : integer;
variable s2 : integer;
variable t6 : time;
variable tconv : time;
variable init : std_logic;
begin
-- Init seeds from generic if not already initialized
if(init /= '1')then
s1 := gSEED;
s2 := s1/2 + 50;
init := '1';
end if;
busy_n <= '1';
wait until falling_edge(convst_n);
if(cs_n = '0')and(shtdn_n = '1')then
rand_time(s1, s2, MIN_T6, MAX_T6, t6);
rand_time(s1, s2, MIN_TCONV, MAX_TCONV, tconv);
busy_n <= '0' after t6;
wait for (tconv - t6);
busy_n <= '1';
dtemp <= din;
end if;
end process convert;
-- mux timing
mux : process (en_n, mux_sel)
variable s1: integer;
variable s2: integer;
variable p : time;
variable init : std_logic;
begin
-- Init seeds from generic if not already initialized
if(init /= '1')then
s1 := gSEED;
s2 := s1/2 + 50;
init := '1';
end if;
rand_time(s1, s2, MIN_DELAY, MAX_DELAY, p);
if(en_n = '1') then
dout <= (others => 'Z') after p;
else
dout(15 downto 12) <= mux_sel after p;
dout(11 downto 0) <= (others => '0') after p;
end if;
end process mux;