Why do we use REG in FGPA / VHDL / VIVADO? - verilog

I am programming with Xilinx's vivado in verilog.
I was wondering why for some outputs we use reg
For example reg [3:0] encoder_output
we use that because our 16 to 4 encoder has 4 outputs right? I am assuming that we use reg whenever we need to "STORE SOMETHING"
Is my idea right??

It's not actually a stupid question, despite all the downvotes. In The Beginning, The Designer created nets and registers. Nets were intended as connections between hardware elements, and had values driven onto them; they didn't hold those values. Nets are normally declared as wire. Registers were data storage elements, and did hold a value; they are normally declared as reg. Over time, it became clear that this division (which sort-of-looks-like "hardware") doesn't make sense, and at least one proposal was made to drop the net/register distinction from the language. This never happened (unless you consider SystemVerilog to be 'Verilog', which I don't).
So, your question made sense 30 years ago, and your answer would have been "correct".
However, in practice, it doesn't matter which you use. The real distinction is that you can only assign to a reg from within sequential code (always/etc), and to a wire otherwise. This requirement is completely arbitrary and only exists for historical reasons. You just need to learn the rules.

Related

Does the ordering of index arguments matter when initializing memory with readmemb

So in order to load memory into a "file" on the FPGA I am using the procedure outlined here.
The rough formula is this
reg [7:0] ex2_memory [0:15];
$readmemh("ex2.mem", ex2_memory);
Which is strange to me because a lot of guides suggest it should be slightly different. For example this was in one of my guides
Sometimes it can be useful to have structures with more than one dimension – for example, we might want to hold 16 8-bit values. Verilog allows you to define multiple sets of indexes for a variable:
reg [7:0] string [15:0];
Notice how there it is [n:0] instead of [0:n] in the readmemb example. So what is the difference between these two ways of defining this multidimensional bus?
For Verilog, the unpacked dimension order does not matter. $readmemh/b always maps the starting address to the lower index, and you can only access one memory element at a time. There is a rare exception for C code when using the Verilog Programming Interface (VPI), but did I say that was rare?
In SystemVerilog it matters more because you can access unpacked arrays as a whole or use part selects similar to the way Verilog allows part selects of packed vector dimensions. It makes a difference between reg [7:0] mr; or reg [0:7] mr; when you select bit mr[0].

What is "net" in HDL synthesis

I am a beginner in circuit synthesis, and I came across the word net a lot, but I am never able to find its standard definition. It seems to me that it refers to any kind of "black box" where it receives inputs and produce outputs. So it can be a sub circuit inside a big circuit and it can be an array of gates. Is my understanding correct?
No, your understanding is not correct.
Verilog
In Verilog, net has a precise definition:
IEEE 1800-2012 states:
6.5 Nets and variables
There are two main groups of data objects: variables and nets. These two groups differ in the way in which they
are assigned and hold values.
A net can be written by one or more
continuous assignments, by primitive outputs, or through module ports.
The resultant value of multiple drivers is determined by the
resolution function of the net type. A net cannot be procedurally
assigned.
A net can be one of many types, for example: wire, supply0, wand, but by far the most common type is wire.
IEEE 1800-2012 goes on to say:
Variables can be written by one or more procedural statements,
including procedural continuous assignments. The last write determines
the value. Alternatively, variables can be written by one continuous
assignment or one port.
The main difference between the behaviour of a variable and a net is their behaviour when assigned to from more than one place, as highlighted by the bold text in the two quotes:
For a net, if you assign to it from more than one place, its resulting value is determined by a resolution function, which for the built-in net types (wire etc). The behaviour of the resolution function depends on the net type and that is the difference between the net types. So, for example, with a wire, if both 1'b0 and 1'b1 are assigned to it, the resulting value will be 1'bx (unknown) if both assignments assign values with the same strength. The resolution function is intended to model real electronics. (There is also the added complication of user-defined net types and drive strengths, but let's leave those out for this discussion.)
For a variable, if you assign to it from more than one place, its resulting value is determined by whatever value is written last (just like a normal software variable). So, for example, if a 1'b0 is assigned and then a 1'b1 is assigned, the resulting value will be 1'b1 because that value was assigned last. There is no resolution function involved nor any concept of drive strength.
Both nets and variables are used to model combinational logic and sequential logic. There are rules for when you can use a net and when you can use a variable and the choice of which to use is governed by those rules (given in the quotes above). These were strict in verilog, but have been relaxed in System-Verilog to such an extent that, if you are not designing using tri-state logic, you don't need nets in System-Verilog.
VHDL has exactly the same distinction. The VHDL equivalent of a Verilog net is a signal; the VHDL equivalent of a Verilog variable is a variable. The rules about which to use where in VHDL are different, however, and more strict (no surprise there).
Electronics
In electronics a net means a piece of metal through which current flows. In other words, a net is the connection between one place and another. Physically, it could be a PCB track, a cable, a bond wire or a metal connection on an IC. Generally, in digital electronics, it is most like to be a metal connection on an IC.
Synthesis
So, to answer your question, if someone uses the term "net" when talking about the output of a logic synthesiser (the gate-level netlist), they almost certainly mean the second idea: the construct in whatever format that gate-level netlist uses that models the connection between one gate and another. As it is common for synthesisers to output their gate-level netlist as Verilog, those connections between gates are probably modeled using Verilog nets anyway (probably wires).

How to treat useless outputs in Verilog?

Apology the title does not explain the question very well, I'll explain it in detail down below.
I'm new to verilog and got painfully stuck with my first lab assignment. One task is to make a 4*4 carry save multiplier, which is made of two types of multipliers, which are in turn made of full adders and AND gates, full adders are made of half adders. I built from the simplest half adders all the way up to the carry save multiplier.
two types of multipliers: http://i129.photobucket.com/albums/p205/Jack_Tianyu_Yang/Capture1_zpsf34b724c.png
hand-drawing of the carry save multiplier
http://i129.photobucket.com/albums/p205/Jack_Tianyu_Yang/photo_zps905f2c13.jpg
The code for the carry save multiplier is here. I instantiated the two types of multipliers and use a lot of internal wires for connections. (I admit it's pretty naive but this is the best i can do for the time being, I'll keep practicing and get better at it.) My QUESTION is this: refer to the "hand-drawing" ,the most left module on the top row, you can see there are two ports---q0_out and q1_out, that are outputs of this multiplier module BUT not part of the outputs in the main output list. Actually, q0_out,q1_out,q2_out,q3_out and m0_out,m1_out,m2_out,m3_out are all not in the output list. They are actually the same value of q0 to q3 and m0 to m3,respectively. (This can be verified by the first image)
When I synthesized the code I pasted below, Xilinx ISE gave me a bunch of same warnings saying for example :"Assignment to q3_out ignored, since the identifier is never used".
When I ask the TA, he said I should "treat the 4*4 carry save multiplier as a black box and the only inputs are m3m2m1m0, q3q2q1q0 and the only output is p7p6p5p4p3p2p1. Outputs like q3_out are 'internal' and should not be presented in the final output list". I don't how to deal with this situation. As you can see, I simply assign q3 to q3_out because q3_out is the same value propagated all the way from q3.
Please feel free to comment on my codes (what to improve, what's a bad coding style) and ask me for more elaboration of the question, also, if possible, please please share some ideas of how to solve this problem. Thank you all in advance.
`timescale 1ns / 1ps
module multiplier44_OMG(
input m0,m1,m2,m3,q0,q1,q2,q3,
output p0,p1,p2,p3,p4,p5,p6,p7
);
wire w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20;
wire w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31,w32,w33,w34,w35,w36,w37; //Internal wires
wire cin0,cin1,cin2,mk1_mul2_3; //These inputs are feeding into the carry save multiplier and are all zeroes.
wire q0_out,q1_out,q2_out,q3_out,m0_out,m1_out,m2_out,m3_out;
assign cin0=1'b0;
assign cin1=1'b0;
assign cin2=1'b0;
assign mk1_mul2_3=1'b0;// Inputs are assigned to zero.
assign q0_out=q0;
assign q1_out=q1;
assign q2_out=q2;
assign q3_out=q3;
assign m0_out=m0;
assign m1_out=m1;
assign m2_out=m2;
assign m3_out=m3;//THIS IS THE PART I DON'T KNOW HOW TO DEAL WITH
and (p0,m0,q0);
multiplier2 mul2_0(m1,m0,q0,q1,cin0,w1,w2,w3,w4,p1);
multiplier2 mul2_1(m2,m1,w1,w2,w3,w5,w6,w7,w8,w9);
multiplier2 mul2_2(m3,m2,w5,w6,w7,w10,w11,w12,w13,w14);
multiplier2 mul2_3(mk1_mul2_3,m3,w10,w11,w12,q0_out,q1_out,w15,w16,w17);
multiplier mul_0(w9,w4,q2,cin1,w18,w19,w20,p2);
multiplier mul_1(w14,w8,w18,w19,w21,w22,w23,w24);
multiplier mul_2(w17,w13,w21,w22,w25,w26,w27,w28);
multiplier mul_3(w15,w16,w25,w26,q2_out,w29,w30,w31);
multiplier mul_4(w24,w20,q3,cin2,w32,w33,m0_out,p3);
multiplier mul_5(w28,w23,w32,w33,w34,w35,m1_out,p4);
multiplier mul_6(w31,w27,w34,w35,w36,w37,m2_out,p5);
multiplier mul_7(w29,w30,w36,w37,q3_out,p7,m3_out,p6);
endmodule
It's does not feel any good staring at the code alone in the lab on a friday night.(Plus it's Spring festival.) I know my question is quite elementary, but even though I need help, GREAT help from the GREAT netizens.
A warning is just a warning, it's not an error. If you have a signal that is generated that has no load, then the synthesizer warns you, but there's nothing really there to 'fix'.
Also, since q3_out is output from mul_7, you shouldn't be driving it with a separate assign statement. Each wire should only have one driver.

Using blocking assignments to infer flip-flops in Verilog

I have read "Nonblocking Assignments in Verilog Synthesis, Coding Styles that Kill!" by Clifford Cummings. He says that the following code (page 12, simplified) is a correct implementation of a flip-flop often used in textbooks, even if not exactly the kind that anyone should use. The document won a best paper award, so I assume the claim is true.
module ff (q, d, clk)
output q;
input d, clk;
reg q;
always #(posedge clk)
q = d;
endmodule
I would like to know why this would continue to work correctly if two or more of these flip-flops were connected in series. Say
module two_ffs (q, d, clk)
input d, clk;
output q;
wire tmp;
ff firstff (tmp, d, clk);
ff secondff (q, tmp, clk);
endmodule
The way I see it, it's possible that the value of tmp is updated before it is used by secondff, thus resulting in one flip-flop rather than two. Can someone please tell me what part of the standard says that cannot happen? Many thanks.
[not that I would ever contemplate writing code like that, I just want to understand the blocking/nonblocking behavior even in cases when poor coding style makes the meaning non-obvious]
Added later:
I now think the paper is unlikely to be correct. Section 5 "Scheduling Semantics" of the 1364-2201 Verilog standard explains what happens. In particular, section 5.6.6 "Port connections" on page 68 says that unidirectional ports are just like continuous assignments. In turn, a continuous assignment is just an always block sensitive to everything. So the bottom line is that that the two instantiations of an ff in my example below are equivalent to a module with multiple always clauses, which everyone would agree is broken.
Added after Clive Cummings answered the question:
I am grateful to CC for pointing out that that the statements above taken out of section 5 of the standard only refer to the timing of update events, and do not imply literal equivalence between e.g. some continuous assignments and always blocks. Nevertheless, I think they explain why some simulators (e.g. Icarus Verilog) will produce different simulation results with a blocking and a non-blocking assignment in the "flip-flop". [On a larger example, I got 2 apparent ffs with a blocking assignment, and the correct five with a non-blocking one.] Other simulators (e.g. Modelsim with default options or Cver) seem to produce the same result no matter which form of assignment is used.
All -
A few corrections and updates. Section 5.6.6 of the 2001 Verilog Standard does not say that "unidirectional ports are just like continuous assignments," it says "Ports connect processes through implicit continuous assignment statements." There is a difference that I will note below.
Second, "a continuous assignment is just an always block sensitive to everything," is not true. Continuous assignments Drive values onto nets that can be driven by other sources with pre-defined resolution functions as described in the Verilog Standard. Always blocks Change values of variables and last procedural change wins (no resolution).
Regarding my description of the 1-always block flip-flop, my description in the paper is not 100% accurate (but is usually accurate). The 2-instantiated flip-flop model in theory does have a race condition, though it is rarely seen. The race is rarely seen because when you make an always block assignment to a variable that is declared as an output, Verilog compilers automatically throw in an "implicit continuous assignment statement" (IEEE-1364-2001, Section 5.6.6, 1st paragraph) to convert the procedural variable into a net-Driving assignment (you never see this happen!) This conversion is typically sufficient to introduce the equivalent of a nonblocking assignment delay on the port, so the simulation works. I have experimented in the past with compiler optimization switches that effectively remove the module ports between the flip-flops and have observed the unwanted race conditions, so technically, my description of an okay 1-always, blocking-assignment flip-flop is not 100% correct; hence, you should still use the nonblocking assignments described in the paper.
The 2-always blocking-assignment example in the same module has a definite race condition. As written, it will probably work because most compilers execute the code top-down, but if you reverse the order of the always blocks, you will probably see a race.
Regards - Cliff Cummings -
Verilog & SystemVerilog Guru
Reading Version 1.3 of the paper, Section 9 Example 13. The text under it explains that it is OK if the module only contains a single always block. My current understanding is that it is not an issue between separate modules. Allowing your example to work. However if a module contained multiple always blocks then the order of execution is undefined and will lead to the race conditions talked about in section 2 of the paper.
The example below is almost the same as the 2 flop example in the question, except it is in 1 module and so has an undefined order of execution, this will likely not work.
module ff (q, d, clk)
output reg q;
input d, clk;
reg d_delay ;
always #(posedge clk)
d_delay = d;
always #(posedge clk)
q = d_delay;
endmodule

Verilog array syntax

I'm new to Verilog, and am having a lot of trouble with it. For example, I want to have an array with eight cells, each of which is 8 bits wide. The following doesn't work:
reg [7:0] transitionTable [0:7];
assign transitionTable[0] = 10;
neither does just doing transitionTable[0] = 10; or transitionTable[0] = 8'h10; Any ideas?
(In case it is not obvious and relevant: I want to make a finite state machine, and specify the state transitions in an array, since that seems easier than a massive case switch.)
When using assign you should declare the array as a wire instead of areg.
Since your goal is to design an FSM, there is no need to store the state values in an array. This is typically done using Verilog parameter's, a state register and a next_state with a case/endcase statement.
The following paper shows a complete example: FSM Fundamentals
If this is targeted towards synthesis:
A little beyond what was answered above, there are standard FSM coding styles that you should adhere to so the tools can perform better optimization. As described in the Cummings paper, one-hot is usually best for FPGA devices and in fact ISE(with default settings) will ignore your encoding and implement whatever it thinks will best utilize the resources on the device. This almost invariably results in a one-hot encoded FSM regardless of the state encoding you chose, provided it recognizes your FSM.
OK, so to answer your question, let's dig a little deeper into Verilog syntax.
First of all, to specify a range of bits, either do [MSB:LSB] or [LSB:MSB]. The standard is MSB:LSB but it is really up to you here, but try to be consistent.
Next, in array instantiation we have:
reg WIDTH reg_name NUMBER;
where WIDTH is the "size" of each element and NUMBER is the number of elements in the array.
So, you first want to do:
reg [7:0] transitionTable [7:0];
Then, to assign particular bytes (8 bits = 1 byte), do:
initial begin
transitionTable[0] = 8'h10;
end
A good book to learn Verilog from is FPGA Prototyping By Verilog Examples by Pong P. Chu.

Resources