Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > concurrent assertion statement and delta races

Reply
Thread Tools

concurrent assertion statement and delta races

 
 
Allan Herriman
Guest
Posts: n/a
 
      02-11-2013
Hi,

I occasionally come across a situation in which I have an architecture
with many if-generate constructs to select different options for some
design. Exactly one of the if-generates must evaluate to true and be
"generated".

In a big design I like to test this by having an unresolved signal
(initialised to false) that is set to true inside each of the if-
generates. I then need to use an assertion to check that the signal is
indeed true, indicating that exactly one of the if-generates is active.

I know I could do this in VHDL-2008 using if-else generate, but I'm using
tools from Xilinx so I am restricted to using 20th century versions
of VHDL.


This has been working fine for me for years, but I just realised today
that my assertions hadn't actually been checking anything. (Which is
fine, 'cause my code never has bugs...)


I'm looking for pointers on the best way to express my assertion in VHDL
'93 or '01.
Alternatively, I'm looking for any other ways to test this aspect of my
design without using a signal.



E.g.

-- The remainder of this post is in VHDL
-- and can be compiled and simulated.

entity foo is
end entity foo;

architecture bar of foo is

signal sig : boolean := FALSE;

begin

sig <= TRUE; -- (inside an if-generate)
-- comment out previous line to test assertions


-- need to assert that sig is TRUE here

attempt_1 : assert sig
report "sig is false #1"
severity note;

-- attempt_1 fails
-- it indicates that sig is always FALSE,
-- regardless of its actual value, due to the
-- attempt_1 equivalent process running before
-- the delta in which sig gets its value


attempt_2 : assert sig or now = 0 ns
report "sig is false #2"
severity note;

-- attempt_2 fails
-- it indicates that sig is always TRUE,
-- regardless of its actual value
-- because the equivalent process runs when now = 0 ns
-- then does a wait on sig, which never has an event.


attempt_3 : postponed assert sig
report "sig is false #3"
severity note;

-- attempt_3 fails as well.
-- Postponed is meant to fix the delta race
-- we had with attempt_1, but it doesn't,
-- indicating that sig is always FALSE
-- regardless of its actual value.
-- (In which case, what is the point of having
-- postponed assert as part of the language? I must
-- be missing something here.)


attempt_5 : process
begin
wait for 0 ns;
assert sig
report "sig is false #5"
severity note;
wait;
end process attempt_5;

-- attempt_5 works correctly, but is really ugly


end architecture bar;

-- Regards,
-- Allan
 
Reply With Quote
 
 
 
 
Tricky
Guest
Posts: n/a
 
      02-11-2013
On Monday, 11 February 2013 10:45:24 UTC, Allan Herriman wrote:
> Hi,
>
>
>
> I occasionally come across a situation in which I have an architecture
>
> with many if-generate constructs to select different options for some
>
> design. Exactly one of the if-generates must evaluate to true and be
>
> "generated".
>
>
>
> In a big design I like to test this by having an unresolved signal
>
> (initialised to false) that is set to true inside each of the if-
>
> generates. I then need to use an assertion to check that the signal is
>
> indeed true, indicating that exactly one of the if-generates is active.
>
>
>
> I know I could do this in VHDL-2008 using if-else generate, but I'm using
>
> tools from Xilinx so I am restricted to using 20th century versions
>
> of VHDL.
>
>
>
>
>
> This has been working fine for me for years, but I just realised today
>
> that my assertions hadn't actually been checking anything. (Which is
>
> fine, 'cause my code never has bugs...)
>
>
>
>
>
> I'm looking for pointers on the best way to express my assertion in VHDL
>
> '93 or '01.
>
> Alternatively, I'm looking for any other ways to test this aspect of my
>
> design without using a signal.
>
>
>
>
>
>
>
> E.g.
>
>
>
> -- The remainder of this post is in VHDL
>
> -- and can be compiled and simulated.
>
>
>
> entity foo is
>
> end entity foo;
>
>
>
> architecture bar of foo is
>
>
>
> signal sig : boolean := FALSE;
>
>
>
> begin
>
>
>
> sig <= TRUE; -- (inside an if-generate)
>
> -- comment out previous line to test assertions
>
>
>
>
>
> -- need to assert that sig is TRUE here
>
>
>
> attempt_1 : assert sig
>
> report "sig is false #1"
>
> severity note;
>
>
>
> -- attempt_1 fails
>
> -- it indicates that sig is always FALSE,
>
> -- regardless of its actual value, due to the
>
> -- attempt_1 equivalent process running before
>
> -- the delta in which sig gets its value
>
>
>
>
>
> attempt_2 : assert sig or now = 0 ns
>
> report "sig is false #2"
>
> severity note;
>
>
>
> -- attempt_2 fails
>
> -- it indicates that sig is always TRUE,
>
> -- regardless of its actual value
>
> -- because the equivalent process runs when now = 0 ns
>
> -- then does a wait on sig, which never has an event.
>
>
>
>
>
> attempt_3 : postponed assert sig
>
> report "sig is false #3"
>
> severity note;
>
>
>
> -- attempt_3 fails as well.
>
> -- Postponed is meant to fix the delta race
>
> -- we had with attempt_1, but it doesn't,
>
> -- indicating that sig is always FALSE
>
> -- regardless of its actual value.
>
> -- (In which case, what is the point of having
>
> -- postponed assert as part of the language? I must
>
> -- be missing something here.)
>
>
>
>
>
> attempt_5 : process
>
> begin
>
> wait for 0 ns;
>
> assert sig
>
> report "sig is false #5"
>
> severity note;
>
> wait;
>
> end process attempt_5;
>
>
>
> -- attempt_5 works correctly, but is really ugly
>
>
>
>
>
> end architecture bar;
>
>
>
> -- Regards,
>
> -- Allan


I wouldnt use a signal at all - I would just XOR all of the conditions together, or have a single assert based on the different conditions:

assert (a xor b xor c)
report "Only ONE of A or B or C may be set"
severity failure;

But you may be bummed in the end by how the tool actually handle's asserts.IIRC, a few years ago some people did a test with asserts forcing a synthesisor to stop. The only one that actually stopped was Quartus, with Synplify giving just a warning (and carrying on), and others not doing anything atall (Cannot remember the ISE result).

Another problem with the signal approach is that even if it is non-resolved, some compilers may simply just remove the net unless it drives an output.
 
Reply With Quote
 
 
 
 
Rob Gaddi
Guest
Posts: n/a
 
      02-11-2013
On Mon, 11 Feb 2013 08:39:56 -0800 (PST)
Tricky <(E-Mail Removed)> wrote:

> I wouldnt use a signal at all - I would just XOR all of the conditions together, or have a single assert based on the different conditions:
>
> assert (a xor b xor c)
> report "Only ONE of A or B or C may be set"
> severity failure;
>
> But you may be bummed in the end by how the tool actually handle's asserts. IIRC, a few years ago some people did a test with asserts forcing a synthesisor to stop. The only one that actually stopped was Quartus, with Synplify giving just a warning (and carrying on), and others not doing anything at all (Cannot remember the ISE result).
>
> Another problem with the signal approach is that even if it is non-resolved, some compilers may simply just remove the net unless it drives an output.


Integers and addition, not bits and XORs. Otherwise 3=1.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
Reply With Quote
 
Allan Herriman
Guest
Posts: n/a
 
      02-11-2013
On Mon, 11 Feb 2013 08:39:56 -0800, Tricky wrote:

> On Monday, 11 February 2013 10:45:24 UTC, Allan Herriman wrote:
>> Hi,
>>
>>
>>
>> I occasionally come across a situation in which I have an architecture
>>
>> with many if-generate constructs to select different options for some
>>
>> design. Exactly one of the if-generates must evaluate to true and be
>>
>> "generated".
>>
>>
>>
>> In a big design I like to test this by having an unresolved signal
>>
>> (initialised to false) that is set to true inside each of the if-
>>
>> generates. I then need to use an assertion to check that the signal is
>>
>> indeed true, indicating that exactly one of the if-generates is active.
>>
>>
>>
>> I know I could do this in VHDL-2008 using if-else generate, but I'm
>> using
>>
>> tools from Xilinx so I am restricted to using 20th century versions
>>
>> of VHDL.
>>
>>
>>
>>
>>
>> This has been working fine for me for years, but I just realised today
>>
>> that my assertions hadn't actually been checking anything. (Which is
>>
>> fine, 'cause my code never has bugs...)
>>
>>
>>
>>
>>
>> I'm looking for pointers on the best way to express my assertion in
>> VHDL
>>
>> '93 or '01.
>>
>> Alternatively, I'm looking for any other ways to test this aspect of my
>>
>> design without using a signal.
>>
>>
>>
>>
>>
>>
>>
>> E.g.
>>
>>
>>
>> -- The remainder of this post is in VHDL
>>
>> -- and can be compiled and simulated.
>>
>>
>>
>> entity foo is
>>
>> end entity foo;
>>
>>
>>
>> architecture bar of foo is
>>
>>
>>
>> signal sig : boolean := FALSE;
>>
>>
>>
>> begin
>>
>>
>>
>> sig <= TRUE; -- (inside an if-generate)
>>
>> -- comment out previous line to test assertions
>>
>>
>>
>>
>>
>> -- need to assert that sig is TRUE here
>>
>>
>>
>> attempt_1 : assert sig
>>
>> report "sig is false #1"
>>
>> severity note;
>>
>>
>>
>> -- attempt_1 fails
>>
>> -- it indicates that sig is always FALSE,
>>
>> -- regardless of its actual value, due to the
>>
>> -- attempt_1 equivalent process running before
>>
>> -- the delta in which sig gets its value
>>
>>
>>
>>
>>
>> attempt_2 : assert sig or now = 0 ns
>>
>> report "sig is false #2"
>>
>> severity note;
>>
>>
>>
>> -- attempt_2 fails
>>
>> -- it indicates that sig is always TRUE,
>>
>> -- regardless of its actual value
>>
>> -- because the equivalent process runs when now = 0 ns
>>
>> -- then does a wait on sig, which never has an event.
>>
>>
>>
>>
>>
>> attempt_3 : postponed assert sig
>>
>> report "sig is false #3"
>>
>> severity note;
>>
>>
>>
>> -- attempt_3 fails as well.
>>
>> -- Postponed is meant to fix the delta race
>>
>> -- we had with attempt_1, but it doesn't,
>>
>> -- indicating that sig is always FALSE
>>
>> -- regardless of its actual value.
>>
>> -- (In which case, what is the point of having
>>
>> -- postponed assert as part of the language? I must
>>
>> -- be missing something here.)
>>
>>
>>
>>
>>
>> attempt_5 : process
>>
>> begin
>>
>> wait for 0 ns;
>>
>> assert sig
>>
>> report "sig is false #5"
>>
>> severity note;
>>
>> wait;
>>
>> end process attempt_5;
>>
>>
>>
>> -- attempt_5 works correctly, but is really ugly
>>
>>
>>
>>
>>
>> end architecture bar;
>>
>>
>>
>> -- Regards,
>>
>> -- Allan

>
> I wouldnt use a signal at all - I would just XOR all of the conditions
> together, or have a single assert based on the different conditions:
>
> assert (a xor b xor c)
> report "Only ONE of A or B or C may be set"
> severity failure;



Quite apart from the bug with xor, that doesn't work for me at a
practical level. The conditions are complicated and there are a lot of
them. Copying and pasting them to two places in the code (the if-
generate and the assert) may introduce errors and makes maintenance
harder. Creating constants for the conditions (to avoid the copy and
paste) makes the code messy.


> But you may be bummed in the end by how the tool actually handle's
> asserts. IIRC, a few years ago some people did a test with asserts
> forcing a synthesisor to stop. The only one that actually stopped was
> Quartus, with Synplify giving just a warning (and carrying on), and
> others not doing anything at all (Cannot remember the ISE result).
>
> Another problem with the signal approach is that even if it is
> non-resolved, some compilers may simply just remove the net unless it
> drives an output.


I'm only interested in the simulation behaviour. I run the regression
tests in the simulator. What happens in synthesis doesn't matter to me
for the purposes of this thread.
I'm using Modemsim 10.1d (the latest version).

Regards,
Allan
 
Reply With Quote
 
HT-Lab
Guest
Posts: n/a
 
      02-12-2013
On 11/02/2013 21:35, Allan Herriman wrote:
...
> I'm only interested in the simulation behaviour. I run the regression
> tests in the simulator. What happens in synthesis doesn't matter to me
> for the purposes of this thread.
> I'm using Modemsim 10.1d (the latest version).

^^^^^^^^^^^^^^^^^
Not since yesterday

10.2 has more suppulent VHDL2008 support and DE users get access to the
FLI (C/C++ interface for VHDL users),

Hans
www.ht-lab.com


>
> Regards,
> Allan
>


 
Reply With Quote
 
Allan Herriman
Guest
Posts: n/a
 
      02-12-2013
On Mon, 11 Feb 2013 21:35:26 +0000, Allan Herriman wrote:

> On Mon, 11 Feb 2013 08:39:56 -0800, Tricky wrote:
>
>> On Monday, 11 February 2013 10:45:24 UTC, Allan Herriman wrote:
>>> Hi,
>>>
>>>
>>>
>>> I occasionally come across a situation in which I have an architecture
>>>
>>> with many if-generate constructs to select different options for some
>>>
>>> design. Exactly one of the if-generates must evaluate to true and be
>>>
>>> "generated".
>>>
>>>
>>>
>>> In a big design I like to test this by having an unresolved signal
>>>
>>> (initialised to false) that is set to true inside each of the if-
>>>
>>> generates. I then need to use an assertion to check that the signal
>>> is
>>>
>>> indeed true, indicating that exactly one of the if-generates is
>>> active.
>>>
>>>
>>>
>>> I know I could do this in VHDL-2008 using if-else generate, but I'm
>>> using
>>>
>>> tools from Xilinx so I am restricted to using 20th century
>>> versions
>>>
>>> of VHDL.
>>>
>>>
>>>
>>>
>>>
>>> This has been working fine for me for years, but I just realised today
>>>
>>> that my assertions hadn't actually been checking anything. (Which is
>>>
>>> fine, 'cause my code never has bugs...)
>>>
>>>
>>>
>>>
>>>
>>> I'm looking for pointers on the best way to express my assertion in
>>> VHDL
>>>
>>> '93 or '01.
>>>
>>> Alternatively, I'm looking for any other ways to test this aspect of
>>> my
>>>
>>> design without using a signal.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> E.g.
>>>
>>>
>>>
>>> -- The remainder of this post is in VHDL
>>>
>>> -- and can be compiled and simulated.
>>>
>>>
>>>
>>> entity foo is
>>>
>>> end entity foo;
>>>
>>>
>>>
>>> architecture bar of foo is
>>>
>>>
>>>
>>> signal sig : boolean := FALSE;
>>>
>>>
>>>
>>> begin
>>>
>>>
>>>
>>> sig <= TRUE; -- (inside an if-generate)
>>>
>>> -- comment out previous line to test assertions
>>>
>>>
>>>
>>>
>>>
>>> -- need to assert that sig is TRUE here
>>>
>>>
>>>
>>> attempt_1 : assert sig
>>>
>>> report "sig is false #1"
>>>
>>> severity note;
>>>
>>>
>>>
>>> -- attempt_1 fails
>>>
>>> -- it indicates that sig is always FALSE,
>>>
>>> -- regardless of its actual value, due to the
>>>
>>> -- attempt_1 equivalent process running before
>>>
>>> -- the delta in which sig gets its value
>>>
>>>
>>>
>>>
>>>
>>> attempt_2 : assert sig or now = 0 ns
>>>
>>> report "sig is false #2"
>>>
>>> severity note;
>>>
>>>
>>>
>>> -- attempt_2 fails
>>>
>>> -- it indicates that sig is always TRUE,
>>>
>>> -- regardless of its actual value
>>>
>>> -- because the equivalent process runs when now = 0 ns
>>>
>>> -- then does a wait on sig, which never has an event.
>>>
>>>
>>>
>>>
>>>
>>> attempt_3 : postponed assert sig
>>>
>>> report "sig is false #3"
>>>
>>> severity note;
>>>
>>>
>>>
>>> -- attempt_3 fails as well.
>>>
>>> -- Postponed is meant to fix the delta race
>>>
>>> -- we had with attempt_1, but it doesn't,
>>>
>>> -- indicating that sig is always FALSE
>>>
>>> -- regardless of its actual value.
>>>
>>> -- (In which case, what is the point of having
>>>
>>> -- postponed assert as part of the language? I must
>>>
>>> -- be missing something here.)
>>>
>>>
>>>
>>>
>>>
>>> attempt_5 : process
>>>
>>> begin
>>>
>>> wait for 0 ns;
>>>
>>> assert sig
>>>
>>> report "sig is false #5"
>>>
>>> severity note;
>>>
>>> wait;
>>>
>>> end process attempt_5;
>>>
>>>
>>>
>>> -- attempt_5 works correctly, but is really ugly
>>>
>>>
>>>
>>>
>>>
>>> end architecture bar;
>>>
>>>
>>>
>>> -- Regards,
>>>
>>> -- Allan

>>
>> I wouldnt use a signal at all - I would just XOR all of the conditions
>> together, or have a single assert based on the different conditions:
>>
>> assert (a xor b xor c)
>> report "Only ONE of A or B or C may be set"
>> severity failure;

>
>
> Quite apart from the bug with xor, that doesn't work for me at a
> practical level. The conditions are complicated and there are a lot of
> them. Copying and pasting them to two places in the code (the if-
> generate and the assert) may introduce errors and makes maintenance
> harder. Creating constants for the conditions (to avoid the copy and
> paste) makes the code messy.
>
>
>> But you may be bummed in the end by how the tool actually handle's
>> asserts. IIRC, a few years ago some people did a test with asserts
>> forcing a synthesisor to stop. The only one that actually stopped was
>> Quartus, with Synplify giving just a warning (and carrying on), and
>> others not doing anything at all (Cannot remember the ISE result).
>>
>> Another problem with the signal approach is that even if it is
>> non-resolved, some compilers may simply just remove the net unless it
>> drives an output.

>
> I'm only interested in the simulation behaviour. I run the regression
> tests in the simulator. What happens in synthesis doesn't matter to me
> for the purposes of this thread.
> I'm using Modemsim 10.1d (the latest version).
>
> Regards,
> Allan



I should clarify:

I'm using Modelsim for simulation. All my testing happens in Modelsim.
The assertions only need to run correctly in Modelsim.

The code is synthesisable, targetting a number of different tools. The
Xilinx tools are the worst case, meaning I can't use VHDL 2008.
I don't care whether the assertions are handled by the synth tools, as
long as it still compiles.

Regards,
Allan
 
Reply With Quote
 
Tricky
Guest
Posts: n/a
 
      02-12-2013
If you're only interested in simulation, how about the use of a shared variable?

shared varaible n_insts : integer := 0;

impure function add_inst return boolean is
begin
n_insts := n_insts + 1;

assert (n_insts <= 1)
report "Too many instances"
severity failure;

return true;
end function;


And then in each generate statement, just have the folowing constant declaration:

constant A_CONST : boolean := add_inst;

This will then count up the number of instances right at the start of the vsim, so you dont even need to run it. Each activated generate will add 1 tothe n_insts variable and bomb out when it goes above 1. This way you nevereven need to know what the generics are, or do you care. current code justneeds the constants adding.
 
Reply With Quote
 
Allan Herriman
Guest
Posts: n/a
 
      02-12-2013
On Tue, 12 Feb 2013 05:59:56 -0800, Tricky wrote:

> If you're only interested in simulation, how about the use of a shared
> variable?
>
> shared varaible n_insts : integer := 0;
>
> impure function add_inst return boolean is begin
> n_insts := n_insts + 1;
>
> assert (n_insts <= 1)
> report "Too many instances"
> severity failure;
>
> return true;
> end function;
>
>
> And then in each generate statement, just have the folowing constant
> declaration:
>
> constant A_CONST : boolean := add_inst;
>
> This will then count up the number of instances right at the start of
> the vsim, so you dont even need to run it. Each activated generate will
> add 1 to the n_insts variable and bomb out when it goes above 1. This
> way you never even need to know what the generics are, or do you care.
> current code just needs the constants adding.



That's an interesting solution to the problem and I thank you for your
efforts.

However, even though the assertions only need to work in simulation, the
code still needs to be synthesisable and portable over a number of
tools. I believe this rules out the use of shared variables.

The basic problem with shared variables is that one version of VHDL
supports shared variables but not protected types. A different version
of VHDL also supports shared variables, but requires that they be
protected types. Both versions of the language are currently in use.

Regards,
Allan
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      02-12-2013
On Tuesday, February 12, 2013 7:59:56 AM UTC-6, Tricky wrote:
> If you're only interested in simulation, how about the use of a shared variable? shared varaible n_insts : integer := 0; impure function add_inst return boolean is begin n_insts := n_insts + 1; assert (n_insts <= 1) report "Too many instances" severity failure; return true; end function; Andthen in each generate statement, just have the folowing constant declaration: constant A_CONST : boolean := add_inst; This will then count up the number of instances right at the start of the vsim, so you dont even need torun it. Each activated generate will add 1 to the n_insts variable and bomb out when it goes above 1. This way you never even need to know what the generics are, or do you care. current code just needs the constants adding.


Right idea, wrong implementation. Since 2002 (?) shared variables must be of a protected type. The functions/procedures (methods) defined in the protected type are guaranteed to execute atomically (one call must complete before another call can start). Otherwise, a compliant simulator could execute two or more of your unprotected initializations at the same time (differentthreads/cores), and one or more of them could see the same current value (e.g. 0), and set the new value to 1. This would lead you to believe that only one generate statement was enabled, when in fact more than one had been enabled.

This is really a good application of a shared protected variable, and it iseasy to implement, to sort of get your feet wet. Warning: once you learn how to do this, you'll find lots of other places where it makes sense to use!

Define a protected type with a local (protected) integer, and within the type, define a method serialize() that increments the protected variable and returns the updated value.

You could just call the serialize in an assertion and make sure the updatedvalue is 2 (1 + this), or define another method, value(), that simply returns the current count without incrementing it.

Then declare a shared variable of the protected type, and call its serialize() method in your constant initialization (use an integer constant) in each generate's declarative region.

This is also handy because it makes the unique serial number avaialble to each generate. This can be useful for lots of other things that require a unique value. Just remember that the order in which the various calls to serialize() are executed is not defined, so it can change from simulator to simulator on the same code, or within the same simulator with seemingly unrelated changes to the code.

Andy
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      02-12-2013
You can use synthesis directives (meta-comments) to turn off translation of problematic code in synthesis. Look in the synthesis user- or reference-guide to determine what those meta-comments are for your tool.

The simulator ignores the meta-comments, and compiles/executes the code, but the synthesis tool ignores the code.

Andy
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
sensitivity list in concurrent assertion valtih1978 VHDL 4 05-17-2012 12:54 PM
delta cycle?? (delta delay) srikanth.padava VHDL 0 02-28-2008 09:01 AM
Modelsim Delta Races Andrew Greensted VHDL 4 03-16-2006 07:51 AM
problems locating the concurrent EDU.oswego.cs.dl.util.concurrent package Pep Java 6 08-16-2005 07:26 AM
OFF TO THE RACES WITH THE D60 !!! Annika1980 Digital Photography 176 02-25-2004 02:52 PM



Advertisments