indirection with strings containing signal names?

N

newdaddy

Hi all,

There's an example in Chap 18 of Ashenden's THE DESIGNER'S GUIDE TO
VHDL which reads a stimulus file using textIO and assigns signals from
a case statement whose case expression is a string naming the input to
be assigned. The stimulus file looks like

0ms signal1 0
10ms signal2 56
15ms otherSig 70
[...]

The case statement in the stimulus_interpreter process (after a line
is read from the stimulus file and converted) looks like

case signal_ID_string is
when "signal1" =>
read (command, signal1, read_ok);
[...]
when "signal2" =>
read (command, signal2, read_ok);
[...]

I feel that this is going to be cumbersome to maintain as several
hundred IO signals get added, resized, etc. Moreover it is starkly
inelegant. What I really want here is to simply to force a level of
evaluation on the string containing the signal name to be changed
(signal_ID_string in the example above) and simply assign the read
value to that signal, and get rid of the case statement altogether.
Something like

read (command, [eval signal_ID_string], read_ok);

though I know this syntax does not exist in the language.

Does anything exist in vhdl that would let me do that? What other
approaches are people using? I'd like to avoid reading values for
every port of the device at every simulation cycle as that would cause
a lot of unnecessary simulation events.

Thanks for any info you can share,

newdaddy
 
T

Tricky

Hi all,

There's an example in Chap 18 of Ashenden's THE DESIGNER'S GUIDE TO
VHDL which reads a stimulus file using textIO and assigns signals from
a case statement whose case expression is a string naming the input to
be assigned. The stimulus file looks like

0ms signal1 0
10ms signal2 56
15ms otherSig 70
[...]

The case statement in the stimulus_interpreter process (after a line
is read from the stimulus file and converted) looks like

case signal_ID_string is
when "signal1" =>
read (command, signal1, read_ok);
[...]
when "signal2" =>
read (command, signal2, read_ok);
[...]

I feel that this is going to be cumbersome to maintain as several
hundred IO signals get added, resized, etc. Moreover it is starkly
inelegant. What I really want here is to simply to force a level of
evaluation on the string containing the signal name to be changed
(signal_ID_string in the example above) and simply assign the read
value to that signal, and get rid of the case statement altogether.
Something like

read (command, [eval signal_ID_string], read_ok);

though I know this syntax does not exist in the language.

Does anything exist in vhdl that would let me do that? What other
approaches are people using? I'd like to avoid reading values for
every port of the device at every simulation cycle as that would cause
a lot of unnecessary simulation events.

Thanks for any info you can share,

newdaddy

I can see this being useful for maybe a small design, but like you
said, it becomes very cumbersom.

If you are trying to handle a complex sequence for something like a
control bus, write a procedure that handles a single control cycle,
and have it fired off at random or other controlled intervals in your
testbench. Use the "uniform" function in math_real to create random
wait times between bus cycles, along with any other random input you
need to the system (remember to test all edge and corner cases first).
You then expand this up so you have several procedures all being
controlled at given and expected intervals, instead of manually
controlling each signal individually via a text stimulus file.

If you like, this may then change your input file to be a list of
procedure calls, rather than a whole list of forced signals.

If it is just a data processor, with for example, a data input and
data_valid input, I tend to just stimulate the data with a random
sequence, or another given sequence, and randomly toggle the valid bit
(only changing the input when you have said the input it valid). this
then shrinks your input process to a few lines that can force in as
many or as few values as you like.

an example, this inputs 2 images into a UUT. The images are created
elsewhere, either from file or a random sequence.:


--------------------------------------------------------------------------------------------------
--input_proc : Reads the data into the UUT from the 2 input files

--------------------------------------------------------------------------------------------------
input_proc : process
variable pix_count : integer := 0;
variable line_count : integer := 0;

--used to randomly inject DATA
constant MIN_WAIT : integer := 0;
constant MAX_WAIT : integer :=
10;
variable s1, s2 : positive :=
RANDOM_SEED + 445654;
variable rand_wait : integer;

--used to end this process when we get to the end of the images;
variable END_IP : boolean :=
false;
begin

wait until reset = '0';

while not ENDSIM and not END_IP loop

--we may be waiting
data_valid <= '0';
rand_int(s1, s2, MIN_WAIT, MAX_WAIT, rand_wait);

--wait for a random period of time before applying the next
input
for i in 1 to rand_wait loop
wait until falling_edge(clk) or ENDSIM = true;
end loop;

--enter the next value into the UUT
vid_in1 <= IMAGE1(line_count)(pix_count);
vid_in2 <= IMAGE2(line_count)(pix_count);
data_valid <= '1';

pix_count := pix_count + 1;

if pix_count = IMAGE_SETUP.lineLength then
pix_count := 0;
line_count := line_count + 1;

if line_count = IMAGE_SETUP.numLines then
END_IP := true;

end if;
end if;

wait until falling_edge(clk) or ENDSIM = true;
end loop;

--dont input any more data
data_valid <= '0';

endsim_ip <= "11";
wait;
end process;
 
K

KJ

I feel that this is going to be cumbersome to maintain as several
hundred IO signals get added, resized, etc.  Moreover it is starkly
inelegant.  

You got that right!
What I really want here is to simply to force a level of
evaluation on the string containing the signal name to be changed
(signal_ID_string in the example above) and simply assign the read
value to that signal, and get rid of the case statement altogether.
Something like

    read (command, [eval signal_ID_string], read_ok);

You would be far better off simply writing additional VHDL code for
your testbench.
Does anything exist in vhdl that would let me do that? What other
approaches are people using?   I'd like to avoid reading values for
every port of the device at every simulation cycle as that would cause
a lot of unnecessary simulation events.

Thanks for any info you can share,

The only advantage to having a text file input driving the simulation
is that you don't need to 'compile' it whereas if you modelled the
system with VHDL code you would. Now consider that the compiling step
will cost you about 1 second per iteration but ask yourself what you
get for that 1 second per iteration?
- Syntax checking
- All the flow control, special cases, etc. that you can imagine

There are others, but I'll stop. The point is that using text file
input to basically drive signals is not a very good use. Using a text
file say for controlling which tests actually get performed or skipped
on a particular simulation run is a better use and it likely won't
grow too cumbersome to maintain...don't forget, that input file
whether big or small is now part of the project and needs to be
maintained just like the testbench and design code.

Kevin Jennings
 
N

newdaddy

I do understand the advantages of prodecural vhdl in TBs, and I
appreciate an thankful all the good advice in that regard. Maybe I
contrived too complicated an example. But I think the question is a
good general one and is still worth answering, or trying to - is there
an facility for indirection or for dynamic calling of code in vhdl,
other than creating some huge case or if-else structure?

newdaddy
 
M

Mike Treseler

newdaddy said:
is there
an facility for indirection or for dynamic calling of code in vhdl,
other than creating some huge case or if-else structure?

Not exactly.
I use generics on the command line like this:

-- run assertions only:
vsim -c test_uart -do "run -all; exit"

-- force an error 116:
vsim -Gwire_g=random -c test_uart -do "run -all; exit"

-- force an error 0:
vsim -Gwire_g=stuck_hi -c test_uart -do "run -all; exit"

-- change template:
vsim -Gtemplate_g=s_rst -c test_uart -do "run -all; exit"

-- slow baud:
vsim -Gtb_tics_g=42 -c test_uart -do "run -all; exit"

-- run with waves: vsim test_uart -do uart.do

-- verify strobe calibration: vsim -Gtb_tics_g=42 test_uart
-- then "do uart.do" from modelsim prompt

See http://home.comcast.net/~mike_treseler/ for details.

The next step might be to use a shell/python/tcl script
to orchestrate the vsim commands.
Then maybe a tk gui to click buttons.
But I just cut and past text commands to an emacs shell.

-- Mike Treseler
 
J

jtw

I've done something like Mike's example many times, including using a
generic to select the appropriate input (and output) file.

For some cases, a VHDL-based functional model is appropriate; for others, a
text file that defines a 'golden' vector set is appropriate; sometimes, time
is of the essence, and you work with what is currently available. (Does it
almost always seem that way?)

JTW
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top