random number generator function

B

bb

Hi,

I am creating a finite state machine, and within one of the states I
need to obtrain a random number by calling a function.

random_value <= rand_val;

I am new to VHDL.

Thanks,
 
T

Thomas Stanka

I am creating a finite state machine, and within one of the states I
need to obtrain a random number by calling a function.

random_value <= rand_val;

Impossible. There is no true random functionality obtainable in HW.
You need something like LFSR (Linear Feedback Shift Register), google
for them and see if they fit your need.
If not, learn more about the problem and come back with more detailed
questions.

bye Thomas
 
J

john.williamson

Impossible. There is no true random functionality obtainable in HW.
You need something like LFSR (Linear Feedback Shift Register), google
for them and see if they fit your need.
If not, learn more about the problem and come back with more detailed
questions.

bye Thomas
 
J

john.williamson

You could use the 'Uniform' procedure (in the IEEE MATH_REAL package),
but strictly for simulation and modelling puroses only.

As Thomas suggests, a hardware implementation is a completely
different proposition.

John
 
M

Mike Treseler

bb said:
I am creating a finite state machine, and within one of the states I
need to obtrain a random number by calling a function.

I use an lfsr function to make byte sequences
for simulations and packet fcs fields.
It's not random, but might be what you need.
See the testbench here http://home.comcast.net/~mike_treseler/
for details.

-- Mike Treseler
--------------------------------------------------------------------
function randomize (arg_byte : char_t)
return char_t is
variable result_v : char_t;
begin
result_v := arg_byte; -- here it is
result_v := shift_left(result_v, 1); -- shift it
if (result_v(result_v'left)) = '1' then -- maybe invert mask
result_v := result_v xor mask_c; -- bits
end if;
return result_v;
end function randomize;
--------------------------------------------------------------------
 
B

bb

Psuedo-random is fine. So an LFSR will work.

Mike,

How would I call that function randomize? Thanks.
 
M

Mike Treseler

bb said:
How would I call that function randomize?

random_byte_s <= randomize(random_byte_s);

See the referenced testbench.
Search for "randomize"

-- Mike Treseler
 
B

bb

This is a finite state machine for "tester", it will generate 10
questions, each question is a random value, and then, the user using
push buttons will enter the bcd value. the tester will then, indicate
if its correct or false.

So, in state 1, ST1, I need a random value to be generated. How will I
include the function randomize in this code? And how will it be called
in ST1?

Yes, this code was tested.



--------------------------------------------------------------
-- FSM for Tester
--------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.all;

--------------------------------------------------------------

entity tester is

port(
clk: in std_logic;
rst: in std_logic;
bist1: in std_logic;
bist2: in std_logic;
x_i: in std_logic_vector(7 downto 0);
LED: out std_logic_vector(7 downto 0):= "00000000";
SSG: out std_logic_vector(7 downto 0):= "00000000";
);
end tester;

--------------------------------------------------------------

architecture FSMD of tester is
signal tempclk : STD_LOGIC_VECTOR (27 downto
0):="0000000000000000000000000000";
signal clk_1hz : std_logic:='0';
signal clk_8hz : std_logic:= '0';
--signal clk_80hz : std_logic:='0';
-- define states using variable
type S_Type is (ST0, ST1, ST2, ST3, ST4, ST5, ST6);
variable State: S_Type := ST0 ;
variable Data_X: std_logic_vector(7 downto 0);
variable rand: integer range 0 to 255;
variable disp_1: integer range 0 to 9;
variable disp_10: integer range 0 to 9;
variable disp_100: integer range 0 to 9;
variable q_counter: integer range 0 to 10;
variable s_counter: integer range 0 to 9;
variable timer: integer range 0 to 10;
begin
--- divide system clock to get clock of 1Hz
process (clk)
begin
if Clk='1' and Clk'event then
tempclk <= tempclk + "0000000000000000000000000001";
end if;
end process;
--- get the clock of 1Hz by taking 26th bit of tempclk
clk_1hz <= tempclk(25);
clk_8hz <= tempclk(22);

process(rst, clk_8hz)
begin
if (rst='1') then -- initialization
State := ST0;
elsif (bist1 and bist2) then
--BIST CODE HERE
elsif (clk_8hz'event and clk_8hz='1') then
case State is

when ST0 => -- Initialize
--INITALIZE STATE VARIABLES
--dont really have any states to init atm, but might later!
q_counter := 0;
s_counter := 0;
timer := 0:
State := ST1;

when ST1 => -- Generate Random Number
--if the q_counter is 10 then get a new random, otherwise, were
done with the test
if (q_counter = 10)
State:= ST6;
else
--RANDOM NUMBER GENERATION HERE -- up to 255
-- rand <=

--This gives us the value that must be displayed on EACH
SEGEMENT of the Seven Segemnt Display
disp_1 <= ((rand / 1) mod 10);
disp_10 <= ((rand / 10) mod 10);
disp_100 <= ((rand / 100) mod 10);
--DISPLAY RANDOM NUMBER
State := ST2;
end if;

when ST2 => -- Get Input
Data_X := x_i;
State := ST3;

when ST3 => -- IDLE
State := ST4;
when ST4 => -- IDLE
State := ST5;

when ST5 => -- Compare

if (Data_X=Rand) then
--Correct
--Display "YES" message or "correct" message
--Increment Score counter
s_counter <= s_counter + 1;
--Increment Question Counter
q_counter <= q_counter + 1;
--GOTO ST1
State:= ST1;

--Timer 80 should be about 10 seconds
elsif (timer = 80) then
--Time has expired on this question, so lets increment the
question counter
--and move on to the next
q_counter <=q_counter + 1;
State := ST1;
else
--incorrect
--keep showing original random number
--decrement the TIMER
timer = timer + 1;
end if;

when ST6 => -- End of Program
--We're done, report result for all time
rand <= s_counter;

when others => -- UNHANDLED EXCEPTION
State := ST0;
end case;
end if;

end process;
--update on every 80hz tick and every random number update
process (rand,clk_8hz)
begin
--- Control the Display on the 80hz clock
if (clk_8hz = '1' and clk_8hz'event) then
if (AN0 = '0') then

AN0 <= '1';
--General BCD decoder for the 1's place
case disp_1 is
when '0000' => SSG <= "0000001";
when '0001' => SSG <= "1001111";
when '0010' => SSG <= "0010010";
when '0011' => SSG <= "0000110";
when '0100' => SSG <= "1001100";
when '0101' => SSG <= "0100100";
when '0110' => SSG <= "1100000";
when '0111' => SSG <= "0001111";
when '1000' => SSG <= "0000000";
when '1001' => SSG <= "0000001";
when others => SSG <= "0001100";
end case;

AN1 <= '0';
elsif (AN1 = '0') then
AN1 <= '1';
--General BCD decoder for the 10's place
case disp_10 is
when '0000' => SSG <= "0000001";
when '0001' => SSG <= "1001111";
when '0010' => SSG <= "0010010";
when '0011' => SSG <= "0000110";
when '0100' => SSG <= "1001100";
when '0101' => SSG <= "0100100";
when '0110' => SSG <= "1100000";
when '0111' => SSG <= "0001111";
when '1000' => SSG <= "0000000";
when '1001' => SSG <= "0000001";
when others => SSG <= "0001100";
end case;
AN2 <= '0';
elsif (AN2 = '0') then
AN2 <= '1';
--General BCD decoder for the 100's place
case disp_100 is
when '0000' => SSG <= "0000001";
when '0001' => SSG <= "1001111";
when '0010' => SSG <= "0010010";
when '0011' => SSG <= "0000110";
when '0100' => SSG <= "1001100";
when '0101' => SSG <= "0100100";
when '0110' => SSG <= "1100000";
when '0111' => SSG <= "0001111";
when '1000' => SSG <= "0000000";
when '1001' => SSG <= "0000001";
when others => SSG <= "0001100";
end case;
AN0 <= '0';
end if;
end if;
end process;

end FSMD;

--------------------------------------------------------------
 
M

Mike Treseler

bb said:
This is a finite state machine for "tester", it will generate 10
questions, each question is a random value, and then, the user using
push buttons will enter the bcd value. the tester will then, indicate
if its correct or false.

So, in state 1, ST1, I need a random value to be generated. How will I
include the function randomize in this code? And how will it be called
in ST1?
Yes, this code was tested.

That seems unlikely.

See the syntax errors below to start with.
Variables and functions must be declared between
IS and BEGIN of the *PROCESS*.
Consider using clock enables instead of multiple clocks.
The number generator is the least of your problems.
Get the basic controller running with a constant sequence first
Start with a known-good CASE example and simulate that first.
Add features one at a time, and debug each one.

A newsgroup like this will answer specific questions
or make comments and suggestions
once you have some working code, but it
is unreasonable to expect more.
Consider finding a local tutor.
Good luck.

-- Mike Treseler

__________________________
vcom -2002 -quiet -work work tester.vhd
** Error: tester.vhd(35): near ")": expecting: IDENTIFIER
** Error: tester.vhd(83): near "0:": (vcom-111) No digits found in
mantissa part of based literal.
** Error: tester.vhd(83): near "0:": (vcom-113) Mantissa part of based
integer literal terminates with '
'; should be ':'.
** Error: tester.vhd(83): near "0:": (vcom-118) Base value 0 is not in
range 2 to 16.
** Error: tester.vhd(84): near ":=": expecting: ';'
** Error: tester.vhd(90): near "State": expecting: GENERATE THEN
** Error: tester.vhd(104): near "when": expecting: END
** Error: tester.vhd(108): near "when": expecting: END
 
B

bb

That seems unlikely.

See the syntax errors below to start with.
Variables and functions must be declared between
IS and BEGIN of the *PROCESS*.
Consider using clock enables instead of multiple clocks.
The number generator is the least of your problems.
Get the basic controller running with a constant sequence first
Start with a known-good CASE example and simulate that first.
Add features one at a time, and debug each one.

A newsgroup like this will answer specific questions
or make comments and suggestions
once you have some working code, but it
is unreasonable to expect more.
Consider finding a local tutor.
Good luck.

-- Mike Treseler

__________________________
vcom -2002 -quiet -work work tester.vhd
** Error: tester.vhd(35): near ")": expecting: IDENTIFIER
** Error: tester.vhd(83): near "0:": (vcom-111) No digits found in
mantissa part of based literal.
** Error: tester.vhd(83): near "0:": (vcom-113) Mantissa part of based
integer literal terminates with '
'; should be ':'.
** Error: tester.vhd(83): near "0:": (vcom-118) Base value 0 is not in
range 2 to 16.
** Error: tester.vhd(84): near ":=": expecting: ';'
** Error: tester.vhd(90): near "State": expecting: GENERATE THEN
** Error: tester.vhd(104): near "when": expecting: END
** Error: tester.vhd(108): near "when": expecting: END

Alright, I will fix those . . .

But where will the function randomize be placed in this code?
 
M

Mike Treseler

KJ said:
Testing produces results....one result of testing is error(s)....'bb' never
said the testing produced no errors ;)

Yup. Pass_v = false. Trolled again :)

-- Mike Treseler
 
M

Mike Treseler

bb said:
But where will the function randomize be placed in this code?

Into which part of the broken glass shall I pour the wine ? :)
Post a working testbench and we'll talk.

-- Mike Treseler
 
B

bb

Alright, it got it to synthesize. In ST1, I can't divide a variable.
so, for me to generate i.e 128, I fixed the values,
disp_1 := 8;
disp_10 := 2;
disp_100 := 1;

So, I would like disp_100, to have a value of 1 or 0. disp_10, and
disp_1, a value from 0-7.

____________________________________


library ieee;
use ieee.std_logic_1164.all;
--use ieee.numeric_std.all;
USE ieee.std_logic_arith.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.RNG.all;
use work.LfsrStd_Pkg.all;
--------------------------------------------------------------

entity tester is

port(
clk: in std_logic;
AN0,AN1,AN2,AN3: inout std_logic;
rst: in std_logic;
bist1: in std_logic;
bist2: in std_logic;
x_i: in std_logic_vector(7 downto 0);
LED: out std_logic_vector(7 downto 0):= "00000000";
SSG: out std_logic_vector(7 downto 0):= "00000000");
end tester;

--------------------------------------------------------------

architecture FSMD of tester is
signal tempclk : STD_LOGIC_VECTOR (27 downto
0):="0000000000000000000000000000";
signal clk_1hz : std_logic:='0';
signal clk_8hz : std_logic:= '0';
signal clk_8khz: std_logic:= '0';
signal rand_disp_1: std_logic_vector(3 downto 0):="0000";
--signal timer_holder: std_logic_vector(7 downto 0);
--signal clk_80hz : std_logic:='0';
-- define states using variable
type S_Type is (ST0, ST1, ST2, ST3, ST4, ST5, ST6);
shared variable State: S_Type := ST0 ;
shared variable Data_X: std_logic_vector(7 downto 0);
shared variable rand: integer range 0 to 255:=128;
shared variable disp_1: integer range 0 to 11;
shared variable disp_10: integer range 0 to 11;
shared variable disp_100: integer range 0 to 11;
shared variable q_counter: integer range 0 to 10;
shared variable s_counter: integer range 0 to 9;
shared variable timer: integer range 0 to 10:=8;
begin
--- divide system clock to get clock of 1Hz
process (Clk)
begin
if Clk='1' and Clk'event then
tempclk <= tempclk + "0000000000000000000000000001";
end if;
end process;
--- get the clock of 1Hz by taking 26th bit of tempclk
clk_1hz <= tempclk(25);
clk_8hz <= tempclk(22);
clk_8khz <= tempclk(13);

process (clk_1hz)
-- variable Random: RndNum := InitRndNum(7);
-- variable rnd: real:=0.0;
begin
rand_disp_1<=LFSR(rand_disp_1);
-- GenRnd(Random);
-- rnd := Random.rnd; -- -50 <= rnd <= 100
end process;

process(rst, clk_8hz)
begin
if (rst='1') then -- initialization
State := ST0;
elsif (bist1 = '1' and bist2 = '1') then
--BIST CODE HERE
elsif (clk_8hz'event and clk_8hz='1') then
case State is

when ST0 =>
-- Initialize
--INITALIZE STATE VARIABLES
--dont really have any states to init atm, but might later!
q_counter := 0;
s_counter := 0;
timer := 0;

disp_1 := 10;
disp_10 := 10;
disp_100 := 10;
AN3 <= '1';
if (bist1 = '1') then
State := ST1;
end if;
when ST1 =>
-- Generate Random Number
--if the q_counter is 10 then get a new random, otherwise, were
done with the test
if (q_counter = 10) then
State:= ST6;
else
--RANDOM NUMBER GENERATION HERE -- up to 255
-- rand <=

--This gives us the value that must be displayed on EACH
SEGEMENT of the Seven Segemnt Display
--disp_1 := ((rand / 1) mod 10);
--disp_10 := ((rand / 10) mod 10);
--disp_100 := ((rand / 100) mod 10);
disp_1 := 8;
disp_10 := 2;
disp_100 := 1;
rand := disp_100 *100 + disp_10 * 10 + disp_1;
--DISPLAY RANDOM NUMBER
State := ST2;
end if;

when ST2 => -- Get Input
Data_X := x_i;
State := ST3;

when ST3 => -- IDLE
State := ST4;
when ST4 => -- IDLE


State := ST5;

when ST5 => -- Compare

if (Data_X=rand) then
--Correct
--Display "YES" message or "correct" message
--set timer to 0, otherwise could get stuck at like 2
timer:= 8;
--Increment Score counter
s_counter := s_counter + 1;
--Increment Question Counter
q_counter := q_counter + 1;
--GOTO ST1
State:= ST1;
AN3 <= '0';

elsif (timer = 0) then
timer :=8;
--Time has expired on this question, so lets increment the
question counter
--and move on to the next
q_counter :=q_counter + 1;
AN3 <= '0';
State := ST1;

--SSG <= "00000001";
else
--incorrect
--keep showing original random number
--decrement the TIMER
AN3 <= '1';
timer := timer - 1;
State:= ST1;
end if;

when ST6 => -- End of Program
--We're done, report result for all time
--rand := s_counter;
disp_1:= s_counter;
disp_10:= 11;
AN3 <= '1';
disp_100:=11;
when others => -- UNHANDLED EXCEPTION
State := ST0;
end case;
end if;

end process;
--update on every 8hz tick and every random number update
process (clk_8khz)
begin
--- Control the Display on the 8hz clock
if (clk_8khz = '1' and clk_8khz'event) then
if (AN0 = '0') then

AN0 <= '1';
--General BCD decoder for the 1's place
case disp_10 is
when 0 => SSG <= "00000011";
when 1 => SSG <= "10011111";
when 2 => SSG <= "00100101";
when 3 => SSG <= "00001101";
when 4 => SSG <= "10011001";
when 5 => SSG <= "01001001";
when 6 => SSG <= "11000001";
when 7 => SSG <= "00011111";
when 8 => SSG <= "00000001";
when 9 => SSG <= "00001001";
when 10=> SSG <= "00110001";--P
when others => SSG <= "11111111";
end case;

AN1 <= '0';
elsif (AN1 = '0') then
AN1 <= '1';
--General BCD decoder for the 10's place
case disp_100 is
when 0 => SSG <= "00000011";
when 1 => SSG <= "10011111";
when 2 => SSG <= "00100101";
when 3 => SSG <= "00001101";
when 4 => SSG <= "10011001";
when 5 => SSG <= "01001001";
when 6 => SSG <= "11000001";
when 7 => SSG <= "00011111";
when 8 => SSG <= "00000001";
when 9 => SSG <= "00001001";
when 10 => SSG <= "11000101"; --o
when others => SSG <= "11111111";
end case;
AN2 <= '0';
elsif (AN2 = '0') then
AN2 <= '1';
--General BCD decoder for the 100's place
case disp_1 is
when 0 => SSG <= "00000011";
when 1 => SSG <= "10011111";
when 2 => SSG <= "00100101";
when 3 => SSG <= "00001101";
when 4 => SSG <= "10011001";
when 5 => SSG <= "01001001";
when 6 => SSG <= "11000001";
when 7 => SSG <= "00011111";
when 8 => SSG <= "00000001";
when 9 => SSG <= "00001001";
when 10 => SSG <= "11100001";--t
when others => SSG <= "11111111";
end case;
AN0 <= '0';
end if;
end if;
end process;

process (clk_8hz)
begin
if Clk_8hz='1' and Clk_8hz'event then
LED <= (conv_std_logic_vector(timer,8));
end if;


end process;

end FSMD;

--------------------------------------------------------------
 
K

KJ

bb said:
Alright, it got it to synthesize. In ST1, I can't divide a variable.
so, for me to generate i.e 128, I fixed the values,
disp_1 := 8;
disp_10 := 2;
disp_100 := 1;

So, I would like disp_100, to have a value of 1 or 0. disp_10, and
disp_1, a value from 0-7.
Congratulations, it sounds like the project is moving along.

KJ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top