Structural Modelling
Structural Modelling
Vasudeva Murthy T
1
Session Objectives
2
Session Topics
3
Cons of Dataflow Modeling
4
Necessity of structural modeling
5
Structural Modeling
• Structural modeling:
– Involves building of design using pre-defined gates
– Smaller sub-modules are instantiated
– Can be considered as schematic in text form
• Primitives
– Pre-defined gates already described in the Verilog language
– Can have only one output but any number of inputs
– Language has no restriction on inputs but depends on
technology being targeted to
– All basic combinational gates available as primitives
– Used directly in the code as smaller case key-words
– and, nand, or, nor, not, xor, xnor, buf, bufif1, bufif0
6
Using Primitives
module mux(
output z,
input I0, I1, sel);
nSel A0 a0
endmodule
7
Timescale directive
`timescale 1 ns/ 10ps
`timescale :
module adder(
•Defines the time units to be used
output sum, carry,
•Wherever the delay operator is
input a,b,cin); encountered the time units will be
considered as 1 ns
xor #(2.1, 2) XO (sum,a,b,cin); •The delay can be upto a precision of 10
and #1.8 A0(a0, a,b), ps
A1(a1,b,cin), •Here xor gate which has name ‘XO’
A2(a2,cin,a); has a rise time of 2.1 ns and a fall time
of 2 ns
or #(1.8, 1.605)
O(carry,a0,a1,a2); •or gate which has name ‘O’ has rise
time of 1.8 ns and fall time of 1.6 ns.
endmodule
•The 1.605 will be rounded of to 1.600
as 0.005 is lesser than precision 10 ps
specified
And gate has equal rise time and fall time
of 1.8 ns
8
Compiler directive
`timescale 1 ns/ 10ps `default_nettype :
`default_nettype none •Value none specifies that
module mux( undefined variables should not
output wire z, default to type wires
input wire I0, I1, sel);
•Simulator requires even port’s
data type to be declared , hence
wire nsel, a0, a1;
‘z,I0,I1,sel’ also declared as
wires
not #(1.1, 1) Inv (nsel, sel);
•Synthesis tool requires only
internal wires ‘nsel, a0, a1’ to be
and #(1.8,1.5) A0(a0,
nsel, I0),
explicitly declared
•Forces the designer to declare all
A1(a1,sel,I1);
internal wires
or #(1.8, 1.605)
O(z,a1,a2);
•Any variable starting with ` is a
compiler directive
endmodule
9
Primitives explained
module adder(
output sum, carry,
Primitives
input a,b,cin); •In-built gates which are
xor #(2.1, 2) XO (sum,a,b,cin);
instantiated
and #1.8 A0(a0, a,b), •They need not be declared, they
A1(a1,b,cin),
are only called
A2(a2,cin,a);
or #(1.8, 1.605) O(carry,a0,a1,a2); •First variable is understood to be
endmodule output
– Here sum, a0,a1,a2, carry are
outputs of ‘xor’, ‘and’ gate A0,
• Any number of gates of same ‘and’ gate A1, ‘and’ gate A2,
functionality can be called in and ‘or’ gate respectively
single line •They can be optionally named
– Here three and gates A0,A1 and •Delays can be specified - again
A2 are being called in same line optionally
10
Component Instantiation
• Instantiation
– Predefined modules can be called just like primitives
– An Instance is a unique copy of a pre-defined module
– Connected to one another by means of nets
Cin
Sum
B
A
Carry
11
Component Instantiation Example
`timescale 1ns/10ps
module adder(
output sum, carry,
input A, B, Cin);
12
Component instantiation rules
• Component instantiation can be done in two ways
– Named port connection / calling by reference
• Mostly preferred in the Industry
– Ordered port connection / calling by position
• An error prone way of instantiating
• Most simulators / synthesis tools require components to
be compulsorily named
• Component can be called more than once in a single line
• Component instantiations do not accommodate delays like
primitives
• While simulating component should have been compiled
before it can be called in a top module
13
Component Instantiation explained
14
Component Instantiation explained
• mux XOR (axorb, B, nB, A); // module mux(output z,input I0, I1, sel);
– In Multiplexer ‘XOR’ port axorb refers to port Z of original ‘mux’
– Similarly port B and port nB are connected to I0 and I1 of ‘mux’
– While port A is connected to port ‘sel’ of reference design ‘mux’
– These connections are order dependent
• Components are preferred to be connected by name
• The names of the reference design ports are associated with DOT
• The names of the connections in the module is written in brackets
mux SUM (.Z(sum), .I0(Cin), .I1(nCin), .sel(axorb)),
CARRY (.Z(carry), .I0(A), .I1(Cin), .sel(axorb));
• In the above example the original design ports are being referred by name
• The interconnects of the sub-modules are being passed through brackets
15
Hierarchal Design
first
sum
A A A
carry Su Su Su
_in Ci Ci Ci carry
B Co B Co B Co _out
second
16
A 4-bit ripple-carry adder
• Four full adders together make a 4-bit adder.
• There are nine total inputs:
– Two 4-bit numbers, A3 A2 A1 A0 and B3 B2 B1 B0
– An initial carry in, CI
• The five outputs are:
– A 4-bit sum, S3 S2 S1 S0
– A carry out, CO
• Imagine designing a nine-input adder without this hierarchical
structure—you’d have a 512-row truth table with five outputs!
17
Hierarchical adder design
• When you add two 4-bit numbers the carry in is always 0, so why does the
4-bit adder have a CI input?
• One reason is so we can put 4-bit adders together to make even larger
adders! This is just like how we put four full adders together to make the 4-
bit adder in the first place.
• Here is an 8-bit adder, for example.
18
A two’s complement subtraction circuit
• To find A - B with an adder, we’ll need to:
– Complement each bit of B.
– Set the adder’s carry in to 1.
• The net result is A + B’ + 1, where B’ + 1 is the two’s complement
negation of B.
19
Small differences
The only differences between the adder and subtractor circuits are:
– The subtractor has to negate B3 B2 B1 B0.
– The subtractor sets the initial carry in to 1, instead of 0.
It’s not too hard to make one circuit that does both addition and
subtraction.
20
Adders/Subractors
• XOR gates let us selectively complement the B input.
• X0=X X 1 = X’
• When Sub = 0, the XOR gates output B3 B2 B1 B0 and the carry in is 0. The adder
output will be A + B + 0, or just A + B.
• When Sub = 1, the XOR gates output B3’ B2’ B1’ B0’ and the carry in is 1. Thus,
the adder output will be a two’s complement subtraction, A - B.
21
N Bit adder
22
Code for hierarchal design
1. module adder_bit_n #(parameter n = 8)
2. (output [n-1:0] sum,
3. output carry_out,
4. input [n-1:0] first, second,
5. input carry_in);
6. genvar j;
7. wire [n:0] carry_wires;
8. assign carry_wires[0] = carry_in;
9. generate
10. for(j=0; j <n; j = j+1)
11. begin :series
12. adder
A(.A(first[j]), .Ci(carry_wires[j]), .B(second[j]), .Su(sum[j]), .Co(carry_wires[j+1]));
13. end
14. endgenerate
16. endmodule
23
Vectors
• Signals which are multi-bits are declared as vectors
• Can be declared as [high:low] or [low:high]
• The left hand value always specifies the index of the MSB
• A bit of the vector is accessible
• Example
– see previous example
• wire [n:0] carry_wires // line 7 – vector being declared
• carry_wires[0] =carry_in // line 8 – Bit of vector is assigned
• carry_out = carry_wires[n] // line 15 – Bit of vector is accessed
• carry_wires[5:2] = 4’d1010 // part of vector being assigned value
• outp = carry_wires[n-1:n-5] // part of vector being accessed
24
Parameters
25
Generate Statement
Generate:
• As the name specifies used to generate a set of hardware
• Simply replicates a given set of function for a specified number of
times
• Two generate statements available
– for generate
• Variables used inside for generate loop known as ‘genvar’
– genvar j // line 6 – j is a variable used in for loop in previous
example
• Loop inside for generate should be labeled
– begin : series // line 11 – for loop labeled with name ‘series’
– if generate
• Used for conditional use of hardware / logic
• Statement is concurrent in nature
26
Summary
27