Testbench\Package Signal Visibility

T

ttsmnl

First thanks for the input. Somewhat new to VHDL. I hope I can protray
my question easily enough to get a quick accurate answer.

I have a testbench which has multiple large procedures. I have these
repeated in many testbenches which is inefficient and not neat. These
procedures "take in" many (>50) signals and vectors when inititiated
from my testbench stimulus. The procedure declaration may define just
one input, however the procedure will "take in" and execute a large
testbench signal set as it is defined at that time. This large signal
set is not required as part of the procedure decleration signal set,
since they are all visible within the testbench. Below is a brief
example in text which I hope helps instead of displaying my huge
example.

procedure SIMULATE_GPS_IN (
signal SIM_SESSION : in string(1 to 10)
)
begin
---- in this procedure, many many sigals and vectors are being
utilized. However since they are all in the tesbench
---- they are visible, and don't have to be passed into the
procedure as part of the declaration statement
---- like the "SIM_SESSION" input string shown above.
end SIMULATE_GPS_IN;

STIMULUS : process

reset <= '0' ;
wait for 10us;
reset <= '1' ;

-- Test #1
A <= "0010"; B <= '1'; C <= X"1234"; -- these signals are viewed
("taken in") by the procedure
wait for 1us;
SIMULATE_GPS_IN (3); -- invoking procedure
-- add self checking tests here.

-- Test #2
A <= "1000"; B <= '0'; C <= X"3421"; -- these signals are viewed
("taken in") by the procedure
wait for 1us;
SIMULATE_GPS_IN (2); -- invoking procedure
-- add self checking tests here.

-- Test #3
A <= "1111"; -- these signals are viewed ("taken in") by the
procedure (using B, C's previous stimulus values)
wait for 1us;
SIMULATE_GPS_IN (7); -- invoking procedure
-- add self checking tests here.

end process;

Now for my question: The signals A, B, and C are utilized (read) by
the procedure when invoked. This all works great. Now when I switch to
a composite package and place all procedures within; can I still pass
just one variable into the package (and thus into the procedure within
the package), or do I now have to pass A, B, and C along with the
SIM_SESSION string value in the procedure call. Again my signal set is
huge, so when implemented inside the testbench (without a package),
the simulation portion of the testbench is very neat and easy to read
(not cluttered with each individual signal). But again, it is not very
neat to repeat every procedure in every testbench. If I can not make
the signals available (global) to the package, then I will have to
change my procedures to look like this.

procedure SIMULATE_GPS_IN (
signal A : in std_logic;
signal B : in std_logic_vector(31 downto 0);
signal C : in std_logic_vector(31 downto 0);
signal SIM_SESSION : in string(1 to 10)
)
begin
------ logic , ......................
end SIMULATE_GPS_IN;

STIMULUS : process

reset <= '0' ;
wait for 10us;
reset <= '1' ;

-- Test #1
wait for 1us;
SIMULATE_GPS_IN (A, B, C, 3); -- invoking procedure with all data
signals which are utilized to execute logic.
-- add self checking tests here.

......
......

end process;


I am trying to avoid making huge procedure declarations. If I have to
then I can't preserve the "neatness" of the testbench style when not
using a package. I HOPE that all makes sense. I believe it is a pretty
straight forward issue, but I just can't figure out how (or if) I can
make all the signals globally visible to the package without passing
them through huge procedure calls. Again (ahead of time) thanks to you
experts out there!!
 
T

Tricky

Putting signals inside a package is perfectly legal VHDL, but dont try
and synthesise it. It is not good practice and at least one vendor
(Altera) just refuses to compile them.

With your procedures, personally I would like to see the declaration
have all the ins/outs rather than randomly accessing signals
internally - it makes it more self contained and a bit clearer whats
going on. And instead of having one big procedure, why not break it up
into several smaller procedures, then it would be clearer to another
user what was going on:

eg:

GPS_INIT(a,b,c);
GPS_DO_STUFF(a,b,c);
GPS_SHUTDOWN(a,b,c);
 
J

Jonathan Bromley

First thanks for the input. Somewhat new to VHDL. I hope I can protray
my question easily enough to get a quick accurate answer.

I have a testbench which has multiple large procedures. I have these
repeated in many testbenches which is inefficient and not neat. These
procedures "take in" many (>50) signals and vectors when inititiated
from my testbench stimulus. The procedure declaration may define just
one input, however the procedure will "take in" and execute a large
testbench signal set as it is defined at that time. This large signal
set is not required as part of the procedure decleration signal set,
since they are all visible within the testbench.

This is a fairly standard problem so I hope the group will
excuse me if I repeat my standard solution, which has
appeared here before.

As you suspected, moving the procedures into a package is:

1) A Very Good Idea -
because it avoids all that copy-paste and gives you a
block of code that you can simply import into future
testbench projects;

2) A Darned Nuisance -
because you now must pass all the relevant testbench
signals to your procedures as explicit arguments.

The explicit argument list is not a problem in the
package itself; in fact it's a pretty good idea,
because it forces you to design and document the
procedure's signal interface clearly in the code
itself. The problem comes when you try to *use*
the procedure in your testbench, because EVERY
time you need to call it you must pass in a huge
pile of signals as arguments. All this you know
already.

Luckily there is a reasonably clean way out. Before
starting, though, let me repeat something that you
have already clearly understood: There are two distinct
kinds of argument (parameter) to this sort of procedure.
First there are the signals, usually defined in the
testbench, that represent some bus or interface to the
DUT. EVERY TIME you call the procedure, you must pass
this same set of signals to it. Secondly, there are
the arguments that decide how THIS SPECIFIC RUN of the
procedure will do its work. With that in mind, let's
run a super-simple example that illustrates the
principles: a procedure to generate a pulse on some
signal. Here it is, in a package (just the body,
for brevity):

package body pulsegen_pkg is
--- Generate a pulse on any signal S.
procedure pulse (
duration: in time; --- This run's behaviour
signal S: inout std_logic --- Which signal to hit
) is begin
S <= '1';
wait for duration;
S <= '0';
end;
end package body pulsegen_pkg;

Now let's move into the testbench.

use work.pulsegen_pkg.all;
architecture TB of my_testbench is
signal test: std_logic;
begin
test_driver: process
--- Here's the important bit. Redeclare
--- a new version of your pulse procedure.
--- It simply specializes the package's
--- procedure so that it works on my
--- chosen signal.
procedure pulse (duration: in time) is
begin
pulse(duration, test);
end;
begin
test <= '0';
pulse(20 ns); --- Much easier. Pulses 'test'.
wait for 200 ns;
pulse(30 ns);
...
end process;
end architecture TB;

This seems to me to be the best of both worlds:
- you have the procedure in a package where it belongs
- you have clearly documented, in the testbench code,
the set of signals that the proc will manipulate
- each call to the procedure now has only the "what's
different this time" arguments; the set of signals
it uses is predefined by the process's version of
the procedure

Of course, it's your choice whether you use the same
name for the procedure or a completely different name.

If your set of signals is some big complicated bus
structure, and you call bus read and write procedures
many times during a testbench process, this approach
can be a really big benefit. The package procedure
is totally re-usable - you can bring it into any
testbench, any time in the future, without copy/paste -
but unfortunately it is necessary to rewrite the
"alias" procedure for each new application. It's not
really a big deal, though.

Hope this helps.
 
V

valtih1978

can I still pass just one variable into the package

The package looks like read-only creature. I think this is a reason you
cannot easily read-write variables in them.
 
M

Mike Treseler

If a package and a variable are in a process scope,
a procedure call can write those process variables.
Variables declared *inside* the package are immutable.

-- Mike Treseler
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top