chapter 4: introduction to logic design with verilog 2016/ece4242/chap 4(0).pdf•verilog becomes...
TRANSCRIPT
Chapter 4: Introduction to Logic Design with Verilog
1 Chapter 4 Copyright 2013 G. Tumbush v1.3
Hardware Description Language • Verilog Background
– Verilog created at Gateway Design Automation in 1983/1984
– Cadence Design Systems purchased Gateway in 1989 • Originally intended for simulation, synthesis support added later
– Cadence transferred Verilog to public domain • Verilog becomes IEEE Standard 1364-1995 and is known as Verilog-95
– Extensions to Verilog-95 submitted to IEEE • IEEE Standard 1364-2001, a.k.a. Verilog-2001
– Minor corrected submitted to IEEE in 2005 • IEEE Standard 1364-2005, a.k.a. Verilog-2005
• Last Verilog standard is IEEE Std 1364-2005
• Verilog RTL synthesis standard is IEEE 1364.1-2005 – But …
Verilog/SystemVerilog
3
In 2009, the IEEE merged the Verilog 1364-2005 and the SystemVerilog extensions (1800-2005) into a single document. For reasons the authors have never understood, the IEEE chose to stop using the original Verilog name, and changed the name of the merged standard to SystemVerilog. The original 1364 Verilog standard was terminated, and the IEEE ratified the 1800-2009 SystemVerilog-2009 standard as a complete hardware design and verification language. In the IEEE nomenclature, there is no longer a current Verilog standard. There is only a SystemVerilog standard. Since 2009, you have not been using Verilog...you have been designing with—and synthesizing—SystemVerilog! (The IEEE has subsequently released a SystemVerilog-2012 standard, with additional enhancements to the original, now defunct, Verilog language.) Source: Synthesizing SystemVerilog Busting the Myth that SystemVerilog is only for Verification, Stuart Sutherland and Don Mills
Chapter 4 Copyright 2013 G. Tumbush v1.3
What is Verilog?
4
•Verilog is a hardware description language (HDL) that allows complex systems to be described in a textual format. •Verilog increases productivity and maintainability
• Allowed designers to keep up with Moore’s law
ABC
X
always @(A or B or C) begin if (A && B && C) X=1; else if (!A && !B && !C) X=1; else X=0; end
Keywords • The Verilog Language Reference Manual (LRM) specifies a
syntax that precisely describes the allowed constructs. – Verilog is case sensitive
• All keywords are lowercase • Never use Verilog keywords as unique names, even if case is different
– Verilog is composed of approximately 100 keywords
and always assign attribute begin buf bufif0 bufif1 case cmos deassign default defparam disable else endattribute end endcase endfunction endgenerate endprimitive endmodule endtable endtask event for force forever fork function generate genvar highz0 highz1 if initial inout input integer join large medium module nand negedge nor not notif0 notif1 nmos or output parameter pmos posedge primitive pulldown pullup pull0 pull1 rcmos reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared small specify specparam strong0 strong1 supply0 supply1 table task tran tranif0 tranif1 time tri triand trior trireg tri0 tri1 vectored wait wand weak0 weak1 while wire wor
Chapter 4 Copyright 2013 G. Tumbush v1.3 6
4.1 Structural Models of Combinatorial Logic
7 Chapter 4 Copyright 2013 G. Tumbush v1.3
The basic building block in Verilog is a module. Verilog 1995 syntax: module <module name> (<list of module ports>); <Direction of ports> < Structural and functional details> endmodule Verilog 2001 syntax: module <module name> (<list of module ports with direction>); < Structural and functional details> endmodule Best practice is to have only one module per file and name file same as module name Exception for library files that contain multiple cell definitions
Gate Level Modeling
• Basic Gates
– or, nor, and, nand
– xor, xnor, not, buf
(not, buf not shown)
• Syntax
– GATE (drive_strength) # (delays) instance_name1(output, input_1, input_2,..., input_N)
Gate Level Modeling
• Three-State Gates
– High impedance is symbolized by z in Verilog
• If checking for high impedance (or unknown),
use === or !==
– The gates are instantiated with the statement: • gateName (drive_strength) # (delays) optionalUniqueName(output, input, control)
buffer when control = 1 z when control = 0
inv when control = 1 z when control = 0
buffer when control = 0 z when control = 1
inv when control = 0 z when control = 1
Gate Level Modeling • Gate Delays
– Recall that all physical circuits exhibit a propagation delay between the transition of a input a resulting transition on the output
– Adding gate delays, allows user to model propagation delays
– Ignored by synthesis tools
• Hint: Don’t rely on gate delays
– Tools “back annotate” delays
after synthesis and place/route
– Wires can have delays: • wire #2 A_long_wire
– All primitives and nets have a
default prop. delay of 0.
// HDL Example 3.2 module simpleCircuit(A, B, C, D, E); output D, E; input A, B, C; wire w1;
// Single delay for all transistions and #5 G1(w1, A, B, C);
// Rise and fall delay and #(1,2) G2(w1, A, B, C);
// Rise, fall, and turn off delay bufif1 #(1,3,2) G3(x, y);
// One Delay: min, typ, max or #(1:2:3) G3(D, w1, E);
// Three delays: min, typ, max for PVT bufif1 #(1:2:3,4:5:6,7:8:9) G6(D, w1, E); endmodule
// Continuous Assignment – no delay assign y = ~a; // Continuous Assignment – LHS delay assign #5 y = ~a; // Illegal Continuous Assignment – RHS delay Assign y = #5 ~a;
Half Adder Example
12 Chapter 4 Copyright 2013 G. Tumbush v1.3
module Add_half(a, b, sum, c_out); input a,b; output c_out, sum; xor(sum, a, b); and(c_out, a, b); endmodule
a
bsum
c_out
module Add_half(input a, b, output sum, c_out); xor (sum, a, b); and (c_out, a, b); endmodule
Verilog 1995 Style
Verilog 2001 Style
4.1.2 Verilog Structural Models
13 Chapter 4 Copyright 2013 G. Tumbush v1.3
module AOI_str(input x_in1, x_in2, x_in3, x_in4, x_in5, output y_out); wire y1, y2; and and_in1_2 (y1, x_in1, x_in2); and and_in3_4_5 (y2, x_in3, x_in4, x_in5); nor nor_y1_y2 (y_out, y1, y2); endmodule
x_in1 y1
y_out
x_in2
x_in3y2
x_in4
x_in5
Verilog Structural Model Exercise
14 Chapter 4 Copyright 2013 G. Tumbush v1.3
Create a module definition for a 2-1 mux using primitives. The inputs are i0, i1, and sel. The output is out. The primitive name for an inverter is not.
Identifiers • User defined words for variables , function names,
module names, block names, and instance names • Identifiers must start with an alphabetic character or underscore
– System tasks and functions start with $
• Variables may contain alphanumeric characters, underscore, and $
• Can be up to 1024 characters long
• Case sensitive
• The “_” is also allowed within numbers for ease of reading
• Declarations, assignments, and statements end with a semicolon
my_sig != My_Sig
wire _my_sig; wire my_sig1; module my_mod1 input _my_sig inout bidir_sig;
Comments • Two types of comments:
– One line comments • Start with // and end at end of line (eol)
– Multi-line comments: • Start with /* and end with */
• Blank spaces are ignored • Cannot appear within keyword text, a user defined operator, or
number
• A “\” is used for line multi-line continuation character // output My_sig;
/* this /* is not */allowed */ /* this is allowed */
4.1.5 Top-Down design and Nested Modules
17 Chapter 4 Copyright 2013 G. Tumbush v1.3
To design complex systems partition into managable blocks.
CPU
MEM
ALU
CONTROLLER Inst
Decode Inst
Fetch
config registers
CPU
4.1.5 Top-Down design and .... example
18 Chapter 4 Copyright 2013 G. Tumbush v1.3
Add_fullsum
c_out
c_in
a
b
sum
c_out
c_in a
bAdd_half
sum
c_out
a
bAdd_half
sum
c_outa
b
Add_full
4.1.5 Top-Down design and .... example (cont)
19 Chapter 4 Copyright 2013 G. Tumbush v1.3
module Add_full(input a,b,c_in, output sum, c_out); wire w1, w2, w3; Add_half add_a_b (a, b, w1, w2); Add_half add_cin_w1 (c_in, w1, sum, w3); or or_w3_w2(c_out, w3, w2); endmodule
sum
c_out
c_in a
bAdd_half
sum
c_out
a
bAdd_half
sum
c_outa
b
Add_full
w1
w2
w3
Data Types • Value Set
0: logic zero, false 1: logic one, true x: unknown, contention z: high impedance, undriven
• Nets – wire, tri: interconnecting wire – wor, trior: Wired OR – wand, triand: Wired AND – tri0, tri1: Net pull up/down when not driven – supply0, supply1: Constant logic value of supply strength – trireg: Retains last value when driven by z
• Verilog wire: – “wire” is combinational and evaluates continuously – Cannot store a value – Default initialization value of z – Nets with drivers assume output value of driver (default of x) – No properties (delay, etc.) associated with wires
• Just interconnect between elements
• Syntax wire [msb:lsb] wire_variable_list;
wire a, b, c; assign a = b; wire x = c;
4.1.7 Vectors in Verilog • Wires can be declared as vectors. Example: wire [3:0] sel; wire [0:3] sel2; • Bit selects do not have to start at 0. Example: wire [4:1] sel; • If bit width is not specified the default is a scalar. • Left most index is the MSB • Right most index is the LSB • Bit select using similar notation. Example sel[2] or sel[2:1]
21 Chapter 4 Copyright 2013 G. Tumbush v1.3
Little endian notation
Danny Cohen introduced the terms Little-Endian and Big-Endian for byte ordering in an article from 1980. In this technical and political examination of byte ordering issues, the "endian" names were drawn from Jonathan Swift's 1726 satire, Gulliver’s Travels, in which civil war erupts over whether the big or the small end of a soft-boiled egg is the proper end to crack open.
Big endian notation
Data Types
• Vectors – Range is specified as: [msb_exp: lsb_exp] – Example: wire[31:0] a;
• 32 bits with MSB as 31 and LSB as 0 • big endian • a is all wires • a[31] specifies the MSB • a[0] specifies LSB • a[15:8] is eight wires, bits 15 through 8 of a
– reg signed [7:0] • Vector for -128 to 127 (2’s complement)
– Keyword “vectored” specifies a vector that can only be modified as an indivisible entity
– Keyword “scalared” allows access to bits and parts (default)
Data Types • Arrays
– reg[31:0] mema[0:4095] • 4096 words of 32 bits per word
• mema[2] is third word
• mema[2][31] is the MSB of the third word
31:0
31:0
31:0
31:0
….
31:0
31:0
31:0
mema[0]
mema[1]
mema[2]
mema[3]
….
mema[4093]
mema[4094
mema[4095]
Data Types
• Memories
– reg[7:0] vid_mem[1:4][7:0][5:0]
• 3D array organized as bytes
• Initialized with $readmemh or $readmemb
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
[7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0] [7:0]
5:0
7:0
1:4
Strings
• Treated as sequence of eight bit ASCII values – No special termination character
• One eight bit ASCII value hold one character • Strings can be manipulated using standard
operators • To store a string, declare a register large enough
to hold all characters reg [8*15:0] myString ;
• The null string (“”) is equivalent to the value zero (0)
String Tasks Function Description
len() Returns string length
putc() Assign one character of string
getc() Returns a character
toupper() Returns the string uppercase
tolower() Returns the string lowercase
compare() Returns the string compare
icompare() Returns the caseless string compare
substr() Returns the sub0string of main string
Function Description
atoi() Returns integer value of the decimal represenation in ASCII string
atohex() Returns hex value of the hex representation in ASCII string
atooct() Returns octal value of the octal representation in ASCII string
atobin() Returns binary value of the binary representation in ASCII string
atoreal() Returns real value of the real representation in ASCII string
itoa() Stores the ASCII decimal representation of i into str (inverse of atoi)
hextoa() Stores the ASCII hex representation of i into str (inverse of atohex)
octtoa() Stores the ASCII octal representation of i into str (inverse of atooct)
bintoa() Stores the ASCII binary representation of i into str (inverse of atobin)
realtoa() Stores the ASCII real representation of i into str (inverse of atoreal)
Top Down Design and Vector Exercise
27 Chapter 4 Copyright 2013 G. Tumbush v1.3
Write a model of a 4-1 mux using the 2-1 mux designed in the last exercise. Inputs are i0, i1, i2, i3, sel[1:0]. Output is out.
4.1.6 Design Hierarchy and Source-Code Org
28 Chapter 4 Copyright 2013 G. Tumbush v1.3
module Add_rca_4(input [3:0] a,b, input c_in, output [3:0] sum, output c_out); wire cin2, cin3, cin4; Add_full add_bit0(a[0], b[0], cin, sum[0], c_in2); Add_full add_bit1(a[1], b[1], cin2, sum[1], c_in3); Add_full add_bit2(a[2], b[2], cin3, sum[2], c_in4); Add_full add_bit3(a[3], b[3], cin4, sum[3], c_out); endmodule
• Using a full adder can create an adder of arbitrary size.
c_in
c_out
Add_rca_4
Add_full
sum c_out
c_in a b
a[0] b[0]
sum[0]
Add_full
sum c_out
c_in a b
a[1] b[1]
sum[1]
Add_full
sum c_out
c_in a b
a[2] b[2]
sum[2]
Add_full
sum c_out
c_in a b
a[3] b[3]
sum[3]
4.1.6 Design Hierarchy and Source .... (cont)
29 Chapter 4 Copyright 2013 G. Tumbush v1.3
Add_rca_4
Add_full
add_bit_0 add_bit1 add_bit2 add_bit3
Add_full Add_full Add_full
Add_half
add_a_b add_cin_w1 or_w3_w2
Add_half or
and_in1_2
xor and
and_in3_4_5
and
nor_y1_y2
Port Connection by Name vs Position
30 Chapter 4 Copyright 2013 G. Tumbush v1.3
module Add_full(input a,b,c_in, output sum, c_out); wire w1, w2, w3; Add_half add_a_b (a, b, w1, w2); Add_half add_cin_w1 (c_in, w1, sum, w3); or or_w3_w2(c_out, w3, w2); endmodule
by position
module Add_full(input a,b,c_in, output sum, c_out); wire w1, w2, w3; Add_half add_a_b (.a(a), .b(b), .sum(w1), .c_out(w2)); Add_half add_cin_w1 (.a(c_in), .b(w1), .sum(sum), .c_out(w3)); or or_w3_w2(c_out, w3, w2); endmodule by name
port name of submodule Add_half local name in module Add_full
Default nettype An interesting “feature” of verilog is an undeclared signal‘s default nettype is a binary wire. For example the 2-1 mux you designed could have been written as: module mux2_1(i0, i1, sel, out); input i0, i1, sel; output out; // wire sel_n, i0_sel_n, i1_sel; not not_sel(sel_n, sel); nand nand_i0_sel_n(i0_sel_n, i0, sel_n); nand nand_i1_sel(i1_sel, i1, sel); nand nand_output(out, i0_sel_n, i1_sel); endmodule; This could cause errors if the signal is a vector.
31 Chapter 4 Copyright 2013 G. Tumbush v1.3
Declaring the default netype as none To catch undeclared or mis-typed signal names: `default_nettype none module mux2_1(input wire i0,i1,sel, output wire out); wire sel_n, i0_sel_n, i1_sel_n; ..... endmodule; Signals used but not declared will result in compile errors
32 Chapter 4 Copyright 2013 G. Tumbush v1.3
4.2.1 4-value Logic and Signal Resolution in Verilog
•Verilog uses a 4-value logic system having the symbols: 1 – logic 1 0 – logic 0 x – unknown z - high impedance
•Undriven inputs and floating signals of type wire are z •Undriven outputs and floating signals of type reg are x •A signal driven to 0 and 1 simultaneously is x •An input to a gate that is X or Z could cause the output to be X
33 Chapter 4 Copyright 2013 G. Tumbush v1.3
AND gate Resolution Example
34 Chapter 4 Copyright 2013 G. Tumbush v1.3
0
1
Z
X
0 1 ZXab
ab
y
a X Z
b
1
0 1 X Z 0 1 X Z 0 1 X Z 0 1 X Z
y
0 0 0 0
0
0
0
1
X
X X
X X
X X X
0 X 0 XX10
OR gate Resolution Exercise
35 Chapter 4 Copyright 2013 G. Tumbush v1.3
01
Z
X
0 1 ZXab
ab
y
a X Z
b
1
0 1 X Z 0 1 X Z 0 1 X Z 0 1 X Z
y
complete the K-map and timing diagram
0 1
1 1 1 1
1
1 x
x x x
x x
x x
Resolution of Contention
36 Chapter 4 Copyright 2013 G. Tumbush v1.3
a
b
ab
out1
out2
out
XX
X
Z
out1 X X
out2 X X
X Xout X
Resolution of Contention – tristate
37 Chapter 4 Copyright 2013 G. Tumbush v1.3
a
b
a
b
XX
X
Z
out1 Z X
out2 X
Xout X
out1
out2
s0
s1 out
s0
s1
Z
Z Z
Z Z
User Defined Primitive (UDP) – The keywords and, or, etc. are defined by the system
and thus are system primitives
– The user can create additional primitives by defining them in tabular format • Scoped by table, endtable keywords
– Declared with primitive … endprimitive
– The current IEEE 1364 standard provides for
multiple-inputs/outputs UDPs but multiple outputs are not common
– The output terminal must be first in the terminal list
– All UDP terminals are scalar
– No bidirectional inout terminals allowed
The high impedance value (z) cannot be specified
UDPs
• Example from of mux:
– Note: the //D0 D1… comment line is just a comment line
The table column order is determined by the input order
primitive mux2_UDP0_SVT16(Q, D0, D1, SEL1); output Q; input D0, D1, SEL1; table // D0 D1 SEL1 : Q 1 ? 0 : 1; ? 1 1 : 1; 0 ? 0 : 0; ? 0 1 : 0; 0 0 ? : 0; 1 1 ? : 1; endtable endprimitive
D0
D1
Q
SEL1
0
1
UDPs
primitive d_edge_ff(q, clock, data); output q; reg q; input clock, data; table // obtain output on rising edge of clock // clock data q q+ (01) 0 : ? : 0 ; (01) 1 : ? : 1 ; (0?) 1 : 1 : 1 ; (0?) 0 : 0 : 0 ; // ignore negative edge of clock (?0) ? : ? : - ; // ignore data changes on steady clock ? (??) : ? : - ; endtable endprimitive
timescale • A “`” (grave accent) indicates a compiler directive • `timescale 1ns/1ps
– Specifies the time unit and time precision • time unit
– 1ns indicates a time unit of 1ns – #10 will have a delay of 10nS
• time precision – Indicates the degree of accuracy, i.e. how delay values are rounded
• Valid time units are s, ms, us, ns, ps, fs • Only 1, 10 , or 100 are valid integers for specifying unit and precision
– Must be specified before and outside module definition • The first line of a module is the `timescale compiler directive if required,
otherwise an optional comment
– Module without timescale directive will inherent timescale from calling module
– Verilog simulates with the smallest time precision unit specified for a given module
– Make time precision no smaller than necessary
Other compiler directives • `include “filename”
– Inserts the contents of a specified file into a file in which it was called. The file name should be given in quotation marks (") and it can be given using full or relative path.
• `ifdef, `else, and `endif – These directives can be used to decide which lines of Verilog code should be
included for the compilation
– Used with `define or +define command line option
• `protect, `endprotect – Encrypts code to new file, compile with the +protect command line option
– After compilation, the new file has regions marked `protected, unprotected
– +autoprotect command line option protects all modules • Used for libraries, etc.
`ifdef NO_SLAVE … `else … `endif
`include “Chip.vh”
4.2.2 Test Methodology
44 Chapter 4 Copyright 2013 G. Tumbush v1.3
Testing ensures your verilog model does what you intend.
Stimulus Generator
DUT
Response Monitor
Testbench
Verilog System Tasks $write // same as $display except no automatic insertion of newline $strobe // same as $display except waits until all events finished $monitor // same as $display except only displays if an expression changes $monitoron // only one $monitor may be active at ant time, $monitoroff // turn current $monitor off $displayb // same as $display using binary as default format $writeb // same as $write using binary as default format $strobeb // same as $strobe using binary as default format $monitorb // same as $monitor using binary as default format $displayo // same as $display using octal as default format $writeo // same as $write using octal as default format $strobeo // same as $strobe using octal as default format $monitoro // same as $monitor using octal as default format $displayh // same as $display using hexadecimal as default format $writeh // same as $write using hexadecimal as default format $strobeh // same as $strobe using hexadecimal as default format $monitorh // same as $monitor using hexadecimal as default format
Testbench Example
46 Chapter 4 Copyright 2013 G. Tumbush v1.3
module Add_half_tb(); wire sum, c_out; reg a, b;
Add_half Add_half_a_b(.sum(sum), .c_out(c_out), .a(a), .b(b));
initial begin #10 a=0;b=0; #10 b=1; #10 a=1; #10 a=1; #10 $finish; // $finish exits simulation, $stop halts end
endmodule
10 20 30 40 50
Testbench Exercise
47 Chapter 4 Copyright 2013 G. Tumbush v1.3
Write a testbench for the 2-1 mux designed in a previous exercise.
4.2.4 Sized Numbers
48 Chapter 4 Copyright 2013 G. Tumbush v1.3
• Values are declared as <size>’<base> <value> • The size specifies the number of bits used for <value> • The base specifies the number format of <value> where b or B specifies binary d or D specifies decimal o or O specifies octal h or H specifies hexadecimal Example: 8’b10100011 = 8’b1010_0011 = 8’hA3 = 8’d165 = 8’o245
size base
Verilog Linting Tool
49 Chapter 4 Copyright 2013 G. Tumbush v1.3
• A linting tool checks code for undesirable constructs.
•The term was derived from the name of the undesirable bits of fiber and fluff found in sheep's wool.
•The Verilog linting tool checks your Verilog code for synthesizability •Developed by Kenneth Hassey and Danny Dauwe as a senior project •http://www.uccs.edu/~gtumbush/linting_tool/linting_tool.html •Linting your code (and fixing errors) will be a requirement for HW.
Only lint designs, not testbenches!