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

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.

Related

VHDL block and guarded input - what does this code do?

I have the following from a beginner's VHDL tutorial:
rising_edge: block(clk’event and clk = ‘1’)
begin
result <= guarded input or force after 10ns;
end block rising_edge
The explanatory text is
"Essentially I have a block called rising_edge, and it's a block with a guard condition which does the following, it checks that we have an event on the clock, and that the clock is equal to one, so we're effectively looking for the so called rising_edge. We're looking for the event where the clock goes from 0 to 1, and if it does, then we can conditionally assign the results, so you'll see that the result variable here says that it is a guarded input or force after 10 ns might seem a bit confusing, but consider it without the guarded keyword. All we're doing is we're assigning the result of the evaluation of input or force, and we're doing it in a guarded setup. So, in this case, the assignment of the signal result is only executed if the guard signal is actually true, and in our example it means that the assignment of the expression, which is input or force, will only happen on the rising_edge of the clock because that's on guard condition."
Now I've read this over and over and searched on the net but have come up blanks as to what this is actually doing. Can someone please gently explain its purpose?
A block is essentially a grouping of concurrent statements. In terms of practical usage, it is very similar to a process, only it has a limited scope wich allows component-style signal mapping(with port and port map). It can be used to improve readability(see this question) and really not much else. Blocks are resonably rarely used and frequently not synthesis supported(see here). To my (limited) knowledge, the use of blocks has no other advantage than readability.
Because your block statement contains a guard condition(clk'event and clk='1' is the guard condition here), it is a guarded block. Inside a guarded block, signals that are declared guarded (like in your example) will only be assigned if the guard condition evaluates to true
The entire statement that has been guarded(i.e. in your case input or force after 10ns) will only be executed when the guard condition evaluates to true, i.e. on the rising edge of clk. Thus, for all intents and purposes this block has the same behaviour as
process(clk)
begin
if clk'event and clk = '1' then
result <= input or force after 10ns;
end if;
end process;
I will say though, this is a terrible example. For one thing, as others have stated, the usage of block is very rare and they are generally only used in quite advanced designs. The usage of clk'event and clk = '1' has been discouraged since 1993(see here). It should also be mentioned again that the usage of rising_edge as a label is a terrible idea, as is the use of force for a signal name(in VHDL 2008, force is a reserved keyword that can be used to force a signal to a value).
Working from the idea that this is supposed to be a beginners tutorial, and with the lack of any explanation as to why such an unusual style has been used, a much more conventional implementation would be:
process : (clk)
begin
if (rising_edge(clk)) then
result <= input or force after 10 ns;
end if;
end process;
A couple of points to note:
This assumes that input and force are either signals, or inputs to the entity.
It is unusual to model signal assignment delays if your code is going to be implemented in a real hardware device.
The code in your question uses after 10ns;, which is not valid; you need a space between the value and the units (as in my code).
The code in your question uses rising_edge as an identifier, when this is actually already defined as a function, assuming you are including standard IEEE libraries newer than I believe VHDL93.
The code in your question uses force as a signal name, when this is also a reserved language keyword since VHDL2008.
My advice to you is to find a different tutorial. The quote you posted is not clearly written, and the code you posted appears to be sending you down a strange path. All I can think is that the tutorial is in fact very, very old.

Ensuring propagation is complete in VHDL without an explicit click

I am looking to build a VHDL circuit which responds to an input as fast as possible, meaning I don't have an explicit clock to clock signals in and out if I don't absolutely need one. However, I am also looking to avoid "bouncing" where one leg of a combinatorial block of logic finishes before another.
As an example, the expression B <= A xor not not A should clearly never assign true to B. However, in a real implementation, the two not gates introduce delays which permit the output of that expression to flicker after A changes but the not gates have not propagated that change. I'd like to "debounce" that circuit.
The usual, and obvious, solution is to clock the circuit, so that one never observes a transient value. However, for this circuit, I am looking to avoid a dependence on a clock signal, and only have a network of gates.
I'd like to have something like:
x <= not A -- line 1
y <= not x -- line 2
z <= A xor y -- line 3
B <= z -- line 4
such that I guarantee that line 4 occurs after line 3.
The tricky part is that I am not doing this in one block, as the exposition above might suggest. The true behavior of the circuit is defined by two or more separate components which are using signals to communicate. Thus once the signal chain propagates into my sub-circuit, I see nothing until the output changes, or doesn't change!
In effect, the final product I'm looking for is a procedure which can be "armed" by the inputs changing, and "triggered" by the sub-circuit announcing its outputs are fully changed. I'd like the result to be snynthesizable so that it responds to the implementation technology. If it's on a FPGA, it always has access to a clock, so it can use that to manage the debouncing logic. If it's being implemented as an ASIC, the signals would have to be delayed such that any procedure which sees the "triggered" signal is 100% confident that it is seeing updated ouputs from that circuit.
I see very few synthesizable approaches to such a procedural "A happens-before B" behavior. wait seems to be the "right" tool for the job, but is typically only synthesizable for use with explicit clock signals.

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.

VHDL - creating a variable number of signals

I'm creating a full adder with a variable number of bits. I've got a component that is a half-adder which takes in three inputs (the two bits to add, and a carry in bit) and gives 2 outputs (one bit output and a carry out bit).
I need to tie the carry out of one half-adder to the carry in of another. And I need to do this a variable number of times (if I'm adding 4 digit numbers, I'll need 4 half adders. If I'm doing 32 bit numbers, I'll need 32 half adders).
I was going to tie the carry outs of one half-adder to the carry in of another using signals, but I don't know how to create a variable number of signals.
I can instantiate a variable number of half-adders using a for-loop in a process, but since signals are defined outside of processes, I can't use a for loop for it. I don't know how I should tie the half-adders together.
The easiest way to write an adder in VHDL is not to worry about full adders and half adders, but just type:
a <= b + c;
where a,b and c are signed or unsigned
95% of the time, the synthesis tools will do a better job than you would.
I think you want variable-width signals not variable numbers of signals
Your signals need to be std_logic_vector(31 downto 0) for example - and then you wire up the bits of those signals to your half-adders appropriately.
Of course, as those signals are numbers, then don't use std_logic_vector use signed or unsigned (and the ieee.numeric_std lib).
And (as Philippe rightly points out) unless this is a learning exercise, just use the + operator.

Is initialization necessary?

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.

Resources