verilog textbook
TRANSCRIPT
-
8/7/2019 VERILOG TEXTBOOK
1/15
Chapter1: Introduction to Verilog
This document uses short examples to demonstrate the basic Verilog syntax, time delays, andconcurrent execution features. We have tried to condense all the interesting and hard parts of
Verilog into 15 pages and skip all of the boring stuff like the what is the difference between real
and integer data types. Studying this document will enable you to model circuits using simplestructural and behavioral Verilog code and provide a solid framework for learning all the detailsof the language.
If Verilog is a new language for you we recommend getting a copy of "Verilog HDL" by SamirPlantikar. It is a well organized Verilog textbook that is filled with lots of examples.
1.0 Why Use Verilog?
Most Verilog and VHDL books begin with several chapters describing the language's history and
advantages. But the arguments boil down to these:
y HDL simulators are better then gate level simulators for 2 reasons: portablemodel development, and the ability to design complicated test benches that reactto outputs from the model under test. Finding a model for a unique component foryour particular gate level simulator can be a frustrating task, with an HDLlanguage you can always write your own model. Also most gate level simulatorsare limited to simple waveform based test benches which complicates the testingof bus and microprocessor interface circuits.
y Verilog is a great low level language. Structural models are easy to design andBehavioral RTL code is pretty good. The syntax is regular and easy toremember. It is the fastest HDL language to learn and use. However Verilog
lacks user defined data types and lacks the interface-object separation of theVHDL's entity-architecture model.
y VHDL is good for designing behavioral models and incorporates some of themodern object oriented techniques. It's syntax is strange and irregular, and thelanguage is difficult to use. Structural models require a lot of code that interfereswith the readability of the model.
y C++as an hardware modeling language is excellent choice for high-levelbehavioral analysis of a system (like evaluating different data flow architecturesin a microprocessor). However C++ lacks the basic hardware concepts likeknowledge of strengths, connections, and concurrent execution whichcomplicates model generation for lower level simulations.
Choosing Verilog, VHDL, orC++will be based on availability of tools, models, and in-house
expertise. If you are just learning your first HDL language we recommend Verilog because you
will be able to quickly become comfortable with the syntax and timing issues of the language:
-
8/7/2019 VERILOG TEXTBOOK
2/15
Chapter 2: Verilog Structure
This chapter gives a quick overview of the structural and behavioral elements ofVerilog and discusses the time flow and time control statements. Verilog differs from
regular programming languages (C, Pascal, ...) in 3 main aspects: (1) simulation time
concept, (2) multiple threads, and (3) some basic circuit concepts like networkconnections and primitive gates. If you know how to program in C and you
understand basic digital design then learning Verilog will be easy.
If you have VeriLogger Pro installed on your computer you can copy and paste the
following code segments into a text file and simulate the examples.
2.1 Modules
In Verilog, circuit components are designed inside a module. Modules can containboth structural and behavioral statements. Structural statements represent circuit
components like logic gates, counters, and microprocessors. Behavioral level
statements are programming statements that have no direct mapping to circuitcomponents like loops, if-then statements, and stimulus vectors which are used to
exercise a circuit.
Figure 1 shows an example of a circuit and a test bench module. A module starts with
the keyword module followed by an optional module name and an optional port list.
The key word endmodule ends a module.
`timescale 1ns / 1ps//create a NAND gate out of an AND and an Invertormodule some_logic_component (c, a, b);
// declare port signalsoutput c;input a, b;
// declare internal wirewire d;
//instantiate structural logic gatesand a1(d, a, b); //d is output, a and b are inputsnot n1(c, d); //c is output, d is input
endmodule
//test the NAND gatemodule test_bench; //module with no portsreg A, B;wire C;
//instantiate your circuitsome_logic_component S1(C, A, B);
//Behavioral code block generates stimulus to test circuitinitial
-
8/7/2019 VERILOG TEXTBOOK
3/15
beginA = 1'b0; B = 1'b0;#50 $display("A = %b, B = %b, Nand output C = %b \n", A, B, C);A = 1'b0; B = 1'b1;#50 $display("A = %b, B = %b, Nand output C = %b \n", A, B, C);A = 1'b1; B = 1'b0;#50 $display("A = %b, B = %b, Nand output C = %b \n", A, B, C);A = 1'b1; B = 1'b1;#50 $display("A = %b, B = %b, Nand output C = %b \n", A, B, C);
endendmodule
Figure 1 shows a simple logic circuit and test bench.
2.2 Structural Design with Gate Primitives and the Delay operator
Verilog defines some basic logic gates as part of the language. In Figure 1, modulesome_logic_component instantiates two gate primitives: the not gate and the and gate.
The output of the gate is the first parameter, and the inputs are the rest of theparameters. These primitives are scaleable so you can get multiple input gates just by
adding inputs into the parameter list. For example:
nand a1(out1, in1, in2); //2-input NAND gatenand a2(out1, in1, in2, in3, in4, in5); //5-input NAND gate
By default the timing delay for the gate primitives is zero time. You can define therising delay, falling delay using the #(rise, fall) delay operator. And for tri-state gates
you can also define the turn-off delay (transition to high impedance state Z) by using
the #(rise, fall, off) delay operator. For examplenotif0 #(10,11,27) inv2(c,d,control) //rise=10, fall=11, off=27(not ifcontrol=0)nor #(10,11) nor1(c,a,b); //rise=10, fall=11 (nor gate)xnor #(10) xnor1(i,g,h); //rise=10, fall=10 (xnor gate)
Also each of the 3 delays can be defined to have minimum, typical, and a maximumvalue using the a colon to separate the values like 8:10:12 instead of 10 in the above
examples. At run time, the Verilog simulator looks for to see ifthe +mindelay, +typdelay, or+maxdelay option has been defined so that it will
know which of the 3 time values to use. In VeriLogger these options are set using
the Project > Project Preferences menu. If none of the options are specified then the
typical value is used.
// min:typ:max values defined for the (rise, fall) delaysor #(8:10:12, 10:11:13) or1(c,a,b);
-
8/7/2019 VERILOG TEXTBOOK
4/15
The delay operator has one subtle side effect: it swallows narrow input pulses.
Normally, the delay operator causes the output response of a gate to be delayed acertain amount of time. However if the input pulse width is shorter then the overall
delay of the gate then the change will not be shown on the output.
Here is a list of logic primitives defined for Verilog:
Gate Parameter List Examples
nand nor and
or xor xnor
scalable, requires atleast 2 inputs(output,
input1, input2, ,inputx)
and a1(C,A,B);nand na1(out1,in1,in2,in3,in4);nor #(5)n1(D,A,B);//delay = 5 time unitsxor #(3,4,5)
x1(E,A,B);//rise,fall,off delaysnor #(3:4:5)n2(F,A,B);//min:typ:max of delays
not buf (output, input) not inv1(c,a);
notif0bufif0control signal activelow(output, input,
control)
notif0 inv2(c,a, control);
notif1bufif1
control signal active
high(output, input,control)
not inv1(c,a, control);
2.3 Structural Design with Assignment Statements
If you have a lot of random logic, the gate primitives of the previous section are
tedious to use because all the internal wires must be declared and hooked up correctly.
Sometimes it is easier to just describe a circuit using a single Boolean equation. InVerilog, Boolean equations which have similar timing properties as the gate
primitives are defined using a continuous assignmentstatement.
For example, the following code excerpt from Figure 1:
wire d;and a1(d, a, b);not n1(c, d);
can be replaced with one statement:
assign c = !(a && b); //notice that wire d was not used here
Assignments can also be made during the declaration of a wire. In this case the assign
keyword is implicitly assumed to be there for example:
wire d;assign d = a || b; //continuous assignment
-
8/7/2019 VERILOG TEXTBOOK
5/15
wire d = a || b; //implicit continuous assignment
By default the timing delay for assignment statements is zero time. You can define apropagation delay using the #delay operator just like we did for the gate primitives.
The following examples have the exact same timing.
wire c;assign #5 c = a && b; //delay in the continuous assignment
wire #5 c = a && b; //delay in the implicit assignment
wire #5 c; //delay in the wire declarationassign c = a && b;
To demonstrate the pulse swallowing effect of the delays operator, consider thefollowing senario. In the above examples, if input a changed value at time 10 (and
held its value for at least 5 time units), then the output c would change values at time
15. If input a had a value pulse that was shorter then the propagation delay of theassignment then the value on a would not be passed to the output.
The delay operator can also use the full rise, fall, and off delays and each delay can
have a minimum:typical: maximum value. The following is a valid line of code.
and #(8:10:12, 10:11:13, 26:27:29) a1(c,a,b); //min:typ:max of(rise,fall,off)
Appendix A defines all of the operators that can be used in an assignment statement.
2.4 Structural Design with using Modules
Verilog supports hierarchical design by allowing modules to instantiate other
modules. For example in Figure1 module test_bench instantiates a component S1 of
type some_logic_component. The code is reprinted here for convince:
module test_bench;...
some_logic_component S1(C, A, B); //instantiate a some_logic_componentmodule
...
endmodule
By default the timing inside a module is controlled by the module itself. However,
modules can be defined to have parameterized delays similar to the #(4,5) delay
operator used with gate primitives. In the module definition, use the parameter
keyword to create delay variables. Parameters can also be used to change other scalarvalues in the module. When the module is instantiated then you can choose to
override the delay values using the #(parameter) notation. For example:
-
8/7/2019 VERILOG TEXTBOOK
6/15
module some_logic_component (c, a, b);... //some code
parameter andDelay = 2; //default delaysparameter invDelay = 2;and #andDelay a1(d, a, b); //using parameter delaysnot #invDelay n1(c, d);
endmodule
module test_bench; //module with no ports...
some_logic_component #(5,4) S3(E, A, B); //override andDelay=5, invDelay=4some_logic_component #(5) S2(D, A, B); //override andDelay=5, invDelay=2some_logic_component S1(C, A, B); //uses default delays....
endmodule
Modules also support a special kind of timing called specify blocks which can be usedin conjunction with SDF analyzers. Specify blocks also support continuous setup and
hold checking.
2.5 Behavioral Design with Initial and Always blocks
Behavioral code is used to describe circuits at a more abstract level then the structural
level statements we have studied. All Behavioral code occurs within either an initial
block or in an always block. A module can contain several initial and always blocks.
These behavioral blocks contain statements that control simulation time, data flowstatements (like if-then and case statements), and blocking and non-blocking
statements.
An initial block executes once during a simulation. Initial blocks are usually used toinitialize variables and to describe stimulus waveforms which exercise which drive
the simulation.
An always block continuously repeats its execution during a simulation. Always
blocks usually contain behavioral code that models the actual circuit operation.
During a simulation each always and each initial block begin to execute at time zero.
Each block executes concurrently with each structural statement and all the other
behavioral blocks. The following example shows a behavioral SRAM model. The
initial block sets the memory cells to zero at startup. The always block executes eachtime there is a change on the write control line, the chip select line, or the address bus.
As an exercise, copy and paste this code into a verilog file and write a test bench to
exercise the model. If you are using VeriLogger Pro then you can draw a test bench.
//SRAM Modelmodule sram(CSB,WRB,ABUS,DATABUS);input CSB; // active low chip select
-
8/7/2019 VERILOG TEXTBOOK
7/15
input WRB; // active low write controlinput [11:0] ABUS; // 12-bit address businout [7:0] DATABUS; // 8-bit data bus
//** internal signalsreg [7:0] DATABUS_driver;wire [7:0] DATABUS = DATABUS_driver;reg [7:0] ram[0:4095]; // memory cellsinteger i;
initial //initialize all RAM cells to 0 at startupbeginDATABUS_driver = 8'bzzzzzzzz;for (i=0; i < 4095; i = i + 1)
ram[i] = 0;end
always @(CSB or WRB or ABUS)beginif (CSB == 1'b0)begin
if (WRB == 1'b0) //Start: latch Data on rising edge of CSB or WRBbeginDATABUS_driver
-
8/7/2019 VERILOG TEXTBOOK
8/15
Chapter 3: Verilog Syntax Details
Our goal up to this point has been to teach you how to model some simple circuitsbefore swamping you with all the details about Verilog types, ports, and numbers. But
as we do more Behavioral design it becomes easier to make mistakes in this area.
Before you begin a big design you might want to get a copy of "Verilog HDL" bySamir Plantikar and memorize Chapters 3, 4, and 7. What follows is just enough
information in order to understand the subsequent behavioral code examples.
3.1 Structural Data Types: wire and reg
Verilog supports structural data types called nets which model hardware connections
between circuit components. The two most common structural data types
arewire and reg. The wire nets act like real wires in circuits. The reg type hold their
values until another value is put on them, just like a register hardware component. The
declarations forwire and reg signals are inside a module but outside any initial or
always block. The initial state of a reg is x unknown, and the initial state of awire is z.
Ports:Modules communicate with each other through ports, the signals listed in the
parameter list at the top of the module. Ports can be of type in, out, and inout.
Here are 3 simplistic rules for matching the structural data type to the type of port:
1. Use reg as the outputs of Behavioral blocks. If you us a wire then the value willnever be seen by other blocks.
2. Use wire for all inputs, inouts, and most outputs of Structural elements.3. If you need a special strength type operation use special net keyword wand, wor,
tir, triand, trior, trireg.
3.2 Behavioral Data Types: integer, real, and time
The types in integer and real are convenient data types to use for counting in
behavioral code blocks. These data types act like their counter parts in otherprogramming languages. If you eventually plan to synthesize your behavioral code
then you would probably want to avoid using these data types because they often
synthesize large circuits.
The data type time can hold a special simulator value called simulation time which is
extracted from the system function $time. The time information can be used to help
you debug your simulations.
..... //code fragment from inside a module
-
8/7/2019 VERILOG TEXTBOOK
9/15
integer i, y;real a;real b = 3.5;real c = 4;time simulationTime;initialbeginy = 4;i = 5 + y;c = c + 3.5;a = 5.3e4;simulationTime = $time;$display("integer y = %d, i = %f \n", y, i);$display("reals c = %f, a = %e, b= %g \n", c, a, b);$display("time simulationTime = %t \n", simulationTime);end
3.3 Number Syntax
Numbers in verilog are in the following format
'
The size is always specified as a decimal number. If no is specified then the defaultsize is at least 32bits and may be larger depending on the machine. Valid base formatsare 'b , 'B , 'h , 'H'd , 'D , 'o , 'O for binary, hexadecimal, decimal, and octal.
Numbers consist of strings of digits (0-9, A-F, a-f, x, X, z, Z). The X's mean
unknown, and the Z's mean high impedance If no base format is specified the number
is assumed to be a decimal number. Some examples of valid numbers are:
2'b10 // 2 bit binary number'b10 // at least a 32-bit binary number
3 // at least a 32-bit decimal number8'hAf // 8-bit hexadecimal
-16'd47 // negative decimal number
3.4 Behavioral Design with blocking and non-blocking statements
There are 2 kinds of assignment statements: blocking using the = operator, and non-
blocking using the
-
8/7/2019 VERILOG TEXTBOOK
10/15
y
-
8/7/2019 VERILOG TEXTBOOK
11/15
wire [7:0] DATABUS = DATABUS_driver; //inout must be driven by a wire....for (i=0; i < 4095; i = i + 1) // Setting individual memory cells to 0ram[i] = 0;
end....ram[ABUS] = DATABUS; //writing to a memory cell....DATABUS_driver = ram[ABUS]; //reading from a memory cell
3.7 Operators
Here is a small selection of the Verilog Operators which look similar but have
different effects. LogicalOperators evaluate to TRUE or FALSE. Bitwise operators
act on each bit of the operands to produce a multi-bit result. Unary Reduction
operators perform the operation on all bits of the operand to produce a single bit
result.
Operator Name Examples
! logical negation
~ bitwise negation
&& logical and
& bitwise andabus =
bbus&cbus;
& reduction and abit = &bbus;
~& reduction nand
|| logical or
| bitwise or
| reduction or
~| reduction nor
^ bitwise xor
^ reduction xor
~^ ^~ bitwise xnor
~^ ^~ reduction xnor
== logical equality, result may be unknown if x or z in the input if (a == b)
=== logical equality including x and z
!= logical inequality, result may be unknown if x or z in the input
!== logical inequality including x and z
> relational greater than
>> shift right by a number of positions a = shiftvalue
-
8/7/2019 VERILOG TEXTBOOK
12/15
>> 2;
>= relational greater than or equal
< relational less than
-
8/7/2019 VERILOG TEXTBOOK
13/15
pci_stimulator.v (bus-functional IO model of the PC that reads/writes FPGA ports)
scanner.v (generates scanner input to feed the FPGA)testbench.v (top level test bench that instantiates the pci_stimulator, the scanner, and the FPGA
top level module, plus any glue logic weve included in the design)
Step 2: Functionally Simulate your Register-Transfer-Level Design
Now that youve got something to test and some basic tests written, its time to simulate thesystem. During this phase of the design, youll be constantly running simulations, examining the
results, and then making changes to your Verilog code to fix bugs you find. This phase is calledfunctional simulation, because its only testing whether the logical (functional) design of the
system is correct, but it doesnt test whether the system meets speed requirements.
If youre using a command line simulator, you would compile these files with a command line
such as the one below. For the purposes of this tutorial, were assuming youre usingSynaptiCADs Verilog simulator, simx, but the syntax would be very similar for most verilogsimulators. To compile the code and run the simulation from the command line, type:
simx testbench.v scanner.v pci_stimulator.v pci_interface.v ocr_processor.v fpga.v
If youre using a graphical debugger with your simulator, all these files should be placed into thesource file folder of your Verilog simulators project file, then you would press the Build button
to compile the files, followed by the Run button to simulate the design. After the design hasfinished simulating (or when you encounter a breakpoint), you can look at the simulation log file
and waveforms captured during the simulation run to see if there were any problems. Most
simulators provide various ways to examine the internal signals of your design to trace down thecause of any errors, so that you make appropriate corrections to your Verilog source files and re-simulate the design. During debug of your design, a graphical debugger is highly recommended,
as its much easier to locate and fix bugs using these tools.
Steps 1 and 2 are essentially an iterative process and typically most of the design is spent in thesetwo phases. These two steps are fairly high level and are somewhat independent of the target
FPGA or ASIC youve decided to use. The exact syntax of commands for the next couple ofsteps will generally depend more on your choice of FPGA vendor, however.
Step 3: Convert RTL-level files to a Gate-level model with a Synthesizer
After youve successfully fixed all the bugs you can find during functional testing, its time to
synthesize your RTL design. You do not need to synthesize your testbench code, only your RTLdesign code (in fact, most test bench code uses Verilog features that synthesis tools cannot
handle). Synthesis is a mostly automated process using a synthesizer tool that converts yourRTL-level design source code (pci_interface.v, ocr_processor.v, and fpga.v) into a single gate-
level Verilog file (this file is often called timingsim.v) that can be fed into a place-and-route(P&R) tool to create a programming file for your FPGA. The generated gate-level Verilog file
-
8/7/2019 VERILOG TEXTBOOK
14/15
will consist of one big module filled with gates connected by wires. This is often referred to as aflattened design, because all the individual modules from your original RTL design has been
flattened out into one big module and all hierarchical information is gone.
Step 4: Perform GateL
evel simulations with FPGA or ASIC librariesNow that weve synthesized the design, its time to simulate the gate-level code generated by thesynthesizer to check if the synthesizer misunderstood anything we told it to do (generally this
occurs if we write some form of improper code that simulates properly at RTL level, but violatesa synthesis coding convention). These errors are relatively rare nowadays as there are many
good books that cover proper coding techniques for writing synthesizable code and synthesizershave also gotten very good at their job.
Gate-level simulations take longer to run than RTL level simulations (especially when SDF
timing is included), but fortunately you dont typically need to run many gate-level simulationssince most bugs are logic errors that should have already been caught during the functional
simulation phase. You should be able to reuse the same test benches during your gate levelsimulation that you created for testing the RTL design, with some minor modifications to handle
things like expansion of buses into individual bits and possibly some changes to the stimulus tocheck stressful timing conditions.
You will need to add some additional command line options to your simulator to compile a gate-
level design. Instead of true Verilog gate level primitives, the gates in the synthesized design filewill be vendor gates. These vendor gates are defined in a Verilog library file or directory
provided by the FPGA vendor. These gates are mostly just wrappers around the Verilog gateprimitives that also include specify blocks where standard delay file (SDF) data can be
incorporated to model the timing of the gates. So, to compile the synthesized design file, you will
need to tell your simulator where to find the vendor library gate models.
FPGA vendor libraries typically come in one of two forms: a single big file that contains all the
gate models or a directory with one file per gate model, where the filename matches the name ofthe gate model.
If its a single big file, you can just include this file into the compile options for your simulator
with a -v option to specify the vendor library file. For example, assume the vendors library fileis called fpga_models.v, you would perform a gate level simulation using a command like:
simx testbench.v scanner.v pci_stimulator. timingsim.v v c:\fpga\fpga_models.v
(Note were using timingsim.v, the flattened gate-level model, rather than the three RTL level
source files now, but were still using the original test bench files to test the design)
On the other hand, if your FPGA vendor ships its library models as individual files in a directorycalled fpga_models_dir, then you would use the -y to specify the vendor library directory. In
this case, you would use a simulation command like:
-
8/7/2019 VERILOG TEXTBOOK
15/15
simx testbench.v scanner.v pci_stimulator. timingsim.v y c:\fpga\fpga_models_dir
Optional Step: Gate-level simulation with SDF timing information
Gate level simulations can optionally be performed with timing information from an SDF file.
The FPGA vendors Place-and-Route tool will generate a separate SDF file that containsestimates of the delay times for the gates in your design based on the way the FPGA was routed(most of the delays in FPGAs are interconnect routing delays rather than delays through the logic
gates themselves).
The SDF file generated by the Place-and-Route tool can be used along with the synthesized gate-level model file to perform time-based simulations with your Verilog simulator.
An $sdf_annotate command can be placed into the gate-level verilog file to incorporate thetiming from the SDF file. These timing simulations are used to detect bugs such as flip flop setup
and hold violations.
You generally dont need to do exhaustive timing simulations, as your design will probably alsobe getting checked by a timing analyzer tool. A timing analyzer scans for timing paths in your
Verilog gate-level netlist that would cause a timing error in your design. A timing analyzerperforms a min-max analysis, so it checks more thoroughly for timing problems than a timing
simulation does. In theory, you could even skip gate-level simulations and just use the timinganalyzer results to verify your design meets timing requirements, but in practice its a very good
idea to perform a timing simulation as an extra check.