Defining Stimulus type and encapsulating parameters

T

Tricky

Guest
I have the following type I can use in testbenches, normally as a
generic:

type stimulus_type is (random, count, from_file)

following the generic, I have to have other generics like:
RANDOM_SEED, COUNT_FROM, FILE_PATH that define how the stimulus is
constrained. But these generics have to always be present and given
some value, even if they are not used. Annoyingly, I have to have
these 3 secondary generics for each ip stimulus.

Would there be a more clever way of doing it to encapsulate the
parameters better, via subtyped records or something (if thats even
allowed) where I could do something like:

generic (
IP_A_STIM : stimulus_type := (type => from_file, filepath => "c:\data
\some_data");
IP_B_STIM : stimulus_type := (type => random, seed => 12345);
....etc
);

This would probably make it difficult, if not impossible to override
the generic via TCL when you call VSIM, but I thought it was an
interesting thought experiment. I cant think how Id even start -
parsing it might fail as the types wouldnt be the same. Anyone else
with some clever ideas?
 
Tricky wrote:

This would probably make it difficult, if not impossible to override
the generic via TCL when you call VSIM, but I thought it was an
interesting thought experiment.
My brain is too tired for such an experiment.
I put canned data into the testbench package as
some constant structure. The generic could just be an index
the defaults to the simplest version.

If the stim data is computable,
I generate the constants in the testbench
using a vhdl function.

-- Mike Treseler
 
On Wed, 29 Apr 2009 08:12:01 -0700 (PDT), Tricky wrote:

I have the following type I can use in testbenches, normally as a
generic:

type stimulus_type is (random, count, from_file)

following the generic, I have to have other generics like:
RANDOM_SEED, COUNT_FROM, FILE_PATH that define how the stimulus is
constrained. But these generics have to always be present and given
some value, even if they are not used. Annoyingly, I have to have
these 3 secondary generics for each ip stimulus.

Would there be a more clever way of doing it to encapsulate the
parameters better, via subtyped records or something
Interesting question.

VHDL doesn't have any notion of variant types, so that's
out. But I think your records idea, together with Mike's
point about using functions, would cut it.

1) Make a record with all the possibilities in it
(in a package, of course):

type t_stim_control is record
kind: stinulus_type; -- (random, count, from_file)
random_seed: integer;
count_from: integer;
file_path: string (1 to 100); -- sadly this must be constrained
end record;

2) Make a function that constructs one of these from arguments,
but has defaults on most of the args, also in the package:

function stim_control
( kind: stinulus_type
; random_seed: integer := 1
; count_from: integer := 0
; file_path: string := ""
)
return t_stim_control
is
variable SC: t_stim_control;
begin
SC.kind := kind; -- other elements default-initialise
case kind is
random => SC.random_seed := random_seed;
count => SC.count_from := count_from;
from_file => file_path := str_pad(file_path, 100);
default => null;
endcase;
return SC;
end;

3) Now you can patch-up your generics nicely,
specifying only the fields you care about:

test1: entity work.test_widget
generic map ( stim_control (
kind => random,
random_seed => 42 )
);

test2: entity work.test_widget
generic map ( stim_control (
kind => from_file,
file_path => "stuff.txt" )
);

You'll need to create the "str_pad" function to convert
the function argument's unconstrained string into a
suitable constrained string to fit in the record -
I reckon you're OK with that!

One nice aspect of this is that, if you add more new
stuff to the record, you will need to update the
"stim_control" function but all your other existing
code will still be backward-compatible with the new
definitions.

Hope this helps
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"Tricky" <Trickyhead@gmail.com> wrote in message
news:1125c227-35c2-4693-8b96-41dba50d4afc@y10g2000prc.googlegroups.com...

type t_stim_control is record
kind: stinulus_type; -- (random, count, from_file)
random_seed: integer;
count_from: integer;
file_path: string (1 to 100); -- sadly this must be constrained
end record;

Am I right in thinking with VHDL-2008 standard, when its fully adopted
in 2018,
I am hoping for 2017 but then again I am an optimist :)

would remove this constraining restriction, allowing the
function to return the record with the given constant string defining
the length?
Not sure if it is answering your question but VHDL2008 allow type generics
and generics on packages,

Another question, how am I going to now override this function call
via the VSIM -gGENERIC=stuff call in TCL? my knowledge of TCL extends
to calling VLIB, VMAP, VCOM and VSIM, though willing to learn/see some
more clever stuff.
As a minimum I would learn 3 extra Modelsim Tcl commands, force, examine and
when

Hans
www.ht-lab.com
 
On Thu, 30 Apr 2009 02:38:26 -0700 (PDT), Tricky wrote:

  type t_stim_control is record
    kind: stinulus_type; -- (random, count, from_file)
    random_seed: integer;
    count_from:  integer;
    file_path: string (1 to 100);  -- sadly this must be constrained
  end record;

Am I right in thinking with VHDL-2008 standard, when its fully adopted
in 2018, would remove this constraining restriction, allowing the
function to return the record with the given constant string defining
the length?
I believe that's correct; Jim Lewis or Alan Fitch will be
more authoritative though. I've somewhat ignored VHDL-2008,
having been overly occupied with SystemVerilog :-(

Another question, how am I going to now override this function call
via the VSIM -gGENERIC=stuff call in TCL?
Oh Ł$%^&*, that blows it: you can't set record generics
from the ModelSim command line. Grrrr. Sorry.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
  type t_stim_control is record
    kind: stinulus_type; -- (random, count, from_file)
    random_seed: integer;
    count_from:  integer;
    file_path: string (1 to 100);  -- sadly this must be constrained
  end record;
Am I right in thinking with VHDL-2008 standard, when its fully adopted
in 2018, would remove this constraining restriction, allowing the
function to return the record with the given constant string defining
the length?

Another question, how am I going to now override this function call
via the VSIM -gGENERIC=stuff call in TCL? my knowledge of TCL extends
to calling VLIB, VMAP, VCOM and VSIM, though willing to learn/see some
more clever stuff.

Thanks for the help, I think ill borrow this into my
Testbench_tools_package. :)

Richard
 
On Wed, 29 Apr 2009 08:12:01 -0700 (PDT), Tricky wrote:

generic:

type stimulus_type is (random, count, from_file)

following the generic, I have to have other generics like:
RANDOM_SEED, COUNT_FROM, FILE_PATH that define how the stimulus is
constrained. But these generics have to always be present and given
some value, even if they are not used. Annoyingly, I have to have
these 3 secondary generics for each ip stimulus.
It suddenly occurred to me: WHY do you need to provide them all?
Why not give them all default values? You could easily arrange
that the default was a sufficiently silly value that it could
be regarded as an error if it _were_ needed. And then you
can override only the generics you actually need.

entity TB_TOP is
generic
( kind: stimulus_type -- no default
; random_seed : integer := 0
; count_from : integer := integer'low -- silly value
; file_path : string := "" -- silly value
);
...

Now it's OK to do....

test1: entity work.TB_TOP
generic map (kind => count, count_from => 1);
-- don't bother to override other generics

But I guess you've thought of that, and have a specific
reason why you don't want it???

Anyway, having done that, I suggest that you would then
do something like this inside the entity's architecture:

architecture STUFF of TB_TOP is
...
function validate_generics return boolean is
-- Returns TRUE if all is OK, FALSE if any problem.
-- Gives information on all known problems,
-- using warning-level reports, before returning.
begin
report "Running test in "
& stimulus_type'image(kind)
& " mode";
case kind is
when random =>
if random_seed <= 0 then
report "random_seed must be positive!"
severity warning; -- NOT error or failure!!!!!
return false;
end if;
when count =>
if count_from = integer'low
report "count_from must be overridden!"
severity warning;
return false;
end if;
... and so on
end case;
return true; -- if everything was OK
end;

Note that the function only yields NOTE and WARNING reports,
so that you don't kill off the sim just yet - you want as
much diagnostic info as you can get, even in error conditions.
But then you can put the whole function into an ASSERT:

...
begin -- the testbench architecture
assert validate_generics -- runs the function at time 0
report "INVALID CONFIGURATION - Review previous warnings"
severity FAILURE;
...

I quite like this technique - it gives lots of useful config
checking and diagnostics, and then halts the sim if it's wrong.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
But I guess you've thought of that, and have a specific
reason why you don't want it???
Actually I didnt really think of that - I was coming at this from the
POV of someone else being presented with the TB and then being
overwhelmed with setup generics, but actually what I didnt consider
was that they are more likely to run it from a TCL script, so this
second method makes ALOT more sense.

Ill still keep the first function in the tool package though - might
be useful one day :)
 
Tricky,
Since Jonathan has already thrown several stones at your
problem, first I will comment.

WRT using records such as, "type t_stim_control is record":
I use these for dynamic controls and make them signals. This
way if I can switch between configurations of my UARTs during
a given test and I don't have to have separate test cases for
it. Note you have to use appropriate synchronization when
switching between different configurations.

I like the initialized generics approach and use this frequently.

Since your switching is static, you could also use separate
architectures for the random and from_file. This adds some
complexity WRT controlling it from a simulation. I typically
use a configuration. With a configuration, I can select
the architecture and map any generics that need to be mapped
or re-mapped. Typically I will leave the generics off the
component and have them only on the entity - this means I can
only map them in the configuration. This also means that each
entity only needs the generics that it uses. Alternately
you could put the entire set of generics on each entity
and the component, but this seems like lots of busy work.

Configurations seem to add some complexity to running your
testbench, but at the end of the day (or project) when you
need to run regressions, all this information is either
specified in a configuration or in your simulation
run script with command line generics. Configurations
allow you to do this in a organized, language standard
fashion. They also allow you to reach down levels of hierarchy,
so there is no need to pass generics through the hierarchy
to get access to them - so I only do this when there is a
logical, encapsulation reason to do this.

With that said, the fine print would also say that I don't
do everything with configurations. For example, I select
between the gate and rtl versions of my design by using
default binding (most recently compiled architecture).
Otherwise, you quickly double the number of configurations
you need.

Cheers,
Jim
SynthWorks VHDL Training
 
Richard,
  type t_stim_control is record
    kind: stinulus_type; -- (random, count, from_file)
    random_seed: integer;
    count_from:  integer;
    file_path: string (1 to 100);  -- sadly this must be constrained
  end record;

Am I right in thinking with VHDL-2008 standard, when its fully adopted
in 2018, would remove this constraining restriction, allowing the
function to return the record with the given constant string defining
the length?
Yes and that works within the function, however, the object to which
you assign the value to must know the size.

OTOH, a protected type with internal variables does this very well.
Unfortunately shared variables cannot currently be design ports.
For now that means putting them in a package and dealing with
issues if you have multiple instances of the same component -
the same issues as putting a record signal in a package.
In VHDL-2008 an interesting option that becomes available is
define the shared variable within the BFM that needs to be
configured and access the shared variable using a hierarchical
reference.

Another question, how am I going to now override this function call
via the VSIM -gGENERIC=stuff call in TCL? my knowledge of TCL extends
to calling VLIB, VMAP, VCOM and VSIM, though willing to learn/see some
more clever stuff.
You can avoid the command line switches by using a VHDL
configuration :)

Cheers,
Jim
 
I like to use a package to define a record with fields for all the
different generics I might need. Then I pass that record down through
the hierarchy as a generic on every entity (you can use sub-records
for sub-levels of hierarchy if you want). This gives me a language-
defined way (works on any simulator or synthesis tool) to manage
generics in an easy way. If you need to add a generic for a lower-
level entity, just add it to the record, define it at the top, and
extract the value only where it is needed. The record is just a
modifiable conduit through which you can pass anything that you want
down through the hierarchy, without having to manually plumb it
through each intervening level of the hierarchy.

The value of the record generic can be defined at the top level, or
defined in a package, or set by a top-level generic index into an
array of such records defined in a package.

I like to avoid the maintenance headaches of configurations and
component declarations.

What I really want is to use records as signal ports, but with user
defined modes for each element (a single record port consisting of in,
out & inout sub-ports). That way you could use the same "conduit"
technique to pass an entire interface up and down through multiple
levels of hierarchy easily.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top