Hey embdev people,
I am new to VHDL and currently getting familiar with a bunch of language
features and there is one thing that bothers me and that I don't really
get.
I have read that within a process, you can use a sensitivity list which
is equivalent to using a "wait on" statement at the end of a process. In
a simulation, there is an initialization phase where every process is
run once until it is suspended. I also read that there is no hardware
equivalent to the initialization phase which means that on a
hardware-level it makes 0 difference if the "wait" statement is at the
end or at the beginning of a process.
My question is now: Why is "allowing sensitivity lists / 'wait'
statements not-at-the-top-of-a-process" not a bad language feature?
I only see potential synthesis bugs that arise from not having the
"wait" statement at the very beginning of a process that are caused by
the possibility that the simulator behaves eventually differently due to
the initialization phase.
Follow-up question:
I just read in a documentation "[...] synthesis tools do not allow to
use after clauses, or they ignore these clauses. [...]"
Again.. why the heck are there any language features that are prone to
bugs because synthesizer and simulator behave differently.
To me, this seems like a declaration of war to the entire idea of
software testing.
VHDL's purpose is not only synthesis, but also simulation, so it has
features, which make writing simulation scripts easier. But these
simulation features are mostly (practically) impossible to implement in
an FPGA. That's why, there are features, which work in simulation, but
not in hardware.
Example: How should "wait for 20 ns;" be synthesised into the FPGA.
If on the other hand you threw all simulation-only features out of the
language, how would you create a clock for simulation? Currently it's
just "clk <= not clk after 5 ns;"
c0mr4t wrote:> I have read that within a process, you can use a sensitivity list which> is equivalent to using a "wait on" statement at the end of a process.
No. The sensitivity list is not in the process, but at the beginning in
the definition (or declaration). And 'wait' might be functionally
equivalent to a sensitivity list in some cases, but only in simulation.
The sensitivity list is ignored by the synthesiser, while 'wait' has an
effect on sythesis (in case it is synthesisable).
To be honest, I'm not sure, if and how far synthesis tools support 'wait
on'.
c0mr4t wrote:> Why is "allowing sensitivity lists / 'wait'> statements not-at-the-top-of-a-process" not a bad language feature?
Why should it? The sensitivity list is a support for the simulator to
decrease simulation time. The wait statement has an effect on the
program/synthesis flow.
If wait was only allowed at the beginning of a process, how would you
describe
1
signal<="0011";
2
waitfor10ns;
3
en<='1';
4
waitfor10ns;
5
en<='0';
6
signal<="1100";
7
waitfor50ns;
8
en<='1';
9
...
(It's not the best example, but similar things are often required in
simulation).
c0mr4t wrote:> Again.. why the heck are there any language features that are prone to> bugs because synthesizer and simulator behave differently.
As above. There are features required for simulation which can't be
synthesised into hardware.
c0mr4t wrote:> To me, this seems like a declaration of war to the entire idea of> software testing.
And there's the problem. VHDL is not a 'software' in the common meaning.
It describes hardware and it's behavioural simulation.
If you know, what programmable logic is and how its simulation works,
you will understand. For the beginning, I would suggest, you learn, what
the sensitivity list is for and what a wait statement does. That will
make it much clearer.
Thank you for your detailed response!
Could you provide an example where someone only wants to simulate
something that cannot be built or synthesized in reality? I can't really
think of any concrete case where I would like to do something like that.
Until now, I thought that the whole idea of VHDL is to simulate
components that can actually be built.
c0mr4t wrote:> Could you provide an example where someone only wants to simulate> something that cannot be built or synthesized in reality?
In short: Testbenches.
VHDL is a hardware description language, its purpose is to describe
hardware. But as humans (even hardware designers ;-) ) are not perfect,
it is necessary to test, if the hardware works as expected.
For software, this is relatively easy. You can step through the program
with a debugger and read all variables, states, memory content and
whatever at any time.
In hardware this is not possible. (Although there is something similar,
but very limited compared to software debuggers.)
For these reasons, the behaviour of the design is simulated. But if you
just put your design in a simulator, nothing happens, because there are
no input signals. So you could stop the simulation at the beginning, set
the input signals, simulate some time (like a few nanoseconds), change
signals, simulate the next time period, change the signals again and so
on. But if you want to restart simulation, you have to do that again. So
it's easier to write the signal changes down somewhere. And this is
normally done in VHDL.
You asked for an example. Imagine you want to describe an clocked
adder/subtractor. It would be something like
1
entitysub_addis
2
port(
3
clk:instd_logic;
4
sub:instd_logic;-- Add if '0', subtract if '1'
5
in_1:insigned(7downto0);
6
in_2:insigned(7downto0);
7
res:outsigned(7downto0)
8
);
9
endentity;
10
11
architecturertlofsub_addis
12
begin
13
14
process
15
begin
16
waituntilrising_edge(clk);-- Can be synthesised in this case
17
ifsub='0'then
18
res<=in_1+in_2;
19
else
20
res<=in_1-in_2;
21
endif;
22
endprocess;
23
24
-- Same functionality as above
25
process(clk)-- Only evaluate process on changes of clk
26
begin
27
ifrising_edge(clk)then
28
ifsub='0'then
29
res<=in_1+in_2;
30
else
31
res<=in_1-in_2;
32
endif;
33
endif;
34
endprocess;
35
36
endarchitecture;
If you put that into a simulator, the result will never change, because
there are no input signal changes, not even a clock. So you need a
testbench to generate input signals.
This could look like
1
architecturetestofsub_add_tbis
2
signalclk:std_logic:='0';
3
signalsub:std_logic;
4
signalin_1:signed(7downto0);
5
signalin_2:signed(7downto0);
6
signalres:signed(7downto0);
7
begin
8
9
clk<=notclkafter5ns;-- Generate 100 MHz clock, changes polarity every 5 nanoseconds
-- The adder/subtractor connected to the signals defined above
28
sub_add_dut:entitywork.sub_add
29
portmap(
30
clk=>clk,
31
sub=>sub,
32
in_1=>in_1,
33
in_2=>in_2,
34
res=>res
35
);
36
37
endarchitecture;
This is just a simple example, but writing the testbench in a
synthesisable way would be impossible because of the missing clock and
even setting the input signals would be more complicated.
But VHDL does not end here. In VHDL you can use mathematical functions,
like sine, and datatypes like 'real', which are not synthesisable. If
you want to, you can for example simulate motors, if you have
mathematical models.
All this can make simulation much easier and much more powerful, but
just cannot be sythesised.
Being precise unfortunately is not one of my strenghts, so if there is
something unclear, just ask.
c0mr4t wrote:> the whole idea of VHDL is to simulate> components that can actually be built.
No. An FPGA will always be connected to some other components, lets say
a memory. For the simulation, you will ususally need to model the
behavior of the connected memory device, even if you never will
synthesize this memory.
The memory model usually does not reflect the exact internal
architecture of the memory device, but it should provide its exact
interface behavior. The memory could be modeled as a simple array of
std_logic_vectors, but let's say from the data sheet you know that the
memory provides the output data word 4 ns after the clock edge, or it
requires a strobe signal in the middle of a 10ns clock period. This can
be modeled using VHDL's after clause. Vendors sometimes offer simulation
models providing the exact timing behavior of their devices. But these
model are intended to be used for simulation only.
Do not bother with after clauses when designing a VHDL model of an FPGA.
Start with a pure functional model which is ideal and has zero delay on
all signals. You can never specifiy the exact timing of the FPGA - it
will be the result of the synthesis and imlementation process. After the
FPGA design is completely implemented, the tools can generate a VHDL
model which is annotated with after clauses that reflect the exact
timing behavior. You can use this generated model for a a so called
timing simulation, but this is usually not necessary except in some
critical cases.
So to say, the after clause is used only for modeling something that
already exists but needs to be simulated anyway. There are many language
construct in any HDL language that are intended for exactly this purpose
- for a pure simulation model