Unexpected behaviour in tristate switch VHDL - vhdl

I have discovered an unexpected problem with a tristate driver developed in VHDL. The behavior of the tristate driver is not understandable in the simulation.
Please have a look at the following code snippet where the signal line_en is set:
process(all)
begin
if (reset = '0') then
line_en <= '0';
elsif (A /= A_reg) then
line_en <= '0';
elsif (B_reg /= B) then
line_en <= '1';
else
line_en <= line_en;
end if;
end process;
In the simulation it happens now that signal B_reg and B both jump from "0000" to "ZZZZ" at the same time. However, in the transition from "0000" to "ZZZZ" line_en goes to '1' although this should not happen with (B_reg /= B), so the condition must not become true in my opinion.
Attached below a screenshot of the simulation:
It is for simulation purposes only. Synthesization is not yet desired.
Thanks in advance for any hint where I made a mistake that I can't see myself at the moment. Maybe it's a timing problem because the process itself is not clocked, so it runs asynchronously.

The comments are right and seemingly pointing in the right direction. It is caused from delta delay (i.e. simulation steps) when simulation is running. By reconsideration of the above logic design and how Vivado integrated simulator works, I came to the conclusion that creating an asynchronous logic can cause flaws or behavior that is not desired or deviates from a synthesized design.
It is for simulation purposes only. I'm aware that comparison with Z won't work in synthesized logic. I added this to the opening question.

Related

Problem with getting the right values of the signals in my vhdl code

I am working on my diploma thesis and I am writing in VHDL. In my code as it is shown below, I have assigned values to the two signals (counting and get_lbp_from_blks) at the same time. However, in my simulation wave in Modelsim I see that signal get_lbp_from_blks gets value 1 two cycles earlier than signal counting. Do you have any idea why is this happening? Waveform from Modelsim
if (making_blocks = '1') then
...doing some stuff...
making_blocks <= '0';
get_lbp_from_blks <= '1';
counting <= '1';
incr_i <= '1';
end if;
PS: Modelsim shows me a message
** Warning: Design size of 34160 statements or 279 leaf instances exceeds ModelSim PE
Student Edition recommended capacity.
Expect performance to be quite adversely affected.".
Is there any possibility that this affects my code?
Thanks in advance!

VHDL - WAIT ON <signal> statement

I'm trying to work through an example of the WAIT ON statement. Every time I try to compile my code the the compiler, Quartus II gives me the following error message.
Error (10533): VHDL Wait Statement error at T1.vhd(23): Wait Statement must contain condition clause with UNTIL keyword
The model Architecture is below. Its function is not important only the reason why the compiler is asking for a UNTIL statement. All the examples I have seen, internet and books show its use as such below:
ARCHITECTURE dflow OF T1 IS
SIGNAL middle : std_logic;
BEGIN
P1 : PROCESS IS
BEGIN
IF CLK = '1' THEN
middle <= input;
END IF;
WAIT ON CLK;
END PROCESS P1;
OUTPUT <= MIDDLE;
END ARCHITECTURE dflow;
I think the basic problem here is that the line
WAIT ON CLK;
is waiting for any type of event on CLK. This could be a transition from 'H' to '1', for example, or it could be either a rising OR falling edge of CLK. In either of these cases, there is no real hardware in the FPGA that can work in this way. It may seem obvious to you that you are looking for a rising edge, because of the if CLK = '1' line, but this is not how the synthesis tool is seeing it.
By adding an until, you can narrow down which particular event you are interested in, hopefully selecting something that can actually be realised in the FPGA. Examples:
wait on clk until clk = '1'; -- Detect a rising edge, OK (ish, see below)
wait on clk until clk = '0'; -- Detect a falling edge, OK (^^)
This method is analogous to the clk'event and clk = '1' technique of edge detection. This is not a recommended method, because you can get a simulation mismatch with reality due to the simulator responding to transitions from 'H' to '1' (among other possibilities), something the hardware cannot do.
The recommended method of detecting edges is with the rising_edge and falling_edge functions:
wait until falling_edge(clk); -- OK, no ambiguity here.
Finally, the whole structure represented here looks pretty non-standard. The common way to write a clocked process is like this:
process (clk)
begin
if (rising_edge(clk)) then
-- Do something
end if;
end process;

VHDL inferring latches

I have a question on VHDL. The code below is for a +/- 2 degree thermostat it works and simulates well, but I have a few unexplained warnings one of them in particular is really bugging me.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all, IEEE.std_logic_arith.all;
ENTITY thermo IS
PORT (
Tset, Tact: in integer;
Heaton: out std_logic
);
END ENTITY thermo;
ARCHITECTURE sequential OF thermo IS
BEGIN
PROCESS (Tact, Tset) IS
VARIABLE ONOFF: std_logic;
BEGIN
IF Tact <= (Tset - 2) then
ONOFF := '1';
ELSIF Tact >= (Tset + 2) then
ONOFF := '0';
ELSE ONOFF := ONOFF;
END IF;
Heaton <= ONOFF;
END PROCESS;
END ARCHITECTURE sequential;
The warning message thats bugging me is this:
Warning (10631): VHDL Process Statement warning at thermo.vhd(19): inferring latch(es) for signal or variable "ONOFF", which holds its previous value in one or more paths through the process<
Like I said the code works ok on ModelSim but this makes me think i am going about things the wrong way. Any suggestions ?
Thanks
Danny J
The process is specified to hold the current value of ONOFF with the line:
ELSE ONOFF := ONOFF;
Holding the value based on combinatorial inputs, like Tact and Tset, requires a latch, as reported in the warning, since usually latches means that the designer created code with an unintentional side effect.
If you want to keep the state, then consider making a clocked process instead; a template is provided in this answer.
If you want a combinatorial output, then get ridge of the internal ONOFF process variable, and make sure that an explicit value is assigned in all branches of the if statement.
You have described a SR latch for the signal ONOFF. This works fine in simulation but makes problems in FPGAs as well as digital circuits build from discrete components.
Your latch is set when the expression Tact <= (Tset - 2) is true. Now image a point in time, when the latch is currently in state '0' and Tact = Tset. Thus, the latch keps '0' as expected. This works as long as Tact is not changing. Now let the temperature fall to Tact = Tset-1. According to the above expression, the latch should keep in state '0'. But, this cannot be ensured in real hardware because the expression is not evaluated at once. Instead the multi-bit comparator for the <= operator may produce a glitch because the comparator itself is composed of several gates. If one of these gates is switching faster than another one, there might be an intermediate result, where the expression is true and, thus, your latch becomes '1'.
To notify the designer, that latches are susceptible for glitches, the synthesis compiler issues the above warning. To circumvent this problem, the FPGA offers D flip-flops which state is only updated on clock-edges. The timing analyzer of the FPGA toolchain ensures, that the evaluation of the above expression is completed before the next rising (or falling) clock-edge. So, the designer has not to worry about glitches!
You can describe a clock-edge triggered SR flip-flop in VHDL which is then mapped to the D flip-flop of the FPGA by the synthesis tool. The code style is as follows:
signal Q : std_logic; -- declare signal in the declarations part of the architecture
...
process(clock)
begin
if rising_edge(clock) then -- flip-flop triggered at the rising clock edge
if set_expression then
Q <= '1';
elsif reset_expression then
Q <= '0';
end if;
end if;
end if;
The state of the SR flip-flop is saved in the signal Q. I have used a signal instead of an variable here, because variables are harder to debug. (I recommend to use signals as often as possible.) In this code example, if both set_expression and reset_expression are both true, then the "set" takes precedence. (Can be flipped if required.) If none of the expressions is true, then the old state is saved as required by a flip-flop.

Why not a two-process state machine in VHDL?

When I learnt how to express finite state machines in VHDL, it was with a two-process architecture. One process handles the clock/reset signals, and another handles the combinatorial logic of updating the state and output. An example is below.
I've seen this style criticised (see the comments and answer to this question for example), but never in any detail. I'd like to know whether there are objective(ish) reasons behind this.
Are there technical reasons to avoid this style? Xilinx' synthesiser seems to detect it as a state machine (you can see it in the output, and verify the transitions), but do others struggle with it, or generate poor quality implementations?
Is it just not idiomatic VHDL? Remember to avoid opinion-based answers; if it's not idiomatic, is there a widely used teaching resource or reference that uses a different style? Idiomatic styles can also exist because, eg. there are classes of mistakes that are easy to catch with the right style, or because the code structure can better express the problem domain, or for other reasons.
(Please note that I'm not asking for a definition or demonstration of the different styles, I want to know if there are objective reasons to specifically avoid the two-process implementation.)
Example
Some examples can be found in Free Range VHDL (p89). Here's a super simple example:
library ieee;
use ieee.std_logic_1164.all;
-- Moore state machine that transitions from IDLE to WAITING, WAITING
-- to READY, and then READY back to WAITING each time the input is
-- detected as on.
entity fsm is
port(
clk : in std_logic;
rst : in std_logic;
input : in std_logic;
output : out std_logic
);
end entity fsm;
architecture fsm_arc of fsm is
type state is (idle, waiting, ready);
signal prev_state, next_state : state;
begin
-- Synchronous/reset process: update state on clock edge and handle
-- reset action.
sync_proc: process(clk, rst)
begin
if (rst = '1') then
prev_state <= idle;
elsif (rising_edge(clk)) then
prev_state <= next_state;
end if;
end process sync_proc;
-- Combinatorial process: compute next state and output.
comb_proc: process(prev_state, input)
begin
case prev_state is
when idle =>
output <= '0';
if input = '1' then
next_state <= waiting;
else
next_state <= idle;
end if;
when waiting =>
output <= '1';
if input = '1' then
next_state <= ready;
else
next_state <= waiting;
end if;
when ready =>
output <= '0';
if input = '1' then
next_state <= waiting;
else
next_state <= ready;
end if;
end case;
end process comb_proc;
end fsm_arc;
(Note that I don't have access to a synthesiser right now, so there might be some errors in it.)
I always recommend one-process state machines because it avoids two classes of basic errors that are exceedingly common with beginners:
Missing items in the combinational process's sensitivity list cause the simulation to misbehave. It even works in the lab since most synthesizers don't care about the sensitivity list.
Using one of the combinational results as an input instead of the registered version, causing unclocked loops or just long paths/skipped states.
Less importantly, the combinational process reduces simulation efficiency.
Less objectively, I find them easier to read and maintnain; they require less boiler plate and I don't have to keep the sensitivity list in sync with the logic.
The only two objective reasons I see are about readability and simulation efficiency in the case of Moore state machines (where primary outputs depend only on the current state, not the primary inputs).
Readability: if you merge together in a single process outputs and next state computations it might be more difficult to read / understand / maintain than with separate combinatorial processes for separate concerns.
Simulation efficiency: in the 2-processes solution your combinatorial process will be triggered on every primary input and / or current state change. This makes sense for the part of the process that computes the next state but not for the part that computes the outputs. The latter shall be triggered only on current state changes.
There is a detailed description about this in ref. [1] below. First, FSMs are classified in 3 categories (first time this is done), then each is examined thoroughly, with many complete examples. You can find the exact answer to your question on pages 107-115 for category 1 (regular) finite state machines; on pages 185-190 for category 2 (timed) machines; and on pages 245-248 for category 3 (recursive) state machines. The templates are described in detail for both Moore and Mealy version in each of the three categories.
[1] V. Pedroni, Finite State Machines in Hardware: Theory and Design (with VHDL and SystemVerilog), MIT Press, Dec. 2013.

Is rising_edge in VHDL synthesizable

In my coding when I write this statement, it is simulated, but not synthesizable. why? Now what should I do to solve this problem???
IF ((DS0='1' OR DS1='1')and rising_edge(DS0) and rising_edge(DS1) AND DTACK='1' AND BERR='1') THEN
RV0 <= not RV;
else
RV0 <= RV;
The most important thing when doing FPGA-designs is to think hardware.
An FPGA consists of a number of hardware blocks, with a predetermined set of inputs and outputs - the code you write needs to be able to map to these blocks. So even if you write code that is syntactically correct, it doesn't mean that it can actually map to the hardware at hand.
What your code tries to do is:
IF ((DS0='1' OR DS1='1')and rising_edge(DS0) and rising_edge(DS1) AND DTACK='1' AND BERR='1') THEN
(...)
If DS0 and DS1 currently have a rising edge (implying that they're also both '1', making the first part with (DS='1' OR DS1='1') redundant), and if DTACK and BERR are both 1, then do something.
This requires an input block that takes two clock inputs (since you have two signals that you want to test for rising edges simultaneously), and such a block does not exist in any FPGA I've encountered - and also, how close together would such two clock events need to be to be considered "simultaneous"? It doesn't really make sense, unless you specify it within some interval, for instance by using a real clock signal (in the sense of the clock signal going to the clock input of a flip-flop), to sample DS0 and DS1 as shown in Morten Zilmers answer.
In general, you'd want to use one dedicated clock signal in your design (and then use clock enables for parts that need to run slower), or implement some cross-clock-domain synchronization if you need to have different parts of your design run with different clocks.
Depending on the IDE environment you use, you may have access to some language templates for designing various blocks, that can help you with correctly describing the available hardware blocks. In Xilinx ISE you can find these in Edit > Language Templates, then, for instance, have a look at VHDL > Synthesis Constructs > Coding Examples > Flip Flops.
An addition to sonicwave's good answer about thinking hardware and synthesis to
the available elements.
The rising_edge function is generally used to detect the rising edge of a
signal, and synthesis will generally use that signal as a clock input to a
flip-flop or synchronous RAM.
If what you want, is to detect when both DS0 and DS1 goes from '0' to
'1' at the "same" time, then such check is usually made at each rising edge
of a clock, and the change is detected by keeping the value from the
previous rising clock.
Code may look like:
...
signal CLOCK : std_logic;
signal DS0_PREV : std_logic;
signal DS1_PREV : std_logic;
begin
process (CLOCK) is
begin
if rising_edge(CLOCK) then
if (DS0 = '1' and DS0_PREV = '0') and -- '0' to '1' change of DS0
(DS1 = '1' and DS1_PREV = '0') and -- '0' to '1' change of DS1
DTACK = '1' AND BERR = '1' then
RV0 <= not RV;
else
RV0 <= RV;
end if;
DS0_PREV <= DS0; -- Save value
DS1_PREV <= DS1; -- Save value
end if;
end process;
...

Resources