Procedure and 'LAST_ACTIVE, 'TRANSACTION etc

N

Niv

Guest
I have inherited a test-bench which I must modify to verify an updated
chip. (Many of the tests are the same or very similar to the old
chip).
However, the t_bench uses multiple processes, of which 6 represent a
repeating style, so I'd like to write 6 procedures to hugely cut down
the amount of text (30,000 lines in total, of which <100 are
comments).
I have about 20 signals, each of which have assigned the 6 processes,
so 120 processes, each fully written out. A simple procedure call
would be so much neater (and save a few trees).
I've read you can't pass 'TRANSACTION and a few other attributes to a
procedure, so is there a trick to overcoming this, and an example
would help?

TIA, Kev Parsons.
 
Niv wrote:

However, the t_bench uses multiple processes, of which 6 represent a
repeating style, so I'd like to write 6 procedures to hugely cut down
the amount of text (30,000 lines in total, of which <100 are
comments).
I have about 20 signals, each of which have assigned the 6 processes,
so 120 processes, each fully written out. A simple procedure call
would be so much neater (and save a few trees).
related example of overloading remote procedures:
http://home.comcast.net/~mike_treseler/proc_overload.vhd

I've read you can't pass 'TRANSACTION and a few other attributes to a
procedure, so is there a trick to overcoming this, and an example
would help?
I use local variables in a single verification process
instead of signal parameters. See:
http://home.comcast.net/~mike_treseler/test_uart.vhd

Good luck.

-- Mike Treseler
 
On Thu, 11 Oct 2007 04:10:24 -0700,
Niv <kev.parsons@mbda.co.uk> wrote:

Kevin

I've read you can't pass 'TRANSACTION and a few other attributes to a
procedure, so is there a trick to overcoming this, and an example
would help?
The trick we normally use is to pass into the procedure not only
the signal in question, but also 'TRANSACTION:

procedure P (
signal sig: in some_type;
sig_tick_transaction : in bit;
...
) is
...
begin
if sig_tick_transaction'event then
-- there was a transaction on sig!!!
...


To make this work, you need to instantiate the concurrent
procedure thuswise:

architecture T of testbench is
signal S1, S2: some_type;
...
begin
CONCURRENT_PROC_1: P(S1, S1'TRANSACTION, ...);
CONCURRENT_PROC_2: P(S2, S2'TRANSACTION, ...);
...

Concurrent procedures instantiated the top level,
like this, get an implied sensitivity list consisting
of all the signals that appear as inputs or inouts
in their actual argument list - including, of course,
the implicit signal S1'TRANSACTION. So the procedure
will wake up on every transaction on S1, and the "if"
statement will then cause the right bit of code to run.

HTH
--
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.
 
My process is as below, for signal "SIG1"
I agree I can pass the SIG1'LAST_ACTIVE into the procedure,
(I was going to do a boolean assign: fred <= SIG1'LAST_ACTIVE, and
pass fred to the proc.
The "SIG1_tst_expected is used in other processes and the error found
is a testbench o/p.
I have to perform this process on 35 separate signals, so a procedure
would seem appropriate.
However, I cannot assign signals in a procedure.
I also will need SIG2_rst_expected, upto SIG35_rst_expected, all
passed to another set of 35 processes (hopefully also becoming
procedures if I can sort this first simple one out.

I thought about trying to use an array somehow:

rst_expected(SIG1)
rst_expected(SIG2)
...
...
rst_expected(SIG35)

but unclear on how to do this exactly, but the idea would be to pass
SIG<n> into the procedure and then the proc sets the appropriate array
entry as required.

A function that returns rst_expected(SIG<n>) might work?
The "error_found" signal is common to all processes, it is declared
and assigne 'L', but any process currently sets it to '1'.

I can see why the original author used multiple processes, but as
there are 35 signals, each with 4 to 6 processes, that's why this test
bench section (1 of 9) is currently 11,000 lines of code!
I'm hoping to drastically reduce this. (The other tb sections add a
further 20,000 code lines).


--
******************************************************************************
-- RESET
CHECKS:
-- Reset check description applies to ALL 35 reset signal
checks.
--
******************************************************************************
-- When reset is detected as asserted, then "expected" is cleared.
The signal
-- is then tested for its inactive level, if OK, test ends until next
reset
-- assertion, otherwise if signal not at inactive level, a timeout
period is
-- waited (for the reset to take effect), if no signal transition to
inactive
-- level occurs within the timeout, an error has
occured.
--
******************************************************************************

--------------------------------------------------------------------------------
-- SIG1 signal should reset to a '0'. (Pulse o/
p).
--------------------------------------------------------------------------------
SIG1_reset_check: PROCESS
VARIABLE timeout : time;
BEGIN
IF (reset_n = '0') THEN
SIG1_rst_expected <= '0'; -- Signal, how to assign
in PROCEDURE/FUNCTION
IF (SIG1 /= '0') THEN
SIG1_rst_expected <= '1';
timeout := disc_rst_dly + simulator_resolution; -- Package
Time Constants --

-- use special event functions from "events" package, eg
"UX_to_0" for sim start --

WAIT UNTIL event_UX_to_0(ai_l_open2) OR
event_1_to_0(ai_l_open2) FOR timeout;
IF (SIG1_rst_expected'LAST_ACTIVE = timeout) THEN
REPORT " 'SIG1' did NOT become inactive, within time limit,
following reset assertion"
SEVERITY error;
error_found <= '1'; -- Signal, how
to assign in PROCEDURE
END IF;
END IF;
END IF;
WAIT ON reset_n;
END PROCESS ai_l_open2_reset_check;

--------------------------------------------------------------------------------

Regards, Kev P.
 
On Sat, 13 Oct 2007 05:39:48 -0700,
Niv <kev.parsons@mbda.co.uk> wrote:

Kevin, I haven't trawled through your code in detail,
but a few preliminary thoughts...

However, I cannot assign signals in a procedure.
You can, if they are SIGNAL-class output arguments
of the procedure.

I also will need SIG2_rst_expected, upto SIG35_rst_expected, all
passed to another set of 35 processes (hopefully also becoming
procedures if I can sort this first simple one out.
I would definitely try to instantiate the procedure in a
FOR...GENERATE loop, and use arrays as appropriate.
Maybe I'm missing something, but I can't see why this
shouldn't work OK.

I'll try to take a closer look some time, and see if I
can make any suggestions that are more useful.

Regards
--
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.
 
"Niv" <kev.parsons@mbda.co.uk> wrote in message
news:1192279188.445468.188340@v29g2000prd.googlegroups.com...
<snip>

I might be misssing something about what you're trying to do, but it seems
like you (and your predecessor) are making this much more complicated than
it needs to be. Either that or what you're really after is not clear to me
from your postings. The 'reset_check' process that you posted could instead
be something like the following....

signal Sig1, Sig1_rst_Expected: std_ulogic;
.....
process
begin
Sig1_rst_Expected <= '-';
wait until reset_n = '0';
Sig1_rst_Expected <= transport '1' after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you've vectorized the signals coming from the device you're testing so
that 'Sig1' is now a vector than the resulting code is exactly the same
number of statements and is, in fact, virtually identical to the 'single
signal' version...

signal Sig1, Sig1_rst_Expected: std_ulogic_vector(1 to 35);
.....
process
begin
Sig1_rst_Expected <= (others => '-');
wait until reset_n = '0';
Sig1_rst_Expected <= (others => transport '1') after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you want to get a bit more detailed on just exactly which of the bits is
in error on the assertion than you can type a few more lines and be a little
more verbose...

process(Sig1, Sig1_rst_Expected)
begin
for i in Sig1'range loop
assert std_match(Sig1(i), Sig1_rst_Expected(i))
report "Sig1(" & integer'image(i) & ") is not correct (or whatever
you want to report here"
severity ERROR;
end loop;
end process;

In either case, a simple 'truth' process (the one that generates the
expected value, or 'truth' value) is created. A single assert per signal
(or simply a single assert if the signals are all collected into a vector)
is all that is needed.

KJ
 
On 14 Oct, 01:19, "KJ" <kkjenni...@sbcglobal.net> wrote:
"Niv" <kev.pars...@mbda.co.uk> wrote in message

news:1192279188.445468.188340@v29g2000prd.googlegroups.com...
snip

I might be misssing something about what you're trying to do, but it seems
like you (and your predecessor) are making this much more complicated than
it needs to be. Either that or what you're really after is not clear to me
from your postings. The 'reset_check' process that you posted could instead
be something like the following....

signal Sig1, Sig1_rst_Expected: std_ulogic;
....
process
begin
Sig1_rst_Expected <= '-';
wait until reset_n = '0';
Sig1_rst_Expected <= transport '1' after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you've vectorized the signals coming from the device you're testing so
that 'Sig1' is now a vector than the resulting code is exactly the same
number of statements and is, in fact, virtually identical to the 'single
signal' version...

signal Sig1, Sig1_rst_Expected: std_ulogic_vector(1 to 35);
....
process
begin
Sig1_rst_Expected <= (others => '-');
wait until reset_n = '0';
Sig1_rst_Expected <= (others => transport '1') after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you want to get a bit more detailed on just exactly which of the bits is
in error on the assertion than you can type a few more lines and be a little
more verbose...

process(Sig1, Sig1_rst_Expected)
begin
for i in Sig1'range loop
assert std_match(Sig1(i), Sig1_rst_Expected(i))
report "Sig1(" & integer'image(i) & ") is not correct (or whatever
you want to report here"
severity ERROR;
end loop;
end process;

In either case, a simple 'truth' process (the one that generates the
expected value, or 'truth' value) is created. A single assert per signal
(or simply a single assert if the signals are all collected into a vector)
is all that is needed.

KJ
I'm verifying some code that is in a safety significant device.
The 35 outputs can only be set or unset by a s/w command (excluding
global reset), one command per o/p.
I have to check all outputs are reset to their appropriate level (one
set of processes; I like the idea of asigning them to a 35 bit SLV and
testing each bit in a loop, with added statements to handle whether
reset to 1 or 0).
I also have to check the received s/w command sets/resets the
targetted o/p ONLY, and that no other o/p has a transaction on it. The
odd cases have been added (I think) to cater for simulation startup
anomalies. Some outputs are just two- state, some are triggers to
start a pulse of specified length.

Kev P.
 
"Niv" <kev.parsons@mbda.co.uk> wrote in message
news:1192397569.579174.20130@e34g2000pro.googlegroups.com...
On 14 Oct, 01:19, "KJ" <kkjenni...@sbcglobal.net> wrote:
"Niv" <kev.pars...@mbda.co.uk> wrote in message

news:1192279188.445468.188340@v29g2000prd.googlegroups.com...
snip

I might be misssing something about what you're trying to do, but it
seems
like you (and your predecessor) are making this much more complicated
than
it needs to be. Either that or what you're really after is not clear to
me
from your postings. The 'reset_check' process that you posted could
instead
be something like the following....

signal Sig1, Sig1_rst_Expected: std_ulogic;
....
process
begin
Sig1_rst_Expected <= '-';
wait until reset_n = '0';
Sig1_rst_Expected <= transport '1' after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you've vectorized the signals coming from the device you're testing so
that 'Sig1' is now a vector than the resulting code is exactly the same
number of statements and is, in fact, virtually identical to the 'single
signal' version...

signal Sig1, Sig1_rst_Expected: std_ulogic_vector(1 to 35);
....
process
begin
Sig1_rst_Expected <= (others => '-');
wait until reset_n = '0';
Sig1_rst_Expected <= (others => transport '1') after timeout;
wait for 0 ns;
end process;

And then verified with

assert std_match(Sig1, Sig1_rst_Expected)
report "Sig1 is not correct (or whatever you want to report here"
severity ERROR;

If you want to get a bit more detailed on just exactly which of the bits
is
in error on the assertion than you can type a few more lines and be a
little
more verbose...

process(Sig1, Sig1_rst_Expected)
begin
for i in Sig1'range loop
assert std_match(Sig1(i), Sig1_rst_Expected(i))
report "Sig1(" & integer'image(i) & ") is not correct (or
whatever
you want to report here"
severity ERROR;
end loop;
end process;

In either case, a simple 'truth' process (the one that generates the
expected value, or 'truth' value) is created. A single assert per signal
(or simply a single assert if the signals are all collected into a
vector)
is all that is needed.

KJ

I'm verifying some code that is in a safety significant device.
The 35 outputs can only be set or unset by a s/w command (excluding
global reset), one command per o/p.
I have to check all outputs are reset to their appropriate level (one
set of processes; I like the idea of asigning them to a 35 bit SLV and
testing each bit in a loop, with added statements to handle whether
reset to 1 or 0).
I also have to check the received s/w command sets/resets the
targetted o/p ONLY, and that no other o/p has a transaction on it. The
odd cases have been added (I think) to cater for simulation startup
anomalies. Some outputs are just two- state, some are triggers to
start a pulse of specified length.

Then instead of setting the expected value to '-' use 'W' (weak don't care)
instead. Then you can add additional processes as necessary for each of the
signals customized as necessary driving the same expected value signal and
let the std_logic resolved function work out the final expected value. So
in addition to the above code I posted (but changing '-' to 'W') you could
add something like the following

process
begin
Sig1_rst_Expected <= (others => 'W');
wait until sw_command'event; -- Assuming sw_command to be a vector too
Sig1_rst_Expected <= (others => transport '0') after timeout;
for i in sw_command'range loop
if (sw_command(i) = '1') then
Sig1_rst_Expected(i) <= transport '1') after timeout;
end if;
wait for 0 ns;
end process;

The assertion check can remain unchanged from my earlier post.

KJ
 

Welcome to EDABoard.com

Sponsor

Back
Top