How many Flip Flops will this code produce? - vhdl

so I have an exam coming up and I am solving tutes. One of the questions is very basic but I don't think I have the exact logic down for it. It simply gives me a small bit of the code and asks how many Flip Flops will this produce. Could you help me understand how I can find this out? Thanks!
Architecture rtl of ex is
signal a,b,q, int: bit_vector(3 downto 0);
begin
process(clk)
begin
If clk = '1' and clk'event then
int <= int +1;
q <=int;
a <= b xor q;
end if;
end process;
b <= int
end;

OK, here's the correct - but snarky - answer, with the caveat that it is almost certainly not what the question calls for.
Given the above Architecture declaration, it is clear that there are no assignments to anything other than internal signals. We are not shown the Entity declaration, but from the Architecture we can assume at least an Input port named clk. There may or may not be outputs; we cannot tell, however they are irrelevant as there are no assignments to them.
Therefore the above architecture cannot affect any outputs, so it will be entirely trimmed during the Logic Minimisation phase of synthesis, and generate no Flipflops whatsoever.

Related

Synchronous counter in VHDL with compare match and load

I created the following Counter with a compare match functionality:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity Counter is
generic (
N : natural := 24
);
port (
-- Input counter clock
clk : in std_logic := '0';
-- Enable the counter
enable : in std_logic := '0';
-- Preload value loaded when clk is rising and load is 1
load_value : in std_logic_vector((N-1) downto 0) := (others => '0');
-- Set to 1 to load a value
load : in std_logic := '0';
-- Compare match input is compared with the counter value
compare_match_value : in std_logic_vector((N-1) downto 0) := (others => '0');
-- Is 1 when compare_match_value = counter_value
compare_match : out std_logic := '0';
output_value : out std_logic_vector((N-1) downto 0) := (others => '0')
);
end Counter;
architecture Behavioral of Counter is
signal counter_value : unsigned((N - 1) downto 0) := to_unsigned(0, N);
begin
output_value <= std_logic_vector(counter_value);
process (clk) is
begin
if rising_edge(clk) then
if enable = '1' then
if load = '1' then
counter_value <= unsigned(load_value);
else
counter_value <= counter_value + 1;
end if;
else
if load = '1' then
counter_value <= unsigned(load_value);
end if;
end if;
end if;
end process;
process (counter_value) is
begin
if unsigned(compare_match_value) = counter_value then
compare_match <= '1';
else
compare_match <= '0';
end if;
end process;
end Behavioral;
The behavior of my counter is to be fully synchronous with the input clk signal. Disabling the counter is always possible and the value is held at the current count value. A load value can be assigned with the load and load_value signal. Whenever the load signal is high and a rising edge is detected, the counter value is updated to the load_value.
Another feature is the compare unit which outputs high on compare_match output. The simulation works as expected but I have a few questions when synthesizing this design on spartan 3 fpga.
Is this considered a good design of my counter because I'm still not much experienced in VHDL.
Are there any undefined states when using the compare unit in further logic in my design? As I see it compare_match is calculated whenever the counter_value is updated.
When using a large number for N, is there anything special about the delay I need to consider?
In general it seems to me a quite good description.
However, I would like to point out some minor things (that might me some answers to your 1st question).
1) As, I see right now your counter does not contain any reset (neither asynchronous nor synchronous). In general you cannot predict the starting point of your counting (even if, probably, it will be all '0's at start-up).
In my opinion, it would be a neater design if you could have a reset signal.
I also noticed that the loading is activated regardless of the fact that the counter is enabled or not. I have no comment about this since it could be a specification for your design. Maybe you can compact the code by moving the "if load" part outside of the "if enable" (i.e. changing the order to the comparisons).
To improve the readability (especially when the designs will be more complex), I advise you to label the process. This will help you to identify the different part of the design.
You can skip lot of the extra-typing if you use the VHDL-mode of emacs. It has built in templates that would take care of the "boring" part related to coding.
I also see that you have default values for your input ports. In my opinion, this is not a very good practice; they would be ignored by synthesizer leading to an IP that might behave differently than what you expect. In general, do not make assumptions (a part those that are specified) on the external signals.
Finally, I have a comment about the compare part.
This goes for both question 1) & 2)
1-2)
In the compare process, you have just listed counter_value in the sensitivity-list.
This means that the process would be activated only when counter_value changes.
Since you compare it with a signal (compare_match_value) that is an input to the block (hence it can change values) it would be better to have it too in the sensitivity-list. Otherwise, the comparison would not apply (i.e. the process would not be activated) when you change compare_match_value.
Linting tools and synthesizer might complain about it (stating warning like incomplete sensitivity-list). As matter of fact it is good practice to list all the signals that may change in the list for combinatorial processes.
Regarding the comparison itself, the way you described it is absolutely fine and you would not have uncovered states. Basically you have specified all possible conditions so no surprises there.
3)
Regarding your 3rd question, since you are targeting an FPGA, you could "relax" about it. FPGAs have dedicated structure for fast arithmetic operations and (as long as you do not use all of them) the synthesizer would use them to close time.
Also in ASIC, synthesizer would probably select an appropriate arithmetic structure to close time.
If you want to be on the safe side, you can add a register at the output of the comparison block. This will prevent creating a long combinatorial path especially if you IP has to be integrated with other blocks. Of course this extra-register would add an 1-clock-cycle latenc, but it will improve your overall timing.
I hope these suggestions could be useful to you and cover (at least partially) your doubts.
Keep on coding :)

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.

issue with vhdl structural coding

The code below is a simple vhdl structural architecture, however, the
concurrent assignment to the signal, comb1, is upsetting the simulation
with the outputs (tb_lfsr_out) and comb1 becoming undefined. Please, please help,
thank you, Louise.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity testbench is
end testbench;
architecture behavioural of testbench is
CONSTANT clock_frequency : REAL := 1.0e9;
CONSTANT clock_period : REAL := (1.0/clock_frequency)/2.0;
signal tb_master_clk, comb1: STD_LOGIC := '0';
signal tb_lfsr_out : std_logic_vector(2 DOWNTO 0) := "111";
component dff
port
(
q: out STD_LOGIC;
d, clk: in STD_LOGIC
);
end component;
begin
-- Clock/Start Conversion Generator
tb_master_clk <= (NOT tb_master_clk) AFTER (1 SEC * clock_period);
comb1 <= tb_lfsr_out(0) xor tb_lfsr_out(2);
dff6: dff port map (tb_lfsr_out(2), tb_lfsr_out(1), tb_master_clk);
dff7: dff port map (tb_lfsr_out(1), tb_lfsr_out(0), tb_master_clk);
dff8: dff port map (tb_lfsr_out(0), comb1, tb_master_clk);
end behavioural;
It's just a little more complex than Radix Ciano(1) says. All tb_lfsr_out elements are showing 'U' from Now = 0 ns. The reason why is that all of the D flip flops aren't initialized.
All tb_lfsr_out elements are showing 'U' from Now = 0 ns. The reason why is that all of the D flip flops aren't initialized.
If you reset all the flip flops the result will always be '0' without a '1' to cause a flip in the XOR gate.
Preset the D flip flops (which can come for free in an FPGA implementation):
This was done by simply adding a default value:
q: out std_logic := '1';
(1) Yes it's a minor change, and to all appearances someone changed their user name and if asked I would have changed Radix to Ciano. Making changes simply to cross a threshold is ridiculous.
The entire purpose of this answer was to avoid stepping on the other answerer's rights of authorship and now he's done the very thing. The issue with his answer being that the complimentary property of XOR prevented the LFSR from working when all inputs were '0's or any inputs were metavalues.
And while you're at it no one noticed the error in the waveform now corrected, apparently too self absorbed in playing games with answer edits. (The signals after the label dff8 were actually from dff7).
There's a message here which is in the form of a question. What's the purpose in answering questions on stackoverflow? See Why I no longer contribute to StackOverflow . And note Mr. Richter's reputation has continued to eek upward, including for the example post on goto he cites as likely to induce severe ire. (And the message there is have patience all you petty editors, sooner or later you're 'reputation' will reach self sustaining levels unless the system is altered to prevent it).
Also note the question's author has to date and after an impassioned plea closing his question not show acceptance of nor use for any answer.
In the mean time quit spoiling why I answer questions on VHDL by changing the words I write, although I have to admit the edit voting history was entertaining.

About sequential code in FPGAs

In VHDL, in a process all steps will be executed sequentially, but I wonder how an FPGA can execute steps sequentially. I am very confused about how sequential assignments, functions and similar are being generated in an FPGA, so can anyone throw some light on this topic?
process(d, clk)
begin
if(rising_edge(clk)) then
q <= d;
else
q <= q;
end if;
end process;
This is just code for a simple D-Latch, but how will this be implemented in an FPGA?
It is not "executed" sequentially as such - but the synthesizer interprets the code sequentially, and creates the hardware design to fit such an interpretation.
For instance, if you assign a value to a signal twice during a clocked process, the first assignment is simply ignored, while the second takes effect (remember that a signal is only assigned at the end of a process statement, not immediately):
signal a : UNSIGNED(3 downto 0) := (others => '0');
(...)
process(clk)
begin
if(rising_edge(clk)) then
a <= a - 1;
a <= a + 1;
end if;
end process;
The above process will always increment a by 1. Similarly, if you have the second assignment inside an if statement, the synthesizer will simply create two paths for a - a decrement for when the if statement is not fullfilled, and an increment for when it is.
If you use variables, the idea is the same - although intermediate values are used, as variables take on their new value immediately.
But it all boils down to that the synthesizer does all the "magic" of interpreting your process in a sequential way, then generating hardware that does what you have described.
Your example basically describes a d-flip-flop (the Xilinx FPGA tools iirc distinguish latches and flip-flops in that flip-flops are edge-sensitive, and latches are level-sensitive), although in a different way than typically recommended.
You can basically write the same code as:
process(clk)
begin
if(rising_edge(clk)) then
q <= d;
end if;
end process;
It will automatically keep its value in the other cases. This will be implemented as a flip-flop inside the FPGA. Most FPGAs consist of blocks of look-up tables and flip-flops, to which quite a lot of different hardware can be mapped. The above code will simply by-pass the look-up table, and just use the flip-flop of one of the blocks.
You can learn more about the internal workings by having a look at the datasheet for your particular FPGA. For Spartan3-series FPGAs for instance, have a look at page 24 of the Xilinx Spartan3 FPGA Family Data Sheet

Resources