2
\$\begingroup\$

I'm trying to use a concurrent assertion in an entity declaration to enforce a minimum pulse-width constraint. Everything works as expected if I use a sequential assertion wrapped inside a passive process:

testcase.vhdl

entity testcase is
 port(clk: in bit);
begin
 check: process is
 begin
 -- Require at least 10ns between clock edges
 assert clk'delayed'last_event >= 10 ns;
 wait on clk;
 end process check;
end entity testcase;
-- Keep the compiler happy
architecture empty of testcase is
begin
end architecture empty;

testcase_testbench.vhdl

entity testcase_testbench is
end entity testcase_testbench;
architecture bench of testcase_testbench is
 signal clk: bit;
begin
 dut: entity work.testcase(empty) port map(clk => clk);
 stimulus: process is
 begin
 -- Valid low and high pulses
 clk <= '0';
 wait for 10 ns;
 clk <= '1';
 wait for 10 ns;
 -- Confirm that we're timing events, not transactions
 clk <= '1';
 wait for 5 ns;
 -- Now send a short pulse to make the assertion fire 
 clk <= '0';
 wait for 5 ns;
 -- Assertion should fire here, at 30ns
 clk <= '1';
 wait;
 end process stimulus;
end architecture bench;

Build and test:

$ ghdl -a testcase.vhdl
$ ghdl -a testcase_testbench.vhdl
$ ghdl -e testcase_testbench
$ ghdl -r testcase_testbench
testcase.vhdl:6:16:@30ns:(assertion error): Assertion violation

However, if I try to use a concurrent assertion I get a compiler error from ghdl:

testcase2.vhdl

entity testcase2 is
 port(clk: in bit);
begin
 check: assert clk'delayed'last_event >= 10 ns;
end entity testcase2;

Attempt to analyse:

$ ghdl -a testcase2.vhdl
canon_extract_sensitivity: cannot handle IIR_KIND_LAST_EVENT_ATTRIBUTE (testcase2.vhdl:4:34)
******************** GHDL Bug occured ****************************
Please report this bug on http://gna.org/projects/ghdl
GHDL release: GHDL 0.33 (20150921) [Dunoon edition]
Compiled with GNAT Version: 4.8
In directory: /home/simon/vhdl/
Command line:
/usr/bin/ghdl1-llvm -P/usr/lib/ghdl/v93/std/ -P/usr/lib/ghdl/v93/ieee/ -c -o testcase2.o testcase2.vhdl
Exception TYPES.INTERNAL_ERROR raised
Exception information:
Exception name: TYPES.INTERNAL_ERROR
Message: errorout.adb:63
Call stack traceback locations:
0x4978f2 0x4f055b 0x4f0350 0x4f2513 0x4f4806 0x5597df 0x5afbba 0x46eef6 0x433013 0x7f64f836082e 0x432450 0xfffffffffffffffe
******************************************************************
ghdl: compilation error

I get the same error if I move the concurrent assertion into the architecture body, or if I shorten the expression to clk'last_event >= 10 ns. Other expressions like clk'event or clk'delayed = '1' compile fine, even if they are somewhat pointless.

I'm fairly new to VHDL but my understanding is that my two testcases should be equivalent. If they aren't, why not? And if they are, why does ghdl complain about the second one?

asked Jan 15, 2017 at 7:01
\$\endgroup\$
2
  • 1
    \$\begingroup\$ There is clearly a ghdl bug here - if the behaviour is legal, this should work' and if it's illegal, ghdl should exit cleanly with a description of the error. I'm trying it on a newer version... \$\endgroup\$ Commented Jan 15, 2017 at 10:36
  • 1
    \$\begingroup\$ clk'delayed'last_event >= 10 ns is a legal boolean expression that tests the maximum unit interval of clk. See IEEE Std 1076-2008 8.1 static name para 6. clk'delayed is a static name, the prefix of of 'last_event and 16.2.4, S'DELAYED particularly S'LAST_EVENT, the requirement the prefix be a static signal name. As Brian relates it's a bug in ghdl. Please report such bugs on https://github.com/tgingold/ghdl/issues . After ghdl-0.33 release ghdl development was re-hosted on github. \$\endgroup\$ Commented Jan 15, 2017 at 17:15

1 Answer 1

3
\$\begingroup\$

Thank you for taking the effort to make a proper MCVE. My build of ghdl-0.34dev does the same, so there is clearly a ghdl bug here.

If the behaviour is legal, this should work, and if it's illegal, ghdl should exit cleanly with a description of the error.

Instead, ghdl isn't crashing, it has identified a shortcoming, a case where it "cannot handle LAST_EVENT attribute" (applied to another attribute) and shutdown with diagnostics.

I'll leave open the question whether a fine reading of the LRM determines its actual legality or not...

Putting anything at all beyond generics and ports in the entity as opposed to the architecture is rare ... I can't say I've ever seen it in production code - so you are out in the tall grass, though it's a valid thing to do.

In any case, moving this assertion into the architecture yields the same error, so that isn't the problem.

So, I've reporting it on ghdl's development site as https://github.com/tgingold/ghdl/issues/256 and I'll update my answer with any developments.

EDIT : A fix for this issue is now tested, and will be pushed to github following a full regression test.

HOWEVER : due to a subtlety in concurrent asserts, the two forms are not equivalent.

ghdl -r testcase_testbench
testcase.vhd:7:9:@30ns:(assertion error): Assertion violation
ghdl -r testcase_testbench
testcase2.vhd:4:5:@10ns:(assertion error): Assertion violation
testcase2.vhd:4:5:@25ns:(assertion error): Assertion violation
testcase2.vhd:4:5:@30ns:(assertion error): Assertion violation

In the first case, the process triggers on clk as requested. Delete the "wait" and put clk in the sensitivity list, and it does the same.

However, in Testcase2, the concurrent Assert is equivalent to a sensitivity list process, but the sensitivity list is clk'delayed.

As Tristan points out on the issue report (same link as above), clk'delayed is active in more than one delta cycle at 10ns, and so fails the test (because last'event is 0 ns between them!) Put clk'delayed in the sensitivity list for the Testcase process and see.

As "diogratia" points out there, a similar example in "The VHDL Designer's Guide" (Peter Ashenden) has a simple change to Testcase2 avoiding the issue : restrict the Assert to clk events...

entity testcase2 is
 port(clk: in bit);
begin
 check: assert (not clk'event) or clk'delayed'last_event >= 10 ns;
end entity testcase2;
architecture empty of testcase2 is
begin
end architecture empty;

EDIT 2 : As of commit b42069e this is fixed in ghdl-0.34dev. If your workaround using a process doesn't meet your needs, you can update to this version, but it means building ghdl from source.

answered Jan 15, 2017 at 10:57
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the comprehensive reply Brian - I'm new enough to the language that I trust the compiler a lot more than myself, but it's nice to know that I hadn't completely misunderstood things here. The context for this example was completely artificial, I'm working through the exercises in Ashenden's book and one of them is to create a model that verifies its own timing constraints: having read about concurrent assertions I was curious to see where I could use them. I'd also assumed that being sensitive to clk'delayed was the same as being sensitive to clk, but I see the difference now. \$\endgroup\$ Commented Jan 16, 2017 at 1:42
  • \$\begingroup\$ Yeah the fix was in Ashenden's book, as above, but (unusually for that book) doesn't explain the subtlety very well. Tristan still hasn't pushed the update but you can build from source with my suggested patches meantime. And if you get ghdl to fail in a similar manner, I'd encourage reporting (with testcase) to github. \$\endgroup\$ Commented Jan 16, 2017 at 12:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.