Design With Verilog: Dr. Paul D. Franzon
Design With Verilog: Dr. Paul D. Franzon
Motivation:
Enrichen your knowledge of synthesizable Verilog that can be described
using continuous assignment and structure
Understand the operators that can be used in procedural code as well
References
Ciletti:
Inside front cover : Summary
Sections 6.4: Synthesis of tri-states
Appendix C : Verilog Data Types
Appendix D: Operators
Smith and Franzon
Sections 2.1, 2.2 : Datatypes
Chapter 3: Structural code and continuous assignment
Sutherland Reference Guide
Arithmetic Operators
Bitwise operators
Operate vectors bit-by-bit
Usage Description
~ ~A Invert each bit of A
& A&B AND each bit of A with B
| A|B OR each bit of A with B
^ A^B XOR each bit of A with B
~^ A ~^ B XNOR each but of A with B
reg [1:0] A, B, C, D;
assign C = A & B;
A[0] C[0]
B[0] A
C
A[1] B
C[1]
B[1]
Usage Description
& &A AND all bits of A together
~& ~&A NAND all bits of A together
| |A OR all bits of A together
~| ~| NOR all bits of A together
^ ^A XOR all bits of A together
~^ or ^~ ~^A or ^~A XNOR all bits of A together
reg [1:0] B;
B[0]
wire C; C
B[1]
assign C = & B;
Logical Operators
Take one-bit inputs and produce a 1-bit result
Generally used in if-else and case statements but can be used for single
bit logic
Conventional operators can also be used in if-else and case statements IF
they produce a 1-bit result
Usage Description
! !A A is not true
&& A&&B A and B are both true
|| A||B A or B are true
Examples:
reg A, B;
reg [1:0] A, B;
if (A&&B)
if (A&&B) // NOT OK
if (A&B) // also OK
Relational Operators
Also produce a 1-bit result:
Usage Description
< A<B True if A<B
> A>B True if A>B
<= A<=B True if A<=B
>= A>=B True if A>=B
Shift
Logical Shift
Usage Description
<< A << B Shift A left by B bits, zero fill on right
>> A >> B Shift A right by B bits, zero fill on left
Usage Description
<<< A <<< B Shift A left by B bits, zero fill on right
>>> A >>> B Shift A right by B bits, sign fill on left if A is
signed, zero filled if not
Miscellaneous Operators
Usage Description
?: sel ? A : B If sel, choose A else choose B
(similar to if else)
{} {A,B} Concatenate A and B, creating a longer
vector
{{}} {A{B}} Replicate B A times, creating a longer
vector
-> ->A Trigger
Not synthesizable
Comments on Operations
Operator Expansion
Operators expanded to the largest element in the expression, before
evaluation
Unsigned vectors are zero filled
{} and {{{} are done BEFORE expansion, and then treated as an operator at the
new width
If assigned to a shorter variable, high order bits are lost
Ex: wire [3:0] A, B, C;
assign C = ({A,A} >> 2) | B[1:0]
//C = lower 4 bits of (8 bits | 0000 00B[1]B[0])
Signed Arithmetic (Verilog 2001)
If any operand is unsigned, arithmetic is unsigned
If ALL operators are signed, signed arithmetic is conducted
Operator can be cast as $signed or $unsigned
Operator Precedence ()
~ ! – (unary)
Order in which operators are evaluated
{} {{}}
**
For example, in
* / %
+-
A = A==B ? {C,D} : {2{E}} | F^G;
>> << >>> <<<
< <= > >=
Order evaluation:
== !== === !===
1. {2{E}} {C,D}
2. F^G & ~&
3. A==B ^ ~^
4. | | ~|
5. ?: &&
Examples
reg [1:0] A,B,C; // Q1: If A = 2’b10;B=2’b01; E = 3’b101;
reg [2:0] D,E,F; what is C, D, G, F, H after execution?
reg [3:0] H;
reg G;
always@(*) begin
C = A | E; // C=11
D = E << 2; // D=100
G = |A; // G=1
F = {A,B[0]}|E; // F=101
H = {2{B}}; // H=0101
end
Examples
What is the logic being described (in detail)?
reg [1:0] A,B,C,D; A[1][0] B[1][0] E[2][1][0]
reg [2:0] E,F;
reg [3:0] H;
C[1]
reg G;
C[0]
D[2]
0 D[1]
0 D[0]
always@(*) begin
G
C = A | E;
D = E << 2; F[2]
G = |A;
F[1]
F = {A,B[0]}|E;
F[0]
H = {2{B}};
H[3]
end H[2]
H[1]
H[0]
Examples
wire [2:0] E
wire [2:0] signed F; G[1] G[0]
wire [1:0] G, H;
A[0] 0 E[0]
// A, B 3-bits wide 0
A[1] E[1]
A[2] E[2]
assign E = A << 2;
assign F = B >>> 1;
B[0] F[0]
assign G = {2{A[0]}}; B[1] F[1]
assign H = {A[1],B[1]}; B[2] F[2]
H[1] H[0]
Continuous Assignment
A[0]
C[0]
Sketch the logic being specified … B[0]
A[1]
input [3:0] A, B; C[1]
B[1]
wire [3:0] C, E;
wire D, F, G; A[2]
C[2]
assign C = A ^ B; B[2]
assign D = |A;
assign E = {{2{A[3]}}, A[2:1]}; A[3] C[3]
assign F = A[0] ? B[0] : B[1]; B[3]
assign G = (A == B);
A[0]
A[1] D
A[2]
A[3] B[0] A
F = G
B
B[1]
A[3] E[3]
A[3] E[2] A[0]
A[2] E[1]
A[1] E[0]
Summary
Verilog contains many useful operators
Arithmetic +-*
Logic &A ^A |A A&B A^B A|C etc.
Relational === == > etc.
Shift – logical and arithmetic
Concatanation and replication – extending vectors
?: = if else
Go to sub-module quiz and then to next sub-module
Continuous Assignemt
Directly specifies logical structure in one line of code
Procedural code often specifies behavior of logic
wire [1:0] B, C, D;
tri [1:0] E;
Examples
wire [3:0] sum;
wire carry;
// A, B, C 4 bits wide
// D 1 bit wide
A + sum
B
C
carry
D
Continuous Assignment
Sketch the logic being specified …
input A, B, C;
tri F;
assign F = A ? B : 1’bz;
assign F = ~A ? C : 1’bz;
A
Tri-State Buffer
•Connect to shared bus B
Further Examples
wire [3:0] A, B, D; B: Rotator
C-bits
wire [1:0] C, E;
A[3]A[2]A[1]A[0]
assign B = {A,A} >> C;
A[3]A[2]A[1]A[0] A[3]A[2]A[1]A[0]
C bits
assign D = {4{A[3]},A} >> E; B is 4-bits
A[3]A[2]A[1]A[0] A[3]A[2]A[1]A[0]
D: Signed Right Shift
Structural Verilog
Complex modules can be put together by ‘building’ (instancing) a number of smaller
modules.
e.g. Given the 1-bit adder module with module definition as follows, build a 4-bit adder with
carry_in and carry_out
module OneBitAdder (CarryIn, In1, In2, Sum, CarryOut);
4-bit adder:
module FourBitAdder (Cin, A, B, Result, Cout);
input Cin;
input [3:0] A, B;
output [3:0] Result;
output Cout;
wire Cout;
wire [3:1] chain;
OneBitAdder u1 (.CarryIn(Cin), .In1(A[0]), .In2(B[0]),
.Sum(Result[0]), .CarryOut(chain[1]));
OneBitAdder u2 (.CarryIn(chain[1]), .In1(A[1]), .In2(B[1]),
.Sum(Result[1]), .CarryOut(chain[2]));
OneBitAdder u3 (.CarryIn(chain[2]), .In1(A[2]), .In2(B[2]),
.Sum(Result[2]), .CarryOut(chain[3]));
OneBitAdder u4 (Chain[3], A[3], B[3], Result[3], Cout); // in correct
order
endmodule
Structural Example
Sketch:
FourBitAdder
u1 u2
OneBitAdder OneBitAdder
chain[1]
Cin CarryIn Sum CarryIn Sum
A[0] In1 CarryOut In1 CarryOut
B[0] In2 In2
A[1]
B[1]
Result[0]
Result[1]
Etc.
©2013, Dr. Paul D. Franzon, www.ece.ncsu.edu/erl/faculty/paulf.html 27
Digital ASIC Design
Instance Formats
Module instance formats
Structural Verilog
Features:
Four copies of the same module (OneBitAdder) are built (‘instanced’) each
with a unique name (u1, u2, u3, u4).
Module instance syntax:
OneBitAdder u1 (.CarryIn(Cin),
All nets connecting to outputs of modules must be of wire type (wire or tri):
wire [3:1] chain;
No glue logic!
Generally it is a good idea to only implement logic in the leaf cells of a
hierarchical design, and not at a higher level
i.e.
module good(A,B,C); module bad(A,B,C);
good_leaf u1(A,B); assign D=C&D;
not
good_leaf u2(A,C); good_leaf u1(A,B);
endmodule good_leaf u2(A,C);
endmodule
Why?
Hint: Consider what module must be synthesized in a single run
Sample Netlist
module counter ( clock, in, latch, dec, zero );
input [3:0] in;
input clock, latch, dec;
output zero;
wire \value[3] , \value[1] , \value53[2] , \value53[0] , \n54[0] ,
\value[2] , \value[0] , \value53[1] , \value53[3] , n103, n104, n105,
n106, n107, n108, n109, n110, n111, n112, n113, n114, n115;
NOR2 U36 ( .Y(n107), .A0(n109), .A1(\value[2] ) );
NAND2 U37 ( .Y(n109), .A0(n105), .A1(n103) );
NAND2 U38 ( .Y(n114), .A0(\value[1] ), .A1(\value[0] ) );
NOR2 U39 ( .Y(n115), .A0(\value[3] ), .A1(\value[2] ) );
XOR2 U40 ( .Y(n110), .A0(\value[2] ), .A1(n108) );
NAND2 U41 ( .Y(n113), .A0(n109), .A1(n114) );
INV U42 ( .Y(\n54[0] ), .A(n106) );
INV U43 ( .Y(n108), .A(n109) );
AOI21 U44 ( .Y(n106), .A0(n112), .A1(dec), .B0(latch) );
INV U45 ( .Y(zero), .A(n112) );
NAND2 U46 ( .Y(n112), .A0(n115), .A1(n108) );
OAI21 U47 ( .Y(n111), .A0(n107), .A1(n104), .B0(n112) );
DSEL2 U48 ( .Y(\value53[3] ), .D0(n111), .D1(in[3]), .S0(latch) );
DSEL2 U49 ( .Y(\value53[2] ), .D0(n110), .D1(in[2]), .S0(latch) );
DSEL2 U50 ( .Y(\value53[1] ), .D0(n113), .D1(in[1]), .S0(latch) );
DSEL2 U51 ( .Y(\value53[0] ), .D0(n105), .D1(in[0]), .S0(latch) );
EDFF \value_reg[3] ( .Q(\value[3] ), .QBAR(n104), .CP(clock), .D(
\value53[3] ), .E(\n54[0] ) );
EDFF \value_reg[2] ( .Q(\value[2] ), .CP(clock), .D(\value53[2] ), .E(
\n54[0] ) );
EDFF \value_reg[1] ( .Q(\value[1] ), .QBAR(n103), .CP(clock), .D(
\value53[1] ), .E(\n54[0] ) );
EDFF \value_reg[0] ( .Q(\value[0] ), .QBAR(n105), .CP(clock), .D(
\value53[0] ), .E(\n54[0] ) );
endmodule
Parameter
Parameter is like “constant” in C
parameter bit_width = 8;
In Verilog 2001…
Parameter Passing
Can pass parameters to modules, overwriting their local values
module top;
Parameter RFsize1 = 64;
Parameter AddressSize1 = 6;
module RegFile( …
input [Asize-1:0] WriteAddress, ReadAddress,
);
parameter Asize=5;
parameter size=32;
reg [15:0] Register [0:size-1];
Exercise
module mod2 (G,H,I)
Sketch Design, including hierarchy;
Declare needed variables and ports input [1:0] G;
input H; output [1:0] I;
module Ex1 (A, B, C); wire [1:0] I;
input [1:0] A; assign I = G & {2{H}};
output B; output [1:0] C; endmodule
wire B; wire [1:0] C; u1
mod1 u1 (A,B); A[0]
B
mod2 u2 (A,B,C);
endmodule A[1]
module mod1 (E,F)
input [1:0] E;
u2
output F; A[0] C[0]
wire F;
assign F = &E; A[1]
C[1]
endmodule