random number generator function

Discussion in 'VHDL' started by bb, Nov 22, 2007.

  1. bb

    bb Guest

    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,
     
    bb, Nov 22, 2007
    #1
    1. Advertising

  2. On 22 Nov., 06:34, bb <> wrote:
    > 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
     
    Thomas Stanka, Nov 22, 2007
    #2
    1. Advertising

  3. bb

    Guest

    On Nov 22, 6:20 am, Thomas Stanka <>
    wrote:
    > On 22 Nov., 06:34, bb <> wrote:
    >
    > > 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
     
    , Nov 22, 2007
    #3
  4. bb

    Guest

    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
     
    , Nov 22, 2007
    #4
  5. bb wrote:
    > 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;
    --------------------------------------------------------------------
     
    Mike Treseler, Nov 22, 2007
    #5
  6. bb

    bb Guest

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

    Mike,

    How would I call that function randomize? Thanks.

    On Nov 22, 8:58 am, Mike Treseler <> wrote:
    > bb wrote:
    > > 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 herehttp://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;
    > --------------------------------------------------------------------
     
    bb, Nov 22, 2007
    #6
  7. bb wrote:

    > How would I call that function randomize?


    random_byte_s <= randomize(random_byte_s);

    See the referenced testbench.
    Search for "randomize"

    -- Mike Treseler
     
    Mike Treseler, Nov 22, 2007
    #7
  8. bb

    bb Guest

    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;

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

    On Nov 22, 1:01 pm, Mike Treseler <> wrote:
    > bb wrote:
    > > How would I call that function randomize?

    >
    > random_byte_s <= randomize(random_byte_s);
    >
    > See the referenced testbench.
    > Search for "randomize"
    >
    > -- Mike Treseler
     
    bb, Nov 24, 2007
    #8
  9. bb wrote:
    > 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
     
    Mike Treseler, Nov 25, 2007
    #9
  10. bb

    KJ Guest

    "Mike Treseler" <> wrote in message
    news:...
    > bb wrote:
    >
    >> Yes, this code was tested.

    >
    > That seems unlikely.
    >

    Testing produces results....one result of testing is error(s)....'bb' never
    said the testing produced no errors ;)
    ..
    KJ
     
    KJ, Nov 26, 2007
    #10
  11. bb

    bb Guest

    On Nov 25, 6:42 pm, Mike Treseler <> wrote:
    > bb wrote:
    > > 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


    Alright, I will fix those . . .

    But where will the function randomize be placed in this code?
     
    bb, Nov 26, 2007
    #11
  12. KJ wrote:

    > 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
     
    Mike Treseler, Nov 26, 2007
    #12
  13. bb wrote:

    > 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
     
    Mike Treseler, Nov 26, 2007
    #13
  14. bb

    bb Guest

    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;

    --------------------------------------------------------------
     
    bb, Nov 27, 2007
    #14
  15. bb

    KJ Guest

    "bb" <> wrote in message
    news:...
    > 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
     
    KJ, Nov 28, 2007
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kingsley Oteng

    Random Number Generator??

    Kingsley Oteng, Apr 27, 2004, in forum: VHDL
    Replies:
    11
    Views:
    52,958
    rahul.iyer
    Aug 9, 2010
  2. tshad

    Random number/letter generator

    tshad, May 5, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    9,605
    tshad
    May 6, 2005
  3. TheDustbustr
    Replies:
    1
    Views:
    494
    Sami Hangaslammi
    Jul 25, 2003
  4. globalrev
    Replies:
    4
    Views:
    810
    Gabriel Genellina
    Apr 20, 2008
  5. VK
    Replies:
    15
    Views:
    1,314
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page