Guest
Hi, I'm still wading my way through VHDL, after years in Verilog.
I got to generate random numbers using 'uniform', but I got stuck
trying to turn the verbose code into a function. Since I'm using it a
lot, having a one line function call makes the code much more readable.
This is for a testbench, so needs not be synthesizable.
I've included the code below (simplified from the actual code, just
contains the random # generator). It works as included, but when I try
to comment out the verbose section and use the function, I get
compilation error - "Actual for formal 'seed1' is not a variable". Can
anyone help?
I have a feeling that it has to something with seed1/2 being shared
variables. I figured out that the function needs to be impure. Do I
need the function defined with no arguments? I tried using the
function with no argument (is it legal?), declaring seed1/2 as shared
variables, even trying prodecures.
Thank you in advance.
(The problematic function is commented out, from FUNCTION_START to
FUNCTION_END), along with the function call.)
===============================================================
LIBRARY ieee;
LIBRARY modelsim_lib;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.textio.all;
use work.image_pkg.all;
entity tb_rand is
end tb_rand;
architecture behavior of tb_rand is
signal sim_done : boolean := FALSE;
signal result : std_logic_vector(15 downto 0);
signal stim32 : std_logic_vector(31 downto 0);
begin
stimulus : process
variable L : line;
variable seed1 : positive; -- Seed values for random gen
variable seed2 : positive; -- Seed values for random gen
variable rand_hi : real; -- Random real-num value, 0 to 1.0
variable rand_lo : real; -- Random real-num value, 0 to 1.0
variable int_rand_hi: integer; -- Random int value, 0..65536
variable int_rand_lo: integer; -- Random int value, 0..65536
variable stim_hi : std_logic_vector(15 downto 0); -- random 16b
variable stim_lo : std_logic_vector(15 downto 0); -- random 16b
variable i : integer;
-------------------------------------------------------------------------
-- FUNCTION_START
-- Function get_rand
-- impure function get_rand (seed1, seed2 : positive)
-- return std_logic_vector is
--
-- variable rand : real;
-- variable int_rand_hi : integer;
-- variable int_rand_lo : integer;
-- variable result : std_logic_vector(31 downto 0);
-- begin
-- -- Get 16-bit random slv
-- UNIFORM(seed1, seed2, rand);
-- int_rand_hi := integer(trunc(rand*65536.0));
-- stim_hi := std_logic_vector(to_unsigned(int_rand_hi,
-- stim_hi'LENGTH));
--
-- -- Get 16-bit random slv
-- UNIFORM(seed1, seed2, rand);
-- int_rand_lo := integer(trunc(rand*65536.0));
-- stim_lo := std_logic_vector(to_unsigned(int_rand_lo,
-- stim_lo'LENGTH));
--
-- result := stim_hi & stim_lo;
--
-- return result;
-- end get_rand;
-- FUNCTION_END
----------------------------------------------------------------
------------------------------------------------------------------
-- Test Vector stimuli
------------------------------------------------------------------
begin
seed1 := 1;
seed2 := 2;
for i in 1 to 10 loop
wait for 1 ns;
--------------------------------------------------------------
-- VERBOSE_START
-- Get 16-bit random slv
uniform(seed1, seed2, rand_hi);
int_rand_hi := INTEGER(TRUNC(rand_hi*65536.0));
stim_hi := std_logic_vector(to_unsigned(int_rand_hi,
stim_hi'LENGTH));
-- Get 16-bit random slv
uniform(seed1, seed2, rand_lo);
int_rand_lo := INTEGER(TRUNC(rand_lo*65536.0));
stim_lo := std_logic_vector(to_unsigned(int_rand_hi,
stim_hi'LENGTH));
-- Concatenate the two to form 32-bit random slv
stim32 <= stim_hi & stim_lo;
-- VERBOSE_END
--------------------------------------------------------------
-- I'd Like to replace above code
-- from 'VERBOSE_START' to 'VERBOSE_END'
-- with the following line, or something like it.
-- 'FUNCTION_START' to 'FUNCTION_END' needs to be uncommented.
-- stim32 <= get_rand(seed1, seed2) & get_rand(seed1, seed2);
wait for 1 ns;
write(L, string'("stim32 = " & HexImage(stim32)));
writeline(output, L);
end loop;
wait for 100 ns;
sim_done <= TRUE;
wait;
end process;
end behavior;
I got to generate random numbers using 'uniform', but I got stuck
trying to turn the verbose code into a function. Since I'm using it a
lot, having a one line function call makes the code much more readable.
This is for a testbench, so needs not be synthesizable.
I've included the code below (simplified from the actual code, just
contains the random # generator). It works as included, but when I try
to comment out the verbose section and use the function, I get
compilation error - "Actual for formal 'seed1' is not a variable". Can
anyone help?
I have a feeling that it has to something with seed1/2 being shared
variables. I figured out that the function needs to be impure. Do I
need the function defined with no arguments? I tried using the
function with no argument (is it legal?), declaring seed1/2 as shared
variables, even trying prodecures.
Thank you in advance.
(The problematic function is commented out, from FUNCTION_START to
FUNCTION_END), along with the function call.)
===============================================================
LIBRARY ieee;
LIBRARY modelsim_lib;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.textio.all;
use work.image_pkg.all;
entity tb_rand is
end tb_rand;
architecture behavior of tb_rand is
signal sim_done : boolean := FALSE;
signal result : std_logic_vector(15 downto 0);
signal stim32 : std_logic_vector(31 downto 0);
begin
stimulus : process
variable L : line;
variable seed1 : positive; -- Seed values for random gen
variable seed2 : positive; -- Seed values for random gen
variable rand_hi : real; -- Random real-num value, 0 to 1.0
variable rand_lo : real; -- Random real-num value, 0 to 1.0
variable int_rand_hi: integer; -- Random int value, 0..65536
variable int_rand_lo: integer; -- Random int value, 0..65536
variable stim_hi : std_logic_vector(15 downto 0); -- random 16b
variable stim_lo : std_logic_vector(15 downto 0); -- random 16b
variable i : integer;
-------------------------------------------------------------------------
-- FUNCTION_START
-- Function get_rand
-- impure function get_rand (seed1, seed2 : positive)
-- return std_logic_vector is
--
-- variable rand : real;
-- variable int_rand_hi : integer;
-- variable int_rand_lo : integer;
-- variable result : std_logic_vector(31 downto 0);
-- begin
-- -- Get 16-bit random slv
-- UNIFORM(seed1, seed2, rand);
-- int_rand_hi := integer(trunc(rand*65536.0));
-- stim_hi := std_logic_vector(to_unsigned(int_rand_hi,
-- stim_hi'LENGTH));
--
-- -- Get 16-bit random slv
-- UNIFORM(seed1, seed2, rand);
-- int_rand_lo := integer(trunc(rand*65536.0));
-- stim_lo := std_logic_vector(to_unsigned(int_rand_lo,
-- stim_lo'LENGTH));
--
-- result := stim_hi & stim_lo;
--
-- return result;
-- end get_rand;
-- FUNCTION_END
----------------------------------------------------------------
------------------------------------------------------------------
-- Test Vector stimuli
------------------------------------------------------------------
begin
seed1 := 1;
seed2 := 2;
for i in 1 to 10 loop
wait for 1 ns;
--------------------------------------------------------------
-- VERBOSE_START
-- Get 16-bit random slv
uniform(seed1, seed2, rand_hi);
int_rand_hi := INTEGER(TRUNC(rand_hi*65536.0));
stim_hi := std_logic_vector(to_unsigned(int_rand_hi,
stim_hi'LENGTH));
-- Get 16-bit random slv
uniform(seed1, seed2, rand_lo);
int_rand_lo := INTEGER(TRUNC(rand_lo*65536.0));
stim_lo := std_logic_vector(to_unsigned(int_rand_hi,
stim_hi'LENGTH));
-- Concatenate the two to form 32-bit random slv
stim32 <= stim_hi & stim_lo;
-- VERBOSE_END
--------------------------------------------------------------
-- I'd Like to replace above code
-- from 'VERBOSE_START' to 'VERBOSE_END'
-- with the following line, or something like it.
-- 'FUNCTION_START' to 'FUNCTION_END' needs to be uncommented.
-- stim32 <= get_rand(seed1, seed2) & get_rand(seed1, seed2);
wait for 1 ns;
write(L, string'("stim32 = " & HexImage(stim32)));
writeline(output, L);
end loop;
wait for 100 ns;
sim_done <= TRUE;
wait;
end process;
end behavior;