Is initialization necessary? - vhdl

In VHDL, is initialization necessary when creating a signal or a vector?
What happens if one forgets to initialize a signal or integer value?

In simulation, if you do not set an initial value, each element of your vector will get the default value (this is defined by the VHDL language specification). For enum types, this is the first element defined in the enumeration type: booleans will be false, std_logic will be 'U' (undefined). Note that 'U' has no meaning in electrical circuits. It is merely a hint for the verification engineer that you don't know which value the flip-flop has at power-on.
After synthesis: FPGA synthesizers will use the initial value that you set as the "power on" value of the flip-flops and memories if the target technology supports this! If the technology does not support a forced initial value (and for ASICs), the initial value at power-on is not known. It could be 1 or 0. (See for example: http://quartushelp.altera.com/11.0/mergedProjects/hdl/vhdl/vhdl_pro_power_up_state.htm)
Two possible styles:
Choose an explicit initial value, with or without explicit reset circuits (usually for modern FPGAs)
Set 'U' as initial value, and have a proper reset circuit to force a known reset value
If you go with the first choice, be sure to check if your target technology supports this style!

In simulation, everything in VHDL is initialised at the start to the "left-most" element of the range which represents them.
So, std_logic will get 'U', boolean will get false, integer will get a big negative number. Any enumerated types you've defined yourself will init to their first member. etc.
You can override this with an explicit initialisation:
variable i : integer := 0;
the simulator will then use your initialisation.
When it comes to synthesising your code, in an ASIC, explicit initialisations are ignored (there's no silicon to support them!), and everything initialises unpredictably. So you have a reset pin and explicit code which assigns the value you want when that pin is asserted.
When you target an FPGA and don't explicitly initialise, most of the time things will initialise to something 'like zero', but you can't rely on it (sometimes inverters are pushed around and things look like they've inited to 'one'). So you have a reset pin and explicit code which assigns the value you want when that pin is asserted.
Some synthesisers (XST at least) will support explicit initialisations and pass them into the netlist so that you can rely on them. In this case you can still have a reset signal - which can do something different so a particular flipflop could initialise to one value and reset to another!

It is not strictly necessary in VHDL, just like it is not necessary in C/C++, but a similar result can occur. Without initializing a signal or vector of signals, a simulator will typically simulate that it is in an unknown state (assuming you are using std_logic signals). However, a synthesis engine will pick one or the other as an initial value since when an FPGA is programmed all memory elements will be initialized one way or another (i.e. they are not initialized to an unknown state).
Some people will not initialize a signal on declaration, but will instead use their circuit to initialize the memory element (e.g. create reset logic to initialize the memory element). Other will initialize the memory element when it is declared. These are design decisions which have their own tradeoffs.

Related

When should I use reg instead of wire? [duplicate]

This question already has answers here:
Using wire or reg with input or output in Verilog
(5 answers)
Closed 6 years ago.
I'm confused about reg and wire when I was doing my homework. I could not understand differences between reg and wire exactly. Can you explain shortly? Also, I wonder that what will happen when I use output q instead of output reg q?
In simulation, a Verilog wire behaves like a piece of metal, a track, a wire, whilst a Verilog reg is a variable, it is storage*.
The difference between them in simulation can be illustrated by showing what happens if I assign to them from more than one place. If I assign to a wire from more than one place, the simulation will behave exactly as if I had shorted those two wires together. So,
wire w;
assign w = 1'b1;
assign w = 1'b0;
initial
$display("w= %b", w);
will display x. The value of w will be x because one assign is driving 1'b1 and the other 1'b0 and so this will resolve to an x. In this way it is modelling the behavoiur of real hardware, where x represents an unknown value (the value of a real piece of wire drive high by one driver and low by another will really be unknown).
If I assign to a reg - a variable - from more than one place, I will get different behaviour. Instead of resolving to an x, the reg will just take whatever value is assigned last. So,
reg r;
initial
r = 1'b1;
initial
r = 1'b0;
initial
#1 $display("r= %b", r);
will display either 1 or 0 depending on which initial block is executed last (something that is not deterministic).
Notice, that the reg is driven from initial blocks. A reg has to be driven from an initial or an always block (so-called procedural code). Assuming you are writing Verilog, not System Verilog, you cannot assign to a reg from an assign statement nor from the output of an instantiated module. So, if you want to assign to something from procedural code, you have to use a reg; if you want to assign to something from an assign statement or the output of an instantiated module, it has to be a wire. And, therefore it follows that whether you define an output as a reg or a wire depends entirely on where you're assigning to it. If you're assigning to it from an always block, it needs to be a reg; if you're assigning to it from an assign statement or the output of an instantiated module, it needs to be a wire.
That is the difference in the behaviour of a reg and a wire in simulation. Your synthesiser, will interpret a reg differently. If you assign to a reg from more than one always block (you can't synthesise initial blocks), then you logic synthesiser will synthesise two pieces of hardware driving the same piece of metal, track, wire, whatever - something you probably don't want.
*That does not mean a reg will necessarily become storage (ie a flip-flop) when synthesised. Whether, a `reg becomes a flip-flop or combinational logic depends on whether it is assigned in a sequential- or combinational-style always block.
output q is equivalent to output wire q.
reg is used for sequential logic such as flop. It is also required in always* blocks even for the combo blocks.
wire is used for the combinatorial logic.

VHDL concurrent selective assignment synthesis

a real junior question with hopefully a junior answer, regarding one of the main assignments of VHDL (concurrent selective assignment) can anyone explain what a VHDL compiler would synthesise the following description into?
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY Q2 IS
PORT (a,b,c,d : IN std_logic;
EW_NS : OUT std_logic
);
END ENTITY Q2;
ARCHITECTURE hybrid OF Q2 IS
SIGNAL INPUT : std_logic_vector(3 DOWNTO 0);
SIGNAL EW_NS : std_logic;
BEGIN
INPUT <= (a & b & c & d); -- concatination
WITH (INPUT) SELECT
EW_NS <= '1' WHEN "0001"|"0010"|"0011"|"0110"|"1011",
'0' WHEN OTHERS;
END ARCHITECTURE hybrid;
Why do I ask? well I have previously gone about things the wrong way i.e. describing things on VHDL before making a block diagram of the components needed. I would envisage this been synthed as a group of and gate logic ?
Any help would be really helpful.
Thanks D
You need to look at the user guide for your target FPGA, and understand what is contained within one 'logic element' ('slice' in Xilinx terminology). In general an FPGA does not implement combinatorial logic by connecting up discrete gates like AND, OR, etc. Instead, a logic element will contain one or more 'look-up tables', with typically four (but now 6 in some newer devices) inputs. The inputs to this look up table (LUT) are the inputs to your logic function, and the output is one of the outputs of the function. The LUT is then programmed as a ROM, allowing your input signals to function as an address. There is one ROM entry for every possible combination of inputs, with the result being the intended logic function.
A function with several outputs would simply use several of these LUTs in parallel, with the same inputs, one LUT for each of the function's outputs. A function requiring more inputs than the LUT has (say, 7 inputs, where a LUT has only 4), simply combines two LUTs in parallel, using a multiplexer to choose between the output of the two LUTs. This final multiplexer uses one of the input signals as it's control, and again every possible combination of inputs is accounted for.
This may sound inefficient for creating something simple like an AND gate, but the benefit is that this simple building block (a LUT) can implement absolutely any combinatorial function. It's also worth noting that an FPGA tool chain is extremely good at optimising logic functions in order to simplify them, and to better map them into the FPGA. The LUT provides a highly generic element for these tools to target.
A logic element will also contain some dedicated resources for functions that aren't well suited to the LUT approach. These might include dedicated carry chains for adders, multiplexers for combining the output of several LUTS, registers (most designs are synchronous). LUTs can also sometimes be configured as small shift registers or RAM elements. External to the logic elements, there will be more specific blocks like large multipliers, larger memories, PLLs, etc, none of which can be as efficiently implemented using LUT resource. Again, this will all be explained in the user guide for your target FPGA.
Back in the day, your code would have been implemented as a single 74150 TTL circuit, which is a 16-to-1 mux. you have a 4-bit select (INPUT), and this selects one of 16 inputs to the chip, which is routed to a single output ('EW_NS`). The 74150 is obsolete and I can't find any datasheets, but it's easy to find diagrams of what an 8-to-1 mux looks like (here, for example). The 16->1 is identical, but everything is wider. My old TI databook shows basically exactly the diagram at this link doubled up.
But - wait. Your problem is easier, because you're not routing real inputs to the output - you're just setting fixed data values. On the '150, you do this by wiring 5 of the 16 inputs to 1, and the remaining 11 to 0. This makes the logic much easier.
The 74150 has basiscally exactly the same functionality as a 4-input look-up table (where the fixed look-up data is the same as fixed levels at the '150 inputs), so it's trivial to implement your entire circuit in a single LUT in an FPGA, as per scary_jeff's answer, rather than using a NAND-level implementation. In a proper chip, though, it would be implemented as a sum-of-products, or something similar (exactly what's in the linked diagram). In this case, draw a K-map and find a minimum solution. My 2 minutes on the back of an envelope comes up with three 3-input AND gates, driving a 3-input OR gate. I'll leave it as an exercise to you to check this :)

Unconstrained std_logic_vector

I have an assignment to create a Test Bench for a N-bit multiplier. The code is odd to me. It is a black box n-bit but for his std_logic_vectors he does not specify any size. Im guessing this is done with the test bench. I have not seem this before and was hoping someone could explain how this works
VHDL supports unconstrained std_logic_vectors. This means that you can design a block that doesn't specify the length of the inputs and outputs. There can be a number of pitfalls to doing this (see this article), but in the case of something like a multiplier it can help with code reuse. You get to define what the input and output widths of the block are by connecting them to a std_logic_vector of the desired width.
Since you indicated that the block is a multiplier, I would check the documentation or interface to see if there are generics associated with the port widths. That is a common way of creating a generic block interface with I/O specific logic inside. That way you can specify how "wide" the logic needs to be, without having to have a separate block for every possible width.

Do all Flip Flops in a design need to be resettable (ASIC)?

I'm trying to understand clock-reset in a chip. In a design what criteria are used to decide whether a flop should be assigned to a value (typically to zero) during reset?
always_ff #(posedge clk or negedge reset) begin : process_w_reset
if(~reset) begin
flop1 <= '0;
....
end else begin
if (condition) begin
flop1 <= something ;
....
end
end
end
always_ff #(posedge clk) begin : process_wo_reset
if (condition) begin
flop1 <= something ;
....
end
end
Is it a bad practice to not to reset a flop which is used later as a control signal in a comb logic? What if the design makes sure that the flop will have a valid value (0 or 1) assigned to it before its used in a comb logic block (i.e. in a if statement or in FSM comb logic) ?
I feel like it's better to always reset all the flops in the design. In that way there won't be any Xs after reset in the chip. However, it seems like for datapath logic, resetting flop might need not be a big deal as it'll be just pipe stages. However if a flop is in control path (i.e. FSM next state comb logic) then it should be reset to a default value. Is my understanding correct? I don't know much about DFT and not sure if it has any other implication.
Assuming that reset means asynchronous reset, as in the code examples.
The answer is partly opinion based, since a design can be made to work with reset of a minimum number of the Flip-Flops (FFs) and all of the FFs.
I suggest that a minimum number of FFs are reset, and typically that leads to reset of most FFs in the control path, and no reset of FFs in the data path. The advantages of this approach are outlined below.
Simulation is often conservative with respect to propagation of uninitialized values, both for Verilog and VHDL, so it is like simulation can check both 0 and 1 values at once when the value is uninitialized.
Bugs due to FFs that are not reset, are therefore likely to show earlier in verification with simulation, and the designer thereby gets valuable feedback about wrong design assumptions, which may lead to corrections in the design that fixes other bugs. Just resetting all the FFs is likely to hide such bugs.
It may seem like design and verification is just easier if all FFs are reset, both in control and data path, since it fixes all those "annoying" X propagation in the design. But it requires an increased number of tests in order to verify all value combinations when X propagation is suppressed through reset.
Implementation gives a smaller load on the reset signal, so it is easier to meet timing of the reset net throughout the chip.
DFT (Design For Test) in general, then adding reset to the FFs will not aid DFT in finding nets stuck at reset value. With a DFT scan chain approach where all the FFs are loaded through the scan chain, then the lack of reset on some FFs will not require more vectors.
Generally you need to think about where the 'X's will propagate in your simulation and which ones matter and which ones are don't care conditions. For example, if you have a block of logic which doesn't start operating until an enable bit is set, so long as the enable bit itself is set and enough upstream logic is reset so reset values will propagate through to the enabled logic in time, you are most likely OK with not reseting the logic in between. However, you do want to reset any logic that feeds back into itself, (for example state machines) otherwise the upstream resets will never be able to establish a known state in the feedback block.
I agree with Morten Zilmer that you should only reset flops that require resetting, although my background is more FPGA than ASIC.
It's worth pointing out there is a gotcha in Verilog / SystemVerilog - if you have a clocked process that drives registers that are reset and registers that aren't you will end up inferring a clock enable or an additional mux on the input of your flip-flop.
This is usually not what was intended.
There is a more detailed explanation in this answer. I also wrote a blog post outlining a mechanism for abstracting away synchronous/asynchronous and active high/low reset.
As a general rule of thumb, you should probably always reset control signals.
For data flops, resetting can cost you area, so it really depends on whether you care about area.
In recent years simulators started to support X propagation modes that allow you to catch some of the X issues in RTL (instead of gate level simulation). It is a good practice to run these to make sure you don't have a reset problem with uninitialized sram or flops.

what exactly is a variable in VHDL?

I know how to use variables in VHDL and what I can do with that, but I don't know exactly what it is in hardware ?
What is the difference between signals and variables in hardware and where the value of a variable store ?
Is it a wire or it depends on my code ?
According to the "QuantumRipple" comments I extend this question :
I synthesized the following simple code with ISE (Xilinx synthesis tool) and the variable (var) synthesized into a D flip flop ??
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY test IS
port(
clk : in std_logic;
input : in std_logic;
output : out std_logic
);
END test;
ARCHITECTURE Behavioral OF test IS
BEGIN
PROCESS(clk)
VARIABLE var : std_logic;
BEGIN
IF clk'event AND clk = '1' THEN
var := input;
END IF;
output <= var;
END PROCESS;
END Behavioral;
Thanks for comments and answers ...
Variables can be used in several functionally distinct ways. As a result, the synthesizer can implement them in several ways.
The following applies to clocked processes:
If you independently set the variable in a process before you read it, it will synthesize purely into [a group of] LUTs. (complicated logical functions or a vector variable will require more than one LUT even for a single assignment)
If you update a variable multiple times and read it between updates, it will synthesize into several [groups of] LUTs. This case is no different than if you created a different named variable for each update, read pair.
If you read the value of the variable before it is set in the process and assign it after all reads it will synthesize into a flip flop. Variables in this configuration behave equivalently to signals.
If you set the variable based of a combination of itself and another value before it is independently set, it will synthesize into an (unnamed) flip flop and a [group of] LUTs hanging off of that.
These can also be combined to an extent. For example, if you read a variable at the start of a process and assign it at the end, but also update and read the variable in the middle, it will generate a flip flop whose output is used for the first read, and also some LUTs whose output is used for the second read.
Multiple assignments without intermediary reads also get collapsed into one group of LUTs (nothing taps off of the intermediary value).
Another important thing to understand about how VHDL is synthesized is that signals and variables do not really get translated into specific things. A signal refers to a specific wire in the design (not the stuff in between like LUTs and Flip Flops). Signals that are assigned in clocked processes will usually refer to the Dout wire from a certain Flip Flop and signals that are assigned in a combinatorial process or concurrent statement will usually refer to a wire coming out of a LUT, although it might refer to the same wire as another signal (including clocked signals!) if there was no logic in the assignment (a simple a <= b).
The assignment statements describe the relationship between wires.
Variables do not refer to a fixed wire, but rather just describe behavior.
Each variable assignment that is used to assign something else before it is assigned again creates a reference to a different wire (although these wires will typically not be explicitly named like signal wires - that's the point of variables).
The synthesizer takes that behavior and tries to determine what set of LUTs and Flip Flops are required to make the hardware do that. Note that while signals refer to some fixed wires, they don't refer to all wires. The synthesizer creates many un-named (the synthesizer generates an arbitrary name) wires to connect the generated components (LUTs and flip flops) between each explicitly named wire. It is because variables are so flexible in what the describe (not a fixed wire) that they can cause the generation of so many different combinations of basic components depending on how they are used.
For your specific code, yes, the variable var will cause a flip flop to be synthesized.
It would also do the exact same thing if 'var' was a signal and the output <= var; assignment was outside of the process.
In your code, var is set based on the sole assignment to refer to the Dout wire of a clocked element (flip flop) that has a Din of input, then the output is assigned to refer to the same wire as var.
In fact, it does the exact same thing as just doing
IF clk'event and clk = '1' THEN
output <= input;
END IF;
in this case, output is just directly assigned to refer to the Dout wire of the clocked element that has a Din of input instead of using var as a proxy.

Resources