Introduction to Verilog HDL: A Hardware Specification Language
430 likes | 452 Vues
Learn about the structural and behavioral aspects of Verilog HDL, its modules, synthesis tools, system description, module instantiation, primitives, identifiers, datatypes, full adder simulation, and useful simulation commands.
Introduction to Verilog HDL: A Hardware Specification Language
E N D
Presentation Transcript
CSE 341 Verilog HDL An Introduction
Hardware Specification Languages • Verilog • Similar syntax to C • Commonly used in • Industry (USA & Japan) • VHDL • Similar syntax to ADA • Commonly used in • Government Contract Work • Academia • Europe
Structural vs. Behavioral • Structural • Shows primitive components and how they are connected • Modules are defined as a collection of interconnected gates and other previously defined modules • Modules are built up to make more complex modules • The design describes the structure of the circuit • Behavioral • Shows functional steps of how the outputs are computed • Abstract description of how the circuit works • Does not include any indication of structure (implementation) details • Useful early in design process • Allows designer to get a sense of circuit’s characteristics before embarking on design process • After functionality is well defined, structural design may follow • Synthesis Tools • Generate implementation based on the behavioral specification
Overview • System is described as a set of modules consisting of: • Interface • Declares nets & registers which comprise the two (2) fundamental data types in Verilog • Nets • Used to connect structures (eg. - gates) • Need to be driven • Reg • Data storage element • Retain value until overwritten by another value • Don’t need to be driven • Description • Defines structure
Modules • Instantiating modules can help make code easier to write, modify, read, and debug • Examples • Carry Lookahead Adder • Partial Full Adder • Carry Lookahead Unit • Barrel Shifter • 7-Segment Display Decoder • Basic Module Format
Modules • Structure modulemodulename(port list); parameters port declarations (inputoroutput) wire declarations reg declarations submodule instantiations … text body … endmodule • Instantiations • modulenameinstance_name(port list);
Datatypes • Net • Wire • Register • Reg • Static Storage Element
Parameters • Parameters • Used to define constants in modules • Examples parameter and_delay=2, or_delay=1; and #and_delay (f,a,b);
Primitive Structural Modules • Define the structure of the module • Form the module’s body • Format • gate#n(output, inputs) • Note: The integral delay (#n ) may be neglected • If omitted, delay = 0 • Gates • and • or • nand • not • xor
Identifiers • Names given to hardware objects • Wires (busses) • Registers • Memories • Modules • Alphanumeric • May Include: • _ • $ • May NOT Start With: • Number • $
Numbers • Syntax • Sized • Size’FormatNumber • Size • Number of digits • Format (Base) • h (Hexadecimal) • d (Decimal) Default • o (Octal) • b (Binary) • Number • Number specified • Unsized • ’FormatNumber
Numbers • Examples • 4’b1011 • 8’hfe902a30 • 2’d37 • Same as 37 (default) • 4’h a729 • ‘d 62923 • 8’b 1101zzzz • 16’h x
The Full Adder • Consider a Full Adder
The Full Adder • Basic Module module fulladder() ; wire w1, w2, w3, w4, s, cout; reg a, b, c; xor g1(w1, a, b), g2(s, w1, c); and g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or g6(cout, w2, w3, w4); --> Simulation <-- endmodule
Simulation • The simulation is an event-driven, time-ordered depiction of the circuit’s behavior under the prescribed specifications. • Structure initial begin Simulation end
Simulation • Some Useful Simulation Commands • $monitor(“format”, variable list); • Displays the specified entities when the values change • Modelled after C’s printf • Extra commas add spaces in the output • Format • %b • bit • %d • decimal • %h • hexadecimal • $display (“format”, variable list); • Similar to monitor, but displays variable list in the format specified whenever it is encountered
Simulation • Some Useful Simulation Commands • $time • Keeps track of simulator’s time • Used to maintain current time by simulator • The simulation will display the time when an event occurs • Referenced by $time • Specification of Units • ‘timescaleunits/least significant digit to be printed • Example • ‘timescale 10 ns / 100 ps • Units of 10 ns are used, printing out to no more precision than 100 ps
Simulation • Some Useful Simulation Commands • Integral Delay • #n • Delays action by n time units (as defined by the timescale) • In other words… • n time units after the current time, the described event will take place • May also be used for setting module & gate delays • Example will follow
Simulation • A bit in the simulation may take one of four values: • 1 (true) • 0 (false) • X (unknown) • Z (High Impedance)
The Full Adder • Basic Module module fulladder() ; wire w1, w2, w3, w4, s, cout; reg a, b, c; xor g1(w1, a, b), g2(s, w1, c); and g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or g6(cout, w2, w3, w4); initial begin $monitor($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); #10 a=0; b=0; c=0; #10 a=1; #10 b=1; #10 c=1; a=0; #10 a=1; #10 // Required for iverilog to show final values $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); end endmodule
Simulation • Timescale • Compiler Directive • Preceded by ` • Note, this is not an apostrophe • `timescale reference_time_unit / time_precision
The Full Adder • Basic Module `timescale 1ns/1ns module fulladder() ; wire w1, w2, w3, w4, s, cout; reg a, b, c; xor g1(w1, a, b), g2(s, w1, c); and g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or g6(cout, w2, w3, w4); initial begin $monitor($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); #10 a=0; b=0; c=0; #10 a=1; #10 b=1; #10 c=1; a=0; #10 a=1; #10 // Required for iverilog to show final values $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); end endmodule
Simulation • Other Common Directives • Define • Defines constants or macros • Structure • `definenamedefinition; • Example • `define delay 1 • Include • Allows for multiple source file use • Not needed in Xilinx • Structure • `includefilename • Example • `include multiplexors.v
Full Adder Functional Simulation • Text Output # 0 a=x, b=x, c=x, s=x, cout=x # 10 a=0, b=0, c=0, s=0, cout=0 # 20 a=1, b=0, c=0, s=1, cout=0 # 30 a=1, b=1, c=0, s=0, cout=1 # 40 a=0, b=1, c=1, s=0, cout=1 # 50 a=1, b=1, c=1, s=1, cout=1 # 60 a=1, b=1, c=1, s=1, cout=1 • Waveform
Full Adder Under Unit Delay Model • Basic Module `timescale 1ns/1ns module fulladder() ; wire w1, w2, w3, w4, s, cout; reg a, b, c; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); initial begin $monitor($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); #10 a=0; b=0; c=0; #10 a=1; #10 b=1; #10 c=1; a=0; #10 a=1; #10 // Required for iverilog to show final values $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); end endmodule
Full Adder Under Unit Delay Model • Basic Module `timescale 1ns/1ns module fulladder() ; wire w1, w2, w3, w4, s, cout; reg a, b, c; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); initial begin $monitor($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); #10 a=0; b=0; c=0; #10 a=1; #10 b=1; #10 c=1; a=0; #10 a=1; #10 // Required for iverilog to show final values $display($time,,,, "a=%b, b=%b, c=%b, s=%b, cout=%b",a,b,c,s,cout); end endmodule
Full Adder Unit Delay Simulation • Text Output # 0 a=x, b=x, c=x, s=x, cout=x # 10 a=0, b=0, c=0, s=x, cout=x # 12 a=0, b=0, c=0, s=0, cout=0 # 20 a=1, b=0, c=0, s=0, cout=0 # 22 a=1, b=0, c=0, s=1, cout=0 # 30 a=1, b=1, c=0, s=1, cout=0 # 32 a=1, b=1, c=0, s=0, cout=1 # 40 a=0, b=1, c=1, s=0, cout=1 # 41 a=0, b=1, c=1, s=1, cout=1 # 42 a=0, b=1, c=1, s=0, cout=1 # 50 a=1, b=1, c=1, s=0, cout=1 # 52 a=1, b=1, c=1, s=1, cout=1 # 60 a=1, b=1, c=1, s=1, cout=1 • Waveform
Comments • Single Line Comments • Comment preceded by // • Example or #1 // OR gate with a delay of one time unit g6(cout, w2, w3, w4); • Multiple Line Comments • Comment encapsulated by /* and */ • Example and #1 g1(e, a, b); /* In this circuit, the output of the AND gate is an input to the OR gate */ or #1 g2(f, c, e);
Creating Ports • Port names are known only inside the module • Declarations • Input • Output • Bidirectional • Full Adder Module
Creating Ports in the Full Adder `timescale 1ns/1ns module fulladder(a,b,c,s,cout); input a,b,c; output s,cout; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); endmodule
Creating Ports in the Full Adder `timescale 1ns/1ns module fulladder(a,b,c,s,cout); input a,b,c; output s,cout; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); endmodule
Instantiation • Modules can be instantiated to complete a design • 4-bit Ripple Carry Adder
Vectors • Scalar • A single bit net or reg • Vector • A multiple bit net or reg • Advantage • Vectors make for a more natural way of scaling up a design • Example • Consider the 4-bit adder • Using scalars: • A3 A2 A1 A0 + B3 B2 B1 B0 + Cin = Cout S3 S2 S1 S0 • Using vectors: • A + B + Cin = Cout, S • A[3:0] + B[3:0] + Cin = Cout, S[3:0]
Vectors • Details • wire and reg may be declared as multibit • [expression_1:expression_2] • Note: • Left expression is MSB, right is LSB • Expression must be constant, but may contain • constants • operators • parameters
Vectors • Concatenation • A bitvector can be created by concatenating scalar carriers and/or bitvectors • Example reg sum[3:0] reg cout [cout,sum] • Replication • n{bitvector} • Replicates the bitvectorn times. • Example • 4{b’1001} results in 1001100110011001
Creating the 4-bit Adder `timescale 1ns/1ns module fulladder(a,b,c,s,cout); input a,b,c; output s,cout; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); endmodule module fourBitAdder(x,y,s,cout,cin); input [3:0] x,y; output [3:0] s; input cin; output cout; wire c[3:0]; fulladder f0 (x[0],y[0],cin,s[0],c[0]); fulladder f1 (x[1],y[1],c[0],s[1],c[1]); fulladder f2 (x[2],y[2],c[1],s[2],c[2]); fulladder f3 (x[3],y[3],c[2],s[3],cout); endmodule
Creating the 4-bit Adder `timescale 1ns/1ns module fulladder(a,b,c,s,cout); input a,b,c; output s,cout; xor #1 g1(w1, a, b), g2(s, w1, c); and #1 g3(w2, c, b), g4(w3, c, a), g5(w4, a, b); or #1 g6(cout, w2, w3, w4); endmodule module fourBitAdder(x,y,s,cout,cin); input [3:0] x,y; output [3:0] s; input cin; output cout; wire [3:0] c; fulladder f0 (x[0],y[0],cin,s[0],c[0]); fulladder f1 (x[1],y[1],c[0],s[1],c[1]); fulladder f2 (x[2],y[2],c[1],s[2],c[2]); fulladder f3 (x[3],y[3],c[2],s[3],cout); endmodule
Creating a Testbench • Provides for efficient testing of circuit • Process • Create a module dedicated for testing • Instantiate • Test Module • Circuit to be Tested • Wire the modules together • Note that initial assignments in blocks must always be made to registers
Testbench for the 4-bit Adder `timescale 1ns/1ns module testbench(); wire [3:0] x,y,s; wire cin,cout; testAdder test (x,y,s,cout,cin); fourBitAdder adder (x,y,s,cout,cin); endmodule module testAdder(a,b,s,cout,cin); input [3:0] s; input cout; output [3:0] a,b; output cin; reg [3:0] a,b; reg cin; initial begin $monitor($time,,"a=%d, b=%d, c=%b, s=%d, cout=%b",a,b,cin,s,cout); $display($time,,"a=%d, b=%d, c=%b, s=%d, cout=%b",a,b,cin,s,cout); #20 a=2; b=3; cin=0; #20 a=1; b=7; cin=0; #20 // Required for iverilog to show final values$display($time,,"a=%d, b=%d, c=%b, s=%d, cout=%b",a,b,cin,s,cout); end endmodule // Don’t forget to include the fourBitAdder and fulladder modules
4-bit Adder Unit Delay Simulation • Text Output # 0 a= x, b= x, c=x, s= x, cout=x # 20 a= 2, b= 3, c=0, s= x, cout=x # 22 a= 2, b= 3, c=0, s= X, cout=0 # 23 a= 2, b= 3, c=0, s= 5, cout=0 # 40 a= 1, b= 7, c=0, s= 5, cout=0 # 42 a= 1, b= 7, c=0, s= 2, cout=0 # 43 a= 1, b= 7, c=0, s=12, cout=0 # 45 a= 1, b= 7, c=0, s= 0, cout=0 # 47 a= 1, b= 7, c=0, s= 8, cout=0 # 60 a= 1, b= 7, c=0, s= 8, cout=0 • Waveform
Icarus Verilog • iverilog • Available on the CSE systems • Using iverilog • Enter source code using any editor • Save using .v exention • Compile • iverilog -t vvp filename.v -o out_filename • Note that neglecting to specify the output filename (-o out_filename), iverilog will output to a.out. • View Results • vpp out filename
Example • Simulate the following circuit using Verilog HDL.
Example module eg_function(); reg a,b,c; wire f; ckt inst1(f,a,b,c); initial begin $monitor($time,"a =%b, b=%b, c=%b, f=%b",a,b,c,f); $display($time,"a =%b, b=%b, c=%b, f=%b",a,b,c,f); #0 a=0; b=0; c=0; #10 a=1; b=1; c=0; #10 a=1; b=1; c=1; #10 // Required for iverilog to show final values $display($time,"a =%b, b=%b, c=%b, f=%b",a,b,c,f); end endmodule module ckt(f,a,b,c); parameter delay=1; output f; input a,b,c; wire x,y; and #delay (x,a,b); or #delay (y,b,c); xor #delay (f,x,y); endmodule