Verilog
Verilog
org
A Brief Introduction to
VHDL and Verilog
Hardware Definition Languages (HDLs)
Background Green slides are relevant for both Verilog and VHDL code
Background
Forward
VHDL and Verilog are “Hardware Description” languages (HDLs) that are used to
define the structure and/or behavior of digital circuits. They are “concurrent” languages,
different than “procedural” languages like C or Java. If you take some time to
understand concurrency, the languages will make more sense.
VHDL and Verilog are different and competing languages, but they are used for the
same purpose. Verilog is more widely used in industry today, but VHDL is catching up.
Although they are different, they are also similar in many ways. They are presented
together because there are more similarities than differences.
Background
Concepts: Behavioral vs. Structural Models
“Behavioral” code defines outputs as functions of inputs, without describing any
circuit components or modules that might be used in constructing the circuit.
“Structural” code is a form of netlist, defining a circuit as a collection of subordinate
components or modules and their interconnecting wires.
A B C Y I$001: INV(B,N$001)
Drive an output B
C I$002: AND2(N$001,C,N$002)
signal Y to a 1
whenever input B is Y I$003: INV(C,N$003)
not asserted at the A I$004: AND2(A,N$003,N$004)
same time C is, or I$005: OR2(N$002,N$004,Y)
when A is asserted
when C is not.
Background
Concepts: Behavioral vs. Structural Models
Behavioral descriptions are more abstract, higher-level, quicker and easier to write,
easier for others to understand and follow, and largely self documenting.
Structural descriptions are often used when existing IP blocks can be reused. They
are easier to debug, easier to analyze (for timing and area), and can be easier to
optimize.
Most designers write behavioral code for individual, lower-level circuits, and
structural code when reusing existing IP or connecting lower-level blocks into
more complex circuits.
Background
Example: Behavioral vs. Structural Models
This example compares a structural 4-bit comparator schematic to VHDL and Verilog
behavioral descriptions. The HDL descriptions are far easier and faster to create, their
function is clear to the reader, and they are portable between CAD tools.
Background
Example: Behavioral vs. Structural Models
This example compares structural vs. behavioral Verilog for a 4-bit adder. Same advantages!
Behavioral Adder
Simpler and easier to read.
Background
Concept: HDLs can be Simulated and/or Synthesized
VHDL and Verilog descriptions can be simulated to check for logical correctness, and
synthesized to automatically create a physical circuit definition.
Many free VHDL and Verilog tools are available, and lots of reference and example
designs in both languages can be found around the internet
Background
Design Projects
Verilog and VHDL organize the workspace using Projects. Projects contain all the
source files needed for a given design. External files can also be used by placing
them in a library, and making the library visible within a project.
Source files include Verilog and VHDL source files and constraint files that are used
by the synthesizer to guide implementation.
Verilog source files contain modules. Modules are the basic Verilog constructs that
define circuits. A simple design might use a single module; more complex designs
might use several. A project can include any number of modules.
VHDL source files contain design units. There are five possible design units: entity,
architecture, configuration, package, and package body. Entity and architecture
design units describe circuits. Configuration, package, and package body are
optional organizational tools. A project can include any number of design units.
Verilog modules and VHDL design units stored in external libraries can be used in
other projects.
Background
Models for Synthesis
Verilog and VHDL source code can be written to:
• Model and study circuits;
• Specify circuits and concisely document behavioral requirements;
• Use specific pre-existing IP blocks;
• Define circuits for synthesis.
Synthesis models must model physical wires that transport signals between
components or to the outside world, as well as circuit components.
VHDL “wires” use a 9-valued type to model signals: 0, 1, L, H, W, Z, U, X, -
Verilog “wires” use a 4-valued type to model signals: 0, 1, X, Z
VHDL uses “entity” statements to define a component, and “architecture”
statements to define behavior
Verilog uses “modules” to define components and their behaviors
Background
Verilog Modules: A first look
Modules are the principle design entity in Verilog. All
circuits are defined in modules. A simple design might
use a single module; more complex designs might use
several. A project can include any number of modules.
The keyword “module” is followed by the module name
and the port list. The port specifies all port signals as
inputs, outputs, or inout (bi-directional).
Local signals are declared immediately following the
module/port statement.
Combinational assignments are made using the assign
statement. Sequential assignments are made inside an
“always” block. A module can have any number of
assign statements and always blocks. Assignment
statements are described in the following slides.
Simple
The module declaration statement
Z
defines the “bounding box”, and the A X
module body statements define the
circuit functions B Y
is used.
.component_port(topmodule_port)
Verilog
Concept: Sequential vs. Concurrent Models
• A sequential processing algorithm defines a set of steps that are taken in a
specific order
• Concurrent processing steps occur whenever new input data is available, with no
implied sequence relationship between separate concurrent processes
• Consider a simulation of a 2-input mux: At what time(s) should gate A1 be
simulated? What about gate O1?
A
A N2
A1
B B
N1 O1 Y
C
A2
C N3
Y
T0 T1 T2 T3 T4 T5 T6
HDL simulators model time by dividing it into arbitrarily small “simulator time steps”, which are the
smallest amounts of time that are relevant to the circuit (typically 10ps).
In any given simulator time step, the CPU only simulates circuit components whose inputs have
changed. Each simulator time step can take as much CPU time as is needed - during some time steps,
many circuit nodes may change, requiring a lot of CPU time. During other steps, very few nodes may
change, requiring almost no CPU time.
Background
Concurrency: Modelling time
A B
N$60 I$19: NAND3(N$43,N$41,N$44,N$53)
Block 1 N$42 I$22
N$43 I$20: OR3(N$45,N$43,N$46,N$54)
N$53
I$19 N$61 I$21: NAND2(N$53,N$54,N$58)
N$44
N$58 I$23 I$25 I$22: OR2(B,N$42,N$60)
B I$21 N$64 I$23: OR2(N$42,N$58,N$61)
Block 3 N$45
Clk N$46 I$20 N$62 I$24: FF(Clk,B,N$62)
N$54 I$25: AND3(N$60,N$61,N$62,N$54)
I$24
Clk
Block 2
A source file that can be expressed in Verilog or VHDL is Current time Simulator Time Steps
shown as a block diagram. A schematic and netlist for
...
Block 3 that might result from synthesis is also shown B ... 0 0 0 - - - ...
(note that all “instances” and “nets” that are not given N$42 ... 1 1 0 - - - ...
names in the source file are assigned auto-generated, N$43 ... 1 1 1 - - - ...
unique identifiers). Only some nets will change in any Clk ... 0 0 1 - - - ...
given time step. Here, only N$42 and Clk change. Only N$54 ... 1 1 1 - - - ...
those instances whose inputs have changed in a given N$58 ... 0 0 0 - - - ...
time step are simulated. Most digital simulators work this N$61 ... 0 0 0 - - - ...
way – this is called “event driven simulation”.
...
Time
Background
Concurrency: Modeling time
Assigning new values to output nets requires a variable amount of CPU time for each simulator step,
depending on how many instances must be simulated. “Simulator time” is held constant until all circuit
nodes/instances have been simulated and there are no more changes in that step. Only then does
simulator time advance.
Combinational assignments in Verilog and VHDL are “concurrent”. This means combinational outputs
are updated after an input changes, regardless of where the assignment statement appears in the
source file. To change a combinational net:
• Verilog uses an “assign” statement, and assigns outputs to combinational nets immediately;
• VHDL uses a signal assignment operator (<=), and requires that all signal updates must happen in a
later simulator time step - no changes can occur in the same step in which the input changed.
Flip-flop outputs can only be updated after a “procedure” checks for a clock edge. If an edge has
occurred in the current time step, any required output changes are scheduled for a later time:
• Verilog uses a “procedural block” and a “non-blocking” operator (<=), and any changes take affect
at the end of the current simulation step;
• VHDL uses a “process block” and a signal assignment operator (<=), and any changes are
scheduled for a later time step.
Background
www.realdigital.org
Verilog Concurrency Model
Verilog combinational assignments are “continuous”, meaning the left hand side is always driven and
new values are assigned as soon as the right hand side is evaluated. Assignment statements can
appear in any order in the source file without changing the results. Simulator time does not advance
when processing continuous assignment statements. The code below will produce identical results.
No combinational net should be assigned more than once, because assignment statements are
concurrent and the results will not be determinant. The assign statement on the left will have the
expected results; the example on the right will not.
Memory requires a “procedural assignment” so that a timing signal can be checked. Memory
assignments use the “non-blocking” operator that updates outputs at the end of the simulation step.
Non-blocking procedural assignments can only occur inside an “always” block (described later).
Syntax
Intro 5/5
11/13
Verilog Concurrency Model
Combinational Non-blocking assignments are used for memory. They
Evaluating outputs requires
assignments are are concurrent, and must be inside of an always block.
variable amounts of CPU time, concurrent and take There can be any number of them, but they all take
depending on the number of effect immediately effect at the end of the simulation step.
instances that must be
simulated. “Simulator time” is
held constant during the
simulator time step, until all assign x = ... assign x = ... assign x = ... assign x = ...
assign y = ... assign y = ...
circuit nodes/instances have assign y = ...
assign z = ...
assign z = ... always @ (A)
been simulated and there are begin always @ (B)
no more changes. Only then GRN <= 1'b0 begin
does simulator time advance. If.. BLUE <=...
else if...
Red <=...
end
always @ (B)
begin
CPU
Simulation Step Step 1 Step 2 Step 3 Step 4 Time
Simulation Time 000001 000002 000003 000004
CPU time per simulation step (represented by colored box size) depends on
how much processing is required; it will vary for every step. Simulation Time is
fixed during each Simulation Step, and only increments at the end of the step.
Verilog
VHDL Concurrency Model
VHDL combinational signal assignment statements are “scheduled”. The right hand side is evaluated,
and if required the left hand side signal is updated, but at a later time. A specific update time can be
specified using the “after” keyword, for example: If you do not include
“after” (and it is most common not to), then the simulator schedules the update for one “delta delay”
later. Delta delay does not correspond to a physical time. It is just “not now” in terms of simulator time. It
preserves concurrency by allowing all assignments in a given time step to be evaluated without
changing simulator time, and scheduling unspecified assignments for the next “delta” time step.
As in Verilog, only signals that change in the current time step cause assignment statements to be
simulated. Once all changes have been simulated, simulator time advances. In VHDL, the simulator
advances one delta delay and repeats the process – any signals that have changed in the current delta
delay start another round of simulation, until there are no more changes and no more scheduled delta
delays. Then the simulator advances one step, and the process repeats.
Signal assignment statements use the <= operator. They can appear in any order in the source file
without changing the results. Simulator time does not advance when processing signal assignments.
The code below will produce identical results.
VHDL
VHDL Concurrency Model
Memory requires a “process statement” so that a timing signal can be checked. Memory assignments
use the same signal assignment operator (<=) that updates in the next delta delay. Memory
assignments can only occur inside an “process” block (described later).
The simulator operates in a simple loop: check the time queue to see what signals have changed;
simulate any instances whose inputs have changed; schedule the new signal to take affect in the next
delta delay (or at an used-supplied “after” time); repeat until there are no more delta delays. Then,
increment the simulation step, and repeat.
VHDL
VHDL Concurrency Model
Evaluating whether Combinational x and y are y gets assigned in x and q are updated in the
assignments outputs updated here, the first delta delay, first delta delay (assuming
outputs must be are scheduled for the after one x in the second clk had a rising edge), y in
updated requires next delta delay delta delay the second
variable amounts of
CPU time, depending
on the number of
instances that must y <= a and b; y <= a and b; x <= a xor b;
x <= c or d; x <= y or d; process (clk) begin
be simulated. if (risingedge(clk))
“Simulator time” is q <= d;
held constant during end process;
y <= q and c;
the simulator time
step, until all circuit
nodes/instances
have been simulated CPU
and there are no Simulation Step Time
Step 1 Step 2 Step 3 Step 4
more changes. Only Simulation Time 000001 000002 000003 000004
then does simulator
CPU time per simulation step (represented by colored box size) depends on
time advance. how much processing is required; it will vary for every step. As many delta
delays as needed are added until there are no more changes. Simulation Time
is fixed during each Simulation Step, and only increments at the end of the
step.
VHDL
Verilog
Verilog
Verilog Syntax: Identifiers and Numbers
White Space: Spaces, tabs, and new lines and form feeds can
separate words and are ignored.
Verilog
Verilog Syntax: Constants and Parameters
Constants: A parameter statement defines local parameters (constants) inside of a
module. Parameters are not visible outside the module. They can be changed without
resynthesizing under certain conditions. Typical uses include defining a bus width, or
specifying a number of modules to synthesize in a variable bus-width design.
Localparam is the same, but constants cannot be changed. Localparam is often used
to define numbers or state identifiers (Localparam is most commonly used).
Global constants (and macros) can be defined using the ‘define keyword. They are
visible outside the module, throughout the project.
Examples:
Verilog
Verilog Syntax: Operators
Verilog
Wires and Assignments
Wires transport signals between modules and I/O pins. Wires can connect to other wires, to ‘0’
or ‘1’ logic values, to modules, or to I/O pins.
“assign” statements assign values to wires, but not to inferred memory devices – that requires
an “always block” (more on that in a later slide). “assign” statements are “continuous
assignment” statements, which means they are always active and take effect immediately.
Wires must be declared prior to use with a wire statement. Examples:
All module input signals (ports) must be wires. Wires declared inside a module are not visible
outside that module.
Verilog
Registers and Assignments
Verilog supports two variable types (wire and reg) and two assignment types: “wire
assignments” (pervious slide), and “procedural assignments”. Procedural assignments store
outputs in registers (reg) types. Verilog has two procedural assignments: “initial”, run once at
the start of simulation, and “always”, which always runs.
Registers can only be assigned within an always block. Wires cannot be assigned in an
always block.
Registers store the last value that was assigned to them (wires store nothing). Reg types are
required for instantiating memory. Registers are declared prior to use with a reg statement.
Examples:
Registers can connect to module outputs, but not to inputs (only wires can connect to module
inputs).
Possible values for reg and wire variables are 0, 1, X (unknown), and Z (high impedance)
Verilog
Always Procedural Block
Procedural assignments define sequential
behavior – that is, events that happen only
under certain conditions.
Verilog
Procedural Assignments: Blocking vs. Non-blocking
Always blocks assign values to variables of type “reg”. Wires cannot be assigned new values.
Reg variables are assigned new values with “blocking” or “non-blocking” assignments.
Blocking assignments (=) take effect immediately, but non-blocking assignments (<=) take
effect at the end of the simulation step. Non-blocking assignments are concurrent.
Flip-flops are inferred (created) using an always block that checks for a posedge on clk
(and/or rst). Output values are assigned using a non blocking (<=) assignment.
Always blocks can define combinational logic, sequential logic, or a mixture of both. If only
combinational logic is defined, then use blocking assignments; otherwise, use non-blocking.
Do not make assignments to the same variable from more than one always block.
A module can have as many procedural (always) blocks as necessary. Statements in a
procedural block are executed in order, but the blocks themselves are concurrent to other
blocks.
“Initial” procedural blocks are similar to always blocks, but they execute only once at the very
start of a simulation. Initial blocks are used to setup initial conditions for simulation.
Verilog
Procedural blocks: If-then and Case statements
If-then and case statements can only appear in procedural
blocks (always blocks). They allow conditions to be checked
prior to taking action, and use C-like syntax.
If and case statements can be used to infer memory, by
incompletely specifying all possible outcomes of a condition
check. If not all possibilities are specifically covered,
synthesis will generate extra latches.
If and case statements can also be used to define purely
combinational logic, but care must be taken to avoid creating
unwanted memory.
If statements can have one “else” block, but any number of
“else if” blocks. If only one assignment is needed, the begin…
end keywords are not required.
End case statements with “default”, or risk latches.
Verilog
Procedural blocks: If-then and Case statements
Verilog
Modules
Modules are the principle design entity in Verilog. The
keyword “module” is followed by the module name and
the port list.
The port list names and specifies all port signals as
inputs, outputs, or inout (bi-directional). Locally
declared wires and regs are typically declared
immediately following the module/port statement.
Combinational assignments are made using the assign
statement. Sequential assignments are made inside an
always block. A module can have any number of assign
statements and always blocks.
Cout
A Cin
x2
B
fa3
y2 Y
sum2
Cout
A Cin
x3
B
fa4
y3 Y
sum3
Cout
cout
Adder_4bit
Verilog
Hierarchical design
Cin Cin
Larger digital systems use X[15:0] Cin x0 A
B
Cin
fa1
x0
hierarchical design, with a x
sum
Y[15:0]
Y
sum0
modules. x
Cin
x1 A
B
Cin
fa2
y1 Y
sum sum1
Data B
Each module at every level Adder_16bit y
Cout
is designed and tested Digital System Cout
Cin
independently. Leaf modules x
x2 A Cin
fa3
typically use behavioral y
sum y2 B
Y
sum2
Adder_4bit
Verilog
Multiplexor Examples
Using if statement
Verilog
ALU Example
Verilog
Flip-Flops and Latch
D Flip-flop
Asynch reset
D Flip-flop
Synch reset
Verilog
State Machine Models
Present
State
Circuit Combo Circuit
Inputs Logic Outputs
Next-State Next State Output Circuit
Logic State Register Logic Outputs
Next
State
Circuit
Inputs Present
State State
Register
Clk Clk
RST
RST
Mealy Model State Machine Combined Model State Machine
Background
State Machines
X
init
X
BELL
pick
Y Y
Z Z
Z
left right
LED1 Z LED1
LED2
Verilog
State Machine (con’t)
X
init
X
BELL
pick
Y Y
Z Z
Z
left right
LED1 Z LED1
LED2
Syntax
Intro 5/5
11/13
Testbench
A testbench is a separate Verilog source file that is written specifically to
test other Verilog modules. It uses Verilog structures, syntax, and rules,
plus a few extra items that are intended specifically to drive the simulator,
and not to define a circuit.
The remainder of the testbench source file drives inputs into the
simulator.
Syntax
Intro 5/5
11/13
Testbench con’t
Verilog
Miscellaneous
Memory Arrays: Verilog models memory as an array of regs. Memories are accessed by providing an
array access. Examples:
Other types: “Integer”, “time”, and “real” are legal Verilog variable types that are used in behavioral
modeling and in simulation, but rarely in sauce code intended for synthesis.
Verilog