Verilog (Part 2)
3
Procedural Assignment
Definition:
• Procedural assignment is the method of assigning values to variables inside procedural blocks (initial,
always).
• Unlike continuous assignment (assign) which is used for wire, procedural assignment applies only to
reg, integer, real, and time variables.
• It enables modeling of sequential behavior (state machines, clocked logic, control flow).
• Initial Block
• Executes only once, starting at simulation time 0.
• Commonly used in testbenches to set initial values, create one-time stimulus, or reset signals.
• Not synthesizable into hardware.
4 of
Procedural Assignment: Initial Block
• Initial Block
• Executes only once, starting at simulation time 0.
• Commonly used in testbenches to set initial values, create one-time stimulus, or reset signals.
• Not synthesizable into hardware.
• Syntax
• Typical Use Cases
Initializing signals before simulation.
Generating reset signals.
Creating one-time test stimulus.
• Example
5 of
Procedural Assignment: Always Block
• AlwaysBlock
• Executes continuously or for the entire duration of the simulation.
• Used to model synthesizable hardware and repetitive testbench behavior.
• Often combined with sensitivity lists to define when it executes.
• Syntax
• Typical Use Cases
Clock generation in testbenches.
Describing combinational logic.
Modeling sequential logic (flip-flops, FSMs).
• Example
6 of
Procedural Assignment
• Sensitivity Lists
• A sensitivity list defines which events or signals will trigger the execution of an always block.
• It is written after the @ symbol.
• It ensures that the block executes only when one of the listed signals changes.
• Syntax
• Types of Sensitivity
Level-sensitive: Triggered whenever any value change occurs on the listed signals.
Edge-sensitive: Triggered on specific edges (rising or falling) of the listed signals.
Automatic (@*): Includes all signals used on the right-hand side of assignments (introduced in Verilog-2001).
7 of
Procedural Assignment
• Blocking assignment (=)
• Executes sequentially: each statement must finish before the next one executes.
• Commonly used in combinational logic.
• Example:
• Non-blocking assignment (<=)
• Executes in parallel: all right-hand sides are evaluated first, then assignments update simultaneously.
• Commonly used in sequential (clocked) logic.
• Example:
8 of
Statement Groups
• Statement groups allow multiple procedural statements to be treated as a single unit.
• Used inside procedural blocks (initial, always) when more than one statement needs to execute together.
• Two main grouping keywords:
begin ... end → executes sequentially.
fork ... join → executes in parallel.
• Sequential Group: begin ... end
Used when statements must execute in order, one after another.
Most common grouping structure in procedural blocks.
• Parallel Group: fork ... join
Executes all statements simultaneously (in parallel).
Commonly used in testbenches to trigger multiple actions at the same time.
9 of
Conditional Constructs
• If–Else Statement
The if–else statement in Verilog is a conditional control structure used to make decisions based on the
value of one or more logic expressions.
It allows selective execution of statements — only one branch of code is executed depending on whether the
condition evaluates to true (1) or false (0).
This construct is fundamental for describing behavioral models, control flow, and conditional logic inside
always or initial procedural blocks.
• Design Guidelines
Always include an else clause to define a deterministic output → avoids latch creation.
Use @(*) in the sensitivity list for combinational logic to ensure all signals are monitored.
For clocked logic (sequential), use @(posedge clk) or @(negedge clk) with non-blocking assignments.
Use begin ... end when multiple statements follow an if or else.
10 of
Conditional Constructs
• Case Statements
The case statement in Verilog is a multi-branch decision structure.
It compares one expression against multiple constant values and executes the matching branch.
It provides a cleaner and more parallel alternative to multiple if–else if chains.
Each case item can contain one or more values, and the default branch handles unmatched cases.
• Design Rules and Cautions
• Always include a default case → ensures defined output.
• Avoid overlapping case values (leads to undefined behavior).
• Prefer casez over casex to prevent simulation mismatches.
• For SystemVerilog, use:
• unique case → ensures only one branch matches.
• priority case → similar to nested if–else.
11 of
Conditional Constructs
• Looping Statements
Looping statements repeat a group of statements multiple times under specific conditions.
They are used in testbenches, algorithmic descriptions, and data initialization.
In synthesizable designs, only deterministic loops (fixed bounds) are allowed.
Loop Type Description Typical Use
forever Repeats infinitely Clock generation
repeat(n) Executes a block n times Finite repetition
while (cond) Executes while condition is Dynamic iteration
true
for (init; cond; step) Iterates with counter Array access, index-based
variable loops
disable Stops a named block early Early termination
12 of
System Tasks
• System tasks are predefined Verilog functions used to display information, control simulation, and
manage files.
• They are not synthesizable — only used in testbenches.
• All system tasks start with the $ symbol.
• Display and Monitoring Tasks
1. $display – Print Message Once
Prints text and variable values once, at the time it is executed.
Can include format specifiers, similar to C’s printf().
13 of
System Tasks
2. $write – Continuous Print Without Line Break
• Similar to $display, but does not insert a newline automatically.
• Useful for printing data in the same line or formatted tables.
3. $monitor – Automatic Change Tracking
• Continuously monitors listed signals.
• Prints updated values whenever any signal in the list changes.
4. $strobe – Print at End of Current Time Step
• Similar to $display, but delays printing until the end of the current simulation time unit.
• Useful when multiple updates occur in the same time step.
14 of
System Tasks
File I/O task
5. $fopen and $fclose
• $fopen("filename") opens a file for writing or reading.
• $fclose(file_descriptor) closes the opened file.
• Returns a file descriptor (integer) used for subsequent operations.
6. $fdisplay, $fwrite, $fmonitor
Task Description Line End
$fdisplay Print to file (like $display) Adds newline
$fwrite Print to file continuously No newline
$fmonitor Monitor signals to file Auto-updates
15 of
System Tasks
File I/O task
7. $readmemb and $readmemh
• Used to initialize memory arrays from files.
• $readmemb → binary format file
• $readmemh → hexadecimal format file
16 of
System Tasks
Simulation Control Tasks
8. $time and $realtime
• $time returns current simulation time as an integer.
• $realtime returns the exact simulation time as a floating-point value.
9. $stop and $finish
Task Description Simulation Effect
Pauses simulation; can
$stop Halts temporarily
resume later
Terminates simulation
$finish Ends simulation
completely
17 of
System Tasks
Simulation Control Tasks
10. $dumpfile and $dumpvars
• Used to create waveform files (VCD – Value Change Dump) for post-simulation analysis.
• Supported by tools like GTKWave.
Summary Table
Category System Task Description Typical Use
$display, $write,
Display Print messages and signals Console logging
$strobe
Monitor $monitor Auto-update on signal change Signal tracing
$fopen, $fdisplay,
File I/O Read/write files Memory init, logs
$fwrite, $readmemh
Simulation Control $time, $stop, $finish Time and flow control End or pause sim
Debug / Waveform $dumpfile, $dumpvars Generate waveform file Visual debug
18 of
Testbench Design
• A testbench is a non-synthesizable Verilog environment used to verify and validate the functionality
of a hardware design, called the DUT (Design Under Test).
• It applies stimulus signals to the DUT, observes the outputs, and checks whether the DUT behaves as
expected.
• Structure of a Testbench
Component Description
DUT (Design Under Test) The module being tested
Stimulus Generator Generates inputs for DUT
Clock / Reset Generator Provides timing reference
Monitor Observes DUT outputs
Checker Compares actual output vs. expected
output
System Tasks Display, log, control simulation
19 of
Testbench Design
Common Stimulus Generation Techniques
• A testbench is a non-synthesizable Verilog environment used to verify and validate the functionality
of a hardware design, called the DUT (Design Under Test).
• It applies stimulus signals to the DUT, observes the outputs, and checks whether the DUT behaves as
expected.
Component Description
• Structure of a Testbench
DUT (Design Under Test) The module being tested
Stimulus Generator Generates inputs for DUT
Clock / Reset Generator Provides timing reference
Monitor Observes DUT outputs
Checker Compares actual output vs. expected
output
System Tasks Display, log, control simulation
20 of
Testbench
1. Static (Manual) Stimulus
• Simplest form — values are directly assigned in the initial block.
• Useful for debugging small designs or initial verification.
2. Sequential (Pattern-Based) Stimulus
• Inputs are applied following a time-based pattern (e.g., every 10 ns).
• Common for simulating timed input sequences.
3. Algorithmic Stimulus
• Uses loops or mathematical relationships to generate inputs systematically.
• Helps in structured testing (e.g., testing all combinations).
21 of
Testbench
4. File-Based Stimulus
• Reads input test vectors from external files (text, CSV, or memory files).
• Ideal for large test sets or real-world datasets.
5. Randomized Stimulus
• Uses Verilog’s built-in $random or $urandom functions.
• Good for stress testing and corner-case detection.
22 of
Testbench
7. Clock and Reset Generation
• Essential for synchronous designs.
• Commonly generated using forever loops and delays.
8. Combination of Techniques
Realistic testbenches often combine multiple stimulus generation methods:
23 of
Testbench
9. Practical Guidelines
Rule Recommendation
Include timing control (#delay) Prevents simultaneous signal changes
Initialize all signals Avoids unknown (‘X’) values
Keep reset active at start Ensures DUT starts cleanly
Use $display and $monitor For easy debugging
Log test results $fdisplay to record output
End simulation with $finish Avoid infinite runs
24 of
Testbench
Printing Results to the Simulator Transcript
• In Verilog simulation, the simulator transcript (console window) displays text
messages from the testbench or DUT.
• Used for debugging, monitoring signals, and reporting simulation progress.
Main System Tasks
Task Description Adds Newline Typical Use
Prints message once
$display Yes One-time messages
immediately
Prints message without line
$write No Inline output
break
Prints after all signal updates
$strobe Yes Stable post-update values
at current time step
Automatically prints when any
$monitor Yes Continuous monitoring
listed variable changes
25 of
Testbench
1. Format Specifiers
Used inside print strings:
%d (decimal), %b (binary), %h (hex), %t (time), %s (string), %0t (formatted time).
2. Using $monitor
3. Printing to Files
$fdisplay, $fwrite – same behavior as $display / $write, but send output to a file.
26 of
Testbench Example Printing Results to the Simulator
Transcript
27 of
Testbench
• Automatic Result Checking
Automatic result checking is the process of allowing a testbench to evaluate the
DUT outputs automatically and determine whether they match the expected
(golden) results.
• The testbench acts as a self-verifying environment.
• It compares the DUT output to an expected value computed within the testbench.
• If mismatches occur, error messages are printed to the simulator transcript.
Benefit Description
Automation No manual checking needed
Accuracy Reduces human error
Regression testing Enables repeated runs automatically
Speed Faster detection of functional bugs
Scalability Works even with large test vector sets
28 of
• Testbench Example Automatic Result Checking
29 of
• Testbench Example Using Loops to Generate Stimulus
• Using Loops to Generate Stimulus
• In Verilog testbenches, loops (for, repeat, while, forever) are often used to
automatically generate input patterns (stimulus) for the Design Under Test
(DUT).
• This makes testing faster, cleaner, and more scalable, especially when you need to
apply many test vectors.
Loop Type Description Typical Use
for Executes a block a fixed number of times Systematic testing of multiple inputs
repeat(n) Repeats a block n times Simple fixed iteration
while (condition) Repeats while condition is true Dynamic stimulus generation
forever Repeats infinitely Clock generation or continuous toggling
30 of
Testbench
31 of
Testbench
Using External Files in Test Benches
• In Verilog, external files (such as .txt, .dat, or .mem) can be used within a
testbench to:
• Provide input test vectors to the DUT automatically
• Store simulation outputs or log results
• Import large datasets for functional or memory verification
Purpose
Feature
and Advantages Description
Automation Load data automatically from files
Scalability Useful for large test sets
Flexibility Modify test data without editing HDL code
Traceability Save results for debugging and regression
Simulate data-driven systems like filters or
Realism
memories
32 of
Testbench
File Operation System Tasks
Task Description
$fopen("filename", "mode") Opens a file ("r", "w", "a") and returns a file descriptor
$fclose(fd) Closes an open file
$fdisplay(fd, ...) Prints formatted data to file (like $display)
$fwrite(fd, ...) Prints without newline
$fscanf(fd, "format", vars...) Reads formatted data from file
$feof(fd) Returns true when end of file is reached
$readmemb("file", array) Reads binary values into a memory array
$readmemh("file", array) Reads hexadecimal values into a memory array
33 of
Testbench Example Using External Files in Test Benches
34 of