Verilog HDL: A Guide to Digital Design and Synthesis d S th i
Design Abstraction Levels g
SYSTEM
MODULE + GATE
CIRCUIT
DEVICE G S n+ D n+
What is HDL?
A Hardware Description Language (HDL) is a highhigh level programming language with special language constructs used to model the function of hardware logic circuits. Y can D i and Si l t circuits with a C i it You Design d Simulate i it ith Clike syntax The special language constructs p p g g provide y the ability you y to:
Describe the connectivity (structure) of a circuit Describe the functionality (behavior) of a circuit Describe the timing information and timing constraints of a circuit D Describe a circuit at various l ib i i i levels of abstraction l f b i Express concurrency
Why Use an HDL
Model the design in higher level of abstraction
Reduce the design capturing efforts Easy for handling complex design y g p g Separate from implementation, increase the portability Potential for design re-use
Mix behavior/structural descriptions i a d i Mi b h i / t t l d i ti in design
Model datapath and regular portion of circuit structurally Model control and irregular portion of circuit behaviorally
Model the design and testbench with the same language
Outline
Design Style HDL Modeling Behavioral Modeling Structural Modeling Description Styles Structural styles
Gate level Structural Hierarchy
Data Flow Behavioral styles
Register Transfer Level
Mixed Simulation: Test bench
Design Style: Schematics, Netlist, and HDLs
Schematic Gate-Level Sw witch-Le evel Language
module adder(a, b, c, s) input [31:0] a, b; output [31:0] s; output c; HDL endmodule.
Sch hematic c
VDD V 0 3V M1 Z IN 0 0 NCH M2 Z IN V V PCH R1 A IN 15 Netlist C1 Z 0 1P VIN A 0 PWL (0 0 1N 3V)
What is Verilog HDL?
The Verilog Hardware Description Language is designed for describing a hardware design or part of a design. The Verilog is both a behavioral and a structure language Verilog V il models can b d d l be developed f diff l d for different l t levels of l f abstractions: Algorithmic : a model that implements a design algorithm in high-level l hi h l l language constructs t t RTL (Register Transfer Level): a model that describes the flow of data between registers and how a design processes that d t th t data Gate level: a model that describes the logic gates and the connections between logic gates in a design. Transistor level
Verilog History
Verilog was created by Phil Moore in 1983 4 at Gateway Design 1983-4 Automation and the first simulator was written a year later. In 1989, Gateway Design Automation was acquired by Cadence Design System. System In 1990, Cadence decided to open the language to the public, and thus OVI (Open Verilog International) was formed. In 1993, I 1993 an IEEE working group was established under th ki t bli h d d the Design Automation Sub-Committee to produce the IEEE Verilog 1364. In D I December 1995 th fi l d ft of V il was approved and b 1995, the final draft f Verilog d d the result is known as IEEE Std. 1364-1995. IEEE 1364-2001 is the latest Verilog HDL standard.
Importance of HDLs
Designs can be described at a very abstract level by use of HDLs. Designers can write their RTL description without choosing a specific fabrication technology. y g g By describing designs in HDLs, functional verification of the design can be done early in the design cycle. Designing with HDL is analogous to the computer programming. programming
Verilog Applications
For system architects Verilog HDL support high level language architects, constructs which can be used to describe and verify the architecture and performance of the system. For ASIC and FPGA designers, Verilog HDL supports RTL designers language constructs which can be used to describe, verify, and synthesize to more detailed level of design abstraction (most often gate-level netlist) gate level For model developers, Verilog supports describing and packaging mechanisms (e.g., module path delay description, code e c ypt o ) for modeling ASIC o FPGA ce s, o higher encryption) o ode g S C or G cells, or g e level components (IPs). For verification engineers, Verilog supports system tasks which can be used to create testbenches for all level of simulation.
Methodology gy
Top-Down Bottom-up
Target
Module 1
Module 2
Module 3
Basic Comp.
Basic Comp.
Basic Comp.
Basic Comp.
Basic Comp.
Basic Comp.
Example
Behavior Level Model
The highest level of description Only model circuits functionality or algorithm without concern for the real hardware implementation details
statement1
expression True
False F l
statement3
statement2
RTL Model
Identify the combinational portion and registers of the circuit under design Describe the data flow between the registers Timing (clock) is an important issue
combinational
registers
clock
Gate-Level Model
Express the circuit under design as a collection of p g Boolean expressions Logic optimization is performed at this level of description d i ti
FFs
clock
Transistor Level Model
Ready to be implemented as a chip
Vdd
In
Out In
Out O t
Gnd
(a) Schematic
(b) Mask
Verilog Spans a Wide Range of Modeling Levels
always #($dis_poisson(seed,32)) begin if $q_full(qid) $q_remove (qid, job, job_id, status); else fill_queue; end
always @(fetch_done) begin casez (IR[7:6]) 2b00 : LDA (acc, IR[5:0]); ( IR[5 0]) 2b01 : STR (acc,IR[5:0]); 2b10 : JMP (IR[5:0]); 2b11 : ; // NOP endcase end
Architectural
Algorithmic
Increasing level of abstraction
RTL Gate Switch
assign rt1 = (11&buserr) | zero; assign sub = rt1 ^| op; assign out1 = i1 & i2 | op;
behavioral b h l (non-structural) gate/switch / h (structural)
Basic Limitation of Verilog g
Description of digital systems only p g y y
Abstraction Levels in Verilog g
Behavioral Beha ioral RTL Gate Layout (VLSI) y ( ) Our focus
Overview of Verilog Module
A Verilog module includes the following p g g parts:
module module_name(port_name)
Port d l ti P t declaration Data type declaration Task and function declaration Module functionality and structure Timing specification
endmodule
Ports Connection Rules
external environment wire inout wire input wire or reg wire output module (internal) wire or reg wire
Verilog Module
module module-name (list-of-port);
input/output declarations local net declarations parallel statements
endmodule d d l
2-input AND gate
module AND2gate(A, B, F); endmodule
We first start by creating a module by name of AND2gate. This module consists of an interface of 3 ports, A, B, and F.
module AND2gate(A, B, F); input A; input B i t B; output F;
endmodule
We next specify what type the ports are. In this example, port A and port B are inputs, while port F is an output
module AND2gate(A, B, F); input A; input B; output F; p and (F,A,B) ; endmodule
Lastly we specify the internal functionality of the AND2 module.
module AND2gate(A, B, F); input A; input B; output F; reg F; always @ (A or B) begin F <= A & B; end endmodule
Lastly we specify the internal functionality of the AND2 module. d l
We declare a sensitivity list with the "always @ (A or B)" line indicating that upon change of input A or input B, we execute the code segment between the begin and end statements. When input A or B changes, we evaluate the inputs and assign the value to F.
NAND gate out of an AND and an Invertor
//create a NAND gate out of an AND and an Invertor module some_logic_component(c, a, b); // declare port signals output c; input a, b; // declare i t d l internal wire l i wire d; //instantiate structural logic g g gates and a1(d, a, b); //d is output, a and b are inputs not n1(c, d); //c is output, d is input endmodule
Half ADDER
a b c_out_bar
sum
c_out _
Examples (cont.)
Module name Module ports
module Add_half ( sum, c_out, a, b ) _ _ ); input a, b; Declaration of port output sum, c_out; modes wire i c_out_bar; t b Declaration of internal
signal
xor (sum, a, b); nand (c_out_bar, a, b); not (c_out, c_out_bar); endmodule
Verilog keywords
Instantiation of primitive gates
a b c_out_bar c_out
sum
Example: Structural XOR (xor built-in, but..)
Says which ports input, output
module xor(Z X Y); xor(Z, X, input X, Y; output Z; wire notX, notY, XnotY, YnotX; X tY Y tX not (notX, X), (notY, Y); or (Z, YnotX, XnotY); and (YnotX, notX, Y), (YnotX notX Y) (XnotY, X, notY); endmodule
Default is 1 bit wide data nets to connect components
notXYnotX
X Y X Y Z
XnotY notY
Note: d N t order of gates d f t doesnt matter, t tt since structure determines relationship
Example: Behavioral XOR in Verilog
module xorB(Z, X, Y); input X, Y; output Z; reg Z; always @ (X or Y) Z = X ^ Y; // ^ is C operator for xor endmodule;
Unusual parts of above Verilog
always @ (X or Y) => whenever X or Y changes, do the following statement reg is only type of behavioral data that can be changed in assignment, so must redeclare Z as reg Default is single bit data types: X, Y, Z
Examples 2 NAND
Structural model
//structural model of a Nand gate // program nand2.v module NAND(in1, i 2 out2); d l NAND(i 1 in2, t2) input in1,in2; output out2; nand nand2(out2,in1,in2);// first port must be output. endmodule
Example of gate NAND
Behavioral model of a Nand gate //Behavioral model of a Nand gate // program nand1.v p g module NAND(in1, in2, out); ( ) input in1,in2; output out; assign out=~(in1&in2); endmodule
Example : 1-bit half adder Verilog description of a half adder and schematic
module Add_Half(sum,c_out,a,b); input a,b; output c_out,sum; xor (sum,a,b); and (c_out,a,b); endmodule
*Tips: The output port of primitives must be first in the list of ports.
Verilog Example: Structural Models
Structural models Are built from gate primitives and/or other modules They describe the circuit using logic gates much as you would see in an implementation of a circuit. Identify Gate instances wire names delay from a or b to f instances, names, f.
a f b sel module mux (f, a, b, sel); output f; input a, b, a b sel; and or not endmodule g1 (f1, a, nsel), g2 (f2, b, sel); g3 (f f1 f2) 3 (f, f1, f2); g4 (nsel, sel);
Behavioral Description p
module Add_half ( sum, c_out, a, b ); input a, b; output sum, c_out; sum c out; a Add_half reg sum, c_out; b always @ ( a or b ) begin sum = a ^ b; // Exclusive or c_out c out = a & b; // And end endmodule
sum c_out
Structural Vs. Behavioral Models
Structural model
Just specifies primitive gates and wires i.e., the structure of a logical netlist You basically know how to do this now now.
Behavioral model
More like a procedure in a programming language Still specify a module in Verilog with inputs and outputs... ...but inside the module you write code to tell what you want to have happen, NOT what gates to connect to make it happen i i.e., you specify th b h i you want, not th structure t do it if the behavior t t the t t to d
Why use behavioral models
For testbench modules to test structural designs For high-level specs to drive logic synthesis tools
Mux: Structural Verilog
module mux(f a b sel); mux(f, a,b,sel); input a,b,sel; output f; wire f1, f2;
b a sel
not(nsel, ( l
sel); l)
and a1(f1, a,nsel); and a2(f2, b, sel); ( , , ); or (f, f1, endmodule f2);
Mux: Dataflow Model
module mux2(f, a,b,sel); d l (f b l) output f; input a,b,sel; a b sel; assign f = (a & ~sel) | (b & sel); endmodule
Mux: Behavioral Model
module mux2(f, a,b,sel); output f; input a,b,sel; reg f; always @(a or b or sel) l @( l) if (sel==1) f = b; else ; f = a; endmodule
Demux Example
2-to-4 demultiplexer with active low
enable 0 1 1 1 1
a x 0 1 0 1
b x 0 0 1 1
z[3] 1 1 1 1 0
z[2] 1 1 1 0 1
z[1] 1 1 0 1 1
z[0] 1 0 1 1 1
Demux: Structural Model
// 2-to-4 demultiplexer with active-low outputs module demux1(z,a,b,enable); input a,b,enable; output [3:0] z; wire aba bba i e abar,bbar; // local signals not v0(abar,a), v1(bbar,b); nand n0(z[0],enable,abar,bbar); nand n1(z[1],enable,a,bbar); nand n2(z[2],enable,abar,b); nand n3(z[3],enable,a,b); endmodule
Demux: Dataflow model
// 2-to-4 demux with active-low outputs // dataflow model module demux2(z,a,b,enable); input a,b,enable; output [3:0] z; assign z[0] = | {~enable,a,b}; assign z[1] = ~(enable & a & ~b); i [1] ( bl b) assign z[2] = ~(enable & ~a & b); assign z[3] = enable ? ~(a & b) : 1'b1; g [ ] ( ) ; endmodule
Demux: Behavioral Model
// 2-to-4 demultiplexer with active-low outputs module demux3(z,a,b,enable); input a,b,enable; a b enable; output [3:0] z; reg z; // not really a register! always @(a or b or enable) case ({enable,a,b}) default: z = 4'b1111; 3'b100: z = 4'b1110; 3 b 0: 3'b110: z = 4'b1101; b 0 ; 3'b101: z = 4'b1011; 3'b111: z = 4'b0111; endcase endmodule d d l
Example: 16-Bit Adder 16 Bit
Design Hierarchy: 16-Bit Adder 16 Bit
Verilog Model: 16-Bit Adder 16 Bit
module Add_rca_16_0_delay (sum, c_out, a, b, c_in);
output [15:0] sum; output c_out; input [15:0] a, b; a input c_in; wire c_in4, c_in8, c_in12, c_out;
Add_rca_4 M1 (sum[3:0], c_in4, a[3:0], b[3:0], c_in);
Add_rca_4 M2 (sum[7:4], c_in8, a[7:4], b[7:4], c_in4); Add_rca_4 M3 (sum[11:8], c_in12, a[11:8], b[11:8], c_in8); Add_rca_4 Add rca 4 M4 (sum[15:12], c out, a[15:12], b[15:12], c_in12); c_out, c in12);
endmodule
Verilog Model: 4-Bit Adder 4 Bit
module Add_rca_4 (sum, c_out, a, b, c_in); output [3: 0] sum; output c_out; input [3: 0] a, b; input c_in; wire c_in2, c_in3, c_in4; Add_full M1 (sum[0], c_in2, a[0], b[0], c_in); Add_full M2 (sum[1], c_in3, a[1], b[1], c_in2); Add_full Add full M3 (sum[2] c_in4, a[2] b[2], c_in3); (sum[2], c in4 a[2], b[2] c in3); Add_full M4 (sum[3], c_out, a[3], b[3], c_in4); endmodule
Verilog Model: Full Adder and Half Adder
Program 2
1 to 2 De multiplexer 1-to-2 De-multiplexer
Select y0 D y0
0 DMUX 1
y1 y1 Select
Select 0 1
y0 D 0
y1 0 D
Program 2 (cont ) (cont.)
module demux ( D, select, y0, y1); input D, select; output y0,y1; reg y0,y1; y g always @( D or select ) begin if( select == 1b0) begin y0 = D; y1 = 1b0; g end else begin y0 = 1b0; y1 = D; end end endmodule
y0
y1
Select
Example of Flip-flop
module Flip_flop ( q data in clk rst ); Flip flop q, data_in, clk, input data_in, clk, rst; output q; reg q; always @ ( posedge clk ) begin ) ; if ( rst == 1) q = 0; else q = data_in; end endmodule d d l
rst
data_in
clk
Declaration of synchronous behavior Procedural statement
Sub Module
Complex circuit Many modules in a circuit Module, sub-module, sub-sub-module,
B1
B2
B3
Example of Call Module
module B1(a b c); B1(a, b, .. endmodule module B2(a, b, c, d); .. endmodule module B3(x, y, z); .. endmodule
B1
B2
B3
Structural Module: example1
co a
module half_adder (s, a, b, co); input a, b; output s, co; wire w0, w1, w2; assign w0 = a & b, w1 = ~w0, w2 = a | b 2 b, s = w1 & w2, co = w0; endmodule
w0
w1
s w2
a 0 0 1 1 b 0 1 0 1 s 0 1 1 1 co 0 0 0 1
Structural Module: example ( CONT..)
module full_adder (s, a, b, co, ci); _ ( ) input a, b, ci; output s, co; wire w0, w1, w2; i 0 1 2 assign co = w1 | w2; half_adde i0 a adder 0 (.co(w1), .s(w0), .a(a), .b(b)); half_adder i1 (.co(w2), .s(s), .a(w0), .b(ci)); endmodule
a b w0
i0 a
co
w1
co
HA
b i1 a s
co
w2 s
HA
cii b s
Structural Module: example (cont..)
module adder4 (s a b co ci); (s, a, b, co, input [3:0] a, b; input ci; output [3:0] s, output co; wire w0, w1, w2; full_adder full adder i0 (.co(w0), .s(s[0]), .a(a[0]), .b(b[0]), .ci(ci)); full_adder i1 (.co(w1), .s(s[1]), .a(a[1]), .b(b[1]), .ci(w0)); full_adder f ll dd i2 (.co(w2), .s(s[2]), .a(a[2]), .b(b[2]), .ci(w1)); full_adder i3 ( ( ), ( [ ]), ( [ ]), ( [ ]), ( )); (.co(co), .s(s[3]), .a(a[3]), .b(b[3]), .ci(w2)); endmodule
ci a[0] b[0]
i0 ci a b i1 ci a b i2 ci a b i3 ci a b
FA
s co
s[0] w0 s[1] w1
a[1] b[1]
FA
s co
a[2] b[ ] b[2]
FA
s co
s[2] w2
a[3] b[3]
FA
s co
s[3] co
Behavioral Module: example1
module adder4 (s a b co, ci); (s, a, b, co
input [3:0] a, b; input ci; output [3:0] s, output co; reg [3:0] reg co; s;
always @(a or b or ci) {co, s} = a + b + ci;
endmodule d d l