package containing a global signal and a proc whic modifies it
Hi All,
I'm trying to set up a testbench, and for various reasons, I'd like to have
a package which contains some global signals and some procedures which can
be used to control those signals. When I try to do this, it is crashing
fuse (the xilinx simulation compiler). This may simply be a bug in their
compiler, but I thought I'd ask here first to see if the code I'm using is
correct. I've boiled it down to the minimal test case copied below. If
the "sig <= '1'" line is commented out, it compiles, but with that line
included, fuse crashes.
Ken
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE pkg IS
SIGNAL sig : STD_LOGIC;
PROCEDURE proc;
END pkg;
PACKAGE BODY pkg IS
PROCEDURE proc IS
BEGIN
sig <= '1';
END proc;
END package BODY pkg;
ENTITY ent IS
END ent;
USE WORK.pkg.ALL;
ARCHITECTURE model OF ent IS
BEGIN
PROCESS
BEGIN
proc;
END PROCESS;
END;
Re: package containing a global signal and a proc whic modifies it
Ken Cecka wrote:
> Hi All,
>
> I'm trying to set up a testbench, and for various reasons, I'd like to have
> a package which contains some global signals and some procedures which can
> be used to control those signals. When I try to do this, it is crashing
> fuse (the xilinx simulation compiler). This may simply be a bug in their
> compiler, but I thought I'd ask here first to see if the code I'm using is
> correct. I've boiled it down to the minimal test case copied below. If
> the "sig <= '1'" line is commented out, it compiles, but with that line
> included, fuse crashes.
>
> Ken
>
> LIBRARY IEEE;
> USE IEEE.STD_LOGIC_1164.ALL;
>
> PACKAGE pkg IS
> SIGNAL sig : STD_LOGIC;
> PROCEDURE proc;
> END pkg;
>
> PACKAGE BODY pkg IS
> PROCEDURE proc IS
> BEGIN
> sig <= '1';
> END proc;
> END package BODY pkg;
>
> ENTITY ent IS
> END ent;
>
> USE WORK.pkg.ALL;
>
> ARCHITECTURE model OF ent IS
> BEGIN
> PROCESS
> BEGIN
> proc;
> END PROCESS;
> END;
>
Obviously a crash is bad :-( but your code is incorrect. Any signals
which are read or assigned in a procedure in a package must be on the
parameter list. So you need
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE pkg IS
SIGNAL sig : STD_LOGIC;
PROCEDURE proc (signal s : out std_logic);
END pkg;
PACKAGE BODY pkg IS
PROCEDURE proc(signal s : out std_logic) IS
BEGIN
s <= '1';
END proc;
END package BODY pkg;
ENTITY ent IS
END ent;
USE WORK.pkg.ALL;
ARCHITECTURE model OF ent IS
BEGIN
PROCESS
BEGIN
proc(s => sig);
END PROCESS;
END;
Re: package containing a global signal and a proc whic modifies it
Alan Fitch wrote:
> Obviously a crash is bad :-( but your code is incorrect. Any signals
> which are read or assigned in a procedure in a package must be on the
> parameter list. So you need
Rats. That's exactly what I was hoping to avoid. Thanks for setting me
straight.
Re: package containing a global signal and a proc whic modifies it
"Alan Fitch" <[email protected]> wrote in message
news:[email protected] et...
> Ken Cecka wrote:
> > Hi All,
> >
> > I'm trying to set up a testbench, and for various reasons, I'd like to
have
> > a package which contains some global signals and some procedures which
can
> > be used to control those signals. When I try to do this, it is crashing
> > fuse (the xilinx simulation compiler). This may simply be a bug in
their
> > compiler, but I thought I'd ask here first to see if the code I'm using
is
> > correct. I've boiled it down to the minimal test case copied below. If
> > the "sig <= '1'" line is commented out, it compiles, but with that line
> > included, fuse crashes.
> >
> > Ken
> >
> > LIBRARY IEEE;
> > USE IEEE.STD_LOGIC_1164.ALL;
> >
> > PACKAGE pkg IS
> > SIGNAL sig : STD_LOGIC;
> > PROCEDURE proc;
> > END pkg;
> >
> > PACKAGE BODY pkg IS
> > PROCEDURE proc IS
> > BEGIN
> > sig <= '1';
> > END proc;
> > END package BODY pkg;
> >
> > ENTITY ent IS
> > END ent;
> >
> > USE WORK.pkg.ALL;
> >
> > ARCHITECTURE model OF ent IS
> > BEGIN
> > PROCESS
> > BEGIN
> > proc;
> > END PROCESS;
> > END;
> >
>
> Obviously a crash is bad :-( but your code is incorrect. Any signals
> which are read or assigned in a procedure in a package must be on the
> parameter list. So you need
>
> LIBRARY IEEE;
> USE IEEE.STD_LOGIC_1164.ALL;
>
> PACKAGE pkg IS
> SIGNAL sig : STD_LOGIC;
> PROCEDURE proc (signal s : out std_logic);
> END pkg;
>
> PACKAGE BODY pkg IS
> PROCEDURE proc(signal s : out std_logic) IS
> BEGIN
> s <= '1';
> END proc;
> END package BODY pkg;
>
> ENTITY ent IS
> END ent;
>
> USE WORK.pkg.ALL;
>
> ARCHITECTURE model OF ent IS
> BEGIN
> PROCESS
> BEGIN
> proc(s => sig);
> END PROCESS;
> END;
>
>
> regards
> Alan
>
> --
> Alan Fitch
> Doulos
> http://www.doulos.com
One solution is to have the procedure declared inside the architecture: this
way you can access all the signals without having to pass them. The downside
is that your architecture code won't be as neat as you'd like.
Re: package containing a global signal and a proc whic modifies it
Alvin Andries wrote:
> "Alan Fitch" <[email protected]> wrote in message
> news:[email protected] et...
>> Ken Cecka wrote:
>>> Hi All,
>>>
>>> I'm trying to set up a testbench, and for various reasons, I'd like to
> have
>>> a package which contains some global signals and some procedures which
> can
>>> be used to control those signals. When I try to do this, it is crashing
>>> fuse (the xilinx simulation compiler). This may simply be a bug in
> their
>>> compiler, but I thought I'd ask here first to see if the code I'm using
> is
>>> correct. I've boiled it down to the minimal test case copied below. If
>>> the "sig <= '1'" line is commented out, it compiles, but with that line
>>> included, fuse crashes.
>>>
>>> Ken
>>>
<snip>
<snip>
>
> One solution is to have the procedure declared inside the architecture: this
> way you can access all the signals without having to pass them. The downside
> is that your architecture code won't be as neat as you'd like.
>
> Regards,
> Alvin.
>
>
Hi Alvin,
what you state is correct for a procedure inside a process. If you
declare a procedure in an architecture, all outputs must be on the
argument list. Inputs may be omitted if and only if the signals are
declared before the procedure,
What my colleague Jonathan often suggests is to write a simple wrapper
procedure inside the process where it's used, e.g.
ARCHITECTURE model OF ent IS
BEGIN
PROCESS
procedure proc is
begin
proc(s);
end procedure;
BEGIN
proc;
END PROCESS;
END;
That means you only have to sort out the parameter list once per process.
Re: package containing a global signal and a proc whic modifies it
Alvin Andries wrote:
> "Alan Fitch" <[email protected]> wrote in message
> news:[email protected] et...
>> Ken Cecka wrote:
>>> Hi All,
>>>
>>> I'm trying to set up a testbench, and for various reasons, I'd like to
> have
>>> a package which contains some global signals and some procedures which
> can
>>> be used to control those signals. When I try to do this, it is
crashing
>>> fuse (the xilinx simulation compiler). This may simply be a bug in
> their
>>> compiler, but I thought I'd ask here first to see if the code I'm using
> is
>>> correct. I've boiled it down to the minimal test case copied
below. If
>>> the "sig <= '1'" line is commented out, it compiles, but with that line
>>> included, fuse crashes.
>>>
>>> Ken
>>>
<snip>
<snip>
>
> One solution is to have the procedure declared inside the
architecture: this
> way you can access all the signals without having to pass them. The
downside
> is that your architecture code won't be as neat as you'd like.
>
> Regards,
> Alvin.
>
>
Hi Alvin,
what you state is correct for a procedure inside a process. If you
declare a procedure in an architecture, all outputs must be on the
argument list. Inputs may be omitted if and only if the signals are
declared before the procedure,
What my colleague Jonathan often suggests is to write a simple wrapper
procedure inside the process where it's used, e.g.
ARCHITECTURE model OF ent IS
BEGIN
PROCESS
procedure proc is
begin
proc(s);
end procedure;
BEGIN
proc;
END PROCESS;
END;
That means you only have to sort out the parameter list once per process.
Re: package containing a global signal and a proc whic modifies it
On Thu, 11 Sep 2008 13:58:03 GMT, Ken Cecka <ceckak[email protected]> wrote:
>Alan Fitch wrote:
>
>> Obviously a crash is bad :-( but your code is incorrect. Any signals
>> which are read or assigned in a procedure in a package must be on the
>> parameter list. So you need
>
>Rats. That's exactly what I was hoping to avoid. Thanks for setting me
>straight.
Mike Treseler's testbench examples show a reasonable compromise.
His package exports procedures with signal parameters as Alan Fitch
showed.
But to keep the main process using them clean, he overrides these
procedures, locally to the process, with parameterless procedures. These
have visibility to all the signals the process has, and simply call the
package procedures, passing these signals as appropriate.
------------- Alan's package ---------------------
PACKAGE pkg IS
SIGNAL sig : STD_LOGIC;
PROCEDURE proc (signal s : out std_logic);
END pkg;
PACKAGE BODY pkg IS
PROCEDURE proc(signal s : out std_logic) IS
BEGIN
s <= '1';
END proc;
END package BODY pkg;
----------- Modified user architecture ---------------------
USE WORK.pkg.ALL;
ARCHITECTURE model OF ent IS
BEGIN
PROCESS
-- local procedures (here) can see all signals the process can see
-- Override pkg proc with no ambiguity; different parameters
procedure proc is
BEGIN
proc(s => sig);
END proc;
-- now the user process can be kept clean
BEGIN
proc;
END PROCESS;
END;
Re: package containing a global signal and a proc whic modifies it
On Thu, 11 Sep 2008 17:31:59 +0100, Brian Drummond wrote:
>Mike Treseler's [...]
> package exports procedures with signal parameters as Alan Fitch
>showed.
>
>But to keep the main process using them clean, he overrides these
>procedures, locally to the process, with parameterless procedures. These
>have visibility to all the signals the process has
One little heads-up might be in order here: *visibility*
of signals referenced in the procedure is not the only
issue.
The only thing that can drive a signal is a *process*.
If a *procedure* wishes to drive a signal, then
either:
- that procedure must be declared in a process, so that the
enclosing process is unambiguously the signal's driver;
or:
- the procedure must drive the signal through its
parameter list. The procedure is then called from
within the body of some process, and it's the signal
supplied by the process as an actual parameter
that is driven.
Visibility matters too, of course, but it doesn't
explain why (for example) a procedure in a package
is not permitted to drive global signals of the
package directly, and why a procedure declared
in an architecture is not permitted to drive
architecture-level signals except through its
parameter list.
Note that a procedure is perfectly entitled to *read* a
signal that is visible, without going through a parameter.
Sorry to nit-pick about something that I'm sure
Brian already knows, but it's potentially quite
confusing.
--
Jonathan Bromley, Consultant
Re: package containing a global signal and a proc whic modifies it
On Thu, 11 Sep 2008 19:12:17 +0100, Jonathan Bromley
<[email protected]> wrote:
>On Thu, 11 Sep 2008 17:31:59 +0100, Brian Drummond wrote:
>
>>Mike Treseler's [...]
>> package exports procedures with signal parameters as Alan Fitch
>>showed.
>>
>>But to keep the main process using them clean, he overrides these
>>procedures, locally to the process, with parameterless procedures. These
>>have visibility to all the signals the process has
>
>One little heads-up might be in order here: *visibility*
>of signals referenced in the procedure is not the only
>issue.
>
>The only thing that can drive a signal is a *process*.
>If a *procedure* wishes to drive a signal, then
>
>either:
>- that procedure must be declared in a process, so that the
> enclosing process is unambiguously the signal's driver;
>
>or:
>- the procedure must drive the signal through its
> parameter list. The procedure is then called from
> within the body of some process, and it's the signal
> supplied by the process as an actual parameter
> that is driven.
Good explanation. Thanks for not letting me gloss over it...
>"a procedure in a package
>is not permitted to drive global signals of the
>package directly"
....
>Sorry to nit-pick about something that I'm sure
>Brian already knows, but it's potentially quite
>confusing.
not at all!
Yes I knew the section I enclosed in quotes above, but I didn't really
understand why! So I found this useful too.
Re: package containing a global signal and a proc whic modifies it
Brian Drummond wrote:
> On Thu, 11 Sep 2008 13:58:03 GMT, Ken Cecka <[email protected]> wrote:
>
>>Alan Fitch wrote:
>>
>>> Obviously a crash is bad :-( but your code is incorrect. Any signals
>>> which are read or assigned in a procedure in a package must be on the
>>> parameter list. So you need
>>
>>Rats. That's exactly what I was hoping to avoid. Thanks for setting me
>>straight.
>
> Mike Treseler's testbench examples show a reasonable compromise.
> His package exports procedures with signal parameters as Alan Fitch
> showed.
>
> But to keep the main process using them clean, he overrides these
> procedures, locally to the process, with parameterless procedures. These
> have visibility to all the signals the process has, and simply call the
> package procedures, passing these signals as appropriate.
My goal was to be able to write a bunch of standalone testbenches that are
fairly terse and decoupled from the full signal list, and have a large
library of useful test functions in a package.
Your (Mike's) suggestion sounds like it would solve my problem, although it
still means I'd have to replicate the wrapper procs in each of my
testbenches.
The compromise I settled on was to create a record type in my package which
contains all the signals. I tie the record to the DUT in a wrapper
component, then instantiate the wrapper in my testbenches and pass the
record to all the procs.
It's still a little ugly because I have to tristate the whole record (have
to pass it around through INOUT ports), but it achieves my goal of having
terse testbenches with very little copied code.