concurrent signal assignment: order can matter?

R

ralvarexo

Hi,

until now I thought that with concurrent statements order does not matter. Then I wanted to demonstrate delta delay effects with several versions of an RS-FF.
However, the simulator I use (Active HDL 8.3) produces different results for the following 3 versions:

concurrent_1:
qni <= not (s and qi);
qi <= not (r and qni);

concurrent_1:
qi <= not (r and qni);
qni <= not (s and qi);

concurrent_3_with_process:
process(s,qi)
begin
qni <= not (s and qi);
end process;

process(r, qni)
begin
qi <= not (r and qni);
end process;

I would have expected that all 3 versions fail when r and s are simultaneously change from 0 to 1.
However, only the 3rd fails as expected, the other 2 are simulated without any warning, but different result - order matters!

I was under the impression that a concurrent assignment is a short hand fora process with the same assigment AND all righthand signals in the sensitivity list. But according to the results it looks as if the assignments are evaluated/updated only once, i.e. no implied sensitivity list.

While all 3 variants will produce the same HW during synthesis they behave in a different way during simulation. What is even more disturbing is that the order of concurrent statemenst matters during simulation, IMO negating the concept of delta delays.

I am aware that the resulting HW will likely show some other behaviour (metastability) depending on the actual elements used, but this example was choosen to show the inner workings of the simulator.

Is this behaviour of the simulator in accordance with the standard?

Greetings,

Mike
 
K

KJ

While all 3 variants will produce the same HW during synthesis they behave in a different way during simulation. What is even more disturbing is that the order of concurrent statemenst matters during simulation, IMO negating the concept of delta delays.

I am aware that the resulting HW will likely show some other behaviour (metastability) depending on the actual elements used, but this example was choosen to show the inner workings of the simulator.

Is this behaviour of the simulator in accordance with the standard?

You might want to check that your simulator isn't reporting something
after all. What I get when running your example on Modelsim is an
infinite loop when R and S switch simultaneously. Below, I've also
posted the full code.

Kevin Jennings

# Loading std.standard
# Loading ieee.std_logic_1164(body)
# Loading work.foo_sig_assignment(rtl)
# ** Error: (vsim-3601) Iteration limit reached at time 1 ns.

--- Start of code ---
library ieee;
use ieee.std_logic_1164.all;

entity foo_sig_assignment is
end foo_sig_assignment;

architecture RTL of foo_sig_assignment is
begin
concurrent_1: block
signal r: std_logic;
signal s: std_logic;
signal qi: std_logic;
signal qni: std_logic;
begin
r <= '0', '1' after 1 ns;
s <= '0', '1' after 1 ns;
qni <= not (s and qi);
qi <= not (r and qni);
end block concurrent_1;

concurrent_2: block
signal r: std_logic;
signal s: std_logic;
signal qi: std_logic;
signal qni: std_logic;
begin
r <= '0', '1' after 1 ns;
s <= '0', '1' after 1 ns;
qi <= not (r and qni);
qni <= not (s and qi);
end block concurrent_2;

concurrent_3_with_process: block
signal r: std_logic;
signal s: std_logic;
signal qi: std_logic;
signal qni: std_logic;
begin
r <= '0', '1' after 1 ns;
s <= '0', '1' after 1 ns;
process(s,qi)
begin
qni <= not (s and qi);
end process;

process(r, qni)
begin
qi <= not (r and qni);
end process;
end block concurrent_3_with_process;
end RTL;
--- End of code ---
 
P

Paul Uiterlinden

Hi,

until now I thought that with concurrent statements order does not matter.

Your thoughts are correct.
Then I wanted to demonstrate delta delay effects with several versions of
an RS-FF. However, the simulator I use (Active HDL 8.3) produces different
results for the following 3 versions:

concurrent_1:
qni <= not (s and qi);
qi <= not (r and qni);

concurrent_1:
qi <= not (r and qni);
qni <= not (s and qi);

concurrent_3_with_process:
process(s,qi)
begin
qni <= not (s and qi);
end process;

process(r, qni)
begin
qi <= not (r and qni);
end process;

Then Active HDL 8.3 is in error.
I would have expected that all 3 versions fail when r and s are
simultaneously change from 0 to 1. However, only the 3rd fails as
expected, the other 2 are simulated without any warning, but different
result - order matters!

What exactly are the results?
I was under the impression that a concurrent assignment is a short hand
for a process with the same assigment AND all righthand signals in the
sensitivity list.

That is correct.
But according to the results it looks as if the
assignments are evaluated/updated only once, i.e. no implied sensitivity
list.

While all 3 variants will produce the same HW during synthesis they behave
in a different way during simulation. What is even more disturbing is that
the order of concurrent statemenst matters during simulation, IMO negating
the concept of delta delays.

I am aware that the resulting HW will likely show some other behaviour
(metastability) depending on the actual elements used, but this example
was choosen to show the inner workings of the simulator.

Is this behaviour of the simulator in accordance with the standard?

As said before: no. What I would expect is an error message like Kevin
already has shown is produced by ModelSim: "Iteration limit reached".

It is same situation as this concurrent signal assignment, providing the
value of s is not unknown:

s <= not s;

The value of s toggles every delta cycle, without any progression in "real"
time.

Things change if you add an "after" clause:

s <= not s after 1 ns;

Then you can observe the resulting wave form.

You can do the same in your original code and observe the resulting wave
forms. They should be identical in all three cases.
 
M

Michael Hermann

Hi Kevin and Paul,

thanks for confirming my thoughts. I tried Kevins code and my simulator also barfed on all 3 versions - as expected. So the good news is that concurrent IS concurrent.
Of course I now tried to find out why my experiment failed. It took quite a while but now I have hopefully narrowed it down to a more or less minimalistic version.

(As a side note: I wanted NOT to use the example a <= not a; because everybody believes in oscillation problems here, independet of delta cycles or not).

Well, now it looks like for HDL 8.3 there is a difference in the one-file version and the more traditional separation in testbench and unit under test.

The one file minimalistic version fails (which is OK):

---
library ieee;
use ieee.std_logic_1164.all;

entity rsff_tb is
end rsff_tb;

architecture tb of rsff_tb is
signal i : std_logic;
signal q : std_logic;
signal qi, qni: std_logic;
begin

qi <= i nand qni;
qni <= i nand qi;
q <= qi;

i <= '0', '1' after 1ns;

end tb;
---

The two file version does NOT fail in HDL 8.3!

--- test bench (first file)
library ieee;
use ieee.std_logic_1164.all;

entity rsff_tb is
end rsff_tb;

architecture tb of rsff_tb is
signal i : std_logic;
signal q : std_logic;
begin

UUT: entity rsff port map (i => i, q => q);
i <= '0', '1' after 1ns;

end tb;
---

--- unit under test (second file)
library ieee;
use ieee.std_logic_1164.all;

entity rsff is
port
( i: in std_logic;
q: out std_logic
);
end;

architecture fail of rsff is
signal qi, qni: std_logic;
begin
--process(i,qni,qi)
--begin
qi <= i nand qni;
qni <= i nand qi;
--end process;
q <= qi;
end;
---

If I wrap the signal assignments in the UUT again by the process (comments), then the two-file version fails again, i.e. shows the expected behaviour.

Strange! Up to a better explanation I have to believe HDL 8.3 is incorrect here.

Mike
 
K

KJ

Hi Kevin and Paul,
The two file version does NOT fail in HDL 8.3!

--- test bench (first file)

Seems to me the test bench should be the second file, not the first.
Inside the architecture you instantiate the entity 'raff' which hasn't
been compiled yet if you have a completely empty work library. That
is likely not contributing to your particular probllem, just a
comment.

Modelsim also had the following complaints when compiling your code
'as-is' (other than swapping the order so that 'raff' is compiled
first.

** Error: C:/Sim/Junk/Junk3.vhd(111): Unknown entity 'rsff'. Use
expanded name.
** Warning: [4] C:/Sim/Junk/Junk3.vhd(112): (vcom-1207) An abstract
literal and an identifier must have a separator between them.

The error has to do with the following line of code
UUT: entity rsff port map (i => i, q => q);
which should be
UUT: entity work.rsff port map (i => i, q => q);

The warning is to the following line of code
i <= '0', '1' after 1ns;
which should be
i <= '0', '1' after 1 ns;

Again, these most likely have nothing to do with your problem, so this
is just a comment but I believe in both cases Modelsim is correct to
the LRM which would mean that Active HDL 8.3 is not correctly
reporting non-compliant stuff that it should (unless you are disabling
or otherwise ignoring these complaints).
If I wrap the signal assignments in the UUT again by the process (comments), then the two-file version fails again, i.e. shows the expected behaviour.

I'm still not clear just what you mean by 'expected behaviour'. What
I would expect for any model of an RS flip flop is an infinite loop
and the simulator to stop if 'R' and 'S' are set at exactly the same
time. I'm not sure if that's what you expect or not, but that would
be the correct 'response' in this situation.

In any case, when running the code you posted (both forms with and
without the process) Modelsim does stop with an infinite loop
reporting the following error:
** Error: (vsim-3601) Iteration limit reached at time 1 ns.
Strange! Up to a better explanation I have to believe HDL 8.3 is incorrect here.
The fact that you are getting different end results would indicate
that Active HDL is not correct in one case. Does Active HDL ever
report an infinite loop and stop for you?

Kevin Jennings
 
M

Michael Hermann

Hi Kevin,

sorry for the confusion:
With "first" and "second" I did not want to imply an order, actually I just wanted to separate the two files. Could have said Unit-file and TB-file as well.
They are actually compiled in the required order, otherwise it would not work at all.
The missing "work" in front of the entity probably works (no pun intended), because the rsff is in the current working library which is just what work indicates.
So it is surely cleaner to write work.rsff but I do understand why Active HDL does not complain here.
Same for the 1ns.
But at least for the 1ns you are still correct, that IF this is wrong according to the LRM then Active HDL should at least issue a warning.
It does not.

Now for the IMO more interesting stuff:
For this particular description of a RSFF and the concept of delta cycles I would expect the oscillation. In fact this is what Active HDL probably sees in the one-file case and also in the two-file case with process().
At least the simulation stops at 1ns because of "delta cycle limit reached" - perfect for me.
The reason I'm digging into this is because I want to explain the working of the simulator in a lecture. I planned to show how the concept of delta cycles enables a sequential machine to simulate concurrency in a deterministic way.
I also wanted to show some limits. Therefore the RSFF example, because a RSFF is normally a circuit which is quite well-behaved.

Correct me if I'm wrong, but in this admittedly constructed case the oscillation is due to

a) the specific description
b) the delta cycle concept.

Since my original experiment failed, revealing a potential problem in Active HDL, I have not progressed to the next step.
This would have been to replace the two-liner by a one-liner
like

qi <= s nand (r nand qi);

Same result in HW but now I would expect no oscillation during simulation, since the feedback is now calculated in a single cycle and no change of qi is detected after the update phase.

Again, this example does not tell anything about the behaviour of the synthesized HW, it shall merely illustrate the kind of problem the delta cycle concept solves and where there are limits.

But before I can explain this with some degree of confidence to innocent students I must make sure I understand the topic myself well enough. There I got trapped.

For your last question:
Yes, as I said I can get Active HDL into the loop and stop with an appropriate kernel message.
But not as often as intended, your Modelsim seems right now the better, i.e. more standard compliant simulator!

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top