Verilog One Stop Solution
Verilog One Stop Solution
Authored By
Kittu K Patel
(KV06 : 14/10/2030)
Preface
Introduction
Verilog is a Hardware Description Language (HDL) widely used in the design and verification
of digital circuits, including FPGAs and ASICs. It enables designers to model, simulate, and
synthesize hardware systems from simple gates to complex SoCs. Understanding Verilog is
a critical skill for any aspiring VLSI or embedded systems engineer.
Target Audience
This book is crafted for:
2
VeriCore VLSI Design
Salient Features
• 100+ conceptual explanations with real-world analogies.
Acknowledgement
I would like to express my heartfelt gratitude to everyone who encouraged me during the
creation of this book. A special thanks to Vishal Moladiya and Harekrishna Ray for
their invaluable guidance, peer reviews, and support. This book would not have reached its
current form without your honest feedback and motivation.
Feedback
Your suggestions and corrections are highly appreciated. Please share your feedback with us
at: [email protected]
“From RTL to your first real job—this book is your companion in silicon success.”
3
Contents
Preface 2
4
Contents VeriCore VLSI Design
5
Contents VeriCore VLSI Design
6
Contents VeriCore VLSI Design
7
Chapter 1 : Overview of Digital
Design with Verilog
Introduction
Verilog is a Hardware Description Language (HDL) that provides a means to describe, sim-
ulate, and synthesize digital systems such as microprocessors, memory units, and custom
ASICs. This chapter presents a comprehensive overview of digital design through the lens
of Verilog.
Learning Objectives
By the end of this chapter, you should be able to:
Pro Tip: If you know C or JavaScript, Verilog’s syntax will feel familiar—making the
learning curve smoother!
In 1995, Verilog was standardized as IEEE 1364. The evolution continued with en-
hancements in Verilog-2001 and later SystemVerilog, which added features for testbenches,
assertions, and classes.
8
Chapter 1 Overview of Digital Design with Verilog
6. Fabrication: Manufac-
ture chip or burn into FPGA
Pro Tip
Mnemonic Trick: \Smart Men Simulate Systems In Fabricated Factories" —
One word per step in the design flow.
9
Chapter 1 Overview of Digital Design with Verilog
Pro Tip
Career Tip: Verilog is your ticket to internships and full-time VLSI roles. Start projects
and share them on GitHub and LinkedIn!
Theory
1. Describe the historical evolution of Verilog.
10
Chapter 1 Overview of Digital Design with Verilog
Output-Based
1. Predict the behavior of a Verilog ‘always‘ block with blocking assignment.
Summary
• Verilog is a widely used HDL for modeling digital systems.
Pro Tip
Final Insight: Focus on simulation and modeling first. Don’t rush into synthesis—get
your logic right!
11
Chapter 2: Hierarchical Modeling
Introduction
Hierarchical modeling is a foundational concept in digital design, where systems are broken
down into smaller, manageable components called modules. This enables the designer to ap-
proach complex problems with modular design principles, enhancing readability, reusability,
and scalability of Verilog code.
Verilog’s support for hierarchy allows us to:
Learning Objectives
• Understand the principle and benefits of hierarchical modeling.
• Bottom-up design: Smaller blocks are designed first, then integrated to form the
complete system.
12
Chapter 2 Hierarchical Modeling
Top-Level System
Module A Module C
Module B
Pro Tip
Pro Tip: Modularize your code as early as possible! This helps you simulate and debug
each block independently.
Analogy:
Imagine you’re building a car. You wouldn’t design it as one massive blueprint—you’d
create separate designs for the engine, wheels, and electronics, then assemble them. That’s
hierarchical modeling in action!
2.2 Module
A module is the fundamental building block in Verilog. Every hardware component or
system is described as a module. It may represent a logic gate, an ALU, or even a full CPU.
Syntax of a Module
module module_name (input_ports, output_ports);
// declarations
// functionality
endmodule
13
Chapter 2 Hierarchical Modeling
Pro Tip
Pro Tip: Always use meaningful names for ports and modules. It helps when you debug
large designs!
2.3 Instance
Instantiation is the process of using one module inside another. You can think of it like
calling a function in programming—only here, you’re plugging in hardware blocks.
Analogy:
If a module is a blueprint of a house, instantiation is like building actual houses from the
same blueprint but placing them in different locations with different paint colors or features.
14
Chapter 2 Hierarchical Modeling
Pro Tip
Pro Tip: Prefix your instance names (like u1, inst ) to track them easily during simu-
lation and debugging.
Top Module
Decoder Adder
Best Practices
• Keep each module focused on a single function.
2. Testbench
A non-synthesizable module that drives the inputs to the DUT and monitors the outputs.
15
Chapter 2 Hierarchical Modeling
3. Stimulus Generator
Provides changing input values to the DUT to validate different functionalities.
4. Monitor
Watches the output signals of the DUT and logs or displays them.
5. Checker
Compares DUT outputs with expected values and flags errors.
Pro Tip
Pro Tip: Break your testbench into generator, monitor, and checker blocks for better
modularity and reuse.
Testbench DUT
Stimulus GeneratorMonitor
Checker
1. initial Block
Executes once at simulation start.
initial begin
// Simulation-only behavior
end
2. always Block
Executes indefinitely in a loop as long as simulation runs.
16
Chapter 2 Hierarchical Modeling
Pro Tip
Trick to Remember:
initial – like a “main()” in C, runs once.
always – like a “while(1)” loop, runs forever!
‘timescale 1ns/1ps
Common Use-Cases
• Apply stimulus to DUT
Pro Tip
Pro Tip: Use waveform viewers (like GTKWave) to visualize the simulation time-
line—great for debugging!
17
Chapter 3 Basic Concepts
Code-Based Questions
1. Write a Verilog code for a 4-bit ripple carry adder using hierarchical modules.
2. Modify a testbench to toggle the reset signal after 10 time units.
3. Create a module and instantiate it twice in a top-level design.
4. Use delays and event controls to simulate a D Flip-Flop.
5. Debug a hierarchical design with incorrect instance connections.
Pro Tip
Pro Tip: For each Verilog module you write, create a testbench that stimulates *all*
input cases for maximum coverage.
2.7 Summary
In this chapter, we explored hierarchical modeling in Verilog, one of the most powerful ways
to scale designs. Here’s what we covered:
• Modules in Verilog are like reusable building blocks.
• Hierarchy is established by instantiating modules within other modules.
• The simulation process requires a testbench, a DUT, and simulation tools.
• initial and always blocks form the heart of Verilog simulations.
• Delays and event controls allow temporal modeling.
Pro Tip
Trick: Always begin designing from the bottom-up (build modules) or top-down (define
structure first)—but never both at the same time!
Learning Outcomes
• Understand and use hierarchical modeling in Verilog.
• Create, instantiate, and simulate Verilog modules.
• Use simulation blocks like initial, always, and delays properly.
• Build structured testbenches that interact with DUTs efficiently.
“Think modular, code reusable, simulate always — that’s the Verilog way!”
18
Chapter 3: Basic Concept
Introduction
In digital design, mastering Verilog begins with understanding its basic building blocks.
This chapter covers the essential syntax, data types, variables, and structures used to write
functional and efficient code. A solid grasp of these concepts is vital before diving into more
complex design styles.
Learning Objectives
• Understand the lexical rules and conventions used in Verilog.
• \t – Horizontal Tab
• \b – Backspace
Pro Tip
Use escape sequences while printing strings using system tasks like $display for format-
ting output.
19
Chapter 3 Basic Concepts
20
Chapter 3 Basic Concepts
• \n – Newline
• \t – Tab
• \b – Backspace
Pro Tip
Use whitespace generously to improve code readability. Although Verilog ignores it, hu-
mans don’t!
3.2.2 Comments
Verilog supports two types of comments:
• // Single-line comment
• /* Multi-line comment */
// Valid identifiers:
reg clk_1;
wire _enable;
integer \abc$def; // Escape identifier
21
Chapter 3 Basic Concepts
3.2.4 Literals
Verilog literals can be signed or unsigned, and may also include undefined or high-impedance
states.
Examples:
Pro Tip
Unsigned numbers roll over on overflow. Use signed when dealing with negative values!
22
Chapter 3 Basic Concepts
Ignore Whitespace
Parse Identifiers
Parse Literals
Handle Comments
23
Chapter 3 Basic Concepts
reg clk;
reg [7:0] count;
Pro Tip
Use reg inside procedural blocks and wire outside them for connections!
integer i;
Note: Can be used in loops but not synthesizable for hardware mapping.
real pi;
initial pi = 3.14159;
time delay;
delay = $time;
—
Difference Table
Pro Tip
Always assign reg in initial or always blocks. Use assign only for wire types.
24
Chapter 3 Basic Concepts
Input Signal
Wire
Output
3.4 Vectors
In Verilog, vectors are used to represent buses or multi-bit signals. A vector groups multiple
scalar wires or regs into a single entity.
3.4.1 Syntax
wire [3:0] data; // 4-bit vector (data[3] down to data[0])
reg [7:0] count; // 8-bit register
Note: The index is specified as [MSB:LSB]. Verilog supports both big-endian (MSB to
LSB) and little-endian declarations.
Pro Tip
Tip: When using vectors, always double-check bit ordering. [7:0] counts from 7 down
to 0!
3.5 Arrays
Verilog supports arrays of regs or nets (from Verilog-2001 onward). Arrays help in organizing
repetitive hardware like registers, memory banks, etc.
25
Chapter 3 Basic Concepts
Access:
register_file[2] = 8’hFF;
mem_2d[1][2] = 4’b1010;
Pro Tip
Analogy: Think of a 2D array like an Excel sheet with rows and columns storing digital
data.
—
3.6 Memories
In Verilog, a memory is essentially a one-dimensional array of vectors.
3.6.1 Declaration
reg [7:0] memory [0:255]; // 256 locations, each 8-bit wide
Pro Tip
Pro Tip: Verilog memories do not support multi-port access by default — you must
model it!
—
Block Diagram – Memory Block Access
26
Chapter 3 Basic Concepts
Clock
3.7.1 Syntax
parameter WIDTH = 8;
reg [WIDTH-1:0] data_bus;
27
Chapter 3 Basic Concepts
Pro Tip
Pro Tip: Always prefer named parameter overriding. Avoid using defparam in modern
Verilog for better readability and tool support.
initial begin
$display("Simulation starts at time %t", $time);
$monitor("a = %b, b = %b, out = %b", a, b, out);
end
28
Chapter 3 Basic Concepts
3.9.2 Example
‘define WIDTH 8
reg [‘WIDTH-1:0] my_bus;
Pro Tip
Trick to Remember: Think of ‘define like a search-and-replace command for your
code!
—
Practice Questions
// Q2
parameter WIDTH = 4;
reg [WIDTH-1:0] b;
initial begin
b = 4’b1010;
$display("b = %b", b);
end
—
Summary
29
Chapter 3 Basic Concepts
• Memories store multiple data locations and are used for RAM/ROM models.
• System tasks like $display, $monitor are essential for simulation output.
Learning Outcome:
• You can now differentiate between data types and storage styles in Verilog.
“In Verilog, simplicity lies in structure — think in modules, wires, and clocks.”
30
Chapter 4: Modules and Ports
Introduction
Verilog’s design structure is fundamentally based on the use of modules. Each design unit
is modeled as a module, containing ports for communication, and internal logic to define its
functionality. This modularity promotes reuse, readability, and scalability in digital system
design.
Learning Objectives
• Understand the structure and importance of Verilog modules.
4.1.1 Syntax
verilog module (module name) (port list);
// Declarations
// Functionality
endmodule
31
Chapter 4 Modules and Ports
Pro Tip
Pro Tip: Think of modules like LEGO blocks — you can build anything by combining
simple, reusable pieces!
32
Chapter 4 Modules and Ports
Input Output
Module
Inout
Pro Tip
Pro Tip: Always declare port directions explicitly! Verilog infers wires by default —
which may cause synthesis issues if not declared correctly.
• Positional Association: The ports are connected in the order they are defined.
7 module top ;
8 wire x , y , z , s , c ;
9 full_adder fa1 (x , y , z , s , c ) ; // Positional mapping
10 endmodule
33
Chapter 4 Modules and Ports
7 . sum ( s ) ,
8 . cout ( c )
9 );
10 endmodule
Pro Tip
Pro Tip: Prefer named associations for better readability and error prevention, especially
in large designs.
Example:
1
2 module top ;
3 wire d , clk , q ;
4 dff d1 (. d ( d ) , . clk ( clk ) , . q ( q ) ) ;
5 endmodule
If you want to monitor signal q inside dff, you can refer to it as:
verilog top.d1.q
Pro Tip
Pro Tip: Avoid writing to hierarchical signals. Hierarchical referencing is best used for
monitoring, not design.
Practice Questions
Theoretical:
1. What are the different ways to connect ports in Verilog?
34
Chapter 4 Modules and Ports
Summary
• Modules are the building blocks of Verilog designs.
Learning Outcome:
35
Chapter 5: Gate Level Modelling
Introduction
Gate-level modelling represents the most basic level of abstraction in digital design. It deals
directly with logic gates and their interconnections. This style is essential for understanding
how synthesized logic maps onto physical gates.
Learning Objectives
• Understand the different types of logic gates available in Verilog.
• not – Inverter
• buf – Buffer
36
Chapter 5 Gate Level Modelling
Pro Tip
Pro Tip: Think of gates as mathematical functions. An AND gate is like multiplication:
1 * 1 = 1, everything else is 0.
Pro Tip
Trick to Remember:
Think of AND as ”both must be true”, OR as ”either can be true”, XOR as ”only
one must be true”, and NAND as ”AND but inverted”.
• NOR Gate: Inverted output of OR. Output is high only when both inputs are low.
37
Chapter 5 Gate Level Modelling
• XNOR Gate: Inverted output of XOR. True when inputs are equal.
Pro Tip
Hardware Hint:
NAND and NOR gates are known as Universal Gates — any digital logic can be im-
plemented using just these two!
Explanation
The output will update 5 time units after both inputs become valid. Use this in
testbenches to visualize delays.
Pro Tip
Use multiple delay values to model real-world rise and fall transitions of gates.
38
Chapter 5 Gate Level Modelling
2. What are the possible values that a signal can take in Verilog?
2. Given a NOT gate connected to a wire initialized to 1, what will be the delayed output?
3. Trace the waveform of a 2-input NAND gate over a 10-time unit simulation.
Pro Tip
In waveform viewers (like GTKWave or ModelSim), gate delays help visualize timing,
races, and glitches. Always simulate your design even if delays are not synthesized.
39
Chapter 5 Gate Level Modelling
5.5 Summary
• Gate-level modeling represents logic using basic gates such as AND, OR, NOT, NAND,
NOR, XOR, and XNOR.
• Truth tables and diagrams are essential for understanding gate operations.
Learning Outcome:
“Logic gates are the atoms of digital design — master them to build anything!”
40
Chapter 6: Data Flow Modelling
Introduction
Dataflow modeling is one of the core abstraction styles used in Verilog to describe how data
moves through a design using continuous assignments. Unlike gate-level or behavioral mod-
eling, dataflow emphasizes *how data flows* between signals based on logical or arithmetic
operations, without explicitly describing how it’s implemented.
41
Chapter 6 Data Flow Modelling
Gate-Level Modeling
Dataflow Modeling
Behavioral Modeling
Comparison Table:
Real-World Analogy
Think of dataflow modeling like water pipelines: you don’t worry about each pipe’s
structure but just how water (data) flows from tank (input) to faucet (output) through
connections (assignments).
42
Chapter 6 Data Flow Modelling
Learning Objectives
• Understand the purpose and application of dataflow modeling in Verilog.
• Learn about the ‘assign‘ statement and how continuous assignments work.
“Flow the logic, not the gates — that’s the dataflow mindset.”
Definition
A continuous assignment describes a logic expression that is continuously evaluated and
assigned to a net. Any change in the right-hand-side variables automatically triggers re-
evaluation and updates the output.
43
Chapter 6 Data Flow Modelling
Explanation: This implements a simple 2-to-1 multiplexer. When sel=1, y=b; other-
wise, y=a.
44
Chapter 6 Data Flow Modelling
Interview Insight
Pro Tip
Always remember that assign statements work best for modeling combinational logic.
They’re synthesizable and resemble actual gate-level hardware more closely than pro-
cedural logic.
Practice Questions
1. What is the main difference between continuous and procedural assignments?
45
Chapter 6 Data Flow Modelling
Key Takeaways:
“With assign, you define how data flows — no clocks, no waits, just logic.”
If input changes last less than 5 units, the output remains unchanged.
46
Chapter 6 Data Flow Modelling
• A single delay
Real-World Examples
Example 1: Basic Delay
1 assign #3 y = a ^ b ;
Pro Tip
Delays are ignored during synthesis but are vital in simulation. Use them in testbenches
to accurately test real-time behavior.
47
Chapter 6 Data Flow Modelling
• Multiple delay types are supported: single, rise/fall, and full delays.
• Always simulate with delays to visualize waveform behaviors, but avoid them in syn-
thesis code.
Learning Outcome
• Understand different types of delays and their syntax in Verilog.
Syntax:
1 assign out = expression ;
Operands in Verilog
Operands are the basic data items on which operations are performed. They may include
constants, wires, or even another expression.
48
Chapter 6 Data Flow Modelling
Types of Operators
Verilog offers various operators, categorized as:
2. Relational Operator:
1 assign is_greater = ( a > b ) ;
2 assign is_equal = ( a == b ) ;
3. Logical Operator:
1 assign logic_result = ( a && b ) || (! c ) ;
4. Bitwise Operator:
49
Chapter 6 Data Flow Modelling
5. Shift Operator:
1 assign left_shift = a << 2;
2 assign right_shift = b >> 1;
7. Reduction Operator:
1 assign any_bit_high = | a ;
2 assign all_bits_low = ~| a ;
8. Conditional Operator:
1 assign out = ( sel ) ? a : b ;
• Multiplicative: *, /, %
• Additive: +, -
• Equality: ==, !=
• Bitwise: &, |, ^
• Logical: &&, ||
• Conditional: ? :
50
Chapter 6 Data Flow Modelling
Pro Tip
Always use parentheses to clarify precedence in complex expressions. It not only
reduces bugs but makes your code more readable.
“Think of dataflow modeling as plumbing logic—where signals flow like water through gates
and pipes!”
Explanation: This is the simplest form of logic gate. Think of it like a door that only
opens when both switches (inputs) are ON.
Analogy: Like a streetlight system where light turns ON if any one sensor detects motion.
51
Chapter 6 Data Flow Modelling
Analogy: Like a train junction that decides which track to follow based on a lever (selector).
Explanation: Adds two 1-bit values, just like primary school math.
Example 8: Comparator
52
Chapter 6 Data Flow Modelling
53
Chapter 6 Data Flow Modelling
54
Chapter 6 Data Flow Modelling
Pro Tip
You can simulate all the above examples using tools like ModelSim or EDA Playground.
Try changing input values to visualize how logic flows!
Q5. Design a 4-input OR gate and simulate it with all combinations of inputs.
Q8. Design a module that performs bitwise XOR of two 8-bit numbers.
Q9. Build a module to compute the modulus (%) of two 4-bit numbers.
Q10. Write a Verilog code for multiplying two 4-bit numbers using ‘*‘.
55
Chapter 6 Data Flow Modelling
Q14. Implement a parity generator using the reduction XOR (ˆ) operator.
Q18. Concatenate two 4-bit inputs and store the result in an 8-bit output.
Q19. Create a barrel shifter using assign statements (hint: use shifts).
Q22. Implement a 4-bit full adder using four 1-bit full adders.
56
Chapter 6 Data Flow Modelling
Pro Tip
Tip: Start writing these on simulation platforms like ModelSim or EDA Playground to
test your syntax and logic. Simulating is the best way to validate and learn!
57
Chapter 6 Data Flow Modelling
58
Chapter 6 Data Flow Modelling
6.7 Summary
In this chapter, we explored the foundations of Dataflow Modeling in Verilog, one of the
most intuitive and efficient ways to describe hardware behavior using continuous assignments.
Below is a recap of all important concepts covered:
• Continuous Assignments: Defined using the assign keyword, suitable for combi-
national logic.
• Delay Types:
• Expression Components:
• Operator Types: Covered in depth with syntax, examples, and application tips.
• Pro Tips: Coding best practices, synthesis tips, and simulation advice were provided
to guide both beginners and advanced learners.
59
Chapter 6 Data Flow Modelling
Key Takeaway
Dataflow modeling is ideal for describing simple combinational circuits. It provides a
clean, readable, and hardware-accurate way of connecting expressions to outputs using
the assign keyword.
Dataflow Modeling
60
Chapter 7: Behavioral Modeling
Introduction
Behavioral modeling in Verilog allows designers to describe the functionality of a digital
system rather than its structural implementation. It focuses on what the system does, not
how it is physically realized with gates or data paths.
61
Chapter 7 Behavioral Modeling
Pro Tip
Use behavioral modeling to define sequential behavior and test logic. Keep it RTL-
compliant for synthesis, and fully expressive for testbenches!
Key Takeaway: Behavioral modeling is the highest abstraction level in Verilog. It empow-
ers you to describe complex logic in compact, readable, and expressive ways.
“Behavioral modeling brings your ideas to life—by telling the system what to do, not how to
do it.”
Learning Objectives
Objective Map
Behavioral modeling is the heart of algorithmic digital design. These objectives will
help you grasp the essence of control structures, sequential logic, and design abstrac-
tion.
62
Chapter 7 Behavioral Modeling
2. Differentiate between blocking and non-blocking assignments and know when to use
each.
3. Apply timing controls like delay control (#), event control (@), and level-sensitive
constructs.
5. Use sequential and parallel blocks to describe concurrent and ordered logic flows.
63
Chapter 7 Behavioral Modeling
Pro Tip
Behavioral modeling is used in 90% of simulation and verification tasks. Master it to
enhance your coding and debugging skills in both industry and academia!
64
Chapter 7 Behavioral Modeling
• Not synthesizable.
65
Chapter 7 Behavioral Modeling
Pro Tip
Use initial blocks in testbenches to apply stimulus or set default values. Use always
blocks when describing logic based on clocks or input changes.
7.1.5 Summary
• initial blocks run only once and are perfect for stimulus generation in testbenches.
• always blocks run continuously and form the backbone of synthesizable RTL.
• Understanding when and where to use each block is key to effective Verilog modeling.
66
Chapter 7 Behavioral Modeling
Key Characteristics:
• Easier to debug.
67
Chapter 7 Behavioral Modeling
Key Characteristics:
• Executes in parallel.
68
Chapter 7 Behavioral Modeling
Start Clock Edge Evaluate RHS (b) Start Clock Edge Evaluate RHS (b, a)
End of Blocking
Pro Tip
Golden Rule: Never mix blocking and non-blocking assignments in the same always
block. It may cause unpredictable simulation results!
7.2.6 Summary
• Blocking (=) executes sequentially — best for combinational logic.
• Non-Blocking (<=) executes concurrently — ideal for sequential logic.
• Use non-blocking in always @(posedge clk) for safe and reliable RTL code.
• Mixing both types in the same block is a common source of bugs — avoid it!
Introduction
Conditional logic is fundamental to any digital system, allowing the circuit to behave differ-
ently depending on inputs or internal states. In Verilog, the most commonly used conditional
statement is the ‘if‘ statement.
69
Chapter 7 Behavioral Modeling
Analogy
Think of conditional statements like a traffic signal system. If the light is green,
vehicles move. If it’s red, they stop. This simple decision-making mechanism governs
how the circuit reacts to different situations.
Start
Is condition true?
Yes No
Execute Execute
True Block False Block
Continue
• Control units
70
Chapter 7 Behavioral Modeling
• Priority encoders
Quick Recap:
71
Chapter 7 Behavioral Modeling
Comparison Table
Statement Ignores ‘x‘ Ignores ‘z‘
case No No
casex Yes Yes
casez No Yes
Pro Tip
Use casex and casez with caution in synthesis as they may result in unexpected logic
due to wildcard matching.
72
Chapter 7 Behavioral Modeling
• casex treats ‘x‘ and ‘z‘ as wildcards — good for simulation, not synthesis.
• casez ignores only ‘z‘ — better than casex for synthesis use.
Analogy
Think of loops like an assembly line machine: you instruct it to stamp a part multiple
times until the job is complete. In Verilog, loops allow similar repetition of tasks in
code.
• for loop
• while loop
• repeat loop
• forever loop
73
Chapter 7 Behavioral Modeling
1. for Loop
The for loop is the most common loop in Verilog. It is counter-based and resembles the
loop syntax in C/C++.
Syntax: “‘verilog for (initialization; condition; increment) begin // Statements end
Example: Generating 8-bit test pattern module forexample; integer i; reg [7:0]
pattern; initial begin for (i = 0; i ¡ 8; i = i + 1) begin pattern[i] = 1’b1; end end endmodule
2. while Loop
The while loop executes as long as a condition is true. However, it is generally not synthe-
sizable due to potential infinite looping.
Syntax: while (condition) begin // Statements end Example: Toggle signal until
condition met module whileexample; reg clk; integer count = 0; initial begin clk = 0; while
(count ¡ 5) begin #5 clk = clk; count = count + 1; end end endmodule
3. repeat Loop
The repeat loop executes a block of statements a fixed number of times. Often used in
clocked designs.
Syntax: repeat (n) begin // Statements end
Example: Repeat clock toggle 10 times module repeatexample; reg clk; initial begin
clk = 0; repeat (10) begin #5 clk = clk; end end endmodule
4. forever Loop
The forever loop runs indefinitely and is used mostly in testbenches and clock generation.
Syntax: forever begin // Statements end Example: Clock generator using forever
module foreverexample; reg clk; initial begin clk = 0; forever #5 clk = clk; end endmodule
Pro Tip
Always add appropriate conditions or delay in loops like while and forever to avoid
infinite loops and simulation hangs.
74
Chapter 7 Behavioral Modeling
Quick Checklist:
Pro Tip
Use case for synthesis-safe design. Avoid casex unless you fully understand how X/Z
values propagate in simulation.
75
Chapter 7 Behavioral Modeling
76
Chapter 7 Behavioral Modeling
Best Practices
• Always include a default case to avoid latches.
Pro Tip
Always initialize your output in a case structure or use a default path to prevent latch
inference during synthesis.
Learning Outcome
After completing this section, students should be able to:
77
Chapter 7 Behavioral Modeling
• while loop
• repeat loop
• forever loop
78
Chapter 7 Behavioral Modeling
Detailed Examples
1. for Loop
2. while Loop
3. repeat Loop
4. forever Loop
reg clk = 0; initial begin forever begin #5 clk = clk; // toggle clock every 5 time units end
end
Pro Tip
Use forever loops only with proper delay elements like # or (posedge clk) to prevent
simulation from hanging.
Interview Trick
You may be asked: “Is this code synthesizable?” Always analyze if the loop bounds and
contents are deterministic and finite. If not, it’s for simulation only.
79
Chapter 7 Behavioral Modeling
Syntax
initial begin
statement1;
statement2;
statement3;
end
Example
Output:
Time 0: Start
Time 10: Middle
Time 20: End
80
Chapter 7 Behavioral Modeling
Syntax
initial fork
statement1;
statement2;
statement3;
join
Example
Output:
Time 2: C
Time 5: A
Time 10: B
81
Chapter 7 Behavioral Modeling
Pro Tip
Pro Tip
Always ensure to use fork...join with care inside testbenches, especially when one
of the processes never terminates — it can cause the simulation to hang!
Output:
Time 5: Task 1 done
Time 10: Task 2 done
Interview Insight
• fork ... join is often asked in testbench-related interviews.
• Trick: If you use fork inside a procedural block, all forks must finish or the simulation
may get stuck.
82
Chapter 7 Behavioral Modeling
Learning Objectives
• Understand the difference between delay control and event control.
\item Use ‘#‘, ‘@‘, and ‘wait‘ for controlling simulation time and event flow.
Syntax
#time; // Waits for ’time’ units
Syntax
@(event_expression); // Waits until event_expression becomes true
83
Chapter 7 Behavioral Modeling
Syntax
wait(condition); // Suspends execution until condition is true
initial begin
wait(clk == 1);
$display("clk is HIGH at time %0t", $time);
end
Output:
Explanation: This waits until ‘clk‘ becomes ‘1‘, regardless of how long it takes.
Pro Tip
Pro Tip
Avoid putting wait inside infinite loops without an escape condition. It may lead to
simulation deadlock if the condition never becomes true.
84
Chapter 7 Behavioral Modeling
85
Chapter 7 Behavioral Modeling
• Loops available:
• Grouping statements:
• Avoid using ‘fork ... join‘ in synthesizable code. Use only for testbenches.
86
Chapter 8: Task and Function
Introduction
In Verilog, reusable blocks of code are essential for improving readability, modularity, and
scalability of complex designs. Tasks and functions serve this purpose by encapsulating
frequently used operations. While both can be invoked from procedural blocks, they differ
significantly in their usage and capabilities.
This chapter covers both in detail, helping you distinguish when and how to use them
effectively in real-world Verilog projects.
Learning Objectives
• Understand the purpose and syntax of tasks and functions.
Why It Matters
Tasks and functions help you avoid repetition, reduce errors, and improve code main-
tainability in Verilog. Whether writing RTL or testbenches, mastering these will boost
your efficiency and skillset.
87
Chapter 8 Task and Function
Syntax of a Task
Task Syntax
task task_name;
input [bit_width] input_name;
output [bit_width] output_name;
inout [bit_width] inout_name;
// Task body
begin
// Statements
end
endtask
Key Features
• Can include delays (#) and event control (@).
• Can return multiple values using output and inout.
• Used for simulation and behavioral modeling.
• Cannot be used directly in continuous assignments.
initial begin
print_number(4);
end
Output: Number is: 4
88
Chapter 8 Task and Function
initial begin
multiply(3, 4, res);
$display("Result: %d", res);
end
Output: Result: 12
initial begin
delay_print(5);
end
Pro Tips
• Tasks are powerful in testbenches and can simplify repeated sequences.
• Always use output and inout for returning values—functions cannot do that.
• Avoid using tasks with delays in RTL blocks intended for synthesis.
• Use meaningful task names like add two nums, reset dut, etc.
89
Chapter 8 Task and Function
Start
Task Call
Execute Statements
Return Control
End
What is a Function?
A function in Verilog is a reusable block of code that returns a single value. Functions are
primarily used for combinational logic without any timing delays.
• They cannot include time-consuming operations like delays (#), event controls
(@), or wait statements.
• All inputs must be passed by value — there are no output or inout ports.
90
Chapter 8 Task and Function
Syntax of a Function
Function Syntax
function [bit_width] function_name;
input [bit_width] arg1;
input [bit_width] arg2;
begin
function_name = expression;
end
endfunction
—
Examples of Functions in Verilog
initial begin
$display("Sum = %d", add(2, 3));
end
Output: Sum = 5
initial begin
$display("Max = %d", max_val(8, 12));
end
Output: Max = 12
91
Chapter 8 Task and Function
initial begin
$display("AND = %b", and_func(4’b1101, 4’b1011));
end
Pro Tips
• Use functions to simplify combinational logic like arithmetic, comparisons, and
encoding.
• Best suited for hardware logic that’s fast, predictable, and simple.
92
Chapter 8 Task and Function
initial begin
$display("Sum = %d", adder(5, 10)); // Output: 15
end
initial begin
show_msg("Hello");
end
93
Chapter 8 Task and Function
begin
#d;
$display("Waited for %0d time units", d);
end
endtask
94
Chapter 8 Task and Function
95
Chapter 8 Task and Function
96
Chapter 8 Task and Function
97
Chapter 8 Task and Function
4. How are input, output, and inout ports used differently in tasks and functions?
98
Chapter 8 Task and Function
initial begin
$display("%d", sum(4’d3, 4’d5));
end
task show_delay;
input [3:0] x;
begin
#x;
$display("Delayed by %d", x);
end
endtask
initial begin
show_delay(4);
end
99
Chapter 8 Task and Function
function add_numbers;
input [3:0] a, b;
add_numbers = a + b;
endfunction
task invalid_delay;
input [3:0] a;
begin
$display("Waiting...");
wait(a == 1);
end
endfunction
Design Questions
9. Design a function that counts the number of 1’s in an 8-bit input.
10. Design a task that swaps two 8-bit values using ‘inout‘.
11. Implement a function that performs a logical AND operation on two inputs and returns
the result.
12. Write a task that accepts an input and displays whether it is odd or even.
13. Design a function that performs a priority encoding for 4-bit input.
16. Create a task to generate a PWM signal (simulate with delay and display).
18. Design a task to loop through an array and print each value.
100
Chapter 8 Task and Function
• Use task when you need delays, multiple outputs, or procedural operations.
• Never insert a delay (#), event, or wait statement in a function — this violates
synthesizable code rules.
• Always verify that your task ends (no infinite waits) — to avoid simulation hang.
• Remember: A task can call another task or function, but a function can **only**
call another function.
8.6 Summary
• Verilog provides two primary subprograms: task and function, to modularize re-
peated logic.
• Tasks:
• Functions:
• While functions are preferred in RTL design (synthesizable logic), tasks are mainly
used in testbenches.
101
Chapter 8 Task and Function
• Both are reusable, modular constructs that improve code clarity, testability, and main-
tenance.
102
Chapter 9 : Useful Modelling
Technique
Introduction
In Verilog, modeling techniques are not just limited to ‘module‘, ‘initial‘, or ‘always‘ blocks.
For simulation clarity, debugging, and performance tuning, certain special modeling meth-
ods are frequently used. These include procedural assignments, conditional compilation,
timescale precision, dump files, and more. This chapter explores all these useful modeling
strategies in depth, which are especially critical in verification environments and testbench
construction.
Learning Objectives
• Understand the purpose and syntax of procedural continuous assignments (‘assign-
deassign‘, ‘force-release‘).
• Learn conditional compilation and execution techniques for flexible code testing.
• Generate and interpret waveform files using Value Change Dump (VCD).
103
Chapter 9 Useful Modelling Technique
9.0.1 assign-deassign
The ‘assign‘ statement in a procedural context behaves similarly to a continuous assignment,
except it is done within an ‘initial‘ or ‘always‘ block.
Syntax
assign <net> = <value>;
deassign <net>;
Example: “‘verilog reg clk; initial begin assign clk = 1; #5; deassign clk; // Removes
the continuous assignment end
9.0.2 force-release
The force statement overrides any existing value or driver on a signal (net or variable), and
release restores the previous value.
Syntax
force <net/var> = <value>; release <net/var>;
Example:
reg reset; initial begin force reset = 1; // Overrides all other drivers #10; release reset;
// Restores value from other sources end
104
Chapter 9 Useful Modelling Technique
Pro Tip
Pro Tip
Avoid using assign-deassign and force-release in RTL. These constructs are meant only
for simulation and can create undefined behaviors if mixed with synthesizable logic.
Common Directives
105
Chapter 9 Useful Modelling Technique
Syntax
Syntax
‘define DEBUG
module example;
...
‘ifdef DEBUG
initial $display("Debug Mode Enabled");
‘endif
endmodule
module tb;
initial begin
‘ifdef SIMULATION
$display("This is a simulation-only block.");
‘endif
$display("Testbench running...");
end
endmodule
Output (when SIMULATION defined):
Output (when SIMULATION undefined):
module check;
initial begin
‘ifdef ASIC
$display("ASIC flow selected.");
‘else
$display("FPGA flow selected.");
‘endif
end
endmodule
Output:
106
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Always end conditional compilation blocks with ‘endif to avoid errors.
• Never include hardware logic inside ‘ifdef blocks that are excluded during syn-
thesis.
• Group macro definitions at the top of the file for better readability.
Syntax
Syntax Format
‘timescale <time_unit> / <time_precision>
Example:
This means:
107
Chapter 9 Useful Modelling Technique
• 1ps is the time precision: how accurate the simulator tracks time events.
module test;
initial begin
#1 $display("1ns passed");
#2 $display("2ns more passed");
end
endmodule
Output:
108
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Always define ‘timescale at the top of every Verilog file for consistency.
• Use higher precision (e.g., 1ps) in testbenches for more accurate timing control.
• For FPGA/ASIC flow, timescale has no synthesis impact — it’s for simulation
only.
1. $display
109
Chapter 9 Useful Modelling Technique
Formats:
• %b - binary
• %d - decimal
• %h - hexadecimal
2. $monitor
Continuously prints whenever any variable in the list changes.
110
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Prefer $display for static messages and $monitor for tracking changes over
time.
• System tasks are non-synthesizable; they are used only for simulation and
debugging.
111
Chapter 9 Useful Modelling Technique
Purpose
The VCD file stores simulation signal changes in a time-stamped format, allowing the user
to examine transitions, glitches, or timing issues.
Example
module tb;
reg clk, rst;
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, tb);
end
initial begin
clk = 0;
forever #5 clk = ~clk;
112
Chapter 9 Useful Modelling Technique
end
initial begin
rst = 1;
#10 rst = 0;
end
endmodule
Waveform Viewer
Tools like GTKWave allow you to load VCD files and inspect each signal’s behavior during
simulation.
Usage:
gtkwave waveform.vcd
• You’ll see the signal transitions and can zoom/pan through time.
113
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Keep your VCD file size small by using specific levels: $dumpvars(1, module)
logs only top level.
• Use GTKWave bookmarks and hierarchy view to quickly navigate large designs.
• VCD does not capture memories or variables by default — use tools like
$dumpvars deeply or switch to FST or other formats if needed.
initial begin
assign data = clk;
#5 clk = 1;
#10 clk = 0;
deassign data;
end
endmodule
Explanation: The ‘data‘ net is connected to ‘clk‘ temporarily using ‘assign‘. Once
‘deassign‘ is executed, ‘data‘ becomes undriven.
initial begin
a = 0;
force b = a;
#5 a = 1;
#10 release b;
114
Chapter 9 Useful Modelling Technique
end
endmodule
Explanation: The value of ‘b‘ is forcibly tied to ‘a‘. Even if ‘a‘ changes, ‘b‘ follows until
‘release‘ is issued.
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, vcd_test);
a = 0; b = 1;
#5 a = 1;
#5 b = 0;
end
endmodule
115
Chapter 9 Useful Modelling Technique
initial begin
x = 0; y = 0;
#10 x = 1;
#10 y = 1;
end
endmodule
assign b = a;
initial begin
a = 0;
force b = 1; // overrides the assign
#10 release b; // returns to original assignment
end
endmodule
116
Chapter 9 Useful Modelling Technique
initial begin
clk = 0;
assign out = clk;
$display("Assigned out to clk");
#5 clk = 1;
#5 deassign out;
$display("Deassigned out");
end
endmodule
117
Chapter 9 Useful Modelling Technique
Code-Based Questions
11. Write a code to demonstrate conditional compilation using ‘ı̀fdef‘ and ‘èlse‘.
17. Simulate a D Flip-Flop and use ‘$time‘ to observe clock edge delays.
Interview-Oriented Questions
21. Explain a real scenario where ‘assign-deassign‘ can be helpful.
22. What would you recommend for temporarily overriding a signal: ‘assign‘ or ‘force‘?
Why?
24. How can timescale affect simulation resolution and delay interpretation?
25. How can you disable a portion of code during simulation without commenting it?
28. If a forced value is never released, what simulation issues may occur?
118
Chapter 9 Useful Modelling Technique
Pro Tip 2
Always pair ‘assign‘ with ‘deassign‘ and ‘force‘ with ‘release‘. Forgetting to undo forced
assignments can cause inconsistent simulations.
Pro Tip 3
Use conditional compilation (‘ı̀fdef‘ / ‘èlse‘) for debugging sections of your code —
much easier than commenting/uncommenting multiple lines.
Pro Tip 4
Generate VCD files (‘.vcd‘) and open in GTKWave to visually debug simulation be-
havior and waveform transitions in time.
Summary
• Procedural continuous assignments include ‘assign-deassign‘ and ‘force-release‘, used
primarily in simulation for overriding signal values.
• ‘force-release‘ can be used on both nets and variables, giving more flexibility during
testing.
• Conditional compilation (‘ı̀fdef‘, ‘èndif‘) helps manage design variations and debug-
specific logic during simulation.
• Timescale affects how delays are interpreted in simulation — using it correctly ensures
proper timing behavior.
• System tasks like ‘display‘, ‘monitor‘, ‘time‘, and‘dumpvars‘ help monitor and debug
simulation behavior.
• Value Change Dump (VCD) files store simulation transitions and are visualized using
tools like GTKWave.
119
Chapter 10 : Finite State Machines
(FSM) in Verilog
Introduction
Finite State Machines (FSMs) are foundational in digital design. They model systems that
move between various states based on input and timing, making them crucial for everything
from vending machines and traffic lights to protocol controllers and embedded systems.
In Verilog, FSMs are implemented using sequential logic inside always blocks, driven by
a clock signal and typically reset at startup. This chapter explains the theory and practical
implementation of FSMs in Verilog.
Learning Objectives
• Understand the concept and components of FSMs.
120
Chapter 10 Finite State Machines (FSM) in Verilog
Structure
• State Register: Stores current state.
• Next-State Logic: Determines next state based on current state and input.
121
Chapter 10 Finite State Machines (FSM) in Verilog
// State transition
always_ff @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next-state logic
always_comb begin
case(state)
IDLE: next_state = in ? S1 : IDLE;
S1: next_state = in ? S2 : IDLE;
S2: next_state = in ? S2 : IDLE;
default: next_state = IDLE;
endcase
end
122
Chapter 10 Finite State Machines (FSM) in Verilog
Pro Tip
Pro Tip
Use meaningful state names and consistent indentation to make FSM code easy to
read and debug. Use enumerated types (SystemVerilog) for improved readability and
simulation debugging.
Flowchart
in=0
in=1 in=1
IDLE S1 S2
in=1
in=0
in=0
Structure
• State Register: Stores the current state.
• Next-State Logic: Decides next state based on current state and input.
123
Chapter 10 Finite State Machines (FSM) in Verilog
// State transition
always_ff @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
124
Chapter 10 Finite State Machines (FSM) in Verilog
Flowchart
in=0
in=1
IDLE S1
in=0 in=1
Pro Tip
Pro Tip
Use non-blocking assignments for state transitions and blocking assignments for com-
binational next-state/output logic. Keep output logic separate to avoid synthesis mis-
matches or latch inference.
Use Case:
Mealy FSMs are ideal in designs where quick output response is needed without waiting for a
full state update. Examples: real-time protocol monitors, handshaking circuits, or interface
detection.
125
Chapter 10 Finite State Machines (FSM) in Verilog
• State Register
• Next-State Logic
• Output Logic
126
Chapter 10 Finite State Machines (FSM) in Verilog
// 2. Next-State Logic
always_comb begin
case (state)
IDLE: next_state = (in) ? S1 : IDLE;
...
endcase
end
// 3. Output Logic
always_comb begin
case (state)
...
endcase
end
127
Chapter 10 Finite State Machines (FSM) in Verilog
Pro Tip
Pro Tip
Use 3-block FSMs for clean synthesis and easier maintenance. Flat FSMs are preferred
in high-speed design where latency is critical, especially for Mealy-style machines.
• Binary Encoding
• One-Hot Encoding
• Gray Encoding
• Johnson Encoding
128
Chapter 10 Finite State Machines (FSM) in Verilog
1. Binary Encoding
Each state is assigned a unique binary number. It uses the minimum number of flip-flops
(log2 (N ), where N is the number of states).
Example: 4 States (S0, S1, S2, S3)
Binary Encoding
parameter S0 = 2’b00, S1 = 2’b01, S2 = 2’b10, S3 = 2’b11;
Pros: Efficient in flip-flop usage. Cons: Slower decoding due to complex logic.
2. One-Hot Encoding
Each state uses a separate bit; only one bit is high at any time.
Example: 4 States
One-Hot Encoding
parameter S0 = 4’b0001, S1 = 4’b0010, S2 = 4’b0100, S3 = 4’b1000;
Pros: Fast decoding, simpler combinational logic. Cons: Uses more flip-flops.
3. Gray Encoding
Only one bit changes between adjacent states. Good for low power or noise-sensitive appli-
cations.
Example: 3-bit Gray Code
Pros: Reduces glitches in transitions. Cons: More complex to decode and implement.
4. Johnson Encoding
A twist on Gray encoding. It uses shift register logic with feedback.
Example: For 4 bits:
Pros: Suitable for counters and FSM sequencing. Cons: Less popular in general FSM
designs.
129
Chapter 10 Finite State Machines (FSM) in Verilog
Pro Tip
Pro Tip
Use Binary encoding for large FSMs to save area. Use One-Hot for speed-critical paths
or when FSMs are small. Gray coding is ideal for crossing clock domains or reducing
switching noise.
130
Chapter 10 Finite State Machines (FSM) in Verilog
Verilog Code:
131
Chapter 10 Finite State Machines (FSM) in Verilog
Output:
• y = 1 if even parity
• y = 0 if odd parity
Verilog Code:
Pro Tip
Pro Tip
Use Moore FSM when output depends only on the current state — it’s easier to test.
Use Mealy FSM for faster output responses, especially in reactive systems.
132
Chapter 10 Finite State Machines (FSM) in Verilog
A. Conceptual Questions
1. What is the key difference between Mealy and Moore state machines?
2. Why is the output of a Moore FSM more stable than that of a Mealy FSM?
B. Coding/Verilog-Oriented Questions
11. Write a Verilog code for a Moore FSM to detect the sequence “101”.
12. Write a Verilog code for a Mealy FSM that detects “110” and resets after detection.
14. Design a FSM in Verilog that generates a pulse every third clock cycle.
15. Code an FSM with three states: IDLE, LOAD, and DONE. Transition upon specific
inputs.
19. What are the best practices to define parameters for states?
20. Implement a traffic light controller FSM in Verilog using case statements.
133
Chapter 10 Finite State Machines (FSM) in Verilog
21. During simulation, your FSM skips a state. What could be the cause?
22. Your FSM works in simulation but not in synthesis. What would you check?
24. Explain the difference between blocking and non-blocking assignments in FSMs.
26. What debugging strategy would you apply if the FSM is unstable after reset?
27. In which cases would you prefer a Mealy FSM over a Moore FSM?
30. How would you implement a lock/unlock FSM using a combination of state and input
verification?
134
Chapter 10 Finite State Machines (FSM) in Verilog
• Avoid Latches: Ensure that all state transitions and outputs are defined for
every possible condition to prevent unintended latch inference.
• One-Hot for Speed, Binary for Area: Choose one-hot encoding for faster
FSMs when area isn’t a concern. Prefer binary/gray encoding for area-sensitive
designs.
• Avoid Unused States: Ensure all defined states are reachable. Unreachable
states increase area and can cause simulation warnings.
• Modularize FSMs: For complex designs, modularize FSMs and connect them
through clearly defined interfaces to avoid spaghetti logic.
135
Chapter 10 Finite State Machines (FSM) in Verilog
Verilog
Testbenches
Case Model
Debug/Simulation Reset/Clocking
FSM
State
Moore
Encoding
State
Mealy
Diagrams
136
Chapter 11: Memory Modeling in
Verilog
Introduction
Memory modeling is an essential aspect of digital design, enabling the representation of
storage elements such as RAM, ROM, and register files in Verilog. These models are used
to simulate how memory components behave and interact with the rest of a digital system.
In Verilog, memory is modeled using arrays and procedural constructs. Memory types
can be classified into:
• ROM (Read-Only Memory) – initialized and read-only.
• RAM (Random Access Memory) – readable and writable.
• Register Files – sets of registers used for temporary data storage.
Memory elements are non-synthesizable unless properly mapped with synthesis directives
or inferred using coding styles recognized by tools.
Understanding memory modeling allows designers to:
• Write behavioral models of memory for simulation.
• Create synthesizable memory blocks.
• Integrate memories with FSMs, datapaths, and controllers.
Learning Objectives
After completing this chapter, you will be able to:
• Understand memory declaration in Verilog.
• Model and simulate ROM and RAM behavior.
• Differentiate between behavioral and synthesizable memory.
• Implement read/write operations on memory.
• Create testbenches for memory verification.
137
Chapter 11 Memory Modeling in Verilog
reg [7:0] mem_array [0:255]; // 256 memory locations, each 8 bits wide
Explanation:
These types are used for LUTs, register files, or basic RAM/ROM simulation.
initial begin
rom[0] = 8’hAA;
rom[1] = 8’hBB;
rom[2] = 8’hCC;
// ... initialize all
end
138
Chapter 11 Memory Modeling in Verilog
139
Chapter 11 Memory Modeling in Verilog
module sync_write_async_read (
input wire clk,
input wire [7:0] data_in,
input wire [7:0] addr,
input wire wr_en,
output wire [7:0] data_out
);
reg [7:0] memory [0:255];
Key points:
module sync_read_write (
input wire clk,
input wire wr_en,
input wire [7:0] addr,
input wire [7:0] data_in,
output reg [7:0] data_out
140
Chapter 11 Memory Modeling in Verilog
);
reg [7:0] memory [0:255];
Note: Read and write are controlled through a clock cycle and are mutually exclusive.
—
module dual_port_mem (
input wire clk,
input wire wr_en,
input wire [7:0] wr_addr,
input wire [7:0] data_in,
input wire [7:0] rd_addr,
output reg [7:0] data_out
);
reg [7:0] memory [0:255];
Advantage: Improves performance when simultaneous read and write are required.
—
141
Chapter 11 Memory Modeling in Verilog
Pros:
• Extremely scalable
Explanation:
• 4 registers, each 8-bit wide
142
Chapter 11 Memory Modeling in Verilog
// Write Operation
always @(posedge clk) begin
if (we) begin
reg_array[w_addr] <= w_data;
end
end
endmodule
11.3.3 Verilog Code for 1R1W Register File with Synchronous Read
module reg_file_sync_read (
input clk,
input we,
input [1:0] w_addr, r_addr,
input [7:0] w_data,
output reg [7:0] r_data
);
143
Chapter 11 Memory Modeling in Verilog
• Avoid reading and writing the same location in the same clock cycle.
• For multi-port register files, prioritize arbitration logic to prevent data hazards.
‘timescale 1ns/1ps
module tb_register_file;
// Inputs
reg clk;
reg we;
reg [1:0] w_addr;
reg [1:0] r_addr1, r_addr2;
reg [7:0] w_data;
144
Chapter 11 Memory Modeling in Verilog
// Outputs
wire [7:0] r_data1;
wire [7:0] r_data2;
// Clock generation
initial clk = 0;
always #5 clk = ~clk;
initial begin
// Initialize inputs
we = 0; w_addr = 0; w_data = 8’h00;
r_addr1 = 0; r_addr2 = 1;
145
Chapter 11 Memory Modeling in Verilog
// Disable write
we = 0;
$display("Test Completed.");
$stop;
end
endmodule
Pro Tips
• Always initialize register file contents if required for simulation consistency.
• When using synchronous read, ensure proper handling of setup and hold timing for
inputs.
146
Chapter 11 Memory Modeling in Verilog
• Use meaningful parameter names and labels for register widths and counts — it en-
hances code reusability.
• Avoid using blocking assignments in sequential blocks when designing register files.
• Remember that simultaneous write and read to the same address in the same cycle
may require special handling (read-after-write hazard).
• For synthesizable RTL, avoid initializing memory inside the definition — use an initial
block for simulation only.
• Use one-hot encoding or binary encoding for state machines interfacing with register
files depending on power and area constraints.
147
Chapter 12: User Defined Primitive
(UDP)
Introduction
Introduction
Verilog allows the creation of custom logic through a powerful feature called User Defined
Primitives (UDP). These are low-level representations of logic behavior, typically used to
model gates or flip-flops.
Analogy
Think of a UDP as a handmade switchboard – just like you wire logic manually, you
define how outputs respond to specific inputs via a custom truth table.
Learning Objectives
• Understand the concept of UDPs in Verilog.
• Sequential UDP: Has memory element, output depends on both current input and
previous state.
148
Chapter 12 User Defined Primitive (UDP)
Syntax
table
// input1 input2 : output;
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
table
// a b : out
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
149
Chapter 12 User Defined Primitive (UDP)
table
// clk d : q : q_next
r 0 : ? : 0;
r 1 : ? : 1;
f ? : ? : -;
endtable
endprimitive
Practice Examples
1. XNOR Gate Using UDP
table
0 0 : 1;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
table
0 0 : 0;
0 1 : 1;
1 0 : 1;
1 1 : 1;
endtable
endprimitive
150
Chapter 12 User Defined Primitive (UDP)
table
// en d : q : q_next
1 0 : ? : 0;
1 1 : ? : 1;
0 ? : q : -;
endtable
endprimitive
Practical/Verilog-Based
151
Chapter 12 User Defined Primitive (UDP)
Pro Tips
Pro Tips
• Use UDPs for modeling gate-level primitives only.
• Always simulate UDPs before synthesis – they may not be synthesizable on all
tools.
• Prefer using behavioral constructs (‘always‘, ‘assign‘) for readability unless the
compactness of a UDP is required.
Summary
• UDPs allow custom logic behavior via truth tables.
• They come in two types: combinational (no memory) and sequential (with memory).
• Syntax involves ‘primitive‘, ‘table‘, and optionally ‘reg‘ for sequential behavior.
152
Chapter 13: Event Scheduler
Introduction
In Verilog, the **event scheduler** is the internal mechanism that determines the execution
order of events within a simulation time step. Since multiple statements can be scheduled
for the same time, understanding how Verilog handles their execution is crucial for accurate
modeling and debugging.
It divides simulation time into four main regions for handling scheduled events:
• Active Region
• Inactive Region
• Monitor/Reactive Region
Each region has its own specific role in maintaining simulation integrity and race-free
behavior.
Learning Objectives
• Understand the internal working of the Verilog simulator’s event scheduler.
153
Chapter 13 Event Scheduler
2. Inactive Region: Events postponed from the active region (usually from zero-delay
assignments).
4. Monitor Region: Executes monitoring tasks (‘monitor‘, ‘strobe‘) after all values are
updated.
Active Region
(Blocking, Eval RHS)
Inactive Region
(Zero-delay Scheduled)
NBA Region
(Non-blocking Assignments)
Monitor Region
($monitor, $strobe)
This flow ensures a clean and deterministic simulation order, minimizing unintended
interactions and race conditions.
154
Chapter 13 Event Scheduler
Simulation Walkthrough
• Time 0: a and b set to 0 in the initial block.
initial begin
a = 0;
b = 0;
end
always @(a)
b = a;
always @(a)
a = 1;
endmodule
Explanation: Both always blocks are sensitive to changes in a. Since there is no delay,
the execution order is not deterministic, leading to a race condition.
155
Chapter 13 Event Scheduler
initial begin
x = 0;
y = 0;
#5 x = 1;
y = 1;
end
endmodule
Summary
Concept Description
Event Scheduler Controls execution timing and order of Verilog code
Regions of Execution Active, Inactive, Non-blocking active (NBA), NBA in-
active
Blocking Assignment (=) Immediate execution; may cause race conditions
Non-Blocking Assign- Executes later in NBA region; safer for sequential logic
ment (<=)
#0 Delay Schedules assignment for Inactive region; resolves race
issues
Event Control Triggers execution on signal events using @, posedge,
negedge
Delta Cycle Zero time step used for simulation ordering at same time
instant
156
Chapter 13 Event Scheduler
Pro Tips
• Use <= for sequential logic inside clocked always blocks to avoid race conditions.
• Delta delays help ensure all operations at the same time are handled sequentially
without time progression.
• Explain the event scheduler using real-life analogies like a traffic signal (Red = Wait,
Green = Execute, Yellow = Prepare).
• Use simulation waveforms and flowcharts to analyze and debug timing behavior.
157
Chapter 14: Efficient Testbench
Writing
Introduction
A testbench in Verilog is a simulation environment created to verify the functionality of
a design module. Writing efficient and reusable testbenches is critical in verifying digital
designs before synthesis or tape-out. A poorly written testbench can lead to misleading
simulation results, bugs in design, or even failure at the silicon level.
This chapter aims to provide a structured approach to writing efficient and professional
testbenches using good practices, reusable components, and real-world scenarios.
Learning Objectives
• Understand the purpose and structure of a Verilog testbench.
• Learn how to use initial blocks, procedural constructs, and tasks/functions for verifi-
cation.
158
Chapter 14 Efficient Testbench Writing
Testbench:
1 module tb_mux2to1 ;
2 reg a , b , sel ;
3 wire y ;
4
5 mux2to1 uut (. a ( a ) , . b ( b ) , . sel ( sel ) , . y ( y ) ) ;
6
7 initial begin
8 a = 0; b = 0; sel = 0;
9 #10 a = 1;
10 #10 sel = 1;
11 #10 b = 1;
12 #10 sel = 0;
13 end
14 endmodule
Explanation: This testbench initializes inputs and applies different test cases using time
delays to test how the multiplexer behaves with different combinations of inputs.
Testbench:
1 module tb_dff ;
2 reg clk , d ;
3 wire q ;
4
5 dff uut (. clk ( clk ) , . d ( d ) , . q ( q ) ) ;
6
7 always #5 clk = ~ clk ; // Clock generator
8
9 initial begin
10 clk = 0; d = 0;
11 #10 d = 1;
12 #10 d = 0;
13 #10 d = 1;
14 #20;
15 end
16 endmodule
159
Chapter 14 Efficient Testbench Writing
Explanation: The ‘always‘ block toggles the clock every 5 time units. The ‘initial‘ block
changes the ‘d‘ value at specific times to simulate input behavior.
Testbench:
1 module tb_adder4bit ;
2 reg [3:0] a , b ;
3 wire [4:0] sum ;
4
5 adder4bit uut (. a ( a ) , . b ( b ) , . sum ( sum ) ) ;
6
7 initial begin
8 a = 4 ’ b0000 ; b = 4 ’ b0000 ;
9 #10 a = 4 ’ b0101 ; b = 4 ’ b0011 ;
10 #10 a = 4 ’ b1111 ; b = 4 ’ b1111 ;
11 #10 a = 4 ’ b1010 ; b = 4 ’ b0101 ;
12 end
13 endmodule
Explanation: This testbench applies different sets of 4-bit values to check overflow and
proper addition functionality.
Testbench:
1 module tb_counter ;
2 reg clk , reset ;
3 wire [7:0] out ;
4
5 counter uut (. clk ( clk ) , . reset ( reset ) , . out ( out ) ) ;
6
7 always #5 clk = ~ clk ;
8
9 initial begin
160
Chapter 14 Efficient Testbench Writing
10 clk = 0; reset = 1;
11 #10 reset = 0;
12 #50 reset = 1;
13 #10 reset = 0;
14 #30;
15 end
16 endmodule
Explanation: Clock toggling and reset control demonstrate synchronous behavior and
reset mechanism of the counter.
Testbench:
1 module tb_and_gate ;
2 reg a , b ;
3 wire y ;
4
5 and_gate uut (. a ( a ) , . b ( b ) , . y ( y ) ) ;
6
7 task apply_inputs ;
8 input aa , bb ;
9 begin
10 a = aa ; b = bb ;
11 #5;
12 end
13 endtask
14
15 initial begin
16 apply_inputs (0 , 0) ;
17 apply_inputs (0 , 1) ;
18 apply_inputs (1 , 0) ;
19 apply_inputs (1 , 1) ;
20 end
21 endmodule
Explanation: This example uses a custom task to apply inputs. This method enhances
code readability and modularity.
161
Chapter 14 Efficient Testbench Writing
// Testbench
module tb_seq_detector;
reg clk, reset, in_bit;
wire detected;
initial begin
clk = 0; forever #5 clk = ~clk;
end
initial begin
reset = 1; in_bit = 0;
#10 reset = 0;
#10 in_bit = 1; #10 in_bit = 0; #10 in_bit = 1; #10 in_bit = 1;
#20 $finish;
162
Chapter 14 Efficient Testbench Writing
end
initial begin
$monitor("Time=%0t in_bit=%b detected=%b", $time, in_bit, detected);
end
endmodule
Explanation: This testbench drives the FSM with input sequence to check if it correctly
detects “1011”. The use of ‘$monitor‘ is efficient for observing signal values over time.
// Testbench
module tb_edge_detector;
reg clk, sig;
wire edge;
initial begin
clk = 0; forever #5 clk = ~clk;
end
initial begin
sig = 0;
#12 sig = 1; #10 sig = 0; #10 sig = 1; #20;
$stop;
end
163
Chapter 14 Efficient Testbench Writing
initial begin
$monitor("Time=%0t sig=%b edge=%b", $time, sig, edge);
end
endmodule
module tb_mux2x1();
reg a, b, sel;
wire y;
initial begin
a = 0; b = 1;
sel = 0; #10;
sel = 1; #10;
$finish;
end
endmodule
module tb_adder_4bit();
reg [3:0] a, b;
wire [4:0] sum;
initial begin
a = 4’d9; b = 4’d5; #10;
a = 4’d10; b = 4’d15; #10;
a = 4’d7; b = 4’d2; #10;
164
Chapter 14 Efficient Testbench Writing
$finish;
end
endmodule
2. How does a testbench differ from the design under test (DUT)?
13. Write a testbench that checks both synchronous and asynchronous reset behavior.
17. Use ‘for‘ loop and arrays to automate test cases in a testbench.
165
Chapter 14 Efficient Testbench Writing
19. Write a testbench for a finite state machine (FSM) that detects ‘1011‘.
21. Your testbench runs but shows ‘X‘ outputs. What could be wrong?
23. How would you log all testbench events with timestamps?
24. Your simulation output is stuck. What would be your approach to debug it?
30. Create a testbench for a memory block that tests read and write functionality.
166
Chapter 14 Efficient Testbench Writing
• Use ‘timescale‘: Define timing precision and unit clearly to avoid simulation
mismatch.
• Automation: Automate test vectors using ‘for‘, ‘repeat‘, and ‘case‘ statements
to reduce manual errors.
• Task and Function Reuse: Create reusable test routines with ‘task‘ and
‘function‘ blocks to avoid redundancy.
• Stimulus Timing: Ensure proper delay between stimulus events to allow the
DUT to process inputs.
• Coverage Plan: Think about all edge cases while preparing stimulus (reset,
boundary inputs, illegal states).
• Initial and Always Balance: Use ‘initial‘ for one-time stimulus and ‘always‘
for continuous signal generation.
167
Chapter 14 Efficient Testbench Writing
14.4 Summary
Chapter Summary
• Testbenches are essential for validating digital designs before hardware imple-
mentation.
• A testbench should ideally include input generators, clock logic, reset logic, and
output monitors.
• Simulation tools and waveform viewers like GTKWave are crucial for debugging.
168
Chapter 15: 200 Verilog Interview
Questions (Without Answers)
Introduction
This chapter includes a carefully curated list of 200 Verilog interview questions divided into
multiple categories such as basics, modeling techniques, synthesis, simulation, testbench
development, FSMs, and real-world debugging scenarios. These are designed to test both
theoretical understanding and practical coding ability.
169
Chapter 15 200 Verilog Interview Questions
15. Define and differentiate between combinational and sequential logic in Verilog.
19. What are ‘initial‘ and ‘always‘ blocks used for in simulations?
28. How does a ‘for‘ loop differ from a ‘repeat‘ loop in Verilog?
170
Chapter 15 200 Verilog Interview Questions
62. Explain the difference between a blocking assignment in a ‘begin-end‘ block vs ‘fork-
join‘.
171
Chapter 15 200 Verilog Interview Questions
70. What are the design issues with deeply nested ‘if‘ statements?
73. Describe the purpose and syntax of ‘always comb‘, ‘always ff‘, and ‘always latch‘ in
SystemVerilog.
74. What happens if multiple assignments are made to the same wire?
87. Can we write an ‘always‘ block inside a module more than once?
172
Chapter 15 200 Verilog Interview Questions
102. What are Verilog attributes and where are they used?
173
Chapter 15 200 Verilog Interview Questions
124. What is the difference between a blocking and non-blocking assignment in terms of
simulation results?
137. What are some best practices in Verilog coding for synthesis?
138. How do you check whether your design meets timing constraints?
174
Chapter 15 200 Verilog Interview Questions
146. What is a gray code counter and how would you implement it?
152. Describe how a ring counter works and its Verilog implementation.
159. What are asynchronous FIFO and how are they implemented?
164. How can you ensure a testbench covers all corner cases?
165. What are synthesis directives and how are they used?
168. How does a ‘for‘ loop behave differently in simulation vs. synthesis?
175
Chapter 15 200 Verilog Interview Questions
173. What are synthesis warnings, and how should you handle them?
174. What is a latch? How can you avoid unintentional latch inference?
183. What is the difference between hierarchical and flat design in Verilog?
192. What is an FSM encoding style and how does it impact synthesis?
193. How would you create reusable modules for IP design in Verilog?
176
Chapter 15 200 Verilog Interview Questions
202. Describe a real-world project where you wrote Verilog code and verified it.
177
Chapter 16 : Problems with Solutions
Project Levels
Project Categories
• Beginner
• Intermediate
• Advanced
178
Chapter 16 Problems with Solutions
Verilog Code
module and_gate (input A, input B, output Y);
assign Y = A & B;
endmodule
Pro Tip
Pro Tip: Use ModelSim to simulate this with 4 test cases to verify all input combinations.
Verilog Code
module mux_2to1 (input A, input B, input Sel, output Y);
assign Y = Sel ? B : A;
endmodule
Pro Tip
Pro Tip: Replace the ternary operator with an if-else block in behavioral modeling for
learning.
Verilog Code
module half_adder (input A, input B, output Sum, output Carry);
assign Sum = A ^ B;
assign Carry = A & B;
endmodule
Pro Tip
Pro Tip: Half Adders are used in ripple-carry adders – build one next!
179
Chapter 16 Problems with Solutions
Objective: Implement a Full Adder using two Half Adders and an OR gate.
Verilog Code
module full_adder (
input A, B, Cin,
output Sum, Cout
);
wire Sum1, Carry1, Carry2;
Pro Tip
Pro Tip: Use structural modeling to wire up submodules like in this example!
Objective: Design a 4-bit Ripple Carry Adder using four Full Adders.
Verilog Code
module ripple_adder_4bit (
input [3:0] A, B,
input Cin,
output [3:0] Sum,
output Cout
);
wire C1, C2, C3;
180
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Great first project to test on waveform viewers and learn carry propagation
delays.
Verilog Code
module comparator_4bit (
input [3:0] A, B,
output A_gt_B, A_eq_B, A_lt_B
);
assign A_gt_B = (A > B);
assign A_eq_B = (A == B);
assign A_lt_B = (A < B);
endmodule
Pro Tip
Pro Tip: Expand this into a 16-bit comparator with pipelining later.
Verilog Code
module decoder_3to8 (
input [2:0] A,
input En,
output [7:0] Y
);
assign Y = En ? (1 << A) : 8’b0;
endmodule
Pro Tip
Pro Tip: Decoders are widely used in address decoding in SoC.
181
Chapter 16 Problems with Solutions
Verilog Code
module encoder_8to3 (
input [7:0] D,
output reg [2:0] Y
);
always @(*) begin
casez(D)
8’b1???????: Y = 3’d7;
8’b01??????: Y = 3’d6;
8’b001?????: Y = 3’d5;
8’b0001????: Y = 3’d4;
8’b00001???: Y = 3’d3;
8’b000001??: Y = 3’d2;
8’b0000001?: Y = 3’d1;
8’b00000001: Y = 3’d0;
default: Y = 3’dx;
endcase
end
endmodule
Pro Tip
Pro Tip: Try replacing ‘casez‘ with ‘casex‘ and explore behavior.
Project 9: D Flip-Flop
Objective: Design a positive-edge triggered D flip-flop.
Verilog Code
module d_flip_flop (
input D, clk,
output reg Q
);
always @(posedge clk)
Q <= D;
endmodule
182
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Always use non-blocking assignments inside sequential logic!
Verilog Code
module t_flip_flop (
input T, clk,
output reg Q
);
always @(posedge clk)
if (T)
Q <= ~Q;
else
Q <= Q;
endmodule
Pro Tip
Pro Tip: Used in counters – combine 3 of these to make a 3-bit counter.
Verilog Code
module mux_4to1 (
input [3:0] D,
input [1:0] Sel,
output reg Y
);
always @(*) begin
case (Sel)
2’b00: Y = D[0];
2’b01: Y = D[1];
2’b10: Y = D[2];
2’b11: Y = D[3];
endcase
end
endmodule
183
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Experiment with ‘assign‘ statement for structural style too.
Verilog Code
module demux_1to4 (
input D,
input [1:0] Sel,
output reg [3:0] Y
);
always @(*) begin
Y = 4’b0000;
Y[Sel] = D;
end
endmodule
Pro Tip
Pro Tip: Test on waveform viewer — only one output line should be HIGH at a time.
Verilog Code
module register_4bit (
input clk, rst, en,
input [3:0] D,
output reg [3:0] Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 4’b0000;
else if (en)
Q <= D;
end
endmodule
184
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Useful for pipeline registers in processor design.
Verilog Code
module counter_up_4bit (
input clk, rst,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 4’d0;
else
count <= count + 1;
end
endmodule
Pro Tip
Pro Tip: Try adding enable and direction signals to upgrade it!
Verilog Code
module counter_down_4bit (
input clk, rst,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 4’d15;
else
count <= count - 1;
end
endmodule
185
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Set initial value from input instead of hardcoding.
Verilog Code
module counter_bidirectional (
input clk, rst, dir,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 0;
else
count <= dir ? count + 1 : count - 1;
end
endmodule
Pro Tip
Pro Tip: Add enable signal and explore debounce logic for switches.
Verilog Code
module binary_to_gray (
input [3:0] bin,
output [3:0] gray
);
assign gray[3] = bin[3];
assign gray[2] = bin[3] ^ bin[2];
assign gray[1] = bin[2] ^ bin[1];
assign gray[0] = bin[1] ^ bin[0];
endmodule
186
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Gray code is useful in encoder applications to avoid glitches.
Objective: Generate even and odd parity bits for 4-bit data.
Verilog Code
module parity_generator (
input [3:0] D,
output even_parity, odd_parity
);
assign even_parity = ~^D;
assign odd_parity = ^D;
endmodule
Pro Tip
Pro Tip: Use ^ for XOR reduction and ~^ for XNOR reduction.
187
Chapter 16 Problems with Solutions
Verilog Code
module seq_detect_1011 (
input clk, rst, X,
output reg Z
);
reg [2:0] state;
Pro Tip
Pro Tip: Try Moore version for a better understanding of FSMs.
Verilog Code
module majority_voter (
input A, B, C,
output Y
);
assign Y = (A & B) | (B & C) | (A & C);
endmodule
188
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Expand to 5-input and 7-input majority logic – useful in fault-tolerant systems.
Verilog Code
module dff_async_reset (
input D, clk, rst,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else
Q <= D;
end
endmodule
Pro Tip
Pro Tip: Asynchronous resets can be dangerous in CDC designs. Use sync resets for
FPGA.
Verilog Code
module dff_enable (
input clk, rst, en, D,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else if (en)
Q <= D;
end
endmodule
189
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Use such flip-flops in data latches or gated registers in FSMs.
Verilog Code
module jk_flip_flop (
input J, K, clk, rst,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else if (J & ~K)
Q <= 1;
else if (~J & K)
Q <= 0;
else if (J & K)
Q <= ~Q;
end
endmodule
Pro Tip
Pro Tip: JK flip-flops are used in counters and toggling registers.
190
Chapter 16 Problems with Solutions
Verilog Code
module t_flip_flop (
input T, clk, rst,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else if (T)
Q <= ~Q;
end
endmodule
Pro Tip
Pro Tip: T flip-flops are often used in frequency dividers.
Verilog Code
module counter_sync_en (
input clk, rst, en,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 0;
else if (en)
count <= count + 1;
end
endmodule
Pro Tip
Pro Tip: Use ‘en‘ to control state transition in FSMs as well.
191
Chapter 16 Problems with Solutions
Verilog Code
module clk_div2 (
input clk, rst,
output reg clk_out
);
always @(posedge clk or posedge rst) begin
if (rst)
clk_out <= 0;
else
clk_out <= ~clk_out;
end
endmodule
Pro Tip
Pro Tip: Extend this to divide clock by 4, 8, or N using counters.
Verilog Code
module clk_div4 (
input clk, rst,
output reg clk_out
);
reg [1:0] count;
192
Chapter 16 Problems with Solutions
Verilog Code
module clk_div_n #(parameter N = 10)(
input clk, rst,
output reg clk_out
);
reg [$clog2(N)-1:0] count;
Pro Tip
Pro Tip: Use ‘clog2‘ to make the design more scalable.
193
Chapter 16 Problems with Solutions
Verilog Code
module priority_encoder_4to2 (
input [3:0] D,
output reg [1:0] Y
);
always @(*) begin
casez (D)
4’b1???: Y = 2’b11;
4’b01??: Y = 2’b10;
4’b001?: Y = 2’b01;
4’b0001: Y = 2’b00;
default: Y = 2’bxx;
endcase
end
endmodule
Solution:
1 module edge_detector (
2 input clk ,
3 input signal ,
4 output reg edge_detected
5 );
6 reg signal_d ;
7
194
Chapter 16 Problems with Solutions
Solution:
1 module pulse_gen (
2 input clk ,
3 input trigger ,
4 output reg pulse
5 );
6 reg trigger_d ;
7
8 always @ ( posedge clk ) begin
9 trigger_d <= trigger ;
10 pulse <= trigger & ~ trigger_d ;
11 end
12 endmodule
Solution:
1 module decoder_2to4 (
2 input [1:0] in ,
3 input en ,
4 output reg [3:0] out
5 );
6 always @ (*) begin
7 if ( en )
8 out = 4 ’ b0001 << in ;
9 else
10 out = 4 ’ b0000 ;
11 end
12 endmodule
195
Chapter 16 Problems with Solutions
Solution:
1 module d_ff (
2 input clk ,
3 input rst ,
4 input en ,
5 input d ,
6 output reg q
7 );
8 always @ ( posedge clk or posedge rst ) begin
9 if ( rst )
10 q <= 0;
11 else if ( en )
12 q <= d ;
13 end
14 endmodule
Solution:
1 module sync_counter (
2 input clk ,
3 input rst ,
4 input en ,
5 output reg [3:0] count
6 );
7 always @ ( posedge clk or posedge rst ) begin
8 if ( rst )
9 count <= 0;
10 else if ( en )
11 count <= count + 1;
12 end
13 endmodule
196
Chapter 16 Problems with Solutions
Solution:
1 module up_counter (
2 input clk ,
3 input rst ,
4 output reg [2:0] count
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 count <= 3 ’ b000 ;
9 else
10 count <= count + 1;
11 end
12 endmodule
Solution:
1 module t_ff (
2 input clk ,
3 input rst ,
4 input t ,
5 output reg q
6 );
7 always @ ( posedge clk or posedge rst ) begin
8 if ( rst )
9 q <= 0;
10 else if ( t )
11 q <= ~ q ;
12 end
13 endmodule
197
Chapter 16 Problems with Solutions
Solution:
1 module sync_dff (
2 input clk ,
3 input rst ,
4 input d ,
5 output reg q
6 );
7 always @ ( posedge clk ) begin
8 if ( rst )
9 q <= 0;
10 else
11 q <= d ;
12 end
13 endmodule
Solution:
1 module comparator_1bit (
2 input a , b ,
3 output gt , lt , eq
4 );
5 assign gt = a & ~ b ;
6 assign lt = ~ a & b ;
7 assign eq = ~( a ^ b ) ;
8 endmodule
198
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [7:0] in ,
3 output reg [2:0] out ,
4 output reg valid
5 );
6 always @ (*) begin
7 valid = 1 ’ b1 ;
8 casex ( in )
9 8 ’ b1xxxxxxx : out = 3 ’ b111 ;
10 8 ’ b01xxxxxx : out = 3 ’ b110 ;
11 8 ’ b001xxxxx : out = 3 ’ b101 ;
12 8 ’ b0001xxxx : out = 3 ’ b100 ;
13 8 ’ b00001xxx : out = 3 ’ b011 ;
14 8 ’ b000001xx : out = 3 ’ b010 ;
15 8 ’ b0000001x : out = 3 ’ b001 ;
16 8 ’ b00000001 : out = 3 ’ b000 ;
17 default : begin
18 out = 3 ’ b000 ;
19 valid = 1 ’ b0 ;
20 end
21 endcase
22 end
23 endmodule
199
Chapter 16 Problems with Solutions
Solution:
1 module up_down_counter (
2 input clk ,
3 input rst ,
4 input up_down , // 1 for up , 0 for down
5 output reg [3:0] count
6 );
7 always @ ( posedge clk or posedge rst ) begin
8 if ( rst )
9 count <= 4 ’ b0000 ;
10 else if ( up_down )
11 count <= count + 1;
12 else
13 count <= count - 1;
14 end
15 endmodule
Solution:
1 module binary_to_gray (
2 input [3:0] bin ,
3 output reg [3:0] gray
4 );
5 always @ (*) begin
6 gray [3] = bin [3];
7 gray [2] = bin [3] ^ bin [2];
8 gray [1] = bin [2] ^ bin [1];
9 gray [0] = bin [1] ^ bin [0];
10 end
11 endmodule
200
Chapter 16 Problems with Solutions
Solution:
1 module decoder_3to8 (
2 input [2:0] in ,
3 output reg [7:0] out
4 );
5 always @ (*) begin
6 case ( in )
7 3 ’ b000 : out = 8 ’ b00000001 ;
8 3 ’ b001 : out = 8 ’ b00000010 ;
9 3 ’ b010 : out = 8 ’ b00000100 ;
10 3 ’ b011 : out = 8 ’ b00001000 ;
11 3 ’ b100 : out = 8 ’ b00010000 ;
12 3 ’ b101 : out = 8 ’ b00100000 ;
13 3 ’ b110 : out = 8 ’ b01000000 ;
14 3 ’ b111 : out = 8 ’ b10000000 ;
15 default : out = 8 ’ b00000000 ;
16 endcase
17 end
18 endmodule
Solution:
1 module bi nary_s ubtrac tor (
2 input [3:0] a , b ,
3 output reg [3:0] diff ,
4 output reg borrow
5 );
6 always @ (*) begin
7 { borrow , diff } = a - b ;
8 end
9 endmodule
201
Chapter 16 Problems with Solutions
Solution:
1 module binary_adder (
2 input [3:0] a , b ,
3 output reg [3:0] sum ,
4 output reg carry_out
5 );
6 always @ (*) begin
7 { carry_out , sum } = a + b ;
8 end
9 endmodule
Solution:
1 module multiplier_8bit (
2 input [7:0] a , b ,
3 output reg [15:0] product
4 );
5 always @ (*) begin
6 product = a * b ;
7 end
8 endmodule
202
Chapter 16 Problems with Solutions
Solution:
1 module m a g n i t u d e _ c o m p a r a t o r (
2 input [3:0] a , b ,
3 output reg greater , less , equal
4 );
5 always @ (*) begin
6 if ( a > b ) begin
7 greater = 1;
8 less = 0;
9 equal = 0;
10 end else if ( a < b ) begin
11 greater = 0;
12 less = 1;
13 equal = 0;
14 end else begin
15 greater = 0;
16 less = 0;
17 equal = 1;
18 end
19 end
20 endmodule
Solution:
1 module parity_generator (
2 input [3:0] data ,
3 output reg parity
4 );
5 always @ (*) begin
6 parity = data [0] ^ data [1] ^ data [2] ^ data [3]; // Even
parity
7 end
8 endmodule
203
Chapter 16 Problems with Solutions
Solution:
1 module d_flip_flop (
2 input clk , rst ,
3 input [3:0] d ,
4 output reg [3:0] q
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 q <= 4 ’ b0000 ;
9 else
10 q <= d ;
11 end
12 endmodule
Problem: Design a 4-bit shift register. The shift register should support both left
and right shifting based on the control signal.
Solution:
1 module shift_register (
2 input clk , rst , shift_left , shift_right ,
3 input [3:0] data_in ,
4 output reg [3:0] data_out
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 data_out <= 4 ’ b0000 ;
9 else if ( shift_left )
10 data_out <= data_out << 1;
11 else if ( shift_right )
12 data_out <= data_out >> 1;
13 else
14 data_out <= data_in ;
15 end
16 endmodule
204
Chapter 16 Problems with Solutions
Solution:
1 module c ou n t er _ w it h _ en a b le (
2 input clk , rst , enable , up_down ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else if ( enable ) begin
9 if ( up_down )
10 count <= count + 1;
11 else
12 count <= count - 1;
13 end
14 end
15 endmodule
Problem: Design a 4-bit up/down counter with control logic to select the counting
direction. The counter should increment or decrement based on the ‘updown‘ signal.
Solution:
1 module up_down_counter (
2 input clk , rst , up_down , // up_down is 1 for up , 0 for down
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else if ( up_down )
9 count <= count + 1;
10 else
11 count <= count - 1;
12 end
13 endmodule
205
Chapter 16 Problems with Solutions
Solution:
1 module comparator_8bit (
2 input [7:0] a , b ,
3 output reg greater , equal , less
4 );
5 always @ (*) begin
6 if ( a > b ) begin
7 greater = 1;
8 less = 0;
9 equal = 0;
10 end else if ( a < b ) begin
11 greater = 0;
12 less = 1;
13 equal = 0;
14 end else begin
15 greater = 0;
16 less = 0;
17 equal = 1;
18 end
19 end
20 endmodule
206
Chapter 16 Problems with Solutions
Solution:
1 module bin_to_bcd (
2 input [3:0] bin ,
3 output reg [7:0] bcd
4 );
5 always @ (*) begin
6 case ( bin )
7 4 ’ b0000 : bcd = 8 ’ b00000000 ; // BCD for 0
8 4 ’ b0001 : bcd = 8 ’ b00000001 ; // BCD for 1
9 4 ’ b0010 : bcd = 8 ’ b00000010 ; // BCD for 2
10 4 ’ b0011 : bcd = 8 ’ b00000011 ; // BCD for 3
11 4 ’ b0100 : bcd = 8 ’ b00000100 ; // BCD for 4
12 4 ’ b0101 : bcd = 8 ’ b00000101 ; // BCD for 5
13 4 ’ b0110 : bcd = 8 ’ b00000110 ; // BCD for 6
14 4 ’ b0111 : bcd = 8 ’ b00000111 ; // BCD for 7
15 4 ’ b1000 : bcd = 8 ’ b00001000 ; // BCD for 8
16 4 ’ b1001 : bcd = 8 ’ b00001001 ; // BCD for 9
17 default : bcd = 8 ’ b00000000 ; // Default BCD for invalid
input
18 endcase
19 end
20 endmodule
Solution:
1 module priority_encoder (
2 input [3:0] in ,
3 output reg [1:0] out
4 );
5 always @ (*) begin
6 case ( in )
7 4 ’ b1000 : out = 2 ’ b11 ;
8 4 ’ b0100 : out = 2 ’ b10 ;
9 4 ’ b0010 : out = 2 ’ b01 ;
10 4 ’ b0001 : out = 2 ’ b00 ;
11 default : out = 2 ’ b00 ; // In case of no active input
12 endcase
13 end
14 endmodule
207
Chapter 16 Problems with Solutions
Solution:
1 module up _count er_ena ble (
2 input clk , rst , enable ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else if ( enable )
9 count <= count + 1;
10 end
11 endmodule
Solution:
1 module d ow n _ co u n te r _ en a b le (
2 input clk , rst , enable ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b1111 ;
8 else if ( enable )
9 count <= count - 1;
10 end
11 endmodule
208
Chapter 16 Problems with Solutions
Solution:
1 module johnson_counter (
2 input clk , rst ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else
9 count <= { count [2:0] , ~ count [3]};
10 end
11 endmodule
Solution:
1 module bin_to_gray (
2 input [3:0] bin ,
3 output [3:0] gray
4 );
5 assign gray [3] = bin [3]; // MSB of Gray code is the same as
binary
6 assign gray [2] = bin [3] ^ bin [2];
7 assign gray [1] = bin [2] ^ bin [1];
8 assign gray [0] = bin [1] ^ bin [0];
9 endmodule
209
Chapter 16 Problems with Solutions
Solution:
1 module gray_to_bin (
2 input [3:0] gray ,
3 output [3:0] bin
4 );
5 assign bin [3] = gray [3];
6 assign bin [2] = gray [3] ^ gray [2];
7 assign bin [1] = gray [2] ^ gray [1];
8 assign bin [0] = gray [1] ^ gray [0];
9 endmodule
Solution:
1 module sync_up_counter (
2 input clk , rst ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else
9 count <= count + 1;
10 end
11 endmodule
210
Chapter 16 Problems with Solutions
Problem: Design a 4-bit up/down counter with an enable input. The counter should
count up or down based on the ‘updown‘ signal, and should only count when the
enable signal is active.
Solution:
1 module u p _ d o w n _ c o u n t e r _ e n a b l e (
2 input clk , rst , enable , up_down , // up_down is 1 for up , 0 for
down
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge rst ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else if ( enable ) begin
9 if ( up_down )
10 count <= count + 1;
11 else
12 count <= count - 1;
13 end
14 end
15 endmodule
Solution:
1 module d_flip_flop (
2 input clk , rst ,
3 input [3:0] d ,
4 output reg [3:0] q
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 q <= 4 ’ b0000 ;
9 else
10 q <= d ;
11 end
12 endmodule
211
Chapter 16 Problems with Solutions
Solution:
1 module register_4bit (
2 input clk , rst , load ,
3 input [3:0] data_in ,
4 output reg [3:0] data_out
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 data_out <= 4 ’ b0000 ;
9 else if ( load )
10 data_out <= data_in ;
11 end
12 endmodule
Solution:
1 module s yn c_ re se t_ co un te r (
2 input clk , rst ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk ) begin
6 if ( rst )
7 count <= 4 ’ b0000 ;
8 else
9 count <= count + 1;
10 end
11 endmodule
212
Chapter 16 Problems with Solutions
Solution:
1 module fr equenc y_divi der (
2 input clk ,
3 output reg divided_clk
4 );
5 always @ ( posedge clk ) begin
6 divided_clk <= ~ divided_clk ;
7 end
8 endmodule
Solution:
1 module shift_register (
2 input clk , rst , shift_left , shift_right ,
3 input [3:0] data_in ,
4 output reg [3:0] data_out
5 );
6 always @ ( posedge clk or posedge rst ) begin
7 if ( rst )
8 data_out <= 4 ’ b0000 ;
9 else if ( shift_left )
10 data_out <= { data_out [2:0] , data_in [0]}; // Shift left
11 else if ( shift_right )
12 data_out <= { data_in [3] , data_out [3:1]}; // Shift right
13 end
14 endmodule
213
Chapter 16 Problems with Solutions
Solution:
1 module e v e n _ p a r i t y _ g e n e r a t o r (
2 input [3:0] data_in ,
3 output reg [4:0] data_out // 4 data bits + 1 parity bit
4 );
5 always @ (*) begin
6 data_out [3:0] = data_in ;
7 data_out [4] = ^ data_in ; // XOR all bits to generate parity
8 end
9 endmodule
Solution:
1 module e ve n _ pa r i ty _ c he c k er (
2 input [3:0] data_in ,
3 output reg parity_ok
4 );
5 always @ (*) begin
6 parity_ok = (~^ data_in ) ; // Check if XOR of all bits is 0 (
even parity )
7 end
8 endmodule
214
Chapter 16 Problems with Solutions
Solution:
1 module o d d _ p a r i t y _ g e n e r a t o r (
2 input [3:0] data_in ,
3 output reg [4:0] data_out // 4 data bits + 1 parity bit
4 );
5 always @ (*) begin
6 data_out [3:0] = data_in ;
7 data_out [4] = ~^ data_in ; // XOR all bits and invert to
generate odd parity
8 end
9 endmodule
Solution:
1 module o dd _p ar it y_ ch ec ke r (
2 input [3:0] data_in ,
3 output reg parity_ok
4 );
5 always @ (*) begin
6 parity_ok = ^ data_in ; // XOR all bits , result is 1 for odd
parity
7 end
8 endmodule
215
Chapter 16 Problems with Solutions
Solution:
1 module binary_to_gray (
2 input [3:0] binary ,
3 output reg [3:0] gray
4 );
5 always @ (*) begin
6 gray [3] = binary [3]; // MSB remains the same
7 gray [2] = binary [3] ^ binary [2];
8 gray [1] = binary [2] ^ binary [1];
9 gray [0] = binary [1] ^ binary [0];
10 end
11 endmodule
Solution:
1 module gray_to_binary (
2 input [3:0] gray ,
3 output reg [3:0] binary
4 );
5 always @ (*) begin
6 binary [3] = gray [3]; // MSB remains the same
7 binary [2] = binary [3] ^ gray [2];
8 binary [1] = binary [2] ^ gray [1];
9 binary [0] = binary [1] ^ gray [0];
10 end
11 endmodule
216
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [3:0] in ,
3 output reg [1:0] out
4 );
5 always @ (*) begin
6 casez ( in )
7 4 ’ b0001 : out = 2 ’ b00 ;
8 4 ’ b0010 : out = 2 ’ b01 ;
9 4 ’ b0100 : out = 2 ’ b10 ;
10 4 ’ b1000 : out = 2 ’ b11 ;
11 default : out = 2 ’ b00 ;
12 endcase
13 end
14 endmodule
Solution:
1 module mux_2_to_1 (
2 input [3:0] a , b ,
3 input sel ,
4 output reg [3:0] out
5 );
6 always @ (*) begin
7 if ( sel )
8 out = b ;
9 else
10 out = a ;
11 end
12 endmodule
217
Chapter 16 Problems with Solutions
Solution:
1 module mux_4_to_1 (
2 input [3:0] a , b , c , d,
3 input [1:0] sel ,
4 output reg [3:0] out
5 );
6 always @ (*) begin
7 case ( sel )
8 2 ’ b00 : out = a;
9 2 ’ b01 : out = b;
10 2 ’ b10 : out = c;
11 2 ’ b11 : out = d;
12 default : out = 4 ’ b0000 ;
13 endcase
14 end
15 endmodule
Solution:
1 module full_adder (
2 input [3:0] a , b ,
3 input cin ,
4 output [3:0] sum ,
5 output cout
6 );
7 assign { cout , sum } = a + b + cin ;
8 endmodule
218
Chapter 16 Problems with Solutions
Solution:
1 module subtractor (
2 input [3:0] a , b ,
3 output [3:0] diff ,
4 output borrow
5 );
6 assign { borrow , diff } = a - b ;
7 endmodule
Solution:
1 module multiplier (
2 input [3:0] a , b ,
3 output [7:0] product
4 );
5 assign product = a * b ;
6 endmodule
Solution:
1 module divider (
2 input [3:0] a , b ,
3 output [3:0] quotient ,
4 output [3:0] remainder
5 );
6 assign quotient = a / b ;
7 assign remainder = a % b ;
8 endmodule
219
Chapter 16 Problems with Solutions
Solution:
1 module and_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = a & b ;
6 endmodule
Solution:
1 module or_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = a | b ;
6 endmodule
Solution:
1 module xor_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = a ^ b ;
6 endmodule
220
Chapter 16 Problems with Solutions
Solution:
1 module xnor_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = ~( a ^ b ) ;
6 endmodule
Solution:
1 module not_gate (
2 input [3:0] a ,
3 output [3:0] out
4 );
5 assign out = ~ a ;
6 endmodule
Solution:
1 module nand_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = ~( a & b ) ;
6 endmodule
221
Chapter 16 Problems with Solutions
Solution:
1 module nor_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = ~( a | b ) ;
6 endmodule
Solution:
1 module comparator (
2 input [3:0] a , b ,
3 output reg equal
4 );
5 always @ (*) begin
6 if ( a == b )
7 equal = 1;
8 else
9 equal = 0;
10 end
11 endmodule
222
Chapter 16 Problems with Solutions
Solution:
1 module decoder (
2 input [1:0] in ,
3 output reg [3:0] out
4 );
5 always @ (*) begin
6 case ( in )
7 2 ’ b00 : out = 4 ’ b0001 ;
8 2 ’ b01 : out = 4 ’ b0010 ;
9 2 ’ b10 : out = 4 ’ b0100 ;
10 2 ’ b11 : out = 4 ’ b1000 ;
11 default : out = 4 ’ b0000 ;
12 endcase
13 end
14 endmodule
Solution:
1 module up_counter (
2 input clk , reset ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge reset ) begin
6 if ( reset )
7 count <= 4 ’ b0000 ;
8 else
9 count <= count + 1;
10 end
11 endmodule
223
Chapter 16 Problems with Solutions
Solution:
1 module down_counter (
2 input clk , reset ,
3 output reg [3:0] count
4 );
5 always @ ( posedge clk or posedge reset ) begin
6 if ( reset )
7 count <= 4 ’ b1111 ;
8 else
9 count <= count - 1;
10 end
11 endmodule
224
Chapter 16 Problems with Solutions
Problem: Design a 4-bit ALU (Arithmetic Logic Unit) that supports the following
operations:
• Addition
• Subtraction
• AND
• OR
• XOR
• NOT
The ALU should take two 4-bit inputs and an operation selector input. Based on the
selector, it should perform the desired operation.
Solution:
1 module alu (
2 input [3:0] a , b ,
3 input [2:0] op , // Operation selector
4 output reg [3:0] result
5 );
6 always @ (*) begin
7 case ( op )
8 3 ’ b000 : result = a + b ; // Addition
9 3 ’ b001 : result = a - b ; // Subtraction
10 3 ’ b010 : result = a & b ; // AND
11 3 ’ b011 : result = a | b ; // OR
12 3 ’ b100 : result = a ^ b ; // XOR
13 3 ’ b101 : result = ~ a ; // NOT ( on a )
14 default : result = 4 ’ b0000 ; // Default to 0
15 endcase
16 end
17 endmodule
225
Chapter 16 Problems with Solutions
Solution:
1 module shift_register (
2 input clk , reset , shift_left , shift_right ,
3 input [15:0] data_in ,
4 output reg [15:0] data_out
5 );
6 always @ ( posedge clk or posedge reset ) begin
7 if ( reset )
8 data_out <= 16 ’ b0 ;
9 else if ( shift_left )
10 data_out <= data_out << 1;
11 else if ( shift_right )
12 data_out <= data_out >> 1;
13 end
14 endmodule
Solution:
1 module multiplier (
2 input [7:0] a , b ,
3 output [15:0] product
4 );
5 assign product = a * b ;
6 endmodule
226
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [3:0] in ,
3 output reg [1:0] out
4 );
5 always @ (*) begin
6 casez ( in )
7 4 ’ b0001 : out = 2 ’ b00 ;
8 4 ’ b001x : out = 2 ’ b01 ;
9 4 ’ b01xx : out = 2 ’ b10 ;
10 4 ’ b1xxx : out = 2 ’ b11 ;
11 default : out = 2 ’ b00 ;
12 endcase
13 end
14 endmodule
Solution:
1 module counter (
2 input clk , reset , enable ,
3 output reg [15:0] count
4 );
5 always @ ( posedge clk or posedge reset ) begin
6 if ( reset )
7 count <= 16 ’ b0 ;
8 else if ( enable )
9 count <= count + 1;
10 end
11 endmodule
227
Chapter 16 Problems with Solutions
Solution:
1 module barrel_shifter (
2 input [7:0] data_in ,
3 input [2:0] shift_amount ,
4 input shift_left , shift_right ,
5 output reg [7:0] data_out
6 );
7 always @ (*) begin
8 if ( shift_left )
9 data_out = data_in << shift_amount ;
10 else if ( shift_right )
11 data_out = data_in >> shift_amount ;
12 else
13 data_out = data_in ;
14 end
15 endmodule
Solution:
1 module full_adder (
2 input [7:0] a , b ,
3 input carry_in ,
4 output [7:0] sum ,
5 output carry_out
6 );
7 assign { carry_out , sum } = a + b + carry_in ;
8 endmodule
228
Chapter 16 Problems with Solutions
Solution:
1 module reg_file (
2 input clk , we ,
3 input [1:0] addr ,
4 input [3:0] data_in ,
5 output reg [3:0] data_out
6 );
7 reg [3:0] registers [3:0]; // 4 registers of 4 bits each
8
9 always @ ( posedge clk ) begin
10 if ( we )
11 registers [ addr ] <= data_in ;
12 data_out <= registers [ addr ];
13 end
14 endmodule
Solution:
1 module comparator (
2 input [7:0] a , b ,
3 output reg equal
4 );
5 always @ (*) begin
6 if ( a == b )
7 equal = 1;
8 else
9 equal = 0;
10 end
11 endmodule
229
Chapter 16 Problems with Solutions
Problem: Design a 4-bit RAM with read and write enable. The memory should
have 16 words, each of 4 bits. Use an address bus for selecting the memory location,
and a data bus for reading/writing data. The module should have a read-enable and
write-enable signal to control operations.
Solution:
1 module ram (
2 input clk , reset ,
3 input [3:0] addr , data_in ,
4 input we , re , // Write enable and Read enable
5 output reg [3:0] data_out
6 );
7 reg [3:0] memory [15:0]; // 16 words of 4 bits each
8
9 always @ ( posedge clk or posedge reset ) begin
10 if ( reset )
11 data_out <= 4 ’ b0 ; // Reset output to 0
12 else if ( re )
13 data_out <= memory [ addr ]; // Read operation
14 else if ( we )
15 memory [ addr ] <= data_in ; // Write operation
16 end
17 endmodule
230
Chapter 16 Problems with Solutions
16 if ( we_b )
17 memory [ addr_b ] <= data_in_b ; // Write to port B
18 else
19 data_out_b <= memory [ addr_b ]; // Read from port B
20 end
21 endmodule
231
Chapter 16 Problems with Solutions
Problem: Design a 16-bit FIFO (First In, First Out) buffer. The buffer should have
8 slots, each 16 bits wide. It should have both read and write pointers, and control
signals for read, write, and full/empty indications.
Solution:
1 module fifo_buffer (
2 input clk , reset ,
3 input [15:0] data_in ,
4 input write_en , read_en , // Write and Read enable
5 output reg [15:0] data_out ,
6 output reg full , empty
7 );
8 reg [15:0] memory [7:0]; // 8 slots of 16 bits each
9 reg [2:0] write_ptr , read_ptr ;
10
11 always @ ( posedge clk or posedge reset ) begin
12 if ( reset ) begin
13 write_ptr <= 3 ’ b0 ;
14 read_ptr <= 3 ’ b0 ;
15 full <= 0;
16 empty <= 1;
17 end else begin
18 if ( write_en && ! full ) begin
19 memory [ write_ptr ] <= data_in ;
20 write_ptr <= write_ptr + 1;
21 end
22
23 if ( read_en && ! empty ) begin
24 data_out <= memory [ read_ptr ];
25 read_ptr <= read_ptr + 1;
26 end
27
28 // Check if the FIFO is full or empty
29 full <= ( write_ptr == 3 ’ b111 ) ;
30 empty <= ( read_ptr == write_ptr ) ;
31 end
32 end
33 endmodule
232
Chapter 16 Problems with Solutions
Problem: Design a 32-bit Read-Only Memory (ROM). The ROM should have 256
addresses, each of 32 bits. The ROM contents should be predefined as constants.
Solution:
1 module rom (
2 input [7:0] addr ,
3 output reg [31:0] data_out
4 );
5 always @ (*) begin
6 case ( addr )
7 8 ’ h00 : data_out = 32 ’ h12345678 ;
8 8 ’ h01 : data_out = 32 ’ h9ABCDEF0 ;
9 // Add more cases as needed
10 default : data_out = 32 ’ h00000000 ;
11 endcase
12 end
13 endmodule
Problem: Design an 8-bit Static RAM (SRAM) with a 64-word address space. The
SRAM should have a read-enable signal and a write-enable signal to control the data
input and output operations.
Solution:
1 module sram (
2 input clk , we , re ,
3 input [5:0] addr , // 64 address locations (6 bits )
4 input [7:0] data_in ,
5 output reg [7:0] data_out
6 );
7 reg [7:0] memory [63:0]; // 64 words of 8 bits each
8
9 always @ ( posedge clk ) begin
10 if ( we )
11 memory [ addr ] <= data_in ; // Write data
12 if ( re )
13 data_out <= memory [ addr ]; // Read data
14 end
15 endmodule
233
Chapter 16 Problems with Solutions
234
Chapter 16 Problems with Solutions
235
Chapter 16 Problems with Solutions
236
Chapter 16 Problems with Solutions
Problem: Design a 64-bit register file with 16 registers. The register file should
support read and write operations and include a read-enable and write-enable signal
for controlling these operations.
Solution:
1 module reg_file (
2 input clk , reset ,
3 input [3:0] addr , // 4 - bit address to select one of 16
registers
4 input [63:0] data_in ,
5 input we , re , // Write enable and Read enable
6 output reg [63:0] data_out
7 );
8 reg [63:0] registers [15:0]; // 16 registers of 64 bits each
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset )
12 data_out <= 64 ’ b0 ;
13 else if ( we )
14 registers [ addr ] <= data_in ; // Write operation
15 else if ( re )
16 data_out <= registers [ addr ]; // Read operation
17 end
18 endmodule
237
Chapter 16 Problems with Solutions
Project 109: 128-bit Wide Memory with Address Bus and Control Signals
Problem: Design a 128-bit wide memory with a 256 address bus. Implement control
signals for read, write, and reset operations. The memory should allow for reading
and writing data with the specified width.
Solution:
1 module wide_memory (
2 input clk , reset ,
3 input [7:0] addr , // 256 addresses (8 - bit address bus )
4 input [127:0] data_in ,
5 input we , re , // Write and Read enable signals
6 output reg [127:0] data_out
7 );
8 reg [127:0] memory [255:0]; // 256 locations , each 128 bits wide
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset )
12 data_out <= 128 ’ b0 ;
13 else begin
14 if ( we )
15 memory [ addr ] <= data_in ; // Write operation
16 if ( re )
17 data_out <= memory [ addr ]; // Read operation
18 end
19 end
20 endmodule
238
Chapter 16 Problems with Solutions
239
Chapter 16 Problems with Solutions
Project 111: 32-bit Shift Register with Load and Shift Operations
Problem: Design a 32-bit shift register with both load and shift operations. The shift
register should allow data to be shifted left or right, and it should have a load input
for loading data directly into the register.
Solution:
1 module shift_reg_32bit (
2 input clk , reset , shift_left , shift_right , load ,
3 input [31:0] data_in ,
4 output reg [31:0] data_out
5 );
6 reg [31:0] shift_reg ;
7
8 always @ ( posedge clk or posedge reset ) begin
9 if ( reset )
10 shift_reg <= 32 ’ b0 ;
11 else if ( load )
12 shift_reg <= data_in ; // Load operation
13 else if ( shift_left )
14 shift_reg <= shift_reg << 1; // Shift left operation
15 else if ( shift_right )
16 shift_reg <= shift_reg >> 1; // Shift right operation
17 end
18
19 always @ ( shift_reg ) begin
20 data_out <= shift_reg ;
21 end
22 endmodule
240
Chapter 16 Problems with Solutions
Project 112: 64-bit Asynchronous FIFO with Full and Empty Flags
Problem: Design a 64-bit asynchronous FIFO with full and empty flags. The FIFO
should support write and read operations asynchronously, and it should indicate when
it is full or empty.
Solution:
1 module async_fifo (
2 input clk , reset , write_en , read_en ,
3 input [63:0] data_in ,
4 output reg [63:0] data_out ,
5 output reg full , empty
6 );
7 reg [63:0] memory [15:0]; // 16 slots of 64 bits each
8 reg [3:0] write_ptr , read_ptr ;
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset ) begin
12 write_ptr <= 4 ’ b0 ;
13 read_ptr <= 4 ’ b0 ;
14 full <= 0;
15 empty <= 1;
16 end else begin
17 if ( write_en && ! full ) begin
18 memory [ write_ptr ] <= data_in ;
19 write_ptr <= write_ptr + 1;
20 end
21
22 if ( read_en && ! empty ) begin
23 data_out <= memory [ read_ptr ];
24 read_ptr <= read_ptr + 1;
25 end
26
27 full <= ( write_ptr == 4 ’ b1111 ) ;
28 empty <= ( write_ptr == read_ptr ) ;
29 end
30 end
31 endmodule
241
Chapter 16 Problems with Solutions
Problem: Design a dual-port RAM that allows simultaneous read and write opera-
tions on different ports. Each port should be 16 bits wide, and the RAM should have
16 words in total.
Solution:
1 module dual_port_ram (
2 input clk , reset ,
3 input [3:0] addr_a , addr_b , // 4 - bit address for 16 locations
4 input [15:0] data_in_a , data_in_b ,
5 input we_a , we_b , // Write enable for each port
6 output reg [15:0] data_out_a , data_out_b
7 );
8 reg [15:0] memory [15:0]; // 16 locations , each 16 bits wide
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset ) begin
12 data_out_a <= 16 ’ b0 ;
13 data_out_b <= 16 ’ b0 ;
14 end else begin
15 if ( we_a )
16 memory [ addr_a ] <= data_in_a ; // Write to port A
17 if ( we_b )
18 memory [ addr_b ] <= data_in_b ; // Write to port B
19 data_out_a <= memory [ addr_a ]; // Read from port A
20 data_out_b <= memory [ addr_b ]; // Read from port B
21 end
22 end
23 endmodule
242
Chapter 16 Problems with Solutions
243
Chapter 16 Problems with Solutions
244
Chapter 16 Problems with Solutions
245
Chapter 16 Problems with Solutions
Project 117: Dynamic Memory Allocation with Alloc and Free Operations
Problem: Implement a dynamic memory allocation system that supports memory
allocation and deallocation operations. The memory should be organized into blocks,
and each block should support allocation and freeing of memory.
Solution:
1 module dynamic_memory (
2 input clk , reset ,
3 input alloc , free ,
4 input [7:0] block_size , // Block size for allocation
5 output reg [7:0] allocated_mem
6 );
7 reg [7:0] memory [255:0]; // 256 blocks of memory , each 8 bits
wide
8
9 always @ ( posedge clk or posedge reset ) begin
10 if ( reset )
11 allocated_mem <= 8 ’ b0 ;
12 else begin
13 if ( alloc )
14 allocated_mem <= block_size ; // Allocate memory
block
15 if ( free )
16 allocated_mem <= 8 ’ b0 ; // Free memory block
17 end
18 end
19 endmodule
246
Chapter 16 Problems with Solutions
247
Chapter 16 Problems with Solutions
248
Chapter 16 Problems with Solutions
249
Chapter 16 Problems with Solutions
250
Chapter 16 Problems with Solutions
Problem: Design an FSM to detect a specific 4-bit sequence (e.g., 1011) in a serial
data stream.
Solution:
1 module se quence _detec tor (
2 input clk , reset , serial_in ,
3 output reg detected
4 );
5 typedef enum logic [3:0] {
6 S0 = 4 ’ b0000 ,
7 S1 = 4 ’ b0001 ,
8 S2 = 4 ’ b0010 ,
9 S3 = 4 ’ b0011 ,
10 S4 = 4 ’ b0100
11 } state_t ;
12
13 state_t state , next_state ;
14
15 always_ff @ ( posedge clk or posedge reset ) begin
16 if ( reset )
17 state <= S0 ;
18 else
19 state <= next_state ;
20 end
21
22 always_comb begin
23 case ( state )
24 S0 : next_state = ( serial_in ) ? S1 : S0 ;
25 S1 : next_state = ( serial_in ) ? S1 : S2 ;
26 S2 : next_state = ( serial_in ) ? S3 : S0 ;
27 S3 : next_state = ( serial_in ) ? S4 : S0 ;
28 S4 : next_state = ( serial_in ) ? S1 : S0 ;
29 default : next_state = S0 ;
30 endcase
31 end
32
33 always_ff @ ( posedge clk ) begin
34 detected <= ( state == S4 ) ; // Sequence detected at S4
35 end
36 endmodule
251
Chapter 16 Problems with Solutions
Problem: Design an FSM to control a vending machine that accepts coins (1, 5, and
10 units). The machine dispenses an item when the total amount reaches or exceeds
the price.
Solution:
1 module vending_machine (
2 input clk , reset ,
3 input [3:0] coin , // Accept 1 , 5 , or 10 units
4 output reg dispense
5 );
6 typedef enum logic [2:0] {
7 S0 = 3 ’ b000 , // Initial state
8 S1 = 3 ’ b001 , // Total = 1
9 S2 = 3 ’ b010 , // Total = 5
10 S3 = 3 ’ b011 , // Total = 10
11 S4 = 3 ’ b100 // Dispense
12 } state_t ;
13
14 state_t state , next_state ;
15 reg [3:0] total ; // Keeps track of total amount inserted
16
17 always_ff @ ( posedge clk or posedge reset ) begin
18 if ( reset )
19 state <= S0 ;
20 else
21 state <= next_state ;
22 end
23
24 always_comb begin
25 case ( state )
26 S0 : next_state = ( coin == 1) ? S1 : ( coin == 5) ? S2 : (
coin == 10) ? S3 : S0 ;
27 S1 : next_state = ( coin == 1) ? S2 : ( coin == 5) ? S3 : S4
;
28 S2 : next_state = ( coin == 1) ? S3 : S4 ;
29 S3 : next_state = ( coin == 1) ? S4 : S4 ;
30 S4 : next_state = S0 ; // Reset after dispensing
31 default : next_state = S0 ;
32 endcase
33 end
34
35 always_ff @ ( posedge clk ) begin
36 total <= total + coin ;
37 dispense <= ( total >= 10) ; // Dispense item if total reaches
10
38 end
39 endmodule
252
Chapter 16 Problems with Solutions
22 always_comb begin
23 case ( state )
24 FLOOR0 : next_state = ( floor_request == 2 ’ b01 ) ? FLOOR1 :
25 ( floor_request == 2 ’ b10 ) ? FLOOR2 :
26 ( floor_request == 2 ’ b11 ) ? FLOOR3 :
FLOOR0 ;
27 FLOOR1 : next_state = ( floor_request == 2 ’ b00 ) ? FLOOR0 :
28 ( floor_request == 2 ’ b10 ) ? FLOOR2 :
29 ( floor_request == 2 ’ b11 ) ? FLOOR3 :
FLOOR1 ;
30 FLOOR2 : next_state = ( floor_request == 2 ’ b00 ) ? FLOOR0 :
31 ( floor_request == 2 ’ b01 ) ? FLOOR1 :
32 ( floor_request == 2 ’ b11 ) ? FLOOR3 :
FLOOR2 ;
33 FLOOR3 : next_state = ( floor_request == 2 ’ b00 ) ? FLOOR0 :
34 ( floor_request == 2 ’ b01 ) ? FLOOR1 :
35 ( floor_request == 2 ’ b10 ) ? FLOOR2 :
FLOOR3 ;
36 default : next_state = FLOOR0 ;
37 endcase
38 end
39
40 always_ff @ ( posedge clk ) begin
41 current_floor <= state ;
42 end
43 endmodule
253
Chapter 16 Problems with Solutions
23 always_comb begin
24 case ( state )
25 S0 : next_state = ( user_input ) ? S1 : S0 ;
26 S1 : next_state = ( user_input ) ? S2 : S0 ;
27 S2 : next_state = ( user_input ) ? S3 : S0 ;
28 S3 : next_state = ( user_input ) ? S4 : S0 ;
29 S4 : next_state = S4 ; // Stay in valid password state
30 default : next_state = S0 ;
31 endcase
32 end
33
34 always_ff @ ( posedge clk ) begin
35 valid_password <= ( state == S4 ) ; // Password is valid at S4
36 end
37 endmodule
254
Chapter 16 Problems with Solutions
256
Chapter 16 Problems with Solutions
Answer:
• AND out = 0
• OR out = 1
• XOR out = 1
Answer:
257
Chapter 16 Problems with Solutions
Answer:
• For input signal = 2 (2’b10), the output output signal will be 4’b0100.
Answer:
258
Chapter 16 Problems with Solutions
Problem: Given the following Verilog code for an up/down counter, predict the
output for count direction = 1 (Up mode) and initial value Q = 3.
1 module counter (
2 input clk , reset , count_direction , // 1 for up , 0 for down
3 output reg [3:0] Q
4 );
5 always_ff @ ( posedge clk or posedge reset ) begin
6 if ( reset )
7 Q <= 4 ’ b0000 ;
8 else if ( count_direction )
9 Q <= Q + 1;
10 else
11 Q <= Q - 1;
12 end
13 endmodule
Answer:
• Starting value Q = 3.
259
Chapter 16 Problems with Solutions
Answer:
Answer:
260
Chapter 16 Problems with Solutions
• reg is used to store values in sequential circuits and can hold values across simu-
lation cycles.
• wire is used for combinational circuits, and it cannot store values; instead, it
continuously reflects the value of an expression or module output.
• initial block is used for initializing values or behavior at the beginning of sim-
ulation and executes once at the start.
• always block is used for repetitive actions during simulation, triggered by events
like clock edges.
• Blocking assignments (=) are executed sequentially, meaning the next statement
does not execute until the current one finishes.
• Non-blocking assignments (<=) allow the next statement to execute immediately,
without waiting for the current one.
• if-else is typically used for conditions with two or more possible outcomes and
can evaluate expressions with ranges or conditions.
• case is used for multi-way branching, typically when checking for equality with
constant values.
• for loops are used when the number of iterations is known, and it consists of
three parts: initialization, condition, and increment.
261
Chapter 16 Problems with Solutions
• while loops are used when the number of iterations is unknown, and it continues
as long as a condition is true.
• posedge clk triggers actions on the rising edge of the clock signal.
• posedge reset triggers actions on the rising edge of the reset signal.
• assign is used for continuous assignment, making a signal reflect a given expres-
sion.
• force is used to override a signal’s value during simulation, often used for debug-
ging purposes.
• module is used to define a hardware block or component with inputs and outputs.
• function is used to define a small, reusable block of code that can return a value
and does not include procedural assignments.
• always @* automatically infers the sensitivity list and triggers whenever any of
the inputs change.
• always @(x) explicitly defines the sensitivity list and triggers when the specified
variable x changes.
262
Chapter 16 Problems with Solutions
• memory is an array of reg data types, used to represent storage elements like
RAM.
• reg is used for single-bit or multi-bit storage but is not an array or a memory
block.
• always is used for procedural logic and requires an explicit sensitivity list.
• always comb is used for combinational logic, automatically creating a sensitivity
list.
• posedge for reset ensures that the reset is activated on the rising edge of the reset
signal.
• negedge for reset ensures that the reset is activated on the falling edge of the
reset signal.
21. Difference Between always Block and initial Block in Reset Logic
• always block executes for each clock edge and is typically used for flip-flops and
sequential logic.
• initial block executes only once at the start of simulation, and is commonly
used for initialization of registers.
263
Chapter 16 Problems with Solutions
• initial block runs only once at the start of the simulation and is useful for
initializing values.
• always @* runs continuously as long as any of the signals in the sensitivity list
change.
• real is used for storing floating-point numbers, typically used for simulations that
require precise real-world calculations.
• reg is used for storing binary values, typically integers, and is used in sequential
circuits.
• fork initiates parallel execution of multiple blocks of code, allowing them to run
concurrently.
• join waits for all the parallel processes started by fork to complete before con-
tinuing execution.
• always block can be used for both combinational and sequential logic and needs
a sensitivity list.
• always ff block is specifically for sequential logic with flip-flops or latches, and
handles clocking events like posedge clk.
264
Chapter 16 Problems with Solutions
• casex allows for “don’t care” conditions (denoted by X or Z) which makes it more
flexible in matching values.
• module is used to define a hardware component with ports for input and output
signals, typically for synthesizable blocks.
• task is used for procedural code that can be reused and executed multiple times,
but it cannot return a value like a function.
• posedge in reset logic ensures the reset is activated when the reset signal goes
from low to high (rising edge).
• negedge in reset logic ensures the reset is activated when the reset signal goes
from high to low (falling edge).
• deassign removes the continuous assignment from a wire or register, leaving the
signal undriven.
• force overrides the value of a signal, forcing it to a specific value during simula-
tion, often used for debugging.
• wire is used for connecting components and reflects the continuous value of an
expression.
• logic is a Verilog-2001 data type used as a better version of wire with more
versatile behavior, especially in synthesizable designs.
• mem refers to an array of registers, used for modeling memories like RAM or ROM
in Verilog.
• reg is a single storage element used to store values in a register in sequential logic.
• state represents the current state of the finite state machine (FSM) in sequential
logic.
265
Chapter 16 Problems with Solutions
• state next represents the next state that the FSM will transition to during the
next clock cycle.
• casez allows for “don’t care” conditions in the case expression with z for unknown
values.
• casex is used to compare expressions with both x and z as “don’t care” values.
• initial block runs only once at the start of the simulation to initialize variables.
• always block runs repeatedly whenever an event occurs, such as a clock edge or
signal change.
• forever loop runs indefinitely, continuously executing the block inside it until
simulation ends.
• repeat loop runs a specified number of times, and the number of iterations is
defined before the loop starts.
• posedge is used when you want to trigger an event on the rising edge of a signal
(0 to 1 transition).
• negedge is used when you want to trigger an event on the falling edge of a signal
(1 to 0 transition).
266
Chapter 16 Problems with Solutions
• A) real
• B) reg
• C) wire
• D) integer
Answer: B) reg
• A) 0
• B) 1
• C) Unknown (X)
• D) Undefined
• A) reg clk;
• B) wire clk;
• C) input clk;
• D) output clk;
267
Chapter 16 Problems with Solutions
True/False Questions
1. Verilog allows the declaration of integer variables for representing floating-point val-
ues. (False)
3. In Verilog, wire can store values, while reg can only be used for combinational logic.
(False)
4. The initial block in Verilog is executed only once during simulation. (True)
module test;
reg a, b;
wire out;
initial begin
a = 1;
b = 0;
#10;
$display("Out = %b", out);
end
endmodule
Answer: Out = 0
module test;
reg [3:0] a;
wire [3:0] b;
assign b = a + 4’b1010;
initial begin
a = 4’b0011;
#10;
$display("b = %b", b);
268
Chapter 16 Problems with Solutions
end
endmodule
module test;
reg [3:0] a;
reg b;
wire out;
initial begin
a = 4’b1100;
b = 1;
#10;
$display("Out = %b", out);
end
endmodule
Answer: Out = 1
2. Fill in the blanks to complete the Verilog code for a 2-to-1 multiplexer.
269
Chapter 16 Problems with Solutions
module test;
reg a, b;
wire out;
initial begin
a = 0; b = 1;
#5;
a = 1; b = 0;
#5;
$display("Out = %b", out);
end
endmodule
Answer: The value of out will be displayed twice, first as 0 (when a = 0 and b = 1),
and then 0 again (when a = 1 and b = 0).
module test;
reg [3:0] a, b;
270
Chapter 16 Problems with Solutions
initial begin
a = 4’b1100; b = 4’b1010;
#10;
$display("Out = %b", out);
end
endmodule
Answer: The problem is that the out wire is being assigned the result of an addition,
but no default value for a or b is set in case of unknown conditions. Assign default
values to avoid unknown (X) propagation.
Error Detection
1. In the following code, there is an error in the if condition. Find the mistake.
module test;
reg a, b;
wire out;
always @ (a or b)
begin
if (a = 1)
out = b;
else
out = 0;
end
endmodule
Answer: The mistake is the use of the assignment operator = instead of the equality
operator ==. The corrected condition should be: if (a == 1).
module test;
reg [3:0] a, b;
wire [3:0] sum;
assign sum = a + b;
271
Chapter 16 Problems with Solutions
initial begin
a = 4’b1010;
b = 4’b1100;
$display("Sum = %d", sum);
end
endmodule
Translation: ”Hey, Verilog expert, tell me, when should we use the always block?”
Translation: ”Babu, what is this Verilog code? Once we write the code, we never under-
stand it again!”
272
Chapter 16 Problems with Solutions
Translation: ”If Don’s code goes wrong, hide! Why does everything show ’X’ in Verilog
when errors occur?”
2. B) ’X’ is the default value for wires when there is an undefined state
Translation: ”Tell me, which is happier between reg and wire in Verilog?”
Translation: ”Hey friend, when do we apply timing control in the Verilog always block?”
273
Chapter 16 Problems with Solutions
274
Appendix A
Quick Reference
• module
275
Appendix B
Industry-Standard Tools
• ModelSim / QuestaSim – Comprehensive Verilog simulation.
276
Appendix C
277
Appendix D
Introduction
Preparing for a Verilog or VLSI interview requires a combination of strong conceptual un-
derstanding, practical experience, and communication skills. This appendix offers actionable
tips for each stage of the interview process—before, during, and even after the interview.
• Practice Waveform and Output Prediction: Interviewers often test your ability
to interpret and generate waveforms based on given Verilog code. Use ModelSim or
EDA Playground to simulate examples.
• Brush Up Tool-Based Flows: Familiarize yourself with Vivado (for synthesis and
implementation) and ModelSim (for simulation). Know basic commands and flow
steps.
278
Chapter 16 Problems with Solutions
• Revisit Timing and Gate Delays: Be able to explain timing control (‘posedge‘,
‘negedge‘, ‘@‘) and how delays affect simulation behavior.
• Prepare Mini Projects: Be ready to discuss mini-projects you’ve done using Verilog.
Include counter designs, ALUs, UARTs, memory modules, etc.
• Think in RTL Terms: Explain your logic using terms like “combinational block,”
“sequential logic,” “clock domain,” etc.
• Explain GitHub Projects: If you have a GitHub profile, walk them through your
code—FSMs, testbenches, simulation logs, and synthesis reports.
• Approach Problems Methodically: Break down the problem, explain your thought
process, and write clean, commented code.
• Clarify Design Intentions: When writing code, explain the design goal—e.g., “I’m
using a counter here to control state transitions.”
• Ask Clarifying Questions: If the problem seems vague, don’t hesitate to clarify
constraints or expectations.
Bonus Tips
• Use Timing Diagrams: Whenever possible, draw timing diagrams to explain behav-
ior—especially for setup/hold violations or edge-triggered designs.
• Stay Calm: It’s okay to admit what you don’t know, but demonstrate a willingness
to learn and logical thinking.
279
Chapter 16 Problems with Solutions
Closing Note
Interviews are as much about confidence and clarity as they are about knowledge. Build
your basics, showcase your projects, and demonstrate your enthusiasm for digital design and
hardware.
”Practice doesn’t make perfect. Perfect practice does.” — Vince Lombardi
280
Appendix E
Recommended Books
281
Appendix F
As you move forward, don’t just aim to become a great designer. Strive to be a kind
mentor, a curious thinker, and a fearless innovator. The VLSI world is vast and evolving —
and your contributions will shape the circuits of tomorrow.
You are the spark. The logic. The architect of systems yet to come.
I would love to hear from you — your feedback, suggestions, or simply your thoughts after
282
Chapter 16 Problems with Solutions
283