Random Number Generator

D

Deepu

Guest
Hi All,

I am trying to generate numbers using a function which when called
generates a random number but not to repeat the same number again with
every call.

Code looks like:

reg [15:0] unique_random_number[];
int number_count;

initial begin
unique_random_number = new[9999];
number_count = 0;
end

// Function Calls

unique_random_number(0,30); // 1st Call
unique_random_number(0,30); // 2nd Call
unique_random_number(0,30); // 3rd Call
unique_random_number(0,30); // 4th Call

and so on...

unique_random_number(0,30); // 29th Call
unique_random_number(0,30); // 30th Call
unique_random_number(0,30); // 31st Call


function automatic int unique_random_number(
input int start =
16'd0,
input int end =
16'd10
);
int number;

begin
number = $urandom_range(start,end);

unique_random_number[++number_count] = number;

if (number_count > 9999)
begin
error ("Number assignment not correct");
$finish(2);
end

for (int count = 1; count < number_count; count = count + 1)
begin
if (unique_random_number[count] == number)
begin
number = unique_random_number();
end
end

$display ("[%0d]: +++ [unique_random_number] Unique Number :
%0d +++", $time, number);

unique_random_number = number;

end
endfunction // int

I get an message like:

ncsim: *W,RTSDAD (***): SystemVerilog dynamic array index 9999 does
not exist, 9999 items are in the dynamic array.


Please provide me some help on this..
 
Deepu <pradeep.bg@gmail.com> wrote:

I am trying to generate numbers using a function which when called
generates a random number but not to repeat the same number again with
every call.
The usual software way is to make a list of the numbers
you want, and then shuffle them. (Like cards!)

Another way is to create a bit vector and set a bit when a
number is generated, then don't generate that one again.

-- glen
 
On Sun, 24 Oct 2010 23:41:59 -0700 (PDT), Deepu wrote:

I am trying to generate numbers using a function which when called
generates a random number but not to repeat the same number again with
every call.
Glen's suggestion about shuffling an array is good. Just take
care to do it properly - it's something that is easy to get wrong.

You do know about SystemVerilog's shuffle() method, and
randc qualifier, right?
--
Jonathan Bromley
 
On Sun, 24 Oct 2010 23:41:59 -0700 (PDT), Deepu wrote:

I am trying to generate numbers using a function which when called
generates a random number but not to repeat the same number again with
every call.
Afterthought: If your random number has a very large set of
possible values (for example, if you're trying to generate
random 32-bit values) then none of the techniques mentioned
so far is practical. This is because they all require you to
create arrays with as many entries as there are possible values.

Here's a SystemVerilog non-repeating random value
generator that will cope with large values such as int.
However, it probably WON'T support very large numbers of
draws of the random number, because the constraint will
become very complicated as you draw more and more times
(and, of course, the "used_values" list will grow large).

class nonrepeating_rand #(type T = int);

// The number that will be randomized each time
protected T value;
// List of values already drawn
protected T used_values[$];

// Clear out the list of drawn values to start over
function void reset();
used_values.delete();
endfunction

// Draw a number not seen since previous reset
function T draw();
// Create random value that's not yet been drawn
std::randomize(value) with {!(value inside {used_values});};
// Remember this value on the "drawn" list
used_values.push_back(value);
return value;
endfunction

endclass

Jonathan Bromley
 
Jonathan Bromley <spam@oxfordbromley.plus.com> wrote:
On Sun, 24 Oct 2010 23:41:59 -0700 (PDT), Deepu wrote:

I am trying to generate numbers using a function which when called
generates a random number but not to repeat the same number again with
every call.

Afterthought: If your random number has a very large set of
possible values (for example, if you're trying to generate
random 32-bit values) then none of the techniques mentioned
so far is practical. This is because they all require you to
create arrays with as many entries as there are possible values.
Well, you could use an LFSR with a large period. Then you
know exactly when it will repeat. Successive values tend not
to be as random as you might like, so skipping a few between
the values you use might be needed.

Otherwise, a hash table to detect previously used values
in a small number of cycles might work. A good hash with a
secondary hash should be pretty fast.

-- glen
 

Welcome to EDABoard.com

Sponsor

Back
Top