package containing a global signal and a proc whic modifies

K

Ken Cecka

Guest
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;
 
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
 
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.

Ken
 
Alvin Andries wrote:
"Alan Fitch" <alan.fitch@spamtrap.com> wrote in message
news:NsCdneUOYfz0SFXVnZ2dneKdnZydnZ2d@posted.plusnet...
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.

regards
Alan

--
Alan Fitch
Doulos
http://www.doulos.com
 
Alvin Andries wrote:
"Alan Fitch" <alan.fitch@spamtrap.com> wrote in message
news:NsCdneUOYfz0SFXVnZ2dneKdnZydnZ2d@posted.plusnet...
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.

regards
Alan

--
Alan Fitch
Doulos
http://www.doulos.com
 
On Thu, 11 Sep 2008 13:58:03 GMT, Ken Cecka <ceckak@verizon.net> 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;

I don't see a way to do better than this.

-- Brian
 
On Thu, 11 Sep 2008 17:31:59 +0100, Brian Drummond wrote:

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

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.
 
On Thu, 11 Sep 2008 19:12:17 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> 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.

Thanks,

- Brian
 
Brian Drummond wrote:

On Thu, 11 Sep 2008 13:58:03 GMT, Ken Cecka <ceckak@verizon.net> 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.

Ken
 
Brian Drummond wrote:

Mike Treseler's testbench examples show a reasonable compromise.
His package exports procedures with signal parameters as Alan Fitch
showed.
This one: http://mysite.verizon.net/miketreseler/proc_overload.vhd
overloads a signal parameter from a packaged procedure,
but this is a trivial example.

This one: http://mysite.verizon.net/miketreseler/test_uart.vhd
Is a more complete testbench, but uses
local (unpackaged) procedures with direct (parameterless) access.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top