How to unpack LUTs into logic cells in verilog - verilog

I have a structural verilog containing LUTS all over him.
I want this verilog to be unpacked so that I'll have the same functional but instead LUTS - I'll have logic cell (Like Or/And/Xor etc...).
How can I do it ?
Does Yosys has something built in ?
Is there something else out there over the internet who already implement that kind of thing ?
Because I searched for this and I could not find.

You could do something like the following
read_verilog struct.v lut.v
hierarchy -top top
flatten
synth -noabc
in Yosys, where lut.v contains a Verilog model of the LUT primitive. This would convert LUTs to non-optimised logic. You could also use abc (remove -noabc, or add abc at the end of the script) to optimise the logic.

Related

Are there any performance penalties by using nested Conditional Operator?

Here is an example that use nested conditional operator to map register address to it's value.
reg [4:0] mux;
reg [1:0] addr;
mux = (addr == 2'b00) ? i0 :
((addr == 2'b01) ? i1 :
((addr == 2'b10) ? i2 :
((addr == 2'b11) ? i3 :
4'bz)));
In my application, there are about one hundred registers, so The nested level is very deep. If the expression is C language executed by CPU, it will be very slow.
How about FPGA?
From my experience, it depends on the synthesizer as well as the options used. It can use your code as a functional guideline to generate equivalent logic. Or it can use it as a structural guideline in which case each ?: conditional operator is mapped to a 2:1 mux. You can do experiments with your synthesizer to figure how how the generate the gate equivalent, and read the synthesis options in the manual.
Generally I use the ?: conditional operator when I intentionally want a 2:1 mux (or tri-state driver). For more complex conditional multiplexing, I prefer using case statements or if-else statements. This strategy usually fulfills timing and area requirements.
With large multiplexing (you mentioned "about one hundred registers"), meeting timing and area requirements can be difficult. Sometimes the synthesizer can handle this, other times it needs more guidance. Synthesizer directives (refer to manual) and splitting the multiplexer into chunks is one way to deal with it. Your FPGA may have a macro module of dedicated logic (RAMs, complex arithmetic logic, etc) you could instantiate to substitute for portions of your code.
In this specific case of your example most synthesizers will interpret this as a series of 2-to-1 multiplexers.
In a more general case such as
output = (one_condition)? a : (another_condition)? b : (other_condition)? c : ...
It will use a multiplexer for each condition extending the asynchronous path. A longer asynchronous path means a longer settling time and slower maximum clock frequency.

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).

Creating a 2-D net array in verilog

I was trying to write a program using 2-D net array. But when the code is checked it shows an error (expecting ';', found '['). How should I declare a 2d net array and how to use it ?
Below is the simple code for I written for verification (shows the above error).
module bin(a);
input [0:1] a[0:2];
endmodule
Multidimensional arrays and unpacked arrays as ports are not supported in Verilog. The only arrays Verilog supports in port lists are simple packed arrays (aka vectors).
SystemVerilog does support multidimensional arrays in all variations. All modern Verilog simulators are actually SystemVerilog simulators with backward comparability.
The preferred method to differentiate Verilog and SystemVerilog files is with the file extension. SystemVerilog files should use .sv while Verilog uses the the traditional .v.
Alternativly, simulators have an option to force .v files to be compiled as SystemVerilog. Several use -sv as the compiler option but some use a differnt identifier so you will need to refer to your manual or help-file. The disadvantage to this is approach happens when you are mixing legacy verilog files that happen to use variable/net names that became keep words in SystemVerlog. Using the proper file extension mitigates this risk by compiling each file based in the extension name.
You can't have an unpacked array in ports. Please note that Verilog is a Hardware Description Language, not a Software Language. Only those things will be supported in Verilog, which can be mapped into real hardware.
You can have a packed array in port, not an unpacked array.
Packed array, can be thought of as a bunch of wires in simplest terminology. However, unpacked arrays are not stored consecutively and hence they can't be treated as simple bunch of wires.
module bin(a);
input a[2:0][1:0];
endmodule
This should work, since it is a packed array dimension.Or else you can use a bus to represent your inputs and break it.
module bin(a);
input a[5:0];
wire [1:0] a1, a2, a3;
assign {a1,a2,a3} = a;
endmodule

What is the difference between structural Verilog and behavioural Verilog?

As in the title, what are the main differences between structural and behavioural Verilog?
There is no strict definition of these terms, according to the IEEE Std. However, customarily, structural refers to describing a design using module instances (especially for the lower-level building blocks such as AND gates and flip-flops), whereas behavioral refers to describing a design using always blocks.
Gate netlists are always structural, and RTL code is typically behavioral. It is common for RTL to have instances of clock gates and synchronizer cells.
Structural
Here functions are defined using basic components such as an invertor,
a MUX, a adder, a decoder, basic digital logic gates etc.. It is just
like connecting and arranging different parts of circuits available to
implement a function.
Behavorial
The Behavioral description in Verilog is used to describe the function
of a design in an algorithmic manner. Behavioral modeling in Verilog
uses constructs similar to C language constructs. Further , this is
divided into 2 sub categories .
(a) Continuous
assignment of data to outputs are continuous. This will be
implemented using explicit "assign" statements or by assigning a
value to a wire during its declaration .
In case of assign any change in input will
immediately effect the output . Hence output is to be declared as
wire
(b) Procedural
Here the data assignments are not carried out continuously instead it
happens on specific events specified in sensitivity list. This type of
modelling scheme is implemented using procedural blocks such as
"always"or "initial" .
Here, output variables must be defined as reg because they need to
keep hold of previous value until new assignment occurs after any change in specified sensitivity list.
Hope this helps :)
Structural Verilog is usually referred to a Verilog code which is synthesizable (has an accurate and meaningful hardware realization) and is usually written in Register Transfer Level (RTL).
On the other hand Behavioral Verilog is usually a behavioral description of a hardware or functionality on a higher level. behavioral code does not have to be synthesizable for example when you define a delay in your verilog code scaled by the timescale, the synthesizer does not consider it when it is translating your code into logic and hardware, but rather it has simulation purposes.
The same goes for structural and behavioral VHDL.
Behavioral doesn't use logic gates description you can use And,Or,Not gates that are already defined in verilog
while structural uses logic gates description where you describe that you want a module called (And/Or/Not) and describe what it does & / | / ~.
Structural verilog deals with the primitives in simple word like and, or, not etc..
The primitives are called/inferred from libraries and connected with input output ports.
Example
module structural(y,a,b);
input a,b;
output y;
and a1 (y,a,b); // and is the primitive inferred and a1 is the instance name.
endmodule
Behavioral verilog deals with the logic or behavior of a system. It handles complex logic implementation and which is why in industry all implement the behavioral models of the system called as RTL. Once the behavioral RTL is validated by front end engineers using SV/UVM then this RTL is converted into Gate Level i.e Structural which go for synthesis.
Please refer the book of verilog written by Samir Palnitkar for more details.
Verilog is both a behavioral and a structural language. Internals of each module can be defined at four levels of abstraction, depending on the needs of the design.
Structural Verilog describes how a module is composed of simpler modules or of basic primitives such as gates or transistors. Behavioral Verilog describes how the outputs are computed as functions of the inputs.
Behavioral level
->This is the highest level of abstraction provided by Verilog HDL. mainly construct using
"always" and "initial" block.
Dataflow level
-> At this level, the module is designed by specifying the data flow. condition describe using "assign" keyword.
Gate level
->The module is implemented in terms of logic gates and interconnections between
these gates.
Switch level
->This is the lowest level of abstraction provided by Verilog. A module can be
implemented in terms of switches, storage nodes, and the interconnections
between them.

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