Driving signals from a procedure

A

Andy Peters

I'm baffled by how VHDL deals with procedures and driving signals, and
how some things are visible and others aren't. For example, in the
following skeleton a call to the parameterless procedure InitS() calls
the more-generic procedure Init() in order to initialize my signals s1
and s2. The idea is that the procedure InitS() is visible to other
modules in my test bench (its declaration is in a package) and I'm
trying to avoid passing a lot of signals around.

entity foo;
end entity foo;

architecture bar of foo is
signal s1 : std_logic;
signal s2 : std_logic;

-- initialize any two bits.
procedure Init (
signal b1 : out std_logic;
signal b2 : out std_logic ) is
begin
b1 <= '0';
b2 <= '0';
end procedure Init;

-- call InitS to initialize s1 and s2:
procedure InitS is
begin
Init(s1, s2);
end procedure InitS;

begin -- architecture bar of foo
... do whatever
end architecture bar;

When I compile this, I get

"Cannot drive signal 's1' from this subprogram." and
"Cannot drive signal 's2' from this subprogram." errors.

I realize problem here is that signals s1 and s2 are not available to
be assigned from a procedure if they're not passed in as out signal
parameters.

So, what's a reasonable workaround?

-a
[real e-mail: devel (at) latke (dot) net]
 
A

Andy Peters

Mike said:
I put all the testbench procedures between the
IS and BEGIN of the main test process.
This allows you to access any signal in the
testbench architecture without passing parameters.

Ah, but the "gotcha" in this case is that I want to create a standalone
module -- in this case, it's essentially a signal generator -- that I
can include in my testbench. The idea is that my test bench process
can simply call a "GeneratePattern" procedure in the signal generator
module and have it do its magic.

I found a sorta-solution in Janick Bergeron's book; it's his notion of
"client/server control." I created a global signal (of a custom
"command type") that's twiddled in the main test bench process (the
client), and a process in the signal generator module (the server)
waits on a transaction on that signal. The server parses that command
signal and calls the appropriate procedure.

I hate to say it, but this is one area where Verilog shines; calling
tasks in other modules is as simple as a C function call.

Ah, well!

-a
 
A

ALuPin

You can call your "generator" procedure within the main process
and pass the signals - if necessary - to a different procedure (again
from
the main process).

Rgds
André
 
J

Jonathan Bromley

[for the need to wire-up every signal to any procedure
declared in a package, and related irritations]
Ah, but the "gotcha" in this case is that I want to create a standalone
module -- in this case, it's essentially a signal generator -- that I
can include in my testbench. The idea is that my test bench process
can simply call a "GeneratePattern" procedure in the signal generator
module and have it do its magic.

I found a sorta-solution in Janick Bergeron's book; it's his notion of
"client/server control." I created a global signal (of a custom
"command type") that's twiddled in the main test bench process (the
client), and a process in the signal generator module (the server)
waits on a transaction on that signal. The server parses that command
signal and calls the appropriate procedure.

Yes, but that's a hideous fuss to do something that's essentially
just a remote procedure call.
I hate to say it, but this is one area where Verilog shines; calling
tasks in other modules is as simple as a C function call.

I absolutely agree - although Verilog's cavalier attitude to
process synchronisation (in summary: who cares?!) is a
major problem for anyone who has ever stopped to think about
concurrent programming for more than about five minutes.

There *is* a workaround in VHDL, though it's not ideal.
Suppose you have a general-purpose procedure declared in a
package. Naturally, it has truckloads of signal parameters
to describe all the signals it drives and examines. When
calling this procedure, you are not much interested in these
signal parameters - they're the same every time you call it -
but you do want to be able to parameterise things like
pulse durations, the things that are different from one
call to the next.

So, my preferred solution is to keep the nice-but-clumsy
general-purpose procedure in the package, and then write
a simple jacket procedure inside each process that makes
use of the procedure. The jacket procedure can stitch
signals to the procedure, and it's entirely clear both
to you and to VHDL that the driver on any outputs is the
enclosing process. Better, but far from perfect -
I'd be interested to know if it helps with your issue.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

library ieee;
use ieee.std_logic_1164.all;

package pulsegen_package is
procedure pulsegen (
signal pulse_output: out std_logic;
high_period: in time;
low_period: in time;
pulse_count: in positive
);
end package;

package body pulsegen_package is
-- obvious implementation
end package body;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

library ieee;
use work.pulsegen_package.all;
use ieee.std_logic_1164.all;

entity testbench is end;
architecture T of testbench is

signal S1, S2: std_logic;

begin

S1_driver: process
procedure pulser(high_period: in time) is
begin
-- General procedure, specialised to deliver
-- single pulses on S1
pulsegen(S1, high_period, 10ns, 1);
end
begin
...
pulser(5 ns);
pulser(10 ns);
...
end process S1_driver;

S2_driver: process
procedure pulsetrain(N: in positive) is
begin
-- General procedure, specialised to deliver
-- a train of 100MHz pulses on S2
pulsegen(S2, 5 ns, 5 ns, N);
end
begin
...
pulsetrain(15);
...
end process S2_driver;

end architecture T;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:[email protected]
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top