0% found this document useful (0 votes)
84 views

Verilog One Stop Solution

The document is a comprehensive guide titled 'RTL to Real Job: Verilog Concepts & Interview Essentials' aimed at students and professionals interested in Verilog and VLSI design. It covers fundamental concepts, practical implementations, and includes over 200 interview questions to prepare readers for job placements in the field. The book emphasizes a structured learning approach from basic to advanced topics, supplemented with online resources and instructor materials.

Uploaded by

vanismile
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

Verilog One Stop Solution

The document is a comprehensive guide titled 'RTL to Real Job: Verilog Concepts & Interview Essentials' aimed at students and professionals interested in Verilog and VLSI design. It covers fundamental concepts, practical implementations, and includes over 200 interview questions to prepare readers for job placements in the field. The book emphasizes a structured learning approach from basic to advanced topics, supplemented with online resources and instructor materials.

Uploaded by

vanismile
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 283

RTL to Real Job

Verilog Concepts & Interview Essentials

Authored By
Kittu K Patel
(KV06 : 14/10/2030)

“Empowering Future Chip Designers,


One Line of Code at a Time.”
VeriCore VLSI Design

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:

• Undergraduate and postgraduate students in Electronics, Electrical, and Computer


Engineering.

• Freshers preparing for VLSI job interviews and internship placements.

• Hobbyists and professionals looking to build or refresh their Verilog skills.

Rationale Behind Writing This Book


While many resources exist for learning Verilog, few strike a balance between conceptual
clarity and real-world interview preparation. This book aims to bridge that gap—serving as
both a learning companion and an interview guide, backed by years of academic experience
and industry insights.

About the Book


”RTL to Real Job: Verilog Concepts & Interview Essentials” is a unique blend of theory,
practical implementation, and 200+ hand-picked interview questions. The content flows
logically from beginner topics to advanced modeling and simulation practices, ensuring a
smooth learning curve.

How to Use This Book


• Start with foundational chapters if you’re new to Verilog.

• Refer to summary sections and pro tips for quick revision.

• Use the interview questions for self-assessment and mock interviews.

• Build projects or snippets based on the solved examples to deepen understanding.

2
VeriCore VLSI Design

Salient Features
• 100+ conceptual explanations with real-world analogies.

• 200+ Verilog interview questions (without answers for challenge-based prep).

• LaTeX-formatted, professional layout suitable for academic use.

• Structured flow from RTL design to simulation and synthesis.

• Bonus “Pro Tips” and Mnemonics for memory aid.

Online Resources for Instructors


Instructors can request presentation slides, chapter-wise summaries, and editable quizzes to
accompany the book by emailing us at: [email protected]

Online Resources for Students


Students can access:

• Code examples on GitHub (link to be added in next release)

• Free webinars via Vericore YouTube channel

• Go through NPTEL Lectures

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

Chapter 1: Overview of Digital Design with Verilog 8


1.1 Evolution of Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Emergence as an Industry Standard . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Typical Digital Design Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 Importance of Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.5 Popularity and Trends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.6 Real-World Applications of Verilog . . . . . . . . . . . . . . . . . . . . . . . . 10
1.7 Practice Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Chapter 2: Hierarchical Modeling 12


2.1 Design Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2 Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.4 Component of Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5 Simulation Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.6 Practice Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Chapter 3: Basic Concept 19


3.1 Lexical Conventions and Constants . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Lexical Conventions in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.3 Data Types in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.4 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.5 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.6 Memories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.7 Parameters in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.8 System Tasks and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.9 Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Chapter 4: Modules and Ports 31


4.1 What is a Module? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.2 Types of Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.3 Port Connection Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4
Contents VeriCore VLSI Design

4.4 Hierarchical Name Referencing . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Chapter 5: Gate Level Modelling 36


5.1 Gate Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.2 Gate Delays in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.3 Gates with Different Delays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.4 Practice and Interview Questions . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

Chapter 6: Data Flow Modelling 41


6.1 Continuous Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2 Delays in Dataflow Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6.3: Expression Operators and Operands . . . . . . . . . . . . . . . . . . . . . . . 48
6.4 20 Solved Examples (Problems with Solutions) . . . . . . . . . . . . . . . . . . 51
6.5 Practice Questions (30 Problems) . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.6 Pro Tips for Dataflow Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Chapter 7: Behavioral Modeling 61


7.1 Structured Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
7.2 Procedural Assignment (Blocking and Non-Blocking Assignments) . . . . . . . 67
7.3 Conditional Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.4 Multiway Branching in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . 71
7.5 Loops in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
7.6 Case Statements in Verilog (case, casex, casez) . . . . . . . . . . . . . . . . . . 75
7.7 Loops in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7.8 Sequential and Parallel Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.9 Timing and Event Control in Behavioral Modeling . . . . . . . . . . . . . . . 82
7.10 Summary of Behavioral Modeling in Verilog . . . . . . . . . . . . . . . . . . 85

Chapter 8: Task and Function 87


8.1 Tasks in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.2 Functions in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
8.3 20 Examples of Tasks and Functions in Verilog . . . . . . . . . . . . . . . . . 93
8.4 30 Practice and Interview Questions on Tasks and Functions . . . . . . . . . . 98
8.5 Pro Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

Chapter 9 : Useful Modelling Technique 103


9.1 Procedural Continuous Assignment . . . . . . . . . . . . . . . . . . . . . . . . 103
9.2 Conditional Compilation and Execution . . . . . . . . . . . . . . . . . . . . . 105
9.3 Timescale Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
9.4 Value Change Dump (VCD) File in Verilog . . . . . . . . . . . . . . . . . . . . 112
9.5 10 Practical Examples of Useful Modeling Techniques . . . . . . . . . . . . . . 114
9.6 30 Practice and Interview Questions . . . . . . . . . . . . . . . . . . . . . . . 117

5
Contents VeriCore VLSI Design

9.7 Pro Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

Chapter 10 : Finite State Machines (FSM) in Verilog 120


10.1 What is an FSM? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
10.2 Types of FSMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
10.3 Moore FSM in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
10.4 Melay FSM in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
10.5 FSM Coding Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
10.6 State Encoding Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
10.7 FSM Design Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10.8 Practice and Interview Questions . . . . . . . . . . . . . . . . . . . . . . . . 133
10.9 Pro Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
10.10 Mindmap: FSM Design Concepts . . . . . . . . . . . . . . . . . . . . . . . . 136

Chapter 11: Memory Modeling in Verilog 137


11.1 Memory Declaration and Types . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.2 Read and Write Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
6.1 Continuous Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
11.4 Testbench for 2R1W Register File . . . . . . . . . . . . . . . . . . . . . . . . 144
11.5 Summary and Pro Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

Chapter 12: User Defined Primitive (UDP) 148


12.1 Theory and Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
12.2 Practice and Interview Questions . . . . . . . . . . . . . . . . . . . . . . . . 151

Chapter 13: Event Scheduler 153


13.1 Detailed Theory with Flowchart . . . . . . . . . . . . . . . . . . . . . . . . . 154
13.2 Example: Event Scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Chapter 14: Efficient Testbench Writing 158


14.1 Testbench Examples with Theory . . . . . . . . . . . . . . . . . . . . . . . . 158
14.2 Practice and Interview Questions . . . . . . . . . . . . . . . . . . . . . . . . 165
14.3 Pro Tips for Efficient Testbench Writing . . . . . . . . . . . . . . . . . . . . 167
14.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

Chapter 15: 200 Verilog Interview Questions (Without Answers) 169


15.1 Questions 1–40: Verilog Basics and Syntax . . . . . . . . . . . . . . . . . . . 169
15.2 Questions 41–202: Modeling, Operators, and Control Structures . . . . . . . 171

Chapter 16 : Problems with Solutions 178

A Commonly Used Verilog Syntax 275

B Tools and Simulators 276

C Online Resources for Learning 277

6
Contents VeriCore VLSI Design

D Interview Preparation Tips 278

E Recommended Books 281

F Final Note to Readers 282

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:

• Understand the history and rise of Verilog.

• Describe the standard digital design workflow.

• Recognize Verilog’s role in modern hardware design.

• Identify current trends in HDL-based development.

1.1 Evolution of Verilog


Verilog was developed in 1984 by Gateway Design Automation and later acquired by Cadence
Design Systems. Its simplicity and resemblance to C helped make it a favorite among
designers.
Pro Tip
This is a helpful tip using the reusable style option.

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

1.2 Emergence as an Industry Standard


With increasing design complexity, traditional schematic design became infeasible. Verilog
allowed abstraction, modularity, and rapid simulation. Its ability to describe systems be-
haviorally and structurally set a new industry norm.

1.3 Typical Digital Design Flow


The Verilog-based design flow can be visualized in the following flowchart:

1. Specification: Define system behavior

2. Modeling: Write Verilog code at RTL level

3. Simulation: Verify logical


correctness with testbenches

4. Synthesis: Convert RTL


to gate-level representation

5. Implementation: Place and


route logic on target device

6. Fabrication: Manufac-
ture chip or burn into FPGA

7. Testing: Validate with real-time data

Pro Tip
Mnemonic Trick: \Smart Men Simulate Systems In Fabricated Factories" —
One word per step in the design flow.

1.4 Importance of Verilog


Verilog’s significance lies in its:
• High simulation speed and tool compatibility.
• Versatile use in behavioral, dataflow, gate-level, and switch-level modeling.
• Built-in support for testbenches and assertions.
• Compact syntax for describing complex digital structures.

9
Chapter 1 Overview of Digital Design with Verilog

1.5 Popularity and Trends


More than 90% of modern ASIC/FPGA design workflows use Verilog or SystemVerilog. Its
enduring presence is because of:

• Industry-standard simulation tools like ModelSim, VCS, and XSIM.

• Integration with high-level verification methodologies like UVM.

• Use in RISC-V processor design, AI accelerators, and SoC validation.

Pro Tip
Career Tip: Verilog is your ticket to internships and full-time VLSI roles. Start projects
and share them on GitHub and LinkedIn!

1.6 Real-World Applications of Verilog


• Designing pipelined CPUs and GPUs

• Building finite state machines (FSMs)

• Coding digital filters and communication IPs

• Modeling and synthesizing memory blocks

• Implementing RISC-V cores from scratch

1.7 Practice Questions

Theory
1. Describe the historical evolution of Verilog.

2. What are the major milestones in Verilog standardization?

3. Explain why simulation precedes synthesis.

4. List and describe the steps in digital design flow.

5. Discuss the impact of Verilog on modern VLSI systems.

10
Chapter 1 Overview of Digital Design with Verilog

Output-Based
1. Predict the behavior of a Verilog ‘always‘ block with blocking assignment.

2. Determine the output of a simple 2-input gate module.

3. Given a waveform, identify the corresponding Verilog construct.

4. Debug a snippet of Verilog code and point out errors.

5. Analyze the simulation result with ‘x‘ and ‘z‘ values.

Summary
• Verilog is a widely used HDL for modeling digital systems.

• Understanding its flow and structure is crucial for hardware design.

• It provides flexibility across abstraction levels.

Pro Tip
Final Insight: Focus on simulation and modeling first. Don’t rush into synthesis—get
your logic right!

Learning Outcome Recap:

1. You now understand the complete Verilog design flow.

2. You are aware of real-world uses and career impact of Verilog.

3. You can identify common trends and tools in the industry.

“Digital design begins with logic—but thrives on imagination.”

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:

• Organize complex circuits in a structured way.

• Simulate individual blocks or the entire system.

• Encourage top-down and bottom-up design methodologies.

Learning Objectives
• Understand the principle and benefits of hierarchical modeling.

• Learn how to define and instantiate modules in Verilog.

• Explore simulation block components within a hierarchy.

• Identify best practices in structuring a Verilog project.

2.1 Design Methodology


Verilog supports both:

• Top-down design: Starting with the system-level architecture, we decompose the


design into smaller modules.

• 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

Figure 1: Hierarchical Block Diagram (Top-Down Design)

Pro Tip
Pro Tip: Modularize your code as early as possible! This helps you simulate and debug
each block independently.

Benefits of Hierarchical Design


• Easier to debug and simulate.

• Encourages code reuse across projects.

• Enhances readability and team collaboration.

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

Example: Basic AND Gate Module


module and_gate (
input wire a,
input wire b,
output wire y
);
assign y = a & b;
endmodule

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.

Syntax for Instantiation


module_name instance_name (
.port1(signal1),
.port2(signal2)
);

Example: Instantiating and gate


module top_module (
input wire p, q,
output wire r
);
and_gate u1 (
.a(p),
.b(q),
.y(r)
);
endmodule

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.

Nesting Modules (Multilevel Hierarchy)


Modules can instantiate other modules which can, in turn, instantiate others—forming a
hierarchy tree.

Top Module

Control Unit ALU

Decoder Adder

Figure 2: Multi-level Hierarchical Modeling

Best Practices
• Keep each module focused on a single function.

• Use parameters for module customization.

• Ensure ports and signal types match during instantiation.

2.4 Component of Simulation


Verilog simulation involves several key components that work together to mimic the behavior
of the digital system.

1. Design Under Test (DUT)


This is the core Verilog module being tested in the simulation.

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

Figure 3: Simulation Components Interconnection

2.5 Simulation Block


The simulation block is a Verilog section that controls simulation timing, value changes, and
procedural events. The most common simulation blocks are:

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.

always @(posedge clk) begin


// Repetitive behavior
end

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!

3. Delay and Event Control


Delays (#) and event controls (@) let you mimic timing behavior:

#10 a = 1; // wait 10 time units


@(posedge clk); // wait for positive clock edge

4. Simulation Time Units


Simulation operates on virtual time units defined by ‘timescale‘:

‘timescale 1ns/1ps

Common Use-Cases
• Apply stimulus to DUT

• Monitor output waveforms

• Model real-world delays

Pro Tip
Pro Tip: Use waveform viewers (like GTKWave) to visualize the simulation time-
line—great for debugging!

2.6 Practice Questions


Theoretical Questions
1. What is hierarchical modeling in Verilog?

2. Explain the structure of a Verilog module.

3. Describe the process of instantiating one module into another.

4. What is the purpose of simulation in Verilog?

5. Compare and contrast the initial and always blocks.

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.

• Learn about different Verilog data types and their applications.

• Explore arrays, memories, vectors, and parameters in detail.

• Discover system tasks and compiler directives for efficient modeling.

3.1 Lexical Conventions and Constants


Verilog uses a syntax style similar to C. The following are some key lexical elements:

3.1.1 Escape Sequences


• \n – New Line

• \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

3.1.2 Special Values


Verilog uses two special values:
• x (unknown) – Represents an unknown logic value.

• z (high impedance) – Represents a floating or disconnected signal.

3.1.3 Signed vs Unsigned Numbers


By default, numbers in Verilog are unsigned. Use the signed keyword to explicitly define
signed variables.

reg signed [7:0] a; // Signed 8-bit number


reg [7:0] b; // Unsigned 8-bit number

3.1.4 Negative Numbers and Constants


Verilog supports negative constants using two’s complement representation:
reg signed [3:0] neg = -4; // stored as 1100

3.1.5 Strings and Identifiers


Strings are enclosed in double quotes:
$display("Hello, Verilog!");
Identifiers must begin with a letter or underscore and can contain letters, digits, under-
scores, or escaped characters:
reg [3:0] _a1; // valid
reg \abc 123; // escaped identifier
Pro Tip
Analogy: Think of ‘x‘ as a wire in smoke (uncertain) and ‘z‘ as a wire in air (discon-
nected)!

3.1.6 Example: Handling Special Values


module special_val;
reg x, y, z;
initial begin
x = 1’bx; // unknown
y = 1’bz; // high impedance
$display("x = %b, y = %b", x, y);
end
endmodule

20
Chapter 3 Basic Concepts

Verilog Special States


x = Unknown z = High-Z

Figure 4: Verilog ’x’ and ’z’ States

3.2 Lexical Conventions in Verilog


Lexical conventions define the basic language structure of Verilog. This includes whitespace,
comments, identifiers, literals, operators, and more.

3.2.1 Whitespace Characters


Verilog ignores whitespace characters unless they are inside strings. Common whitespace
characters include:

• \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 */

3.2.3 Identifiers and Escape Sequences


Identifiers name modules, variables, functions, etc. They must begin with a letter or under-
score and can include digits and underscores. Escape identifiers start with a backslash and
are followed by whitespace.

// 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:

• 4’b1010 – 4-bit binary number

• 8’hA3 – 8-bit hexadecimal number

• 6’d45 – 6-bit decimal number

3.2.5 Signed and Unsigned

By default, Verilog numbers are unsigned unless declared otherwise.


“‘verilog reg signed [7:0] num;

Pro Tip
Unsigned numbers roll over on overflow. Use signed when dealing with negative values!

3.2.6 Special Values: x and z

• x – Unknown (used for simulation, uninitialized registers)

• z – High impedance (used in tri-state buffers)

22
Chapter 3 Basic Concepts

3.2.7 Negative Numbers and Strings

Start Reading Code

Ignore Whitespace

Parse Identifiers

Parse Literals

Handle Comments

Lexical Analysis Done

Figure 5: Lexical Convention Flow in Verilog

3.3 Data Types in Verilog


Verilog provides several built-in data types to represent hardware signals and variables.
Understanding them is crucial for proper modeling and simulation.

3.3.1 Net Type


Net types represent physical connections between components. They cannot store a value;
instead, they reflect the value being driven onto them.

• Common types: wire, tri, wand, wor


• No need to assign in procedural blocks

wire clk; // Clock signal


wire [3:0] data; // 4-bit bus

3.3.2 Reg Type


Reg is not a physical register. It holds a value assigned in a procedural block (like always or
initial).

23
Chapter 3 Basic Concepts

reg clk;
reg [7:0] count;

Pro Tip
Use reg inside procedural blocks and wire outside them for connections!

3.3.3 Integer Type


Integer is a 32-bit signed data type used primarily for loop counters and calculations.

integer i;

Note: Can be used in loops but not synthesizable for hardware mapping.

3.3.4 Real Type


Used to represent floating-point values, mainly for testbenches.

real pi;
initial pi = 3.14159;

3.3.5 Time Type


Used to store simulation time.

time delay;
delay = $time;


Difference Table

Type Usage Storage


wire Connection No
reg Procedural code Yes
integer Counters, calc Yes (32-bit signed)
real Decimal values Yes (testbenches only)
time Simulation time Yes (64-bit unsigned)

Table 1: Difference Between Common Data Types

Pro Tip
Always assign reg in initial or always blocks. Use assign only for wire types.

24
Chapter 3 Basic Concepts

Input Signal

Wire

Reg in Always Block

Output

Figure 6: Data Flow using Wire and Reg

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.4.2 Accessing Bits


assign data[0] = 1’b1;
assign data[3:2] = 2’b10;

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

3.5.1 1D Array Example


reg [7:0] register_file [0:15]; // 16 registers, each 8-bit wide

3.5.2 2D Array Example


reg [3:0] mem_2d [0:3][0:3]; // 4x4 4-bit matrix

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

3.6.2 Read/Write Operations


initial begin
memory[0] = 8’b10101010; // Write
$display("Data at mem[0] = %b", memory[0]); // Read
end

3.6.3 Synchronous Read Example


always @(posedge clk) begin
data_out <= memory[addr]; // Read on clock edge
end

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

Address (addr) Memory [0:255] Data Out

Figure 7: Simple Memory Access with Clock and Address

3.7 Parameters in Verilog


Parameters are constants used for defining values that can be changed during module in-
stantiation. They’re extremely useful for making modules reusable and configurable.

3.7.1 Syntax
parameter WIDTH = 8;
reg [WIDTH-1:0] data_bus;

3.7.2 Parameter Overriding


Parameters can be overridden using:

1. Named Parameter Override

my_module #(.WIDTH(16)) inst1 (...);

2. Positional Parameter Override

my_module #(16) inst2 (...);

3.7.3 Local Parameters


Local parameters cannot be overridden outside the module.

localparam MAX_SIZE = 256;

3.7.4 defparam Usage


Legacy method of changing parameter values (not recommended in SystemVerilog):

defparam inst1.WIDTH = 32;

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.

3.8 System Tasks and Functions


System tasks in Verilog begin with a $ and are used for simulation purposes like displaying
values, writing to files, or monitoring changes.

3.8.1 Common System Tasks


• $display – Displays a message.

• $monitor – Monitors changes and displays them.

• $finish – Ends simulation.

• $stop – Stops simulation for debugging.

• $time – Current simulation time.

initial begin
$display("Simulation starts at time %t", $time);
$monitor("a = %b, b = %b, out = %b", a, b, out);
end

3.9 Compiler Directives


Compiler directives start with a backtick (‘) and guide the compiler during simulation.

3.9.1 Important Directives


• ‘define – Used to define a macro.

• ‘ifdef, ‘endif – Conditional compilation.

• ‘include – Include another Verilog file.

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

3.9.3 Theoretical Questions


1. What is the difference between reg and wire?

2. How are parameters and localparams different?

3. Describe the usage of arrays and vectors in Verilog.

4. Explain how a memory block is read and written.

5. Differentiate between $display and $monitor.

3.9.4 Predict the Output


// Q1
reg [3:0] a;
initial begin
a = 4’b1100;
$display("a[2] = %b", a[2]);
end

// Q2
parameter WIDTH = 4;
reg [WIDTH-1:0] b;
initial begin
b = 4’b1010;
$display("b = %b", b);
end


Summary

• Lexical conventions include special characters like , , and identifiers.

• Vectors represent multi-bit signals; arrays group similar data types.

29
Chapter 3 Basic Concepts

• Memories store multiple data locations and are used for RAM/ROM models.

• Parameters increase reusability and flexibility of modules.

• System tasks like $display, $monitor are essential for simulation output.

• Compiler directives optimize your code compilation process.

Learning Outcome:

• You can now differentiate between data types and storage styles in Verilog.

• You know how to use parameters and directives effectively.

• You can apply arrays, vectors, and system tasks in simulation.

“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.

• Learn the types of ports and how to use them effectively.

• Explore valid and invalid ways of port connection with examples.

• Understand hierarchical naming conventions in Verilog.

4.1 What is a Module?


A module in Verilog defines a hardware block. It is the basic building block and can represent
anything from a simple gate to a complex processor.

4.1.1 Syntax
verilog module (module name) (port list);
// Declarations
// Functionality
endmodule

4.1.2 Example 1: AND Gate Module


module andgate ( input wire a, input wire b, output wire y ); assign y = a & b; 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!

4.2 Types of Ports


Ports are module interfaces used to interact with the external environment.

• Input: Takes signals into the module.

• Output: Sends signals out from the module.

• Inout: Bi-directional port.

4.2.1 Example 2: Using All Types of Ports


verilog Copy Edit module bidirexample(input a, output y, inout data); assign y = a; end-
module

4.3 Port Connection Rules


To avoid errors in module instantiations, Verilog defines certain rules:

4.3.1 1. Matching Port Widths


The widths of the connected signal and the port must match.

4.3.2 2. Matching Port Directions


Connecting an output to another output is not valid.

4.3.3 3. Proper Data Types


The data type of the connected signal should be compatible with the port declaration.

32
Chapter 4 Modules and Ports

Diagram: Port Connection

Input Output
Module
Inout

Figure 8: Valid port connections for input, output, and inout

Pro Tip
Pro Tip: Always declare port directions explicitly! Verilog infers wires by default —
which may cause synthesis issues if not declared correctly.

Connecting Port to External Signal


A port in Verilog connects the internal logic of a module to external signals. There are two
ways to connect ports:

• Positional Association: The ports are connected in the order they are defined.

• Named Association: The ports are explicitly named during instantiation.

Example: Positional Connection


1 module full_adder (a , b , cin , sum , cout ) ;
2 input a , b , cin ;
3 output sum , cout ;
4 assign { cout , sum } = a + b + cin ;
5 endmodule
6

7 module top ;
8 wire x , y , z , s , c ;
9 full_adder fa1 (x , y , z , s , c ) ; // Positional mapping
10 endmodule

Example: Named Connection


1 module top ;
2 wire x , y , z , s , c ;
3 full_adder fa1 (
4 .a(x),
5 .b(y),
6 . cin ( z ) ,

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.

4.4 Hierarchical Name Referencing


Verilog allows access to sub-modules using a path of module and instance names. This is
called hierarchical referencing.
Syntax:
<topmodule>.<submodule>.<signal>

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?

2. Explain hierarchical referencing with an example.

3. Why are illegal port connections dangerous in synthesis?

4. How do named associations help in avoiding errors?


Predict the Output:

34
Chapter 4 Modules and Ports

1. Given a module with positional vs named connection, identify errors.

2. What happens if a port is left unconnected?

3. Trace output of a basic full adder using port mapping.

4. Write the hierarchical path to access a flip-flop’s output in nested modules.

Summary
• Modules are the building blocks of Verilog designs.

• Ports allow interfacing between modules and external signals.

• Use named associations for clarity and safety.

• Hierarchical referencing allows access to deep-level signals.

• Illegal connections can break simulation or synthesis behavior.

Learning Outcome:

1. Understand how to define and instantiate modules.

2. Clearly differentiate between legal and illegal port connections.

3. Master the skill of connecting modules with signals using ports.

4. Access internal signals using hierarchical paths safely.

“Modular design is the art of building complexity from simplicity.”

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.

• Learn how to create gate-level circuits using built-in primitives.

• Explore gate delays and their use in timing simulation.

• Analyze Verilog modules through examples and diagrams.

5.1 Gate Types


Verilog provides predefined primitives for various logic gates:

• and, nand – AND, NAND gates

• or, nor – OR, NOR gates

• xor, xnor – XOR, XNOR gates

• not – Inverter

• buf – Buffer

36
Chapter 5 Gate Level Modelling

Truth Table for Common Gates


A B A AND B A OR B
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1

Pro Tip
Pro Tip: Think of gates as mathematical functions. An AND gate is like multiplication:
1 * 1 = 1, everything else is 0.

Circuit Diagram for AND Gate


A
Y
B

Truth Tables of Basic Logic Gates


A B AND (A & B) OR (A — B) XOR (A B̂) NAND ( (A & B))
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 1
1 1 1 1 0 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”.

Circuit Diagram for OR Gate


A
Y
B

Other Common Gate Types


• NAND Gate: Inverted output of AND. High output unless both inputs are high.

• 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!

5.2 Gate Delays in Verilog


Gate delays allow modeling the propagation delay of logic gates in Verilog. They simulate
the real-world behavior of circuits, where signals do not propagate instantaneously. You can
use the ‘#‘ symbol to introduce a delay in the output.
1 module and_gate_delay ( output y , input a , b ) ;
2 assign #5 y = a & b ;
3 endmodule

Listing 1: AND Gate with 5 Time Unit Delay

Explanation
The output will update 5 time units after both inputs become valid. Use this in
testbenches to visualize delays.

5.3 Gates with Different Delays


1. OR Gate Delay:
1 module or_gate_delay ( output y , input a , b ) ;
2 assign #3 y = a | b ;
3 endmodule

2. NOT Gate Delay:


1 module not_gate_delay ( output y , input a ) ;
2 assign #2 y = ~ a ;
3 endmodule

3. NAND Gate with Rise and Fall Delay:


1 module nand_delay ( output y , input a , b ) ;
2 assign #(2 , 4) y = ~( a & b ) ; // rise = 2 , fall = 4
3 endmodule

Pro Tip
Use multiple delay values to model real-world rise and fall transitions of gates.

38
Chapter 5 Gate Level Modelling

5.4 Practice and Interview Questions


Theoretical Questions:

1. Explain the difference between primitive and derived gates in Verilog.

2. What are the possible values that a signal can take in Verilog?

3. Describe gate delays and their usage.

4. Why are gate delays ignored during synthesis?

5. Explain the importance of gate-level modeling in the VLSI design cycle.

Output Prediction Questions:

1. Predict the output of an AND gate with a 5-time unit delay.

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.

4. Modify an OR gate to introduce two types of delays (rise and fall).

5. Identify the error in a module using gate delays.

Hands-On Coding Tasks:

1. Implement an XOR gate with a delay of 2 units.

2. Create a testbench for a NAND gate with delays.

3. Model a 2-to-1 MUX using gate-level primitives.

4. Use waveform viewer to visualize the delay in NOT gates.

5. Modify a 3-input AND gate to include a 1 unit propagation delay.

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.

• Verilog allows incorporating delays using the # operator.

• Truth tables and diagrams are essential for understanding gate operations.

• Proper modeling of gates ensures accurate simulation and functional verification.

• Gate delays help visualize real-world signal behavior during simulation.

Learning Outcome:

1. Identify and model different logic gates in Verilog.

2. Apply gate delays and understand their impact on simulation.

3. Interpret gate-level design through truth tables and circuit diagrams.

“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.

What is Dataflow Modelling?


Dataflow modeling in Verilog is used to describe the functionality of a circuit in terms
of how data moves from input to output using continuous assignments (using ‘assign‘
keyword).

Figure 9: Dataflow modeling concept

41
Chapter 6 Data Flow Modelling

Why Dataflow Modeling?


• It abstracts away structural and timing details.
• Helps model combinational logic efficiently.
• Useful for arithmetic and logical operations.
• Enables simulation of timing via delays.

Where it fits in HDL Design:

Gate-Level Modeling

Dataflow Modeling

Behavioral Modeling

Comparison Table:

Feature Gate-Level Dataflow Behavioral


Abstraction Low Medium High
Description Style Primitive gates Logical expressions Procedural constructs
Code Complexity High Medium Low
Delay Modeling Possible Possible Advanced
Simulation Speed Fast Medium Slow
Synthesis Friendly Yes Yes Yes

Table 2: Comparison between Modeling Styles

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.

• Explore various types of delays used in dataflow modeling.

• Analyze how operators and operands form expressions.

• Practice through examples, questions, and output predictions.

“Flow the logic, not the gates — that’s the dataflow mindset.”

6.1 Continuous Assignment


In Verilog, continuous assignment is the most fundamental aspect of dataflow modeling. It
allows a designer to express hardware logic as direct assignments using the keyword assign,
representing logic gates and combinational logic concisely.

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.

Syntax of Continuous Assignment


assign <net identifier> = <expression>;

Example 1: Simple AND Gate


1 module and_example ( output y , input a , b ) ;
2 assign y = a & b ;
3 endmodule

Listing 2: Simple AND Gate using Continuous Assignment


Explanation: The output y will always reflect the logical AND of inputs a and b. If
either of the inputs change, y is updated automatically.

43
Chapter 6 Data Flow Modelling

Key Properties of Continuous Assignment

• Only used with nets (e.g., wire).

• Cannot be used inside procedural blocks (always or initial).

• Describes combinational logic (no memory).

• Re-evaluates automatically when input signals change.

Example 2: Multiplexer using Dataflow

1 module mux2x1 ( output y , input a , b , sel ) ;


2 assign y = sel ? b : a ;
3 endmodule

Listing 3: 2:1 Multiplexer using Continuous Assignment

Explanation: This implements a simple 2-to-1 multiplexer. When sel=1, y=b; other-
wise, y=a.

Comparison with Procedural Assignment

Feature Continuous Assignment Procedural Assignment


Used with wire reg
Syntax assign y = a & b; y = a & b; inside always
block
Trigger Automatic (event-driven) Based on sensitivity list
Usage Combinational logic only Sequential or combinational
logic

44
Chapter 6 Data Flow Modelling

Block Diagram: Continuous Assignment

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?

2. Implement a 4-to-1 multiplexer using continuous assignment.

3. Predict the output of:


1 wire y ;
2 assign y = ( a ^ b ) & c ;

4. Can we use assign inside an always block? Justify.

5. How do continuous assignments differ from blocking assignments?

45
Chapter 6 Data Flow Modelling

Key Takeaways:

• Continuous assignment is the backbone of dataflow modeling in Verilog.

• It enables real-time updates to logic output based on inputs.

• It provides a direct, synthesizable method for implementing combinational logic.

“With assign, you define how data flows — no clocks, no waits, just logic.”

6.2 Delays in Dataflow Modeling


Introduction
Delays in Verilog’s dataflow modeling allow us to simulate real-world signal propagation. In
real circuits, signals don’t change instantaneously, and Verilog provides syntactic ways to
include timing delays in simulation.
Delays are especially important when writing testbenches or when timing visualization is
required for digital designs.

Why Use Delays?


• To simulate realistic gate and wire propagation.

• To test timing glitches, race conditions, and pulse filtering.

• To create time-based behavior in testbenches.

Types of Delays in Verilog


1. Inertial Delay (Default)
Definition: Inertial delay mimics the behavior where input pulses shorter than the delay
value are filtered out. Verilog implicitly supports this behavior with standard delay notation.
1 assign #5 y = a & b ;

Listing 4: AND Gate with Inertial Delay

If input changes last less than 5 units, the output remains unchanged.

2. Transport Delay (Conceptual Only)


Definition: Transport delay transmits all changes, even glitches. Though Verilog does
not implement it directly, it can be conceptually modeled.
Useful in modeling physical wire behavior or interconnect delays in advanced testbenches.

46
Chapter 6 Data Flow Modelling

3. Timing Control with #


You can specify:

• A single delay

• Rise and fall delays

• Rise, fall, and turn-off delays

1 assign #5 y = a & b ; // Single delay


2 assign #(3 ,5) y = a | b ; // Rise = 3 , Fall = 5
3 assign #(1 ,2 ,3) y = ~( a & b ) ; // Rise = 1 , Fall = 2 , Turn - off = 3

Listing 5: Different Types of Delays

Delay Syntax Table


Delay Type Syntax Explanation
Single Delay #5 Delays output by 5 time units
Rise/Fall Delay #(3,5) Rise = 3, Fall = 5
Rise/Fall/Turn-Off #(3,5,7) Adds Turn-Off delay = 7

Real-World Examples
Example 1: Basic Delay
1 assign #3 y = a ^ b ;

Example 2: Different Rise and Fall Delay


1 assign #(2 ,4) y = a | b ;

Example 3: Full Delay Model


1 assign #(1 ,2 ,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

Comparison Table: Synthesis vs Simulation

Context Delay Use Purpose


Synthesis & NO & Timing not inferred
Simulation & YES & Accurate signal timing and glitches
Testbenches & YES & Timing validation, waveform generation

Summary of Section 6.4


• Delays in dataflow modeling allow time-accurate simulation.

• Verilog supports inertial-like delays using the # symbol.

• 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.

• Apply correct delay modeling in testbenches for verification.

• Differentiate between synthesizable and non-synthesizable constructs.

6.3: Expression Operators and Operands


Expressions in Verilog form the heart of logic design. Dataflow modeling heavily relies on
the ability to describe circuit behavior using mathematical and logical expressions.

Expression: A combination of operands (like wires, variables, constants) and operators


(like +, &, !) to produce a logic value.

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

Table 3: Types of Operands


Type Description Example
Constant Literal numerical value 4’b1010, 8’hFF
Variable/Wire Named signal in a module a, b, clk
Expression Result of another expression (a & b), (x + y)

Types of Operators
Verilog offers various operators, categorized as:

Operator Type Operators Example


Arithmetic +, -, *, /, % assign sum = a + b;
Relational ==, !=, <, >, <=, >= assign result = (a > b);
Logical &&, ||, ! assign out = (a && b);
Bitwise &, |, ^, ~ assign y = a ^ b;
Shift <<, >>, <<<, >>> assign out = a << 2;
Concatenation {a, b}, {{2{a}}} assign out = {a, b};
Reduction &, |, ~&, ~|, ^, ~^ assign zero = ~|a;
Conditional ? : assign y = sel ? a : b;

Examples for Each Operator Type


1. Arithmetic Operator:
1 assign sum = a + b ;
2 assign diff = a - b ;
3 assign prod = a * b ;
4 assign div = a / b ;

Listing 6: Arithmetic Operation

2. Relational Operator:
1 assign is_greater = ( a > b ) ;
2 assign is_equal = ( a == b ) ;

Listing 7: Relational Operation

3. Logical Operator:
1 assign logic_result = ( a && b ) || (! c ) ;

Listing 8: Logical Operation

4. Bitwise Operator:

49
Chapter 6 Data Flow Modelling

1 assign and_op = a & b ;


2 assign xor_op = a ^ b ;

Listing 9: Bitwise Operation

5. Shift Operator:
1 assign left_shift = a << 2;
2 assign right_shift = b >> 1;

Listing 10: Shift Operation

6. Concatenation and Repetition:


1 assign out = {a , b }; // Concatenate a and b
2 assign repeat = {{4{ a }}}; // Repeat ’a ’ 4 times

Listing 11: Concatenation and Repetition

7. Reduction Operator:
1 assign any_bit_high = | a ;
2 assign all_bits_low = ~| a ;

Listing 12: Reduction Operation

8. Conditional Operator:
1 assign out = ( sel ) ? a : b ;

Listing 13: Conditional Operator

Operator Precedence (Highest to Lowest)


• Unary Operators: !, , &, |

• Multiplicative: *, /, %

• Additive: +, -

• Relational: <, >, <=, >=

• Equality: ==, !=

• Bitwise: &, |, ^

• Logical: &&, ||

• Conditional: ? :

50
Chapter 6 Data Flow Modelling

Tip: Use parentheses () for clarity when mixing operators.

Pro Tip
Always use parentheses to clarify precedence in complex expressions. It not only
reduces bugs but makes your code more readable.

“The more expressive your logic, the cleaner your design.”

6.4 20 Solved Examples (Problems with Solutions)


Understanding dataflow modeling becomes much more effective through hands-on problem-
solving. This section presents 20 problems modeled using the ‘assign‘ statement, showcasing
how Verilog can be used to describe circuits at the dataflow level.

“Think of dataflow modeling as plumbing logic—where signals flow like water through gates
and pipes!”

Example 1: 2-Input AND Gate

1 module and_gate ( output y , input a , b ) ;


2 assign y = a & b ;
3 endmodule

Listing 14: 2-input AND gate using assign

Explanation: This is the simplest form of logic gate. Think of it like a door that only
opens when both switches (inputs) are ON.

Example 2: 2-Input OR Gate

1 module or_gate ( output y , input a , b ) ;


2 assign y = a | b ;
3 endmodule

Analogy: Like a streetlight system where light turns ON if any one sensor detects motion.

51
Chapter 6 Data Flow Modelling

Example 3: NOT Gate


1 module not_gate ( output y , input a ) ;
2 assign y = ~ a ;
3 endmodule

Explanation: Acts like a toggle switch.

Example 4: 2-to-1 Multiplexer


1 module mux2to1 ( output y , input a , b , sel ) ;
2 assign y = sel ? b : a ;
3 endmodule

Analogy: Like a train junction that decides which track to follow based on a lever (selector).

Example 5: Half Adder


1 module half_adder ( output sum , carry , input a , b ) ;
2 assign sum = a ^ b ;
3 assign carry = a & b ;
4 endmodule

Explanation: Adds two 1-bit values, just like primary school math.

Example 6: Full Adder


1 module full_adder ( output sum , carry , input a , b , cin ) ;
2 assign sum = a ^ b ^ cin ;
3 assign carry = ( a & b ) | ( b & cin ) | ( a & cin ) ;
4 endmodule

Example 7: 4-bit Adder


1 module four_bit_adder ( output [3:0] sum , input [3:0] a , b ) ;
2 assign sum = a + b ;
3 endmodule

Example 8: Comparator

52
Chapter 6 Data Flow Modelling

1 module comparator ( output gt , eq , lt , input [3:0] a , b ) ;


2 assign gt = ( a > b ) ;
3 assign eq = ( a == b ) ;
4 assign lt = ( a < b ) ;
5 endmodule

Example 9: 4-bit XOR Gate

1 module xor_4bit ( output [3:0] y , input [3:0] a , b ) ;


2 assign y = a ^ b ;
3 endmodule

Example 10: Parity Generator

1 module parity_gen ( output parity , input [3:0] data ) ;


2 assign parity = ^ data ; // XOR all bits
3 endmodule

Example 11: Even Parity Checker

1 module parity_check ( output even , input [3:0] data ) ;


2 assign even = ~(^ data ) ; // Complement of XOR result
3 endmodule

Example 12: 4-bit Subtractor

1 module subtractor ( output [3:0] diff , input [3:0] a , b ) ;


2 assign diff = a - b ;
3 endmodule

Example 13: Bitwise AND

1 module bitwise_and ( output [3:0] y , input [3:0] a , b ) ;


2 assign y = a & b ;
3 endmodule

53
Chapter 6 Data Flow Modelling

Example 14: Bitwise OR

1 module bitwise_or ( output [3:0] y , input [3:0] a , b ) ;


2 assign y = a | b ;
3 endmodule

Example 15: Bitwise NOT

1 module bitwise_not ( output [3:0] y , input [3:0] a ) ;


2 assign y = ~ a ;
3 endmodule

Example 16: Left Shift

1 module shift_left ( output [3:0] y , input [3:0] a ) ;


2 assign y = a << 1;
3 endmodule

Example 17: Right Shift

1 module shift_right ( output [3:0] y , input [3:0] a ) ;


2 assign y = a >> 1;
3 endmodule

Example 18: Concatenation Example

1 module concat_example ( output [7:0] y , input [3:0] a , b ) ;


2 assign y = {a , b }; // Join two 4 - bit numbers
3 endmodule

Example 19: Sign Extension

1 module sign_extend ( output [7:0] y , input [3:0] a ) ;


2 assign y = {{4{ a [3]}} , a }; // Extend sign
3 endmodule

54
Chapter 6 Data Flow Modelling

Example 20: Priority Selector (3-input)

1 module pri ority_ selec tor ( output y , input a , b , c ) ;


2 assign y = a ? 1 ’ b1 : ( b ? 1 ’ b1 : c ) ;
3 endmodule

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!

6.5 Practice Questions (30 Problems)


Practice strengthens understanding. Try solving the following Verilog questions to reinforce
your understanding of dataflow modeling. Each question is designed to address specific
concepts and increase your proficiency step-by-step.

Level 1: Basic Gates (1–5)


Q1. Write Verilog code using dataflow to implement a 2-input NAND gate.

Q2. Implement a 2-input NOR gate using an ‘assign‘ statement.

Q3. Model a NOT gate and verify its truth table.

Q4. Create a 3-input AND gate using a single ‘assign‘ statement.

Q5. Design a 4-input OR gate and simulate it with all combinations of inputs.

Level 2: Arithmetic & Bitwise Operations (6–10)


Q6. Implement a 4-bit adder using the ‘assign‘ statement.

Q7. Write a 4-bit subtractor using dataflow modeling.

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

Level 3: Conditional Logic & Operators (11–15)


Q11. Implement a 2-to-1 multiplexer using a conditional (‘? :‘) operator.

Q12. Design a 4-to-1 multiplexer using nested conditional operators.

Q13. Create a module for a 1-bit comparator (==).

Q14. Implement a parity generator using the reduction XOR (ˆ) operator.

Q15. Design an even parity checker.

Level 4: Shifting & Concatenation (16–20)


Q16. Write a Verilog code for logical left shift by 2 bits.

Q17. Implement arithmetic right shift on a signed number.

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).

Q20. Perform sign-extension of a 4-bit number to 8 bits.

Level 5: Mixed Logic and Design (21–25)


Q21. Create a dataflow model of a 1-bit full adder.

Q22. Implement a 4-bit full adder using four 1-bit full adders.

Q23. Design a 4-bit comparator (greater than, less than, equal).

Q24. Model a 3-bit priority encoder.

Q25. Write a Verilog module that outputs 1 when a number is divisible by 2.

Level 6: Output Prediction & Debug (26–30)


Q26. Predict the output:
1 assign y = 3 ’ b101 & 3 ’ b110 ;

Q27. Predict the output:


1 assign y = ( a < b ) ? a : b ;

Q28. Identify the issue in the following dataflow code:


1 assign y = ( a == b ) & ( c | d ;

56
Chapter 6 Data Flow Modelling

Q29. Debug the following code:


1 assign out = {a , b };
2 endmodule

Q30. Predict and explain the output:


1 assign y = ~(( a & b ) | c ) ;

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!

6.6 Pro Tips for Dataflow Modeling


To become efficient in Verilog, it’s important to follow practices that not only help avoid
bugs but also write readable, scalable, and synthesizable code. Below are some pro tips
specifically for dataflow modeling:

Tip 1: Always Use ‘assign‘ in Dataflow


Dataflow modeling uses the keyword assign to bind continuous assignments. Forgetting
to use assign will result in a syntax error.

Tip 2: Use ‘wire‘ for Outputs


In dataflow modeling, ensure that output ports are declared as wire. Do not use reg
types unless required in procedural blocks.

Tip 3: Use Grouping with Parentheses


Always group operations using parentheses. This helps avoid precedence-related bugs and
improves readability.

Tip 4: Avoid Mixing Blocking (‘


Never use blocking assignments (=) within modules that use continuous assignment via
assign. This can confuse simulators and result in mismatches.

57
Chapter 6 Data Flow Modelling

Tip 5: Match Bit Widths


Bit width mismatches may not always raise errors but can silently cause logic errors.
Always ensure the output has sufficient width to store the result of operations like addition
or shifting.

Tip 6: Use Named Ports for Clarity


When instantiating modules, use named port mapping:
1 and_gate u1 (. a ( a ) , . b ( b ) , . y ( y ) ) ;

This improves readability and avoids wiring mistakes.

Tip 7: Simulate Early and Often


Don’t wait till the end to simulate. Use tools like ModelSim or Icarus Verilog frequently
to test modules. Simulation catches most mistakes before synthesis.

Tip 8: Use Meaningful Names


Avoid generic names like a1, b1, c2. Use clk, data in, sel, etc., for better understanding
and maintainability.

Tip 9: Beware of Overusing Concatenation


While concatenation is powerful, excessive or complex nested concatenation can harm
readability and may introduce bugs. Use only when required.

Tip 10: Use Delay Only in Testbenches


Delays like #5 are simulation constructs and should not be used in RTL designs for syn-
thesis. Use them only in testbenches or behavioral-level code.

58
Chapter 6 Data Flow Modelling

Figure: Dataflow Modeling – A Clear and Concise Way to Define Logic

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:

– Inertial and Transport delay


– Rise, Fall, Turn-off delay for gate-level modeling

• Expression Components:

– Operators (Arithmetic, Relational, Logical, etc.)


– Operands (Wires, Constants, Expressions)

• Operator Types: Covered in depth with syntax, examples, and application tips.

• Examples: We studied 20+ real-world examples of common logic expressions using


dataflow style.

• Practice Questions: A bank of 30 curated problems to test your understanding.

• 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

Continuous Assignment Delay Types

Operators and Operands 20+ Solved Examples

Pro Tips 30 Practice Problems

Figure: Mind Map of Concepts Covered in 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.

Analogy: Programming a Robot


Think of behavioral modeling like programming a robot. Instead of telling the robot
how to move each joint (gate-level) or how to move based on a signal (dataflow), you
write: “If obstacle detected, then turn right.” This describes behavior—precisely what
behavioral modeling captures.

Where Behavioral Modeling is Used:

• For describing sequential and complex digital systems

• In writing testbenches for verification

• When control logic is needed (state machines, counters, etc.)

• To simulate timing-based events using delay/event control

Key Behavioral Constructs:

• initial and always procedural blocks

• if, case, for, and other control statements

• Blocking and non-blocking assignments

• Sequential and parallel block creation

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.

By the end of this chapter, you will be able to:

62
Chapter 7 Behavioral Modeling

1. Understand and implement structured procedural blocks such as initial and


always.

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.

4. Construct various types of control flow mechanisms:

• Conditional statements (if, if-else)

• Multiway branches (if-else-if, case, casex, casez)

• Looping statements (for, while, repeat, forever)

5. Use sequential and parallel blocks to describe concurrent and ordered logic flows.

6. Design and analyze small to mid-sized behavioral Verilog models.

7. Debug behavioral logic using simulation waveform analysis.

8. Write synthesizable behavioral code by following RTL design best practices.

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

7.1 Structured Procedures (initial and always State-


ments)
In behavioral modeling, Verilog provides two structured procedures to describe the behavior
of digital systems: initial and always blocks. These are fundamental for modeling control
flow, algorithmic descriptions, and sequential behavior.

Analogy: Initial vs Always


Think of the initial block as a one-time instruction you give before a mission begins
(like a robot’s startup routine). On the other hand, the always block keeps monitoring
conditions forever, like a robot patrolling continuously based on sensor input.

7.1.1 initial Block


Purpose: Executes the statements inside it only once at the beginning of the simulation
time (time = 0).
1 module test ;
2 reg clk ;
3 initial begin
4 clk = 0;
5 #5 clk = 1;
6 #5 clk = 0;
7 end
8 endmodule

Listing 15: Example of initial block


Key Points:

• Executes only once.

• Mostly used in testbenches.

• Not synthesizable.

7.1.2 always Block


Purpose: Executes the block of code repeatedly for the entire simulation based on an event
or condition.
1 module counter ;
2 reg clk ;
3 reg [3:0] count ;
4

65
Chapter 7 Behavioral Modeling

5 always @ ( posedge clk )


6 count = count + 1;
7 endmodule

Listing 16: Example of always block


Key Points:
• Executes continuously as long as the simulation runs.
• Used in both combinational and sequential circuits.
• Synthesizable and RTL friendly.

7.1.3 Comparison Table

Feature initial always


Execution Executes once at simulation Executes continuously
start
Use case Testbenches, initialization RTL modeling, clocked logic
Synthesis Not synthesizable Synthesizable
Triggered by Time = 0 Sensitivity list or implicit al-
ways
Simulation Use Initialization, debugging Functional description

Table 5: Comparison Between initial and always Blocks

7.1.4 Block Diagram – Structured Procedure Usage

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

7.2 Procedural Assignment (Blocking and Non-Blocking


Assignments)
In Verilog, procedural assignments inside initial or always blocks are classified into two
types:

• Blocking assignments (using =)

• Non-blocking assignments (using <=)

Analogy: Blocking vs Non-Blocking


Imagine cooking breakfast:
- In blocking style, you make tea, wait for it to finish, then toast bread. - In non-
blocking style, you start tea, then simultaneously toast bread.
Similarly, blocking assignments wait for one task to finish before starting the next,
while non-blocking assignments let tasks proceed in parallel.

7.2.1 Blocking Assignment (=)


Behavior: Executes statements sequentially. One statement must complete before the next
begins.
1 always @ ( posedge clk ) begin
2 a = b;
3 c = a ; // ’c ’ gets the new value of ’a ’
4 end

Listing 17: Blocking Assignment Example

Key Characteristics:

• Operates sequentially like traditional programming.

• Easier to debug.

• Can lead to incorrect behavior in sequential circuits.

7.2.2 Non-Blocking Assignment (<=)


Behavior: All RHS expressions are evaluated first, and then assignments happen in parallel
at the end of the simulation time step.

67
Chapter 7 Behavioral Modeling

1 always @ ( posedge clk ) begin


2 a <= b ;
3 c <= a ; // ’c ’ gets old value of ’a ’
4 end

Listing 18: Non-Blocking Assignment Example

Key Characteristics:

• Executes in parallel.

• Best suited for sequential logic (flip-flop modeling).

• Avoids race conditions.

7.2.3 Use Cases

Type When to Use Typical Application


Blocking (=) For combinational logic or Combinational circuits, initial-
testbenches ization
Non-Blocking (<=) For sequential logic or Flip-flops, clocked logic, FSMs
pipelines

Table 6: Usage Comparison of Blocking and Non-Blocking Assignments

7.2.4 Common Pitfall Example

1 always @ ( posedge clk ) begin


2 q = d;
3 q_bar = ~ q ; // q_bar gets wrong value
4 end

Listing 19: Incorrect: Blocking in Sequential Logic

1 always @ ( posedge clk ) begin


2 q <= d ;
3 q_bar <= ~ q ; // q_bar gets correct old value of q
4 end

Listing 20: Correct: Non-Blocking in Sequential Logic

68
Chapter 7 Behavioral Modeling

7.2.5 Block Diagram: Assignment Execution Flow

Start Clock Edge Evaluate RHS (b) Start Clock Edge Evaluate RHS (b, a)

a=b a<= b, c <= a

c=a End of Non-Blocking

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!

7.3 Conditional Statements


Conditional statements in Verilog are used to make decisions based on certain conditions.
These statements guide the simulation or synthesis tool to execute specific blocks of code
when certain criteria are met.

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.

Syntax: “‘verilog if (condition) statement; else statement;

Block Diagram: Conditional Statement Flow

Start

Is condition true?

Yes No

Execute Execute
True Block False Block

Continue

Example 1: Simple If-Else


verilog Copy Edit module ifexample; reg [3:0] a, b; reg [3:0] max;
initial begin a = 5; b = 10;
if (a ¿ b) max = a; else max = b;
$display(”Max = end endmodule
Pro Tip
Conditional statements can be synthesized if they represent combinational logic. However,
unintentional latches may form if not all conditions are covered!

Where It’s Used:

• Control units

70
Chapter 7 Behavioral Modeling

• Priority encoders

• Data path selection

• Conditional data assignments

Quick Recap:

1. if, else, and else if allow decision-making in Verilog.

2. Always wrap multi-line blocks with begin...end.

3. Avoid incomplete conditions to prevent latch inference.

7.4 Multiway Branching in Verilog


Multiway branching is used when a variable or expression needs to be compared against
multiple possible constant values. This is efficiently implemented using the case statement
in Verilog, which is functionally similar to the switch statement in other programming
languages like C or C++.

Analogy: Vending Machine Logic


Imagine you’re selecting an item from a vending machine. Pressing A1 gives you chips,
B2 gives chocolate, and C3 gives soda. The internal logic behind this selection is a
perfect analogy for a case statement.

Syntax of the case Statement


1 case ( expression )
2 constant1 : begin
3 // statements
4 end
5 constant2 : begin
6 // statements
7 end
8 default : begin
9 // statements
10 end
11 endcase

Types of Case Statements in Verilog


• case – Matches exactly (including ‘x‘ and ‘z‘)

71
Chapter 7 Behavioral Modeling

• casex – Ignores ‘x‘ and ‘z‘ bits in the comparison

• casez – Ignores only ‘z‘ bits in the comparison

1. Standard case Statement Example


1 module mux_4to1 ( input [1:0] sel , output reg [3:0] out ) ;
2 always @ (*) begin
3 case ( sel )
4 2 ’ b00 : out = 4 ’ b0001 ;
5 2 ’ b01 : out = 4 ’ b0010 ;
6 2 ’ b10 : out = 4 ’ b0100 ;
7 2 ’ b11 : out = 4 ’ b1000 ;
8 endcase
9 end
10 endmodule

2. casex Statement Example


Useful when we want to treat don’t care (‘x‘) bits in the case expression as wildcards:
1 casex ( opcode )
2 4 ’ b1x0x : instruction = " LOAD " ;
3 4 ’ b0x1x : instruction = " STORE " ;
4 endcase

3. casez Statement Example


Ignore only high-impedance (‘z‘) bits:
1 casez ( data )
2 4 ’ b1zz0 : result = 1;
3 4 ’ b0zz1 : result = 0;
4 endcase

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

Summary of Key Points


• The case statement is useful for selecting between multiple options based on a variable.

• casex treats ‘x‘ and ‘z‘ as wildcards — good for simulation, not synthesis.

• casez ignores only ‘z‘ — better than casex for synthesis use.

• Always include a default case to handle unexpected values.

7.5 Loops in Verilog


Introduction to Loops
Loops in Verilog are used to execute a block of code repeatedly based on a condition or
predefined count. They are primarily used in testbenches, simulation environments,
and occasionally in synthesizable code if designed carefully.

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.

Verilog Provides the Following Loop Constructs:

• for loop

• while loop

• repeat loop

• forever loop

Comparison of Verilog Loop Constructs

Loop Type Structure Usage Synthesizable


for Counter-controlled Array traversal, testbench Yes (with fixed count)
while Condition-based Iteration until condition false No (generally avoided)
repeat Fixed iterations Clock cycle specific repetition Yes (limited usage)
forever Infinite loop Clocks, testbenches No (only for simulation)

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.

Common Errors in Loops


• Infinite loops without proper delay

• Missing increment/decrement statements

• Using while or forever loops in synthesizable code

74
Chapter 7 Behavioral Modeling

Quick Checklist:

1. Use for loops for array or memory initialization

2. Use repeat for specific delay cycles

3. Avoid forever and while loops in synthesizable blocks

7.6 Case Statements in Verilog (case, casex, casez)


Case statements in Verilog are multiway decision constructs, just like the switch-case
statement in C. They are often used to create control logic like decoders, multiplexers, and
FSMs. There are three variants:

• case – performs exact match

• casex – ignores unknowns (X) and high-impedance (Z)

• casez – ignores only high-impedance (Z)

Analogy: Sorting Letters in a Mailroom


Imagine a clerk sorting letters based on ZIP codes. A normal case is like sorting with full,
exact ZIP code. casex is like saying “ignore missing digits” and sort whatever matches,
while casez is like “treat ZIPs with unknown digit as match unless the digit is critical.”

Pro Tip

Use case for synthesis-safe design. Avoid casex unless you fully understand how X/Z
values propagate in simulation.

Syntax of Case Statements


1 case ( expression )
2 constant_1 : statement_1 ;
3 constant_2 : statement_2 ;
4 default : d efault _state ment ;
5 endcase

Listing 21: General Syntax of a Case Statement

75
Chapter 7 Behavioral Modeling

Example 1: Simple Case Statement (Decoder)


1 module decoder ( input [1:0] in , output reg [3:0] out ) ;
2 always @ ( in )
3 begin
4 case ( in )
5 2 ’ b00 : out = 4 ’ b0001 ;
6 2 ’ b01 : out = 4 ’ b0010 ;
7 2 ’ b10 : out = 4 ’ b0100 ;
8 2 ’ b11 : out = 4 ’ b1000 ;
9 endcase
10 end
11 endmodule

Listing 22: 2-to-4 Decoder using Case

Example 2: casex – Ignoring Don’t-Care Bits


1 always @ ( a or b )
2 casex ({ a , b })
3 2 ’ b1x : out = 1 ’ b1 ; // x is ignored
4 2 ’ b0x : out = 1 ’ b0 ;
5 endcase

Listing 23: Using casex for Don’t Care Conditions

Example 3: casez – Ignoring High Impedance (Z)


1 always @ ( select )
2 casez ( select )
3 4 ’ b1ZZZ : out = a ;
4 4 ’ b01ZZ : out = b ;
5 default : out = 0;
6 endcase

Listing 24: Using casez to Match Patterns with Z

Comparison Table: case vs. casex vs. casez


76
Chapter 7 Behavioral Modeling

Feature case casex casez


Ignores X No Yes No
Ignores Z No Yes Yes
Best for Synthesis Yes No Use with care
Use Case Exact match Priority encoders Pattern match with Z
Risky in Simulation No Yes Sometimes

Table 7: Comparison of case, casex, and casez

Best Practices
• Always include a default case to avoid latches.

• Avoid casex in synthesis if signal may carry real X values.

• Use casez with masks for implementing decoders.

• For FSMs, case is safest and synthesizable.

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:

• Use all three types of case statements effectively

• Understand the difference between case, casex, and casez

• Know when to use each construct in behavioral modeling

77
Chapter 7 Behavioral Modeling

7.7 Loops in Verilog


Loops are powerful control structures in Verilog that allow repeated execution of statements
under specific conditions. They are essential for testbenches, repeated hardware behaviors,
and automating multiple similar operations such as register initializations, waveform print-
ing, etc.

Analogy: Washing Dishes


Think of loops as a set of instructions that say: “Keep washing the dishes while there
are dirty ones.” The loop keeps executing until the sink is empty.

Types of Loops in Verilog


• for loop

• while loop

• repeat loop

• forever loop

Comparison of Loop Types

Loop Type Use Case Example


for loop Known number of itera- for (i = 0; i < 10; i = i +
tions 1)
while loop Iterates as long as a con- while (a < b)
dition holds
repeat loop Repeat fixed number of repeat (5) {...}
times
forever loop Continuous, infinite exe- forever #10 clk = clk;
cution (usually used with
delays)

78
Chapter 7 Behavioral Modeling

Detailed Examples
1. for Loop

“‘verilog integer i; initial begin for (i = 0; i ¡ 8; i = i + 1) begin $display(”i = end end

2. while Loop

integer a = 0; initial begin while (a ¡ 5) begin $display(”a = a = a + 1; end end

3. repeat Loop

integer j = 0; initial begin repeat (4) begin $display(”j = j = j + 2; end end

4. forever Loop

reg clk = 0; initial begin forever begin #5 clk = clk; // toggle clock every 5 time units end
end

Loop Use Case in Testbench


initial begin for (i = 0; i ¡ 16; i = i + 1) begin datain = i; #10; end end

Pro Tip
Use forever loops only with proper delay elements like # or (posedge clk) to prevent
simulation from hanging.

Common Mistakes and Tips


• Avoid infinite loops without delays—they’ll hang the simulation.

• Do not use loops with variables not initialized beforehand.

• for loops are synthesizable if bounds are fixed.

• forever loops are mostly used in testbenches, not synthesizable logic.

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

7.8 Sequential and Parallel Blocks


In Verilog, grouping of multiple statements inside a procedural block (‘always‘ or ‘initial‘)
is essential when more than one operation needs to be performed in sequence or in parallel.
This is done using the following constructs:

• Sequential Block: begin ... end

• Parallel Block: fork ... join

7.8.1 Sequential Blocks (begin ... end)


Sequential blocks execute the statements in order, one after the other.

Syntax
initial begin
statement1;
statement2;
statement3;
end

Example

Verilog Code Example


initial begin
$display("Start");
#10;
$display("Middle");
#10;
$display("End");
end

Output:

Time 0: Start
Time 10: Middle
Time 20: End

7.8.2 Parallel Blocks fork...join


Parallel blocks execute all the enclosed statements simultaneously and wait for all of them
to complete.

80
Chapter 7 Behavioral Modeling

Syntax
initial fork
statement1;
statement2;
statement3;
join

Example

Verilog Code Example


initial fork
#5 $display("A");
#10 $display("B");
#2 $display("C");
join

Output:

Time 2: C
Time 5: A
Time 10: B

Comparison Table: Sequential vs Parallel Blocks

Feature Sequential Block Parallel Block


Keyword Used begin ... end fork ... join
Execution Type One statement after another All statements executed con-
currently
Common Use Synchronous tasks, FSMs Clock generation, concurrent
triggers
Simulation Behavior Waits for one to finish before All statements start together,
next waits for all to finish
Delay Handling Cumulative delays Independent delays
Synthesizable? Yes (commonly used in RTL) No (simulation-only construct)

81
Chapter 7 Behavioral Modeling

When to Use What?


• Use begin ... end when sequence/order matters.
• Use fork ... join when multiple events need to occur simultaneously (e.g., gener-
ating multiple signals).
• Avoid fork ... join in RTL design (not synthesizable).

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!

Example: Mixing Delay and Parallelism


Verilog Code Example
initial fork
begin
#5 $display("Task 1 done");
end
begin
#10 $display("Task 2 done");
end
join

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.

7.9 Timing and Event Control in Behavioral Modeling


Introduction
In behavioral modeling, controlling the timing of events is crucial for creating realistic test-
benches and simulating actual circuit behavior. Verilog provides several constructs to specify

82
Chapter 7 Behavioral Modeling

when and how operations are triggered.

Learning Objectives
• Understand the difference between delay control and event control.

\item Use ‘#‘, ‘@‘, and ‘wait‘ for controlling simulation time and event flow.

• Implement realistic timing in testbenches.

7.9.1 Delay Control (#)


Delay control is the simplest way to pause execution for a specified amount of time.

Syntax
#time; // Waits for ’time’ units

Example: Simple Delay


verilog
initial begin
$display("Time = %0d: Start", $time);
#10;
$display("Time = %0d: After 10 units delay", $time);
end
Output: Time = 0: Start Time = 10: After 10 units delay Pro Tip: Use delay control
carefully — excessive use may cause simulation inefficiency.

7.9.2 Event Control (@)


Event control pauses execution until a specific event occurs, such as a signal changing state.

Syntax
@(event_expression); // Waits until event_expression becomes true

Example: Event Control on Clock Edge


always @(posedge clk) begin q <= d; end

Example: Multiple Event Control


always @(posedge clk or negedge reset) begin if (!reset) q <= 0; else q <= d; end Explanation:
The block is triggered when either clk rises or reset falls.

83
Chapter 7 Behavioral Modeling

7.9.3 Wait Statement


The wait statement pauses the execution until the specified condition becomes true.

Syntax
wait(condition); // Suspends execution until condition is true

Example: Wait Until Signal is High

initial begin
wait(clk == 1);
$display("clk is HIGH at time %0t", $time);
end

Output:

clk is HIGH at time 15

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.

7.9.4 Comparison Table

Feature Delay Control (#) Event Control (@) Wait Statement


Triggering Mechanism Time-based Signal change or edge Boolean condition
Use Case Introduce delay in sim- Edge-triggered behav- Wait for specific condi-
ulation iors (e.g., clocks) tion to become true
Simulation Efficiency Slower if overused Efficient Conditional and reac-
tive
RTL Synthesis Support No Yes (in ‘always‘ blocks) No
Example #10; @(posedge clk); wait(clk==1);

84
Chapter 7 Behavioral Modeling

7.9.5 More Examples


Example 1: Combined Delay and Event
initial begin
#5;
@(posedge clk);
$display("5 time units delay + posedge clk");
end

Example 2: Wait for Condition


initial begin
wait(data_ready == 1);
$display("Data is ready at time = %0t", $time);
end

7.9.6 Interview Questions


• What is the difference between ‘@‘ and ‘wait‘?

• Why is # not synthesizable in Verilog?

• Can you use multiple event controls in a single block?

• What is the preferred way to trigger actions on clock edges?

• How would you model asynchronous reset using ‘@‘?

7.10 Summary of Behavioral Modeling in Verilog


• Behavioral modeling describes the functionality of the design using high-level con-
structs like ‘initial‘, ‘always‘, ‘if‘, ‘case‘, ‘loops‘, etc.

• Two main procedural blocks are:

– initial – Executes once at time zero.


– always – Repeats whenever triggered by sensitivity list.

• Procedural assignments are:

– Blocking (‘=‘) – Executes statements sequentially.


– Non-blocking (‘¡=‘) – Executes concurrently.

• Conditional execution is handled using:

– ‘if‘, ‘if-else‘, ‘nested if‘, ‘if-else-if‘

85
Chapter 7 Behavioral Modeling

• Multi-way branching supports:

– ‘case‘, ‘casex‘, ‘casez‘

• Loops available:

– ‘for‘, ‘while‘, ‘repeat‘, ‘forever‘

• Grouping statements:

– Sequential block: ‘begin ... end‘


– Parallel block: ‘fork ... join‘ (simulation only)

• Timing & Event Control:

– Delay Control: #10


– Event Control: (posedge clk)‘
– Wait statements
– Forever loop with event

Pro Tips and Tricks


Pro Tips
• Always use non-blocking in sequential logic for correct simulation.

• Avoid using ‘fork ... join‘ in synthesizable code. Use only for testbenches.

• Prefer ‘casez‘ for don’t-care conditions in case statements.

• Be careful with forever loops—ensure they are used inside testbenches.

• Combine ‘@(posedge clk)‘ with ‘forever‘ to simulate clocked behavior.

• Use ‘display‘and‘monitor‘ for effective debugging.

• Remember: ‘initial‘ blocks are ignored in hardware synthesis.

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.

• Differentiate between tasks and functions with examples and use-cases.

• Learn how to reuse blocks of Verilog code for better modularity.

• Write synthesizable tasks and functions in RTL.

• Gain confidence through 20 examples and 30 interview questions.

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.

8.1 Tasks in Verilog


What is a Task?
A task in Verilog is a reusable block of procedural statements used to group commonly
executed operations. Tasks can contain:

87
Chapter 8 Task and Function

• Multiple inputs, outputs, and inouts


• Delays (‘#‘), event controls, and timing
• System tasks like $display
• Nested blocks and control structures

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.

Example 1: Task with Input Only


task print_number;
input [3:0] num;
begin
$display("Number is: %d", num);
end
endtask

initial begin
print_number(4);
end
Output: Number is: 4

88
Chapter 8 Task and Function

Example 2: Task with Input and Output


task multiply;
input [3:0] a, b;
output [7:0] result;
begin
result = a * b;
end
endtask

reg [7:0] res;

initial begin
multiply(3, 4, res);
$display("Result: %d", res);
end

Output: Result: 12

Example 3: Task with Delay


task delay_print;
input [3:0] delay_time;
begin
#delay_time;
$display("Waited %d time units", delay_time);
end
endtask

initial begin
delay_print(5);
end

Output (after 5 units): Waited 5 time units

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

Flowchart: Task Execution Logic

Start

Task Call

Execute Statements

Return Control

End

8.2 Functions in Verilog

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.

• Functions must return exactly one value.

• 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

Example 1: Simple Addition Function


function [3:0] add;
input [3:0] a, b;
begin
add = a + b;
end
endfunction

initial begin
$display("Sum = %d", add(2, 3));
end

Output: Sum = 5

Example 2: Maximum of Two Numbers


function [3:0] max_val;
input [3:0] a, b;
begin
max_val = (a > b) ? a : b;
end
endfunction

initial begin
$display("Max = %d", max_val(8, 12));
end

Output: Max = 12

91
Chapter 8 Task and Function

Example 3: Bitwise AND Function


function [3:0] and_func;
input [3:0] a, b;
begin
and_func = a & b;
end
endfunction

initial begin
$display("AND = %b", and_func(4’b1101, 4’b1011));
end

Output: AND = 1001

Comparison Table: Tasks vs Functions

Feature Task Function


Return Value Can return multiple via out- Returns only one value
put/inout
Allowed in Assignments No Yes
Delays and Events Allowed (#, @) Not allowed
Time-Consuming Opera- Supported Not Supported
tions
Usage Context Testbenches, control se- Pure combinational logic
quences
Inputs/Outputs Input, output, inout sup- Only inputs supported
ported
Call Syntax task name(args); result = func(args);
Synthesizability Some are, if no delays Mostly synthesizable

Pro Tips
• Use functions to simplify combinational logic like arithmetic, comparisons, and
encoding.

• Never include delays or non-synthesizable operations inside functions.

• Functions can be used within continuous assignments (‘assign‘) — tasks cannot.

• Best suited for hardware logic that’s fast, predictable, and simple.

92
Chapter 8 Task and Function

8.3 20 Examples of Tasks and Functions in Verilog


Example 1: Function for 4-bit Addition
function [3:0] adder;
input [3:0] a, b;
begin
adder = a + b;
end
endfunction

initial begin
$display("Sum = %d", adder(5, 10)); // Output: 15
end

Example 2: Task to Display a Message


task show_msg;
input [7:0] msg;
begin
$display("Message: %s", msg);
end
endtask

initial begin
show_msg("Hello");
end

Example 3: Function to Calculate 2’s Complement


function [7:0] twos_comp;
input [7:0] a;
begin
twos_comp = ~a + 1;
end
endfunction

Example 4: Task to Wait for Delay and Print


task delay_print;
input integer d;

93
Chapter 8 Task and Function

begin
#d;
$display("Waited for %0d time units", d);
end
endtask

Example 5: Function for Bit Reversal


function [3:0] reverse_bits;
input [3:0] data;
integer i;
begin
for (i = 0; i < 4; i = i + 1)
reverse_bits[i] = data[3 - i];
end
endfunction

Example 6: Task to Compare Two Numbers


task compare;
input [3:0] x, y;
begin
if (x > y)
$display("X is greater");
else
$display("Y is greater or equal");
end
endtask

Example 7: Function to Count 1s in a Binary Number


function [2:0] count_ones;
input [3:0] val;
integer i;
begin
count_ones = 0;
for (i = 0; i < 4; i = i + 1)
count_ones = count_ones + val[i];
end
endfunction

94
Chapter 8 Task and Function

Example 8: Task with Nested Blocks


task nested_example;
input [3:0] a;
begin
begin
$display("Inner Block Value: %d", a);
end
end
endtask

Example 9: Function for XOR Operation


function xor_out;
input a, b;
begin
xor_out = a ^ b;
end
endfunction

Example 10: Task to Simulate Clock Generation


task generate_clk;
output clk;
begin
forever begin
#5 clk = ~clk;
end
end
endtask

95
Chapter 8 Task and Function

Example 11: Function to Convert Binary to Gray Code


function [3:0] bin2gray;
input [3:0] bin;
begin
bin2gray = bin ^ (bin >> 1);
end
endfunction

Example 12: Task for Counting Clock Cycles


task count_cycles;
input integer num;
integer i;
begin
for (i = 0; i < num; i = i + 1)
#10 $display("Cycle %0d", i);
end
endtask

Example 13: Function to Check Even or Odd


function is_even;
input [3:0] val;
begin
is_even = (val % 2 == 0);
end
endfunction

Example 14: Task to Swap Two Variables


task swap;
inout [3:0] a, b;
reg [3:0] temp;
begin
temp = a;
a = b;
b = temp;
end
endtask

96
Chapter 8 Task and Function

Example 15: Function to Compute Square


function [7:0] square;
input [3:0] a;
begin
square = a * a;
end
endfunction

Example 16: Task to Display ASCII Value


task ascii_val;
input [7:0] ch;
begin
$display("ASCII: %0d", ch);
end
endtask

Example 17: Function to Perform OR Reduction


function or_reduce;
input [3:0] data;
begin
or_reduce = |data;
end
endfunction

Example 18: Task to Print an Array


task print_array;
input [7:0] arr [3:0];
integer i;
begin
for (i = 0; i < 4; i = i + 1)
$display("Element[%0d] = %0d", i, arr[i]);
end
endtask

97
Chapter 8 Task and Function

Example 19: Function for Bitwise NOR


function bitwise_nor;
input [3:0] a, b;
begin
bitwise_nor = ~(a | b);
end
endfunction

Example 20: Task to Print Binary Representation


task print_binary;
input [3:0] data;
begin
$display("Binary = %b", data);
end
endtask

8.4 30 Practice and Interview Questions on Tasks and


Functions
Conceptual Questions
1. What is the difference between a task and a function in Verilog?

2. Why can’t a function contain ‘delay‘, ‘event‘, or ‘wait‘ statements?

3. Can a function call a task? Why or why not?

4. How are input, output, and inout ports used differently in tasks and functions?

5. Can tasks be used in synthesizable RTL code?

6. What are the default data types of function return values?

7. Explain the difference between automatic and static tasks/functions.

8. What happens if a task never terminates inside a testbench?

9. Can a function have more than one return statement?

10. In what scenario would you choose a task over a function?

98
Chapter 8 Task and Function

Fill-in-the-Blank and True/False


a. Tasks are generally (synthesizable/non-synthesizable).

b. A function must return exactly value.

c. True/False: A task can include time control statements.

d. True/False: A function can return multiple values.

Code Output Prediction


5. Predict the output:

function [3:0] sum;


input [3:0] a, b;
begin
sum = a + b;
end
endfunction

initial begin
$display("%d", sum(4’d3, 4’d5));
end

6. What will be printed?

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

Debugging Based Questions


7. Identify and correct the error in the following code:

function add_numbers;
input [3:0] a, b;
add_numbers = a + b;
endfunction

8. Fix the issue:

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.

14. Create a task to simulate a 5-cycle clock pulse.

15. Implement a function to find the maximum of three 4-bit numbers.

16. Create a task to generate a PWM signal (simulate with delay and display).

17. Write a function to return the absolute value of a signed input.

18. Design a task to loop through an array and print each value.

100
Chapter 8 Task and Function

8.5 Pro Tips


Pro Tips for Mastering Tasks and Functions
• Use function for simple combinational calculations — keep it short and delay-
free!

• 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.

• Automatic tasks/functions are preferred in testbenches to avoid variable over-


writing.

• Always verify that your task ends (no infinite waits) — to avoid simulation hang.

• For large testbenches, organize reusable components into tasks/functions to im-


prove modularity.

• Remember: A task can call another task or function, but a function can **only**
call another function.

• Use ‘begin...end‘ in tasks and functions to enclose multiple statements.

8.6 Summary
• Verilog provides two primary subprograms: task and function, to modularize re-
peated logic.

• Tasks:

– Can contain delays, events, and wait statements.


– Can have input, output, and inout ports.
– Used for procedural, time-based simulation and verification tasks.

• Functions:

– Must execute in zero simulation time.


– Only one output value (return).
– Cannot contain delays or time controls.

• Tasks and functions can be defined as automatic (reentrant) or static (default).

• 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.

• Set and manipulate simulation time precision using ‘timescale‘.

• Use system tasks like ‘display‘, ‘monitor‘, and $time‘ effectively.

• Generate and interpret waveform files using Value Change Dump (VCD).

9.1 Procedural Continuous Assignment


Procedural continuous assignments allow a procedural block (like ‘initial‘ or ‘always‘) to drive
a net continuously using ‘assign‘ and ‘deassign‘, or override it using ‘force‘ and ‘release‘.

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

Comparison Table: assign-deassign vs force-release

Feature assign-deassign force-release


Applies to Only nets (e.g., wire) Both nets and variables
Usage Context Used in procedural blocks Used in testbenches or spe-
cial cases
Restoration Method deassign release
Synthesizable No No
Preferred Use Net override simulation Temporary forcing in simu-
lation

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.

9.2 Conditional Compilation and Execution


In Verilog, conditional compilation allows you to selectively include or exclude parts of the
code during **compile-time** using special compiler directives. These are particularly useful
when working with testbenches, simulation-only features, or platform-specific modules.

Why Use Conditional Compilation?

• To enable/disable debug code without removing it.

• To include simulation-only logic without affecting synthesis.

• To manage different versions of modules or test environments.

Common Directives

• \‘ifdef MACRO – Compile if macro is defined.

• \‘ifndef MACRO – Compile if macro is **not** defined.

• \‘else – Alternate code when ‘ifdef fails.

• \‘endif – Ends a conditional directive block.

• \‘define MACRO – Defines a macro.

• \‘undef MACRO – Undefines a macro.

105
Chapter 9 Useful Modelling Technique

Syntax

Syntax
‘define DEBUG

module example;
...
‘ifdef DEBUG
initial $display("Debug Mode Enabled");
‘endif
endmodule

Example 1: Basic Conditional Block


‘define SIMULATION

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):

Example 2: Using ‘else‘ and ‘ifndef‘


‘define ASIC

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

Comparison Table: ‘ifdef vs ifndef‘


Feature ‘ifdef ‘ifndef
Condition Executes block if macro is Executes block if macro is
defined not defined
Common Usage Enable code for debug/test Exclude simulation-only
mode code in synthesis
Typical Use-case Debug, logging, platform RTL exclusion from sim-
flags specific features

Pro Tips
Pro Tips
• Always end conditional compilation blocks with ‘endif to avoid errors.

• Use meaningful macro names like SIMULATION, DEBUG, SYNTHESIS.

• 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.

9.3 Timescale Directive


In Verilog, the ‘‘timescale‘ directive is used to specify the time unit and time precision
for simulation. This directive is essential for simulation accuracy, particularly when working
with delays (e.g., #5).

Syntax

Syntax Format
‘timescale <time_unit> / <time_precision>

Example:

‘timescale 1ns / 1ps

This means:

• 1ns is the time unit: delay values such as #1 mean 1 nanosecond.

107
Chapter 9 Useful Modelling Technique

• 1ps is the time precision: how accurate the simulator tracks time events.

Why Timescale Matters?

• Affects interpretation of ‘#‘ delays in simulation.

• Helps ensure consistent simulation timing across modules.

• Needed to avoid mismatches when integrating third-party IPs or modules.

Example: Simple Timescale Use

‘timescale 1ns / 1ps

module test;
initial begin
#1 $display("1ns passed");
#2 $display("2ns more passed");
end
endmodule

Output:

Valid Time Units and Precisions

• s, ms, us, ns, ps, fs

• Precision should be equal to or smaller than the time unit

Example: Incorrect Precision

‘timescale 1ns / 10ns // Incorrect!

Error: Precision must not be greater than the time unit.

108
Chapter 9 Useful Modelling Technique

Comparison Table: Time Unit vs Time Precision

Aspect Time Unit Time Precision


Meaning Base unit for delay expres- Accuracy in simulation time
sions tracking
Use-case Determines how long a de- Controls rounding in time
lay like #5 lasts calculations
Example Value 1ns, 10ps 100ps, 1ps
Dependency Delay interpretation de- Must be ≤ Time Unit
pends on this
Impact Simulation realism and be- Delay rounding and event
havior scheduling

Pro Tips

Pro Tips
• Always define ‘timescale at the top of every Verilog file for consistency.

• Mismatched timescales between modules can lead to subtle simulation errors.

• 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.

Useful System Tasks in Verilog


System tasks in Verilog are special constructs that begin with a dollar sign ($) and are used
to perform operations like displaying output, monitoring signals, file I/O, and controlling
simulation. These are only used during simulation and are not synthesizable.

1. $display

Prints messages to the console. Executes only once when called.

109
Chapter 9 Useful Modelling Technique

Syntax and Example


$display("Value of A = %b", A);

Formats:

• %b - binary

• %d - decimal

• %h - hexadecimal

2. $monitor
Continuously prints whenever any variable in the list changes.

$monitor("Time = %0t, A = %b, B = %b", $time, A, B);

3. $time, $stime, $realtime


Used to access simulation time.

• $time – returns 64-bit integer

• $stime – returns 32-bit integer

• $realtime – returns real value

$display("Current time = %0t", $time);

4. $finish and $stop


• $stop – Halts simulation temporarily, user can resume.

• $finish – Completely ends the simulation.

#100 $finish; // End simulation at 100 time units

110
Chapter 9 Useful Modelling Technique

5. $dumpfile and $dumpvars


Used for waveform generation in simulation (especially with GTKWave).

$dumpfile("waveform.vcd"); // Create VCD file


$dumpvars(0, test); // Log all signals in module "test"

Note: Must be placed in the testbench.

Comparison Table: Common System Tasks

Task Purpose Usage Scenario


$display Prints a message once For showing variable values
$monitor Prints on change of any variable For monitoring multiple vari-
in list ables
$time Returns simulation time For debugging delays and tim-
ing
$stop Halts simulation temporarily For intermediate pause in sim-
ulation
$finish Ends simulation To terminate testbench auto-
matically
$dumpfile/$dumpvars Create waveform dump To analyze behavior using
tools like GTKWave

Pro Tips
Pro Tips
• Prefer $display for static messages and $monitor for tracking changes over
time.

• Always use $finish in testbenches to avoid indefinite simulations.

• Combine $dumpfile and $dumpvars for waveform analysis.

• Use $time with $display to log when certain events occur.

• System tasks are non-synthesizable; they are used only for simulation and
debugging.

111
Chapter 9 Useful Modelling Technique

9.4 Value Change Dump (VCD) File in Verilog


A Value Change Dump (VCD) file records all the changes in signal values during simulation
and can be viewed using waveform viewers like GTKWave. This helps in visually debugging
and analyzing how signals behave over time.

Purpose
The VCD file stores simulation signal changes in a time-stamped format, allowing the user
to examine transitions, glitches, or timing issues.

Why Use a VCD File?


• To visualize waveform for better understanding

• To detect bugs or signal contention

• To analyze timing behavior

• Essential in debugging large testbenches

Steps to Generate a VCD File

How to Generate a VCD File


1. Use $dumpfile("filename.vcd") to specify output file.

2. Use $dumpvars(0, top module) to log signals starting from top.

3. Place these in the initial block of your testbench.

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:

• After simulation, run:

gtkwave waveform.vcd

• You’ll see the signal transitions and can zoom/pan through time.

Comparison Table: VCD vs System Task Outputs

Feature VCD File (GTKWave) System Tasks ($display,


$monitor)
Visibility Graphical waveform of all Console message only
signals
Detail Level Very high – includes every Limited to user-defined mes-
transition sages
Storage Output in a file (view later) Printed during simulation only
Best For Post-simulation waveform Quick value checks during run
debugging
Synthesis Impact None (simulation-only) None (simulation-only)

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 logging slows down simulation — only use when needed.

• VCD does not capture memories or variables by default — use tools like
$dumpvars deeply or switch to FST or other formats if needed.

9.5 10 Practical Examples of Useful Modeling Tech-


niques
Example 1: Using assign-deassign
module assign_example;
reg clk;
wire data;

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.

Example 2: Using force-release


module force_example;
reg a, b;

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.

Example 3: Conditional Compilation


‘define DEBUG
module cond_compile;
initial begin
‘ifdef DEBUG
$display("Debugging enabled");
‘else
$display("Debugging off");
‘endif
end
endmodule

Example 4: Timescale Usage


‘timescale 1ns/1ps
module delay_example;
reg clk = 0;
always #10 clk = ~clk;
endmodule
Explanation: Every delay (e.g., #10) is interpreted in nanoseconds with 1ps precision.

Example 5: Dumping VCD File


module vcd_test;
reg a, b;

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

Example 6: Using $monitor


module monitor_demo;
reg x, y;
initial $monitor("Time=%0t, x=%b, y=%b", $time, x, y);

initial begin
x = 0; y = 0;
#10 x = 1;
#10 y = 1;
end
endmodule

Example 7: Using $time


module time_demo;
initial begin
#5 $display("Time is %0t", $time);
end
endmodule

Example 8: Releasing Force in Testbench


module tb;
reg a;
wire b;

assign b = a;

initial begin
a = 0;
force b = 1; // overrides the assign
#10 release b; // returns to original assignment
end
endmodule

Example 9: Using $display to Debug FSM


module debug_fsm;
reg clk = 0;
reg [1:0] state = 0;

116
Chapter 9 Useful Modelling Technique

always #5 clk = ~clk;

always @(posedge clk) begin


$display("Time=%0t, State=%b", $time, state);
state = state + 1;
end
endmodule

Example 10: Combining assign-deassign and $display


module combo_demo;
reg clk;
wire out;

initial begin
clk = 0;
assign out = clk;
$display("Assigned out to clk");
#5 clk = 1;
#5 deassign out;
$display("Deassigned out");
end
endmodule

9.6 30 Practice and Interview Questions


Conceptual Questions
1. What is the purpose of ‘assign‘ and ‘deassign‘ in Verilog?

2. Differentiate between ‘force‘ and ‘assign‘.

3. What happens when ‘deassign‘ is not used after ‘assign‘?

4. What is the main difference between ‘assign-deassign‘ and ‘force-release‘?

5. Can ‘force‘ be used on a ‘reg‘ type variable?

6. Why are ‘assign-deassign‘ and ‘force-release‘ not synthesizable?

7. In what type of design would you use ‘force-release‘?

8. What is the role of ‘release‘ in the simulation?

117
Chapter 9 Useful Modelling Technique

9. When should you use conditional compilation in Verilog?

10. What happens if ‘release‘ is called without a prior ‘force‘?

Code-Based Questions
11. Write a code to demonstrate conditional compilation using ‘ı̀fdef‘ and ‘èlse‘.

12. Simulate a waveform using ‘dumpf ile‘and‘dumpvars‘.

13. Implement a counter and use ‘$monitor‘ to track its changes.

14. Write a testbench to demonstrate ‘assign-deassign‘ behavior.

15. Use $display to print internal signals during simulation.

16. Demonstrate a scenario where ‘force‘ is used to override a wire.

17. Simulate a D Flip-Flop and use ‘$time‘ to observe clock edge delays.

18. Apply ‘assign‘ to a wire and change it with ‘deassign‘.

19. Write a Verilog block using ‘force-release‘ to control a variable in a testbench.

20. Create a waveform viewer using ‘gtkwave‘ and VCD file.

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?

23. Are ‘assign‘ and ‘force‘ synthesizable? Why or why not?

24. How can timescale affect simulation resolution and delay interpretation?

25. How can you disable a portion of code during simulation without commenting it?

26. Describe the contents of a VCD file.

27. Why is dumpvars essential during waveform analysis?

28. If a forced value is never released, what simulation issues may occur?

118
Chapter 9 Useful Modelling Technique

9.7 Pro Tips


Pro Tip 1
Use ‘force-release‘ carefully in testbenches, especially if multiple signals are interacting
— releasing one too early may lead to race conditions.

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.

• ‘assign-deassign‘ is limited to nets and is useful in temporary overriding of drivers.

• ‘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.

• Learn the differences between Mealy and Moore FSMs.

• Design and code FSMs in Verilog using different coding styles.

• Use appropriate state encoding methods: binary, one-hot, or gray.

• Analyze, simulate, and debug FSM-based Verilog models.

10.1 What is an FSM?


A Finite State Machine (FSM) is a sequential logic circuit with a defined set of states. The
system transitions between these states based on input conditions, and produces outputs
either based on the current state (Moore) or both the current state and input (Mealy).
Key Components:

• States: Operational modes like IDLE, RUN, etc.

120
Chapter 10 Finite State Machines (FSM) in Verilog

• Inputs: Control or triggering signals.

• Outputs: Based on the FSM type.

• Transitions: Defined rules to switch between states.

• Clock/Reset: Synchronization and reset control.

10.2 Types of FSMs

Comparison Table: Moore vs Mealy FSMs

Feature Moore Machine Mealy Machine


Output Depends On Current state only Current state + Input
Latency Higher (output updated after Lower (output changes imme-
transition) diately with input)
Design Complexity Simpler logic, more states Fewer states, complex logic
Timing Behavior More stable outputs Outputs may glitch if inputs
change
Common Usage Control-based FSMs Fast-responsive FSMs

10.3 Moore FSM in Verilog

Structure
• State Register: Stores current state.

• Next-State Logic: Determines next state based on current state and input.

• Output Logic: Based only on the current state.

121
Chapter 10 Finite State Machines (FSM) in Verilog

Verilog Code Example

Moore FSM Code Template


module moore_fsm (
input clk, reset,
input in,
output reg out
);
typedef enum logic [1:0] {IDLE, S1, S2} state_t;
state_t state, next_state;

// 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

// Output logic (Moore: based on state)


always_comb begin
case(state)
IDLE: out = 0;
S1: out = 0;
S2: out = 1;
endcase
end
endmodule

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

10.4 Mealy FSM in Verilog

Structure
• State Register: Stores the current state.

• Next-State Logic: Decides next state based on current state and input.

• Output Logic: Based on both current state and current input.

Key Differences from Moore FSM


• Outputs can change immediately on input change, without waiting for clock edge.

• Typically requires fewer states compared to Moore FSM.

• Output may glitch if input is not stable.

123
Chapter 10 Finite State Machines (FSM) in Verilog

Verilog Code Example: Mealy FSM

Mealy FSM Code Template


module mealy_fsm (
input clk, reset,
input in,
output reg out
);
typedef enum logic [1:0] {IDLE, S1} state_t;
state_t state, next_state;

// 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 ? S1 : IDLE;
default: next_state = IDLE;
endcase
end

// Output logic (Mealy: based on state and input)


always_comb begin
case(state)
IDLE: out = 0;
S1: out = in ? 1 : 0;
endcase
end
endmodule

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.

10.5 FSM Coding Styles


Finite State Machines (FSMs) can be written in Verilog using different coding methodologies.
Each style affects readability, synthesis, and debugging. The three most common styles are:

• One-Hot Style (Flat)

• Sequential (Three-Block Style)

• Moore/Mealy Encoding within Case Statements

1. One-Hot (Flat) FSM Style


Description: All states are declared as individual bits, and only one bit is active at a time.

125
Chapter 10 Finite State Machines (FSM) in Verilog

Verilog Snippet: One-Hot FSM


reg [3:0] state;
parameter S0 = 4’b0001, S1 = 4’b0010, S2 = 4’b0100, S3 = 4’b1000;

always @(posedge clk or posedge reset) begin


if (reset)
state <= S0;
else begin
case (state)
S0: state <= in ? S1 : S0;
S1: state <= S2;
S2: state <= S3;
S3: state <= S0;
endcase
end
end

2. Three-Block FSM Style

Description: Splits FSM into three separate blocks for:

• State Register

• Next-State Logic

• Output Logic

126
Chapter 10 Finite State Machines (FSM) in Verilog

Structure of 3-block FSM


// 1. State Register
always_ff @(posedge clk or posedge reset)
if (reset)
state <= IDLE;
else
state <= next_state;

// 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

3. FSM Using Case Statements (Embedded Style)


Description: Common in simpler FSMs. Combines all logic in one always block.

Embedded FSM Style


always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else begin
case (state)
IDLE: if (in) state <= S1;
...
endcase
end
end

127
Chapter 10 Finite State Machines (FSM) in Verilog

Comparison Table: FSM Coding Styles

Feature Three-Block FSM One-Hot / Flat FSM


Readability High Medium
Debugging Ease Easy due to modular Complex for large FSMs
blocks
Synthesis Friendly Yes Yes (tool dependent)
Resource Usage Minimal May use more FFs
Output Latency One clock delay (Moore) Immediate (Mealy)
Best For RTL FSMs with clarity Small control logic, fast
outputs

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.

10.6 State Encoding Techniques


State encoding is the method used to assign binary values to symbolic states of a Finite
State Machine. The encoding impacts performance, area, and power. The most common
types are:

• 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

000, 001, 011, 010, 110, 111, 101, 100

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:

0000 → 0001 → 0011 → 0111 → 1111 → 1110 → 1100 → 1000

Pros: Suitable for counters and FSM sequencing. Cons: Less popular in general FSM
designs.

129
Chapter 10 Finite State Machines (FSM) in Verilog

Comparison Table: State Encoding Techniques

Feature Binary One-Hot Gray/Johnson


Flip-Flop Usage Minimum (log2 N ) One per state Medium
Decoding Logic Complex Simple Moderate
Glitch Resistance Low High High
Speed Medium Fast High
Power Consumption Low Medium/High Low
Best Use Case Large FSMs Small, Fast FSMs Noise-sensitive
FSMs

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.

10.7 FSM Design Examples


To understand FSM design better, let us implement two practical examples:

• Example 1: Moore FSM – Sequence Detector for “101”

• Example 2: Mealy FSM – Parity Detector

Example 1: Moore FSM – Sequence Detector “101”


Problem: Design a Moore FSM that detects the sequence “101” from serial input and
outputs 1 when the sequence is found.
States:
• S0: Initial state

• S1: ‘1’ received

• S2: ‘10’ received

130
Chapter 10 Finite State Machines (FSM) in Verilog

• S3: ‘101’ detected (Output = 1)

Verilog Code:

Moore FSM: 101 Detector


module moore_101_detector(input clk, rst, x, output reg y);
typedef enum reg [1:0] {S0, S1, S2, S3} state_t;
state_t state, next_state;

always @(posedge clk or posedge rst) begin


if (rst)
state <= S0;
else
state <= next_state;
end

always @(*) begin


case(state)
S0: next_state = (x == 1) ? S1 : S0;
S1: next_state = (x == 0) ? S2 : S1;
S2: next_state = (x == 1) ? S3 : S0;
S3: next_state = (x == 1) ? S1 : S0;
endcase
end

always @(*) begin


case(state)
S3: y = 1;
default: y = 0;
endcase
end
endmodule

Output: Output goes HIGH after receiving the sequence 101.

Example 2: Mealy FSM – Even Parity Detector


Problem: Detect whether the incoming serial bit stream has even parity using a Mealy
FSM.
States:

• S0: Even number of 1s so far

• S1: Odd number of 1s so far

131
Chapter 10 Finite State Machines (FSM) in Verilog

Output:

• y = 1 if even parity

• y = 0 if odd parity

Verilog Code:

Mealy FSM: Even Parity Detector


module mealy_parity(input clk, rst, x, output reg y);
typedef enum reg {S0, S1} state_t;
state_t state, next_state;

always @(posedge clk or posedge rst) begin


if (rst)
state <= S0;
else
state <= next_state;
end

always @(*) begin


case(state)
S0: begin
y = (x == 0) ? 1 : 0;
next_state = (x == 0) ? S0 : S1;
end
S1: begin
y = (x == 1) ? 1 : 0;
next_state = (x == 1) ? S0 : S1;
end
endcase
end
endmodule

Output: High output when parity is even, updated on each input.

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

10.8 Practice and Interview Questions


This section includes carefully curated questions that assess your understanding of FSM
design, Mealy vs Moore implementation, and practical application 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?

3. How does state encoding affect the performance of an FSM?

4. What are the types of state encoding in FSMs?

5. What are the benefits of one-hot encoding in large FSMs?

6. Can combinational logic be used inside FSMs? Why or why not?

7. How can you minimize the number of states in an FSM?

8. What is a state transition table? How is it used?

9. Describe an FSM for a traffic light controller.

10. What are the common causes of glitches in FSM output?

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.

13. Modify an FSM to add a reset condition asynchronously.

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.

16. Use one-hot encoding to implement a 4-state FSM.

17. Convert a state diagram to Verilog HDL code.

18. Debug a faulty FSM that remains stuck in a single state.

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

C. Interview-Focused Scenario-Based Questions

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?

23. How would you optimize an FSM for power reduction?

24. Explain the difference between blocking and non-blocking assignments in FSMs.

25. How do you test an FSM thoroughly using testbenches?

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?

28. What are the synthesis considerations for large FSMs?

29. Describe a scenario where a FSM interacts with another 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

10.9 Pro Tips

Pro Tips for FSMs


• Use Parameters for State Naming: Always define state names using ‘pa-
rameter‘ or ‘typedef enum‘ (in SystemVerilog) for readability and ease of main-
tenance.

• 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.

• Use Reset Wisely: Include asynchronous or synchronous resets explicitly for


FSM stability, especially at power-up.

• Case Statements for Clarity: Implement state transitions using ‘case‘ or


‘casez‘ for clear and synthesizable designs.

• Keep FSM Combinational and Synchronous Logic Separate: Separate


state transition logic and output logic to simplify debugging and synthesis.

• Use Simulation Assertions: While debugging FSMs, use ‘assert‘, ‘display‘,


and ‘monitor‘ system tasks to check state behavior.

• Document State Diagrams: Maintain updated state diagrams to map your


HDL implementation clearly — this helps in design reviews and debugging.

• 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

10.10 Mindmap: FSM Design Concepts

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

11.1 Memory Declaration and Types


In Verilog, memory is declared as arrays of data, typically using the ‘reg‘ keyword for sim-
ulation purposes. This section covers the declaration syntax and types of memory you can
model.

11.1.1 Declaring 1-Dimensional Memory Arrays


To declare a simple array of registers (used to model memory):

reg [7:0] mem_array [0:255]; // 256 memory locations, each 8 bits wide

Explanation:

• reg [7:0] specifies each word is 8 bits.

• [0:255] specifies the number of memory locations.

11.1.2 2-Dimensional Memory Declaration


reg [15:0] matrix [0:63]; // 64 locations of 16-bit words

These types are used for LUTs, register files, or basic RAM/ROM simulation.

11.1.3 Constant Memory (ROM)


For modeling ROM:

reg [7:0] rom [0:15];

initial begin
rom[0] = 8’hAA;
rom[1] = 8’hBB;
rom[2] = 8’hCC;
// ... initialize all
end

Use case: Instruction memory in CPU design.

11.1.4 Random Access Memory (RAM)


RAMs require both read and write operations:

138
Chapter 11 Memory Modeling in Verilog

reg [7:0] ram [0:255];

always @(posedge clk) begin


if (wr_en)
ram[addr] <= data_in;
else
data_out <= ram[addr];
end

11.1.5 Memory Initialization with Files


Verilog supports memory pre-loading using external files:

initial $readmemh("data.hex", ram); // Hex initialization


initial $readmemb("data.bin", ram); // Binary initialization

Useful when working with larger programs or instructions.


11.1.6 Synthesizable vs. Non-Synthesizable Memory

Feature Synthesizable Memory Non-Synthesizable Mem-


ory
Declaration Style Procedural with proper sensi- Often with initial blocks or
tivity system tasks
Behavior Implements hardware on FP- Used for simulation only
GA/ASIC
Initialization Usually inferred from block Via $readmemh, loops, or
RAM IP or inferred by tools initial
Usage Inside always blocks with clock For testbenches and simula-
control tions
Examples RAM, ROM using ‘always @‘ File preload, dynamic address-
and ‘case‘ ing in simulation

11.1.7 Flowchart: Declaring and Using Memory in Verilog


(Illustrative flowchart to be added for visual understanding: Declaration → Initialization →
Read/Write → Optional File Loading)

139
Chapter 11 Memory Modeling in Verilog

11.2 Read and Write Operations


Efficient memory access is critical in digital designs. Verilog allows both synchronous and
asynchronous memory read and write operations. This section explains different approaches
with examples.

11.2.1 Synchronous Write with Asynchronous Read


This is a common approach for RAM design.

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];

always @(posedge clk) begin


if (wr_en)
memory[addr] <= data_in;
end

assign data_out = memory[addr]; // Asynchronous read


endmodule

Key points:

• Write happens on the positive clock edge.

• Read is instantaneous, without waiting for a clock.

11.2.2 Synchronous Read and Write


Used when both read and write must be aligned to the clock (e.g., dual-port memory or
register files).

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];

always @(posedge clk) begin


if (wr_en)
memory[addr] <= data_in;
else
data_out <= memory[addr];
end
endmodule

Note: Read and write are controlled through a clock cycle and are mutually exclusive.

11.2.3 Dual-Port Memory Access


Dual-port memories allow concurrent access — one port for read and another for write.

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];

always @(posedge clk) begin


if (wr_en)
memory[wr_addr] <= data_in;
data_out <= memory[rd_addr];
end
endmodule

Advantage: Improves performance when simultaneous read and write are required.

11.2.4 Memory Read/Write Using Case Statements


For larger memory models or ROMs, use ‘case‘ for controlled access.

always @(posedge clk) begin


case (addr)
8’h00: data_out <= memory[0];
8’h01: data_out <= memory[1];

141
Chapter 11 Memory Modeling in Verilog

8’h02: data_out <= memory[2];


default: data_out <= 8’h00;
endcase
end

Pros:
• Extremely scalable

• Clean separation of data and logic


11.2.5 Dynamic Comparison Table: ROM Modeling Techniques


Method Advantages Limitations
Case Statement Easy to read, suitable Not scalable, manual
for ¡16 entries
Array Initialization Neat syntax, scalable Still hardcoded in
to moderate ROM size code
$readmemh/$readmemb Scalable to very large File dependency,
ROM, external data needs file manage-
file ment

11.3 Register File Design


A Register File is a small and fast memory unit comprising multiple registers. It allows
simultaneous reading from multiple locations and optional writing to a specific location.
Register files are often used in CPUs, microcontrollers, and DSPs to store operands, results,
and intermediate values.

11.3.1 Key Features of a Register File


• Supports multiple read and write ports

• Typically synchronous write and asynchronous/synchronous read

• Provides random access to registers

Explanation:
• 4 registers, each 8-bit wide

• 2-bit address lines used to select one of the 4 registers

142
Chapter 11 Memory Modeling in Verilog

• One write enable signal (we) to control writing

11.3.2 Verilog Code for 2R1W Register File (4 Registers, 8-bit


Wide)
module register_file (
input clk,
input we,
input [1:0] w_addr, r_addr1, r_addr2,
input [7:0] w_data,
output [7:0] r_data1,
output [7:0] r_data2
);

reg [7:0] reg_array [3:0]; // 4 registers of 8 bits

// Write Operation
always @(posedge clk) begin
if (we) begin
reg_array[w_addr] <= w_data;
end
end

// Read Operation (asynchronous)


assign r_data1 = reg_array[r_addr1];
assign r_data2 = reg_array[r_addr2];

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
);

reg [7:0] reg_file [3:0];

143
Chapter 11 Memory Modeling in Verilog

always @(posedge clk) begin


if (we)
reg_file[w_addr] <= w_data;

r_data <= reg_file[r_addr];


end
endmodule

11.3.4 Comparison Table: Asynchronous vs Synchronous Read


Feature Asynchronous Read Synchronous Read
Timing Immediate data access Data read after clock edge
Speed Faster access Slightly slower
Use-case Control-heavy logic, test- Pipeline stages, synthesis-
benches friendly
Simulation Debugging Easier to debug Timing alignment required

11.3.5 Key Design Tips


• Always reset register file contents when needed using initial or explicit reset logic.

• Avoid reading and writing the same location in the same clock cycle.

• For multi-port register files, prioritize arbitration logic to prevent data hazards.

11.4 Testbench for 2R1W Register File


This testbench writes values to specific registers and reads them using two read ports. It
helps verify the correctness of the register file’s behavior.

‘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;

// Instantiate the register file


register_file uut (
.clk(clk),
.we(we),
.w_addr(w_addr),
.r_addr1(r_addr1),
.r_addr2(r_addr2),
.w_data(w_data),
.r_data1(r_data1),
.r_data2(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;

// Wait for global reset


#10;

// Write 8’hAA to register 0


we = 1;
w_addr = 2’b00;
w_data = 8’hAA;
#10;

// Write 8’h55 to register 1


w_addr = 2’b01;
w_data = 8’h55;
#10;

// Write 8’hF0 to register 2


w_addr = 2’b10;
w_data = 8’hF0;
#10;

145
Chapter 11 Memory Modeling in Verilog

// Disable write
we = 0;

// Read from register 0 and 1


r_addr1 = 2’b00;
r_addr2 = 2’b01;
#10;

// Read from register 2 and 3 (unwritten)


r_addr1 = 2’b10;
r_addr2 = 2’b11;
#10;

$display("Test Completed.");
$stop;
end

endmodule

11.5 Summary and Pro Tips


Summary
• A Register File is a collection of registers accessible for read and write operations.
It is commonly used in CPU architectures.
• The 2R1W Register File supports two simultaneous read operations and one write
operation per clock cycle.
• It is implemented using an array of registers and accessed using read and write ad-
dresses.
• The write operation is synchronous with the clock and controlled by a write enable
signal.
• Read operations are asynchronous in basic models, but can also be made synchronous
depending on the design requirement.
• Proper testbenches are crucial to validate correct functionality — multiple values and
all register addresses should be tested.

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).

• Include ‘display‘or‘monitor‘ in testbenches to trace register values at each simulation


step.

• 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.

• Differentiate between combinational and sequential UDPs.

• Learn to write UDPs using truth tables.

• Apply UDPs in practical examples.

12.1 Theory and Syntax


User Defined Primitives can be of two types:

• Combinational UDP: No memory, output is purely based on current inputs.

• Sequential UDP: Has memory element, output depends on both current input and
previous state.

148
Chapter 12 User Defined Primitive (UDP)

Syntax

Combinational UDP Syntax


primitive primitive_name(output, input1, input2);
output output;
input input1, input2;

table
// input1 input2 : output;
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive

Comparison: UDP vs Module

Feature UDP Module


Purpose Low-level behavior model- General HDL description
ing
Structure Truth-table based RTL/Behavioral/Structural
Memory Support Only sequential UDPs Full support
Synthesizable Yes (limited) Yes
Parameterization Not supported Fully supported

Example: Combinational UDP


primitive AND_UDP(out, a, b);
output out;
input a, b;

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)

Example: Sequential UDP (D Flip-Flop)


primitive DFF_UDP(q, clk, d);
output q;
reg q;
input clk, d;

table
// clk d : q : q_next
r 0 : ? : 0;
r 1 : ? : 1;
f ? : ? : -;
endtable
endprimitive

Practice Examples
1. XNOR Gate Using UDP

primitive XNOR_UDP(out, a, b);


output out;
input a, b;

table
0 0 : 1;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive

2. OR Gate Using UDP

primitive OR_UDP(out, a, b);


output out;
input a, b;

table
0 0 : 0;
0 1 : 1;
1 0 : 1;
1 1 : 1;
endtable
endprimitive

150
Chapter 12 User Defined Primitive (UDP)

3. Latch Using Sequential UDP

primitive LATCH(q, d, en);


output q;
reg q;
input d, en;

table
// en d : q : q_next
1 0 : ? : 0;
1 1 : ? : 1;
0 ? : q : -;
endtable
endprimitive

12.2 Practice and Interview Questions


Conceptual

• What is the difference between a combinational and sequential UDP?

• Why is UDP not suitable for complex logic design?

• When would you prefer a UDP over a Verilog module?

• What are the limitations of UDPs in synthesis?

Practical/Verilog-Based

1. Create a UDP for a 3-input majority function.

2. Write a UDP for a D latch with an enable signal.

3. Implement a NOR gate using UDP.

4. Modify an existing UDP to include an unknown state.

5. Simulate a UDP in a testbench and check its waveform.

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.

• Avoid using UDPs for large or combinatorially deep logic.

• Prefer using behavioral constructs (‘always‘, ‘assign‘) for readability unless the
compactness of a UDP is required.

• You can use ‘¿ (don’t care) in UDP tables to simplify conditions.

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.

• Ideal for modeling simple gates, flip-flops, or latches at a low level.

• Limited in synthesizability, parameterization, and should be used carefully.

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

• NBA (Non-blocking Assign) 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.

• Differentiate between active, inactive, NBA, and monitor regions.

• Analyze how race conditions are avoided using proper scheduling.

• Visualize the flow using a clear flowchart representation.

153
Chapter 13 Event Scheduler

13.1 Detailed Theory with Flowchart


The Verilog event scheduler processes all events scheduled for the same simulation time in
an ordered sequence of regions. Here’s how the scheduler works during every simulation time
step:

1. Active Region: Executes blocking assignments, continuous assignments, ‘display‘, ‘monitor‘,


‘f inish‘, ‘stop‘, and evaluation of RHS expressions.

2. Inactive Region: Events postponed from the active region (usually from zero-delay
assignments).

3. NBA Region: Executes non-blocking assignments (i.e., all ‘<= assignments).

4. Monitor Region: Executes monitoring tasks (‘monitor‘, ‘strobe‘) after all values are
updated.

Flowchart: Event Scheduler in Verilog

Start Time Step

Active Region
(Blocking, Eval RHS)

Inactive Region
(Zero-delay Scheduled)

NBA Region
(Non-blocking Assignments)

Monitor Region
($monitor, $strobe)

End of Time Step

This flow ensures a clean and deterministic simulation order, minimizing unintended
interactions and race conditions.

13.2 Example: Event Scheduling


module eventdemo; reg a, b;
initial begin a = 0; b = 0; end
always @(a) begin b = a + 1; // Blocking: active region end
always @(b) begin #0 a <= b; // Non-blocking: NBA region (due to <=) end endmodule

154
Chapter 13 Event Scheduler

Simulation Walkthrough
• Time 0: a and b set to 0 in the initial block.

• Changing a triggers first always block.

• b = a + 1 happens immediately (active region).

• b changes, second always is triggered.

• a ¡= b is queued in NBA region.

• After active/inactive regions complete, NBA executes a ¡= b.

13.3 Additional Examples, Summary, and Pro Tips


13.3 Additional Examples, Summary, and Pro Tips
Example 1: Zero Delay Race Condition
module race_condition;
reg a, b;

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.

Example 2: Using #0 to Prioritize Execution


module zero_delay_fix;
reg clk, a, b;

always @(posedge clk) begin


a = 1;

155
Chapter 13 Event Scheduler

#0 b = a; // Ensures ’a’ is updated before ’b’ reads it


end
endmodule

Explanation: The #0 introduces an inactive delay, pushing the second assignment to a


later phase to avoid race conditions.

Example 3: Delays and Event Ordering


module delay_order;
reg x, y;

initial begin
x = 0;
y = 0;
#5 x = 1;
y = 1;
end
endmodule

Explanation: The assignment x = 1 is scheduled at simulation time 5 while y = 1


executes immediately at time 0.

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.

• Avoid simultaneous read/write of the same signal in multiple always blocks.

• Delta delays help ensure all operations at the same time are handled sequentially
without time progression.

• Use #0 to separate assignments when debugging timing or ordering issues.

• 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.

• Grasp techniques for modular, reusable, and maintainable testbench design.

• Develop debugging skills through simulation waveform observation.

• Create testbenches for various digital systems with increasing complexity.

14.1 Testbench Examples with Theory


Example 1: Testbench for 2:1 Multiplexer
Design Under Test (DUT):

158
Chapter 14 Efficient Testbench Writing

1 module mux2to1 ( input a , input b , input sel , output y ) ;


2 assign y = sel ? b : a ;
3 endmodule

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.

Example 2: Testbench for D Flip-Flop


DUT:
1 module dff ( input clk , input d , output reg q ) ;
2 always @ ( posedge clk )
3 q <= d ;
4 endmodule

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.

Example 3: Testbench for 4-bit Adder


DUT:
1 module adder4bit ( input [3:0] a , b , output [4:0] sum ) ;
2 assign sum = a + b ;
3 endmodule

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.

Example 4: Testbench for 8-bit Up Counter with Reset


DUT:
1 module counter ( input clk , reset , output reg [7:0] out ) ;
2 always @ ( posedge clk or posedge reset )
3 if ( reset )
4 out <= 0;
5 else
6 out <= out + 1;
7 endmodule

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.

Example 5: Testbench for AND Gate with Task-based Testcase


DUT:
1 module and_gate ( input a , b , output y ) ;
2 assign y = a & b ;
3 endmodule

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.

Testbench Example 6: Detecting a Sequence using FSM (Moore


Machine)
Objective: Detect the sequence “1011” using a Moore state machine and write an efficient
testbench.

161
Chapter 14 Efficient Testbench Writing

// FSM Module (Moore)


module seq_detector (
input clk,
input reset,
input in_bit,
output reg detected
);
typedef enum reg [2:0] {S0, S1, S2, S3, S4} state_t;
state_t state;

always @(posedge clk or posedge reset) begin


if (reset)
state <= S0;
else begin
case(state)
S0: state <= (in_bit == 1) ? S1 : S0;
S1: state <= (in_bit == 0) ? S2 : S1;
S2: state <= (in_bit == 1) ? S3 : S0;
S3: state <= (in_bit == 1) ? S4 : S1;
S4: state <= S0;
endcase
end
end

always @(state) begin


detected = (state == S4);
end
endmodule

// Testbench
module tb_seq_detector;
reg clk, reset, in_bit;
wire detected;

seq_detector dut (.clk(clk), .reset(reset), .in_bit(in_bit), .detected(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 Example 7: Edge Detection


Objective: Create a module to detect rising edge and verify with a testbench.

// Edge Detector Module


module edge_detector(
input clk,
input sig,
output reg edge
);
reg sig_d;

always @(posedge clk) begin


sig_d <= sig;
edge <= sig & ~sig_d;
end
endmodule

// Testbench
module tb_edge_detector;
reg clk, sig;
wire edge;

edge_detector dut (.clk(clk), .sig(sig), .edge(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

Example 13: Testbench for 2-to-1 Multiplexer


Theory: A 2-to-1 MUX selects one of two inputs based on a select line.

module mux2x1(input a, b, sel, output y);


assign y = sel ? b : a;
endmodule

module tb_mux2x1();
reg a, b, sel;
wire y;

mux2x1 uut(.a(a), .b(b), .sel(sel), .y(y));

initial begin
a = 0; b = 1;
sel = 0; #10;
sel = 1; #10;
$finish;
end
endmodule

Example 14: Testbench for 4-bit Adder


Theory: This testbench verifies a 4-bit adder module.

module adder_4bit(input [3:0] a, b, output [4:0] sum);


assign sum = a + b;
endmodule

module tb_adder_4bit();
reg [3:0] a, b;
wire [4:0] sum;

adder_4bit uut (.a(a), .b(b), .sum(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

14.2 Practice and Interview Questions


These questions are designed to test your understanding of efficient testbench
development and debugging in Verilog.

Conceptual and Design Questions


1. What is the purpose of a testbench in Verilog?

2. How does a testbench differ from the design under test (DUT)?

3. What are the different phases of a testbench execution?

4. What is the role of initial and always blocks in a testbench?

5. How do you generate a clock signal in a testbench?

6. What are self-checking testbenches?

7. What is the use of $monitor‘, $display‘, and $strobe‘?

8. What is the advantage of using tasks and functions inside a testbench?

9. What is the importance of ‘timescale‘ in simulation?

10. How can you simulate asynchronous resets in a testbench?

Verilog-Based Coding Practice

11. Write a testbench to simulate a 2-to-1 multiplexer.

12. Design a testbench to verify a 4-bit binary up-counter.

13. Write a testbench that checks both synchronous and asynchronous reset behavior.

14. Create a testbench for a D flip-flop and monitor metastability.

15. Simulate a full adder using various test vectors in a loop.

16. Generate a clock and reset signal in a structured testbench.

17. Use ‘for‘ loop and arrays to automate test cases in a testbench.

18. Simulate edge-triggered behavior using ‘@(posedge clk)‘ constructs.

165
Chapter 14 Efficient Testbench Writing

19. Write a testbench for a finite state machine (FSM) that detects ‘1011‘.

20. Use ‘repeat‘ and ‘while‘ loops to simulate a counter.

Debugging and Optimization Scenarios

21. Your testbench runs but shows ‘X‘ outputs. What could be wrong?

22. Explain how ‘dumpf ile‘and‘dumpvars‘ help in debugging.

23. How would you log all testbench events with timestamps?

24. Your simulation output is stuck. What would be your approach to debug it?

25. Describe the difference between blocking and non-blocking in testbenches.

26. How can a race condition arise in a poorly written testbench?

27. What is the use of delay modeling in testbenches?

28. Explain how you would simulate a handshaking protocol.

29. Write a checklist to validate a testbench for a UART module.

30. Create a testbench for a memory block that tests read and write functionality.

166
Chapter 14 Efficient Testbench Writing

14.3 Pro Tips for Efficient Testbench Writing

Pro Tips for Better Testbenches


• Start Small: Always test small pieces of your design before building large
testbenches.

• Use ‘timescale‘: Define timing precision and unit clearly to avoid simulation
mismatch.

• Clock Generation: Use ‘always #5 clk = c̃lk;‘ to produce reliable square-wave


clocks.

• Automation: Automate test vectors using ‘for‘, ‘repeat‘, and ‘case‘ statements
to reduce manual errors.

• Self-Checking: Always include assertions or comparisons in your testbench to


validate results automatically.

• Waveform Dumping: Use ‘dumpf ile(”wave.vcd”)‘and‘dumpvars‘ to visualize


signals in GTKWave or ModelSim.

• 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.

• Key constructs include ‘initial‘, ‘always‘, ‘$display‘, ‘$monitor‘, ‘$dumpvars‘,


‘tasks‘, and ‘functions‘.

• Efficient testbenches are modular, self-checking, reusable, and well-documented.

• Simulation tools and waveform viewers like GTKWave are crucial for debugging.

• Practice with real-world testbenches enhances design robustness and verification


speed.

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.

15.1 Questions 1–40: Verilog Basics and Syntax


1. What is the difference between Verilog and VHDL?

2. Explain the purpose of the ‘module‘ keyword in Verilog.

3. What are ‘wire‘ and ‘reg‘ in Verilog?

4. Describe the difference between ‘initial‘ and ‘always‘ blocks.

5. What are blocking and non-blocking assignments in Verilog?

6. Why is non-blocking assignment preferred in sequential circuits?

7. How do you define a 4-bit register in Verilog?

8. What is the default value of a register in Verilog?

9. What is the use of ‘parameter‘ in Verilog?

10. Explain the use of ‘generate‘ blocks in Verilog.

11. What is the difference between ‘case‘, ‘casex‘, and ‘casez‘?

12. What is the role of ‘display‘, ‘monitor‘, and $finish‘?

13. How do you implement a 4:1 multiplexer using Verilog?

169
Chapter 15 200 Verilog Interview Questions

14. What are system tasks in Verilog?

15. Define and differentiate between combinational and sequential logic in Verilog.

16. What are continuous assignments?

17. When would you use ‘assign‘ statements?

18. How can you model tristate logic in Verilog?

19. What are ‘initial‘ and ‘always‘ blocks used for in simulations?

20. Can you declare variables inside ‘always‘ blocks?

21. Explain the difference between ‘posedge‘ and ‘negedge‘.

22. How do you declare and use arrays in Verilog?

23. What are compiler directives in Verilog?

24. What does ‘timescale‘ do?

25. What is ‘blocking delay‘ and ‘non-blocking delay‘?

26. Describe how to write a D Flip-Flop using Verilog.

27. Explain the concept of implicit and explicit nets.

28. How does a ‘for‘ loop differ from a ‘repeat‘ loop in Verilog?

29. What is ‘inferred latch‘ in Verilog and when does it occur?

30. How do you initialize memories in Verilog?

31. What are race conditions in Verilog?

32. How do you define multiple modules in a single file?

33. How do you handle asynchronous reset in Verilog?

34. What are simulation commands available in Verilog?

35. Can a ‘wire‘ be used as output in a module?

36. What is a port list and how is it defined?

37. Explain what is meant by ‘implicit continuous assignment‘.

38. How do you instantiate a module in another module?

39. Describe what a ‘sensitivity list‘ is and when it should be used.

40. What is the difference between simulation and synthesis?

170
Chapter 15 200 Verilog Interview Questions

15.2 Questions 41–202: Modeling, Operators, and Con-


trol Structures
41. What are the types of modeling styles in Verilog?

42. Compare dataflow and behavioral modeling.

43. Explain the concept of hierarchical modeling in Verilog.

44. What are the different types of delays in Verilog?

45. How is a ‘gate delay‘ modeled in Verilog?

46. What are the types of operators supported by Verilog?

47. Describe bitwise vs logical operators in Verilog.

48. What are reduction operators in Verilog? Provide examples.

49. What is the purpose of shift operators?

50. What are conditional operators in Verilog?

51. How does Verilog handle operator precedence?

52. What is the difference between ‘if-else‘ and ‘case‘ statements?

53. How do you avoid latch inference in conditional structures?

54. What are the pitfalls of incomplete ‘case‘ or ‘if‘ statements?

55. What is meant by parallel case vs full case in synthesis?

56. What is ‘disable‘ statement in Verilog?

57. Explain the use of ‘fork-join‘ in Verilog.

58. What is event control? List different types.

59. How is ‘wait‘ statement used in Verilog?

60. Explain how a ‘forever‘ loop differs from a ‘while‘ loop.

61. What is a ‘named block‘ in Verilog?

62. Explain the difference between a blocking assignment in a ‘begin-end‘ block vs ‘fork-
join‘.

63. Describe how you implement priority encoding in Verilog.

64. What are generate-if and generate-for constructs?

171
Chapter 15 200 Verilog Interview Questions

65. How do ‘defparam‘ and ‘parameter‘ differ?

66. What happens if the ‘sensitivity list‘ is incomplete?

67. What is a ‘disable fork‘ statement used for?

68. How do you model a counter in Verilog?

69. How do you create a priority encoder in Verilog?

70. What are the design issues with deeply nested ‘if‘ statements?

71. Describe how to use functions inside Verilog modules.

72. What is the role of ‘random‘, ‘urandom‘, and $dist uniform‘?

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?

75. What is ‘strength‘ and ‘drive‘ in gate-level modeling?

76. What is a ‘primitive‘ in Verilog?

77. How does Verilog resolve multiple drivers on a wire?

78. Explain the concept of 4-state logic in Verilog.

79. What is the use of ‘buf‘ and ‘not‘ primitives?

80. What are the differences between ‘assign‘ and ‘force‘?

81. What are concurrent statements in Verilog?

82. Differentiate between a blocking assignment and a continuous assignment.

83. What is a simulation delta cycle?

84. What is an ‘initial‘ block, and how is it different from ‘always‘?

85. Explain how delays can be modeled in Verilog.

86. What is a delay control and event control?

87. Can we write an ‘always‘ block inside a module more than once?

88. Why do we use ‘posedge‘ and ‘negedge‘?

89. What is the functionality of ‘display‘, $monitor‘, and‘finish‘?

90. How do you use ‘timescale‘ in Verilog?

172
Chapter 15 200 Verilog Interview Questions

91. What are race conditions in Verilog simulations?

92. How do you simulate a memory module in Verilog?

93. What is the difference between ‘force‘ and ‘assign‘?

94. How do you model tristate logic in Verilog?

95. What is the function of ‘casex‘ and ‘casez‘ in Verilog?

96. What are implicit nets in Verilog?

97. How do you prevent implicit nets in a Verilog design?

98. What is synthesis, and how does it relate to Verilog coding?

99. Explain why not all Verilog constructs are synthesizable.

100. What is RTL (Register Transfer Level)?

101. Explain the ‘generate‘ block in Verilog.

102. What are Verilog attributes and where are they used?

103. What is a ‘parameter‘ in Verilog, and how is it used?

104. What is a ‘localparam‘ and how is it different from ‘parameter‘?

105. Can a parameter value be changed during simulation?

106. What are hierarchical names in Verilog?

107. What is a sensitivity list and how does it work?

108. Explain how a flip-flop is modeled in Verilog.

109. How do you implement a finite state machine (FSM) in Verilog?

110. How can we avoid latches in Verilog?

111. What is the role of ‘default‘ in case statements?

112. How do you handle asynchronous reset in sequential circuits?

113. How do you write a 4-to-1 multiplexer in Verilog?

114. How can a testbench be written for a multiplexer?

115. What is the function of the $random‘ system task?

116. How do you use $readmemh‘ and $readmemb‘?

117. Can two ‘always‘ blocks write to the same signal?

173
Chapter 15 200 Verilog Interview Questions

118. What are overlapping and non-overlapping clocks?

119. How can setup and hold time violations be modeled?

120. Describe how you would debug a non-functional Verilog design.

121. What is meant by zero delay in Verilog?

122. How do you model combinational logic using ‘always‘ blocks?

123. How would you implement a priority encoder in Verilog?

124. What is the difference between a blocking and non-blocking assignment in terms of
simulation results?

125. Why is it a bad practice to mix blocking and non-blocking assignments?

126. Describe the types of loops available in Verilog.

127. What is the function of the $time‘ system task?

128. Explain the scope of variables and signals in Verilog.

129. What is a race condition and how can it be avoided?

130. How do you create parameterized modules in Verilog?

131. What is the purpose of testbenches?

132. Can you synthesize a testbench?

133. How can assertions be implemented in Verilog?

134. How do you ensure that your design is resettable?

135. What is a blocking assignment used for in testbenches?

136. What is synthesis tool behavior for ‘casex‘ and ‘casez‘?

137. What are some best practices in Verilog coding for synthesis?

138. How do you check whether your design meets timing constraints?

139. How do you model memory elements like RAM or ROM?

140. What is the difference between $display‘ and $strobe‘?

141. What is the Verilog ‘disable‘ statement used for?

142. Can you write recursive functions in Verilog?

143. What is the difference between ‘wire‘ and ‘reg‘ in Verilog?

174
Chapter 15 200 Verilog Interview Questions

144. Explain the purpose of $dumpvars‘ and $dumpfile‘.

145. How do you model a FIFO using Verilog?

146. What is a gray code counter and how would you implement it?

147. How would you detect a metastability issue in your simulation?

148. What is the role of ‘posedge clk‘ in a D flip-flop model?

149. Explain the use of named blocks in Verilog.

150. What are the different ways to describe hardware in Verilog?

151. What is a testbench delay and how does it affect simulation?

152. Describe how a ring counter works and its Verilog implementation.

153. Can a procedural block drive multiple signals at once?

154. How do you write a priority encoder using a case statement?

155. What’s the difference between RTL and Gate-Level modeling?

156. How would you write a self-checking testbench?

157. How do you log simulation results to a file in Verilog?

158. What is a ‘repeat‘ loop and where is it used?

159. What are asynchronous FIFO and how are they implemented?

160. How can you reduce simulation time in a large design?

161. What is the difference between ‘posedge‘ and ‘negedge‘ triggers?

162. What are the benefits of using ‘generate‘ blocks in Verilog?

163. Explain the role of ‘monitor‘andhowitdif f ersf rom‘display‘.

164. How can you ensure a testbench covers all corner cases?

165. What are synthesis directives and how are they used?

166. Describe the differences between Verilog-1995, Verilog-2001, and SystemVerilog.

167. What are the steps involved in verifying a Verilog design?

168. How does a ‘for‘ loop behave differently in simulation vs. synthesis?

169. What is the difference between ‘initial‘ and ‘always‘ blocks?

170. What precautions must be taken when using asynchronous resets?

175
Chapter 15 200 Verilog Interview Questions

171. What is a glitch, and how can it be avoided in Verilog?

172. What is a combinational feedback loop and why should it be avoided?

173. What are synthesis warnings, and how should you handle them?

174. What is a latch? How can you avoid unintentional latch inference?

175. How can you pass parameters into a module?

176. What is meant by “design under test” (DUT) in a testbench?

177. How do you verify a state machine’s transitions?

178. Can you simulate multiple clock domains in Verilog?

179. What is the effect of using blocking assignments in sequential logic?

180. What is the recommended method to initialize memory in Verilog?

181. What are commonly used verification methodologies for Verilog?

182. How would you implement a watchdog timer in Verilog?

183. What is the difference between hierarchical and flat design in Verilog?

184. How can you control simulation time granularity?

185. What are ‘tri‘ and ‘tri0/tri1‘ nets in Verilog?

186. How would you write a parameterized counter?

187. What is the purpose of ‘localparam‘ over ‘parameter‘?

188. What’s the difference between ‘defparam‘ and ‘parameter override‘?

189. How can you force or release a signal during simulation?

190. What are the different simulation phases in Verilog?

191. What does ‘f inish‘doandhowisitdif f erentf rom‘stop‘?

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?

194. What’s the difference between inter-assignment and intra-assignment delay?

195. Can a single module have multiple ‘initial‘ blocks?

196. What are user-defined primitives (UDP) in Verilog?

197. How is a ‘posedge clk‘ different from ‘posedge‘ any signal?

176
Chapter 15 200 Verilog Interview Questions

198. How do you implement handshaking protocols in Verilog?

199. What is the role of event control statements in Verilog?

200. Describe how to design and verify a UART protocol in Verilog.

201. What is the difference between a synthesizable and non-synthesizable construct?

202. Describe a real-world project where you wrote Verilog code and verified it.

177
Chapter 16 : Problems with Solutions

Let’s Code to Conquer!


This chapter contains structured hands-on Verilog projects to reinforce
concepts and improve real-world design thinking.

Project Levels
Project Categories
• Beginner

• Intermediate

• Advanced

178
Chapter 16 Problems with Solutions

Beginner Projects (1–100)


Project 1: 2-Input AND Gate
Objective: Implement a 2-input AND gate using Verilog.

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.

Project 2: 2-to-1 Multiplexer


Objective: Write a simple 2:1 MUX using assign statement.

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.

Project 3: Half Adder


Objective: Create a Half Adder using gate-level modeling.

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

Project 4: Full Adder

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;

half_adder HA1 (A, B, Sum1, Carry1);


half_adder HA2 (Sum1, Cin, Sum, Carry2);

assign Cout = Carry1 | Carry2;


endmodule

Pro Tip
Pro Tip: Use structural modeling to wire up submodules like in this example!

Project 5: 4-Bit Ripple Carry Adder

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;

full_adder FA0 (A[0], B[0], Cin, Sum[0], C1);


full_adder FA1 (A[1], B[1], C1, Sum[1], C2);
full_adder FA2 (A[2], B[2], C2, Sum[2], C3);
full_adder FA3 (A[3], B[3], C3, Sum[3], Cout);
endmodule

180
Chapter 16 Problems with Solutions

Pro Tip
Pro Tip: Great first project to test on waveform viewers and learn carry propagation
delays.

Project 6: 4-Bit Comparator


Objective: Compare two 4-bit numbers and output greater, less, or equal.

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.

Project 7: 3-to-8 Decoder


Objective: Build a decoder with enable input.

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

Project 8: 8-to-3 Encoder


Objective: Create a basic priority encoder.

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!

Project 10: T Flip-Flop using D Flip-Flop


Objective: Convert D flip-flop into T flip-flop using 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.

Project 11: 4-to-1 Multiplexer


Objective: Implement a 4-to-1 multiplexer using ‘case‘ statement.

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.

Project 12: 1-to-4 Demultiplexer


Objective: Design a 1-to-4 demux controlled by select lines.

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.

Project 13: 4-bit Register with Enable


Objective: Store and hold 4-bit data on clock with enable.

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.

Project 14: 4-bit Up Counter


Objective: Design a 4-bit synchronous up counter with reset.

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!

Project 15: 4-bit Down Counter


Objective: Reverse the direction of counting.

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.

Project 16: Bidirectional Counter


Objective: Create a 4-bit counter that can count up or down based on a control signal.

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.

Project 17: Gray Code Converter


Objective: Convert binary input to gray code.

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.

Project 18: Parity Generator

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.

Project 19: Sequence Detector (1011)

Objective: Detect the pattern ‘1011‘ in a bit stream.

187
Chapter 16 Problems with Solutions

Verilog Code
module seq_detect_1011 (
input clk, rst, X,
output reg Z
);
reg [2:0] state;

parameter S0=0, S1=1, S2=2, S3=3;

always @(posedge clk or posedge rst) begin


if (rst) begin
state <= S0; Z <= 0;
end else begin
case(state)
S0: state <= (X==1) ? S1 : S0;
S1: state <= (X==0) ? S2 : S1;
S2: state <= (X==1) ? S3 : S0;
S3: begin
Z <= (X==1) ? 1 : 0;
state <= (X==1) ? S1 : S2;
end
endcase
end
end
endmodule

Pro Tip
Pro Tip: Try Moore version for a better understanding of FSMs.

Project 20: Majority Voter (3 Inputs)


Objective: Output 1 when two or more inputs are HIGH.

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.

Project 21: D Flip-Flop with Asynchronous Reset


Objective: Design a positive-edge triggered D Flip-Flop with asynchronous reset.

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.

Project 22: D Flip-Flop with Enable


Objective: Create a DFF that only updates output when enable is HIGH.

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.

Project 23: JK Flip-Flop

Objective: Implement a classic JK flip-flop behavior.

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.

Project 24: T Flip-Flop

Objective: Create a toggle flip-flop using JK logic.

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.

Project 25: 4-bit Synchronous Counter with Enable


Objective: Counter that counts only when enable is HIGH.

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.

Project 26: Clock Divider by 2


Objective: Create a clock divider using a T flip-flop logic.

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.

Project 27: Clock Divider by 4


Objective: Use a 2-bit counter to divide clock frequency.

Verilog Code
module clk_div4 (
input clk, rst,
output reg clk_out
);
reg [1:0] count;

always @(posedge clk or posedge rst) begin


if (rst) begin
count <= 0;
clk_out <= 0;
end else begin
count <= count + 1;
if (count == 2’b11)
clk_out <= ~clk_out;
end
end
endmodule

192
Chapter 16 Problems with Solutions

Project 28: Clock Divider by N (Parameterizable)

Objective: Build a clock divider with customizable divide factor.

Verilog Code
module clk_div_n #(parameter N = 10)(
input clk, rst,
output reg clk_out
);
reg [$clog2(N)-1:0] count;

always @(posedge clk or posedge rst) begin


if (rst) begin
count <= 0;
clk_out <= 0;
end else begin
if (count == N-1) begin
count <= 0;
clk_out <= ~clk_out;
end else
count <= count + 1;
end
end
endmodule

Pro Tip
Pro Tip: Use ‘clog2‘ to make the design more scalable.

Project 29: Priority Encoder (4-to-2)

Objective: Encode the highest priority input out of 4.

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

Project 30: Edge Detector (Rising Edge)

Problem: Design a module that detects the rising edge of a signal.

Solution:
1 module edge_detector (
2 input clk ,
3 input signal ,
4 output reg edge_detected
5 );
6 reg signal_d ;
7

8 always @ ( posedge clk ) begin


9 signal_d <= signal ;
10 edge_detected <= signal & ~ signal_d ;
11 end
12 endmodule

194
Chapter 16 Problems with Solutions

Project 31: Pulse Generator


Problem: Generate a single clock cycle pulse for every rising edge of an input.

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

Project 32: 2-to-4 Decoder


Problem: Implement a 2-to-4 decoder using behavioral Verilog.

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

Project 33: D Flip-Flop with Enable and Async Reset


Problem: Design a D flip-flop with enable and asynchronous reset.

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

Project 34: 4-bit Synchronous Counter with Enable


Problem: Create a 4-bit synchronous counter that increments only when enable is
high.

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

Project 35: 3-bit Binary Up Counter (Asynchronous Reset)

Problem: Design a 3-bit up counter with asynchronous reset.

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

Project 36: T Flip-Flop using D Flip-Flop


Problem: Implement a T flip-flop using a D flip-flop logic.

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

Project 37: Synchronous Resettable D Flip-Flop


Problem: Design a D flip-flop with a synchronous reset.

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

Project 38: 1-bit Magnitude Comparator


Problem: Design a 1-bit comparator that gives output for A ¿ B, A ¡ B, A == B.

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

Project 39: 8-to-3 Priority Encoder


Problem: Design an 8-to-3 priority encoder with valid output.

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

Project 40: 4-bit Up/Down Counter

Problem: Design a 4-bit up/down counter. The counter should increment or


decrement based on the updown signal.

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

Project 41: 4-bit Binary to Gray Code Converter


Problem: Implement a 4-bit binary to Gray code converter.

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

Project 42: 3-to-8 Line Decoder


Problem: Design a 3-to-8 line decoder.

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

Project 43: 4-bit Binary Subtractor


Problem: Design a 4-bit binary subtractor. The subtractor should handle borrow
detection.

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

Project 44: 4-bit Binary Adder


Problem: Implement a 4-bit binary adder. The adder should include a carry-out bit.

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

Project 45: 8-bit Multiplier


Problem: Design an 8-bit multiplier. The module should take two 8-bit inputs and
output the 16-bit product.

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

Project 46: 4-bit Magnitude Comparator


Problem: Create a 4-bit magnitude comparator. The output should indicate whether
one number is greater than, less than, or equal to the other.

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

Project 47: 4-bit Parity Generator


Problem: Design a 4-bit parity generator. The module should generate an even or
odd parity bit based on the inputs.

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

Project 48: 4-bit D Flip-Flop


Problem: Design a 4-bit D flip-flop. The flip-flop should latch the input value on
the rising edge of the clock signal.

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

Project 49: Shift Register (4-bit)

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

Project 50: 4-bit Counter with Enable


Problem: Design a 4-bit counter with enable. 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 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

Project 51: 4-bit Up/Down Counter

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

Project 52: 8-bit Comparator


Problem: Design an 8-bit comparator that compares two 8-bit inputs and returns
a result indicating if the first number is greater, equal, or less than the second number.

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

Project 53: 4-bit Binary to BCD Converter


Problem: Create a 4-bit binary to BCD converter. The output should represent the
binary input in Binary Coded Decimal (BCD).

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

Project 54: Priority Encoder


Problem: Design a 4-bit priority encoder that takes 4 input lines and returns a 2-bit
output. The output should represent the highest priority active input.

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

Project 55: 4-bit Up Counter with Enable


Problem: Design a 4-bit up counter with an enable input. The counter should
increment only when the enable signal is active.

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

Project 56: 4-bit Down Counter with Enable


Problem: Design a 4-bit down counter with an enable input. The counter should
decrement only when the enable signal is active.

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

Project 57: Johnson Counter


Problem: Design a 4-bit Johnson counter. The output should create a sequence of
4-bit patterns, cycling through a set of states.

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

Project 58: 4-bit Binary to Gray Code Converter


Problem: Create a 4-bit binary to Gray code converter. The output should convert
a binary number into its corresponding Gray code.

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

Project 59: 4-bit Gray to Binary Converter


Problem: Create a 4-bit Gray code to binary converter. The output should convert
a Gray code number into its corresponding binary value.

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

Project 60: 4-bit Synchronous Up Counter


Problem: Design a 4-bit synchronous up counter. The counter should increment on
every clock pulse, and it should reset to 0 when the reset signal is asserted.

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

Project 61: 4-bit Up/Down Counter with Enable

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

Project 62: 4-bit D Flip-Flop


Problem: Design a 4-bit D flip-flop. The output should store the 4-bit value from
the input ‘d‘ on the rising edge of the clock.

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

Project 63: 4-bit Register with Parallel Load


Problem: Design a 4-bit register that can load data in parallel. The register should
load the input data when the load signal is active.

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

Project 64: 4-bit Synchronous Resettable Counter


Problem: Design a 4-bit counter with synchronous reset. The counter should reset
to 0 on the rising edge of the reset signal, and otherwise increment on the rising edge
of the clock.

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

Project 65: Frequency Divider


Problem: Design a frequency divider that divides the input clock frequency by a
factor of 2. The output should toggle its state on every clock cycle.

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

Project 66: 4-bit Shift Register


Problem: Design a 4-bit shift register. The register should shift left or right based
on the control signal. The data should shift in on every clock cycle.

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

Project 67: 4-bit Even Parity Generator


Problem: Design a 4-bit even parity generator. The output should be a 4-bit value
along with an additional parity bit, such that the total number of ones in the output
(including the parity bit) is even.

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

Project 68: 4-bit Even Parity Checker


Problem: Design a 4-bit even parity checker. The output should indicate whether
the 4-bit input has even parity.

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

Project 69: 4-bit Odd Parity Generator


Problem: Design a 4-bit odd parity generator. The output should be a 4-bit value
along with an additional parity bit, such that the total number of ones in the output
(including the parity bit) is odd.

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

Project 70: 4-bit Odd Parity Checker


Problem: Design a 4-bit odd parity checker. The output should indicate whether
the 4-bit input has odd parity.

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

Project 71: 4-bit Binary to Gray Code Converter


Problem: Design a 4-bit binary to Gray code converter. The output should be the
equivalent Gray code for the 4-bit binary input.

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

Project 72: 4-bit Gray to Binary Converter


Problem: Design a 4-bit Gray code to binary converter. The output should be the
equivalent binary code for the 4-bit Gray code input.

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

Project 73: 4-bit Priority Encoder


Problem: Design a 4-bit priority encoder. The encoder should output a 2-bit binary
code corresponding to the highest-priority active input.

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

Project 74: 4-bit 2-to-1 Multiplexer


Problem: Design a 4-bit 2-to-1 multiplexer. The multiplexer should select one of
the two 4-bit inputs based on the select signal.

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

Project 75: 4-bit 4-to-1 Multiplexer


Problem: Design a 4-bit 4-to-1 multiplexer. The multiplexer should select one of
the four 4-bit inputs based on the 2-bit select signal.

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

Project 76: 4-bit Full Adder


Problem: Design a 4-bit full adder. The adder should take two 4-bit inputs and
produce a 4-bit sum along with a carry-out.

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

Project 77: 4-bit Subtractor


Problem: Design a 4-bit subtractor. The subtractor should take two 4-bit inputs
and produce a 4-bit difference along with a borrow-out.

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

Project 78: 4-bit Multiplication


Problem: Design a 4-bit multiplier. The multiplier should take two 4-bit inputs and
produce an 8-bit product.

Solution:
1 module multiplier (
2 input [3:0] a , b ,
3 output [7:0] product
4 );
5 assign product = a * b ;
6 endmodule

Project 79: 4-bit Divider


Problem: Design a 4-bit divider. The divider should take two 4-bit inputs and
produce a quotient and remainder.

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

Project 80: 4-bit AND Gate


Problem: Design a 4-bit AND gate. The gate should perform a bitwise AND
operation between two 4-bit inputs.

Solution:
1 module and_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = a & b ;
6 endmodule

Project 81: 4-bit OR Gate


Problem: Design a 4-bit OR gate. The gate should perform a bitwise OR operation
between two 4-bit inputs.

Solution:
1 module or_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = a | b ;
6 endmodule

Project 82: 4-bit XOR Gate


Problem: Design a 4-bit XOR gate. The gate should perform a bitwise XOR
operation between two 4-bit inputs.

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

Project 83: 4-bit XNOR Gate


Problem: Design a 4-bit XNOR gate. The gate should perform a bitwise XNOR
operation between two 4-bit inputs.

Solution:
1 module xnor_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = ~( a ^ b ) ;
6 endmodule

Project 84: 4-bit NOT Gate


Problem: Design a 4-bit NOT gate. The gate should perform a bitwise NOT
operation on a 4-bit input.

Solution:
1 module not_gate (
2 input [3:0] a ,
3 output [3:0] out
4 );
5 assign out = ~ a ;
6 endmodule

Project 85: 4-bit NAND Gate


Problem: Design a 4-bit NAND gate. The gate should perform a bitwise NAND
operation between two 4-bit inputs.

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

Project 86: 4-bit NOR Gate


Problem: Design a 4-bit NOR gate. The gate should perform a bitwise NOR
operation between two 4-bit inputs.

Solution:
1 module nor_gate (
2 input [3:0] a , b ,
3 output [3:0] out
4 );
5 assign out = ~( a | b ) ;
6 endmodule

Project 87: 4-bit Comparator


Problem: Design a 4-bit comparator. The comparator should output 1 if both 4-bit
inputs are equal, otherwise 0.

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

Project 88: 4-bit Decoder


Problem: Design a 4-bit decoder. The decoder should take a 2-bit input and
generate one of the four 1-bit outputs based on the input.

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

Project 89: 4-bit Up-Counter


Problem: Design a 4-bit up-counter. The counter should increment by 1 with each
clock cycle.

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

Project 90: 4-bit Down-Counter


Problem: Design a 4-bit down-counter. The counter should decrement by 1 with
each clock cycle.

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

Project 91: 4-bit ALU

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

Project 92: 16-bit Shift Register


Problem: Design a 16-bit shift register with left and right shift operations. The shift
register should support both synchronous and asynchronous reset.

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

Project 93: 8-bit Multiplier


Problem: Design an 8-bit multiplier. The multiplier should take two 8-bit inputs
and produce a 16-bit result. Use a combinational approach without any clocking.

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

Project 94: 4-bit Priority Encoder


Problem: Design a 4-bit priority encoder. The encoder should take a 4-bit input
and produce a 2-bit output that represents the binary code of the highest priority bit.
If no input is active, output should be 00.

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

Project 95: 16-bit Synchronous Counter


Problem: Design a 16-bit synchronous counter that counts from 0 to 65535 and
resets to 0 on a reset signal. The counter should have a clock enable input.

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

Project 96: 8-bit Barrel Shifter


Problem: Design an 8-bit barrel shifter. The barrel shifter should be able to perform
both left and right shift operations. The shift amount should be a 3-bit value, allowing
shifts from 0 to 7 positions.

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

Project 97: 8-bit Full Adder with Carry-In


Problem: Design an 8-bit full adder with carry-in. The adder should take two 8-bit
inputs, a carry-in, and produce an 8-bit sum and a carry-out.

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

Project 98: 4-bit Register File


Problem: Design a 4-bit register file with 4 registers and a 2-bit register address
input. The register file should have a write-enable signal and be able to read and
write to registers.

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

Project 99: 8-bit Comparator


Problem: Design an 8-bit comparator that compares two 8-bit values and outputs
‘1‘ if they are equal, otherwise ‘0‘.

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

Project 100: 4-bit RAM with Read/Write Enable

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

Project 101: 8-bit Dual-Port RAM


Problem: Design an 8-bit dual-port RAM with separate read and write ports. This
memory should allow simultaneous reading and writing to different locations.
Solution:
1 module dual_port_ram (
2 input clk ,
3 input [3:0] addr_a , addr_b ,
4 input [7:0] data_in_a , data_in_b ,
5 input we_a , we_b , // Write enable for both ports
6 output reg [7:0] data_out_a , data_out_b
7 );
8 reg [7:0] memory [15:0]; // 16 words of 8 bits each
9

10 always @ ( posedge clk ) begin


11 if ( we_a )
12 memory [ addr_a ] <= data_in_a ; // Write to port A
13 else
14 data_out_a <= memory [ addr_a ]; // Read from port A
15

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

Project 102: 16-bit FIFO Buffer

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

Project 103: 32-bit ROM

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

Project 104: 8-bit Static RAM (SRAM)

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

Project 105: 64-bit Shift Register File


Problem: Design a 64-bit shift register file with 8 registers. The shift register file
should have a shift-left and shift-right operation, and each register should be 64 bits
wide.
Solution:
1 module shift_reg_file (
2 input clk , reset , shift_left , shift_right ,
3 input [2:0] addr ,
4 input [63:0] data_in ,
5 output reg [63:0] data_out
6 );
7 reg [63:0] registers [7:0]; // 8 registers of 64 bits each
8
9 always @ ( posedge clk or posedge reset ) begin
10 if ( reset )
11 data_out <= 64 ’ b0 ;
12 else if ( shift_left )
13 data_out <= data_in << 1;
14 else if ( shift_right )
15 data_out <= data_in >> 1;
16 else
17 data_out <= registers [ addr ];
18 end
19 endmodule

234
Chapter 16 Problems with Solutions

Project 106: 8-bit FIFO with Full and Empty Flags


Problem: Design an 8-bit FIFO queue with full and empty flags. The FIFO should
have 16 slots, each 8 bits wide, and should manage data with read and write pointers.
Solution:
1 module fifo_queue (
2 input clk , reset , write_en , read_en ,
3 input [7:0] data_in ,
4 output reg [7:0] data_out ,
5 output reg full , empty
6 );
7 reg [7:0] memory [15:0]; // 16 slots of 8 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 and empty conditions
28 full <= ( write_ptr == 4 ’ b1111 ) ;
29 empty <= ( write_ptr == read_ptr ) ;
30 end
31 end
32 endmodule

235
Chapter 16 Problems with Solutions

Project 107: 32-bit Synchronous FIFO with Push and Pop


Problem: Design a 32-bit synchronous FIFO with push and pop operations. The
FIFO should have 16 entries and should support read and write operations with full
and empty flags.
Solution:
1 module fifo_sync (
2 input clk , reset , push , pop ,
3 input [31:0] data_in ,
4 output reg [31:0] data_out ,
5 output reg full , empty
6 );
7 reg [31:0] memory [15:0]; // 16 entries of 32 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 ( push && ! full ) begin
18 memory [ write_ptr ] <= data_in ;
19 write_ptr <= write_ptr + 1;
20 end
21
22 if ( pop && ! 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

236
Chapter 16 Problems with Solutions

Project 108: 64-bit Register File with Read/Write Enable

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

Project 110: 4-port 32-bit Register File


Problem: Design a 4-port register file where each port has a 32-bit data bus. The
register file should support simultaneous read and write operations on different ports.
Solution:
1 module f ou r_ po rt _r eg _f il e (
2 input clk , reset ,
3 input [3:0] addr_a , addr_b , addr_c , addr_d , // 4 address inputs
for 4 ports
4 input [31:0] data_in_a , data_in_b , data_in_c , data_in_d ,
5 input we_a , we_b , we_c , we_d , // Write enables for each port
6 output reg [31:0] data_out_a , data_out_b , data_out_c , data_out_d
7 );
8 reg [31:0] registers [15:0]; // 16 registers of 32 bits each
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset ) begin
12 data_out_a <= 32 ’ b0 ;
13 data_out_b <= 32 ’ b0 ;
14 data_out_c <= 32 ’ b0 ;
15 data_out_d <= 32 ’ b0 ;
16 end else begin
17 if ( we_a )
18 registers [ addr_a ] <= data_in_a ;
19 if ( we_b )
20 registers [ addr_b ] <= data_in_b ;
21 if ( we_c )
22 registers [ addr_c ] <= data_in_c ;
23 if ( we_d )
24 registers [ addr_d ] <= data_in_d ;
25
26 data_out_a <= registers [ addr_a ];
27 data_out_b <= registers [ addr_b ];
28 data_out_c <= registers [ addr_c ];
29 data_out_d <= registers [ addr_d ];
30 end
31 end
32 endmodule

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

Project 113: 16x16-bit Dual-Port RAM with Separate Read/Write Ports

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

Project 114: 64-bit Asynchronous RAM with Clock Gating


Problem: Design a 64-bit asynchronous RAM with clock gating to save power. The
RAM should allow reading and writing asynchronously and should include a clock-
enable signal to control clock gating.
Solution:
1 module a s y n c _ r a m _ w i t h _ c l o c k _ g a t i n g (
2 input clk , reset , clk_en ,
3 input [5:0] addr , // 64 locations with 6 - bit address
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] memory [63:0]; // 64 locations , each 64 bits wide
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset )
12 data_out <= 64 ’ b0 ;
13 else if ( clk_en ) begin // Clock gating condition
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

243
Chapter 16 Problems with Solutions

Project 115: 128-bit 4-way Set-Associative Cache


Problem: Design a 128-bit 4-way set-associative cache with an index width of 6 bits
and a block size of 16 bytes. The cache should support read, write, and invalidation
operations.
Solution:
1 module c a c h e _ 4 _ w a y _ s e t _ a s s o c i a t i v e (
2 input clk , reset , read_en , write_en ,
3 input [5:0] index , // 6 - bit index for 64 cache sets
4 input [127:0] data_in ,
5 output reg [127:0] data_out ,
6 output reg hit
7 );
8 reg [127:0] cache [63:0][3:0]; // 64 sets , 4 ways per set
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset )
12 data_out <= 128 ’ b0 ;
13 else begin
14 hit <= 0;
15 if ( read_en ) begin
16 // Check for a cache hit
17 if ( cache [ index ][0] == data_in || cache [ index ][1] ==
data_in ||
18 cache [ index ][2] == data_in || cache [ index ][3] ==
data_in ) begin
19 hit <= 1;
20 data_out <= data_in ;
21 end
22 end
23 if ( write_en ) begin
24 cache [ index ][0] <= data_in ; // Write operation
25 end
26 end
27 end
28 endmodule

244
Chapter 16 Problems with Solutions

Project 116: 2D Memory with Row and Column Addressing


Problem: Design a 2D memory array where rows and columns are addressed sepa-
rately. The memory should support both row-wise and column-wise access for reading
and writing operations.
Solution:
1 module t w o _ d i m e n s i o n a l _ m e m o r y (
2 input clk , reset ,
3 input [3:0] row_addr , col_addr , // 4 - bit row and column
address
4 input [31:0] data_in ,
5 input we , re , // Write enable and Read
enable
6 output reg [31:0] data_out
7 );
8 reg [31:0] memory [15:0][15:0]; // 16 x16 2 D array of 32 - bit
memory locations
9
10 always @ ( posedge clk or posedge reset ) begin
11 if ( reset )
12 data_out <= 32 ’ b0 ;
13 else begin
14 if ( we )
15 memory [ row_addr ][ col_addr ] <= data_in ; // Write to
memory
16 if ( re )
17 data_out <= memory [ row_addr ][ col_addr ]; // Read from
memory
18 end
19 end
20 endmodule

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

Project 118: 16-bit Memory-Mapped I/O Interface

Problem: Design a 16-bit memory-mapped I/O interface for communication between


a CPU and external devices. The interface should allow data to be transferred between
the I/O device and the CPU memory.
Solution:
1 module memory_mapped_io (
2 input clk , reset , io_read , io_write ,
3 input [15:0] data_in ,
4 output reg [15:0] data_out
5 );
6 reg [15:0] io_device ; // 16 - bit I / O device memory
7
8 always @ ( posedge clk or posedge reset ) begin
9 if ( reset )
10 data_out <= 16 ’ b0 ;
11 else begin
12 if ( io_write )
13 io_device <= data_in ; // Write to I / O device
14 if ( io_read )
15 data_out <= io_device ; // Read from I / O device
16 end
17 end
18 endmodule

247
Chapter 16 Problems with Solutions

Project 119: 2-bit Synchronous Counter with Reset


Problem: Design a 2-bit synchronous counter using an FSM. The counter should
have a reset functionality and count from 0 to 3, then roll over to 0.
Solution:
1 module sy nc_cou nter_2 bit (
2 input clk , reset ,
3 output reg [1:0] count
4 );
5 typedef enum logic [1:0] {
6 S0 = 2 ’ b00 ,
7 S1 = 2 ’ b01 ,
8 S2 = 2 ’ b10 ,
9 S3 = 2 ’ b11
10 } state_t ;
11
12 state_t state , next_state ;
13
14 always_ff @ ( posedge clk or posedge reset ) begin
15 if ( reset )
16 state <= S0 ;
17 else
18 state <= next_state ;
19 end
20
21 always_comb begin
22 case ( state )
23 S0 : next_state = S1 ;
24 S1 : next_state = S2 ;
25 S2 : next_state = S3 ;
26 S3 : next_state = S0 ;
27 default : next_state = S0 ;
28 endcase
29 end
30
31 always_ff @ ( posedge clk ) begin
32 count <= state ;
33 end
34 endmodule

248
Chapter 16 Problems with Solutions

Project 120: 4-bit Johnson Counter FSM


Problem: Design a 4-bit Johnson counter using FSM. The counter should produce a
unique sequence of binary values, where the output toggles between states in a specific
order.
Solution:
1 module johnson_counter (
2 input clk , reset ,
3 output reg [3:0] count
4 );
5 typedef enum logic [3:0] {
6 S0 = 4 ’ b0000 ,
7 S1 = 4 ’ b0001 ,
8 S2 = 4 ’ b0011 ,
9 S3 = 4 ’ b0111 ,
10 S4 = 4 ’ b1111 ,
11 S5 = 4 ’ b1110 ,
12 S6 = 4 ’ b1100 ,
13 S7 = 4 ’ b1000
14 } state_t ;
15
16 state_t state , next_state ;
17
18 always_ff @ ( posedge clk or posedge reset ) begin
19 if ( reset )
20 state <= S0 ;
21 else
22 state <= next_state ;
23 end
24
25 always_comb begin
26 case ( state )
27 S0 : next_state = S1 ;
28 S1 : next_state = S2 ;
29 S2 : next_state = S3 ;
30 S3 : next_state = S4 ;
31 S4 : next_state = S5 ;
32 S5 : next_state = S6 ;
33 S6 : next_state = S7 ;
34 S7 : next_state = S0 ;
35 default : next_state = S0 ;
36 endcase
37 end
38
39 always_ff @ ( posedge clk ) begin
40 count <= state ;
41 end
42 endmodule

249
Chapter 16 Problems with Solutions

Project 121: FSM for Traffic Light Controller


Problem: Design an FSM-based traffic light controller. The system should have three
lights (Green, Yellow, Red), with the proper sequence for vehicle traffic.
Solution:
1 module t r a f f i c _ l i g h t _ c o n t r o l l e r (
2 input clk , reset ,
3 output reg green , yellow , red
4 );
5 typedef enum logic [1:0] {
6 RED = 2 ’ b00 ,
7 GREEN = 2 ’ b01 ,
8 YELLOW = 2 ’ b10
9 } state_t ;
10
11 state_t state , next_state ;
12
13 always_ff @ ( posedge clk or posedge reset ) begin
14 if ( reset )
15 state <= RED ;
16 else
17 state <= next_state ;
18 end
19
20 always_comb begin
21 case ( state )
22 RED : next_state = GREEN ;
23 GREEN : next_state = YELLOW ;
24 YELLOW : next_state = RED ;
25 default : next_state = RED ;
26 endcase
27 end
28
29 always_ff @ ( posedge clk ) begin
30 case ( state )
31 RED : { red , yellow , green } = 3 ’ b100 ;
32 GREEN : { red , yellow , green } = 3 ’ b001 ;
33 YELLOW : { red , yellow , green } = 3 ’ b010 ;
34 default : { red , yellow , green } = 3 ’ b100 ;
35 endcase
36 end
37 endmodule

250
Chapter 16 Problems with Solutions

Project 122: FSM for 4-bit Sequence Detector

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

Project 123: FSM for Vending Machine

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

Project 124: FSM for Simple Elevator Control


Problem: Design an FSM for a simple elevator control system with 4 floors. The
elevator should respond to requests to move between floors.
Solution:
1 module e le v a to r _ co n t ro l l er (
2 input clk , reset ,
3 input [1:0] floor_request , // Floor request (2 - bit input )
4 output reg [1:0] current_floor
5 );
6 typedef enum logic [1:0] {
7 FLOOR0 = 2 ’ b00 ,
8 FLOOR1 = 2 ’ b01 ,
9 FLOOR2 = 2 ’ b10 ,
10 FLOOR3 = 2 ’ b11
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 <= FLOOR0 ;
18 else
19 state <= next_state ;
20 end
21

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

Project 125: FSM for Password Checker


Problem: Design an FSM-based password checker. The FSM should verify a 4-
character password (e.g., ”1101”) by transitioning through states based on the input
sequence.
Solution:
1 module password_checker (
2 input clk , reset ,
3 input user_input ,
4 output reg valid_password
5 );
6 typedef enum logic [2:0] {
7 S0 = 3 ’ b000 , // Initial state
8 S1 = 3 ’ b001 , // Input 1
9 S2 = 3 ’ b010 , // Input 2
10 S3 = 3 ’ b011 , // Input 3
11 S4 = 3 ’ b100 // Valid password
12 } state_t ;
13
14 state_t state , next_state ;
15
16 always_ff @ ( posedge clk or posedge reset ) begin
17 if ( reset )
18 state <= S0 ;
19 else
20 state <= next_state ;
21 end
22

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

Project 126: FSM for Traffic Light with Pedestrian Button


Problem: Design an FSM-based traffic light controller with a pedestrian button.
The pedestrian light should turn green when requested and the system should handle
pedestrian and vehicle light transitions.
Solution:
1 module t r a f f i c _ l i g h t _ w i t h _ p e d e s t r i a n (
2 input clk , reset , pedestrian_button ,
3 output reg green , yellow , red , pedestrian
4 );
5 typedef enum logic [2:0] {
6 VEHICLE_RED = 3 ’ b000 ,
7 VEHICLE_GREEN = 3 ’ b001 ,
8 VEHICLE_YELLOW = 3 ’ b010 ,
9 PEDESTRIAN_GREEN = 3 ’ b011 ,
10 PEDESTRIAN_WAIT = 3 ’ b100
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 <= VEHICLE_RED ;
18 else
19 state <= next_state ;
20 end
21
22 always_comb begin
23 case ( state )
24 VEHICLE_RED : next_state = ( pede strian _butto n ) ?
PEDESTRIAN_GREEN : VEHICLE_GREEN ;
25 VEHICLE_GREEN : next_state = VEHICLE_YELLOW ;
26 VEHICLE_YELLOW : next_state = VEHICLE_RED ;
27 PEDESTRIAN_GREEN : next_state = PEDESTRIAN_WAIT ;
28 PEDESTRIAN_WAIT : next_state = VEHICLE_GREEN ;
29 default : next_state = VEHICLE_RED ;
30 endcase
31 end
32
33 always_ff @ ( posedge clk ) begin
34 case ( state )
35 VEHICLE_RED : { red , yellow , green , pedestrian } = 4 ’ b1000 ;
36 VEHICLE_GREEN : { red , yellow , green , pedestrian } = 4 ’ b0010
;
37 VEHICLE_YELLOW : { red , yellow , green , pedestrian } = 4 ’
b0100 ;
38 PEDESTRIAN_GREEN : { red , yellow , green , pedestrian } = 4 ’
b0001 ;
39 PEDESTRIAN_WAIT : { red , yellow , green , pedestrian } = 4 ’
b0100 ;
40 default : { red , yellow , green , pedestrian } = 4 ’ b1000 ;
41 endcase
42 end
43 endmodule
255
Chapter 16 Problems with Solutions

Project 127: FSM for Traffic Light with Emergency Override


Problem: Design an FSM-based traffic light controller with an emergency override.
When the emergency override button is pressed, the traffic lights should turn red for
all directions except for one.
Solution:
1 module t r a f f i c _ l i g h t _ w i t h _ e m e r g e n c y (
2 input clk , reset , emergency_button ,
3 output reg green , yellow , red
4 );
5 typedef enum logic [2:0] {
6 NORMAL = 3 ’ b000 ,
7 EMERGENCY = 3 ’ b001 ,
8 RED = 3 ’ b010
9 } state_t ;
10

11 state_t state , next_state ;


12
13 always_ff @ ( posedge clk or posedge reset ) begin
14 if ( reset )
15 state <= NORMAL ;
16 else
17 state <= next_state ;
18 end
19
20 always_comb begin
21 case ( state )
22 NORMAL : next_state = ( emergency_button ) ? EMERGENCY :
NORMAL ;
23 EMERGENCY : next_state = RED ;
24 RED : next_state = NORMAL ;
25 default : next_state = NORMAL ;
26 endcase
27 end
28
29 always_ff @ ( posedge clk ) begin
30 case ( state )
31 NORMAL : { red , yellow , green } = 3 ’ b001 ;
32 EMERGENCY : { red , yellow , green } = 3 ’ b100 ;
33 RED : { red , yellow , green } = 3 ’ b000 ;
34 default : { red , yellow , green } = 3 ’ b001 ;
35 endcase
36 end
37 endmodule

256
Chapter 16 Problems with Solutions

Predict the Output - Basic Logic Gate Operations


Problem: Given the following Verilog code, predict the output for the input values
of A = 1 and B = 0.
1 module logic_gates (
2 input A , B ,
3 output AND_out , OR_out , XOR_out
4 );
5 assign AND_out = A & B ;
6 assign OR_out = A | B ;
7 assign XOR_out = A ^ B ;
8 endmodule

Answer:

• AND out = 0

• OR out = 1

• XOR out = 1

Predict the Output - Flip-Flop Behavior


Problem: Given the following Verilog code for a D flip-flop, predict the output Q for
the input D = 1 and clk changes from 0 to 1.
1 module d_flip_flop (
2 input clk , reset , D ,
3 output reg Q
4 );
5 always_ff @ ( posedge clk or posedge reset ) begin
6 if ( reset )
7 Q <= 0;
8 else
9 Q <= D ;
10 end
11 endmodule

Answer:

• At the positive edge of clk, the output Q will be 1 (since D = 1).

257
Chapter 16 Problems with Solutions

Predict the Output - Case Statement


Problem: Given the following Verilog code with a case statement, predict the output
for input signal = 2.
1 module case_example (
2 input [1:0] input_signal ,
3 output reg [3:0] output_signal
4 );
5 always_comb begin
6 case ( input_signal )
7 2 ’ b00 : output_signal = 4 ’ b0001 ;
8 2 ’ b01 : output_signal = 4 ’ b0010 ;
9 2 ’ b10 : output_signal = 4 ’ b0100 ;
10 2 ’ b11 : output_signal = 4 ’ b1000 ;
11 default : output_signal = 4 ’ b1111 ;
12 endcase
13 end
14 endmodule

Answer:

• For input signal = 2 (2’b10), the output output signal will be 4’b0100.

Predict the Output - Shift Register


Problem: Given the following Verilog code for a 4-bit shift register, predict the output
for D = 1 when the clock cycles twice.
1 module shift_register (
2 input clk , reset , D ,
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
9 Q <= { Q [2:0] , D }; // Shift left and insert D
10 end
11 endmodule

Answer:

• Initial state of Q = 4’b0000.

• After first clock cycle with D = 1, Q becomes 4’b0001.

• After second clock cycle with D = 1, Q becomes 4’b0011.

258
Chapter 16 Problems with Solutions

Predict the Output - Up/Down Counter

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.

• After one clock cycle in up mode, Q becomes 4.

• After two clock cycles in up mode, Q becomes 5.

259
Chapter 16 Problems with Solutions

Predict the Output - Memory Initialization


Problem: Given the following Verilog code for initializing a memory array, predict
the output after reading from the memory at address 2.
1 module memory_example (
2 input [1:0] address ,
3 output reg [7:0] data
4 );
5 reg [7:0] memory [0:3]; // 4 x 8 - bit memory array
6
7 initial begin
8 memory [0] = 8 ’ b00000001 ;
9 memory [1] = 8 ’ b00000010 ;
10 memory [2] = 8 ’ b00000100 ;
11 memory [3] = 8 ’ b00001000 ;
12 end
13
14 always_comb begin
15 data = memory [ address ];
16 end
17 endmodule

Answer:

• For address = 2, the output data will be 8’b00000100.

Predict the Output - Multiplexer


Problem: Given the following Verilog code for a 4-to-1 multiplexer, predict the output
for sel = 2 and inputs = {8’b10101010, 8’b11001100, 8’b11110000, 8’b00000000}.
1 module m ul ti pl ex er _4 _t o_ 1 (
2 input [3:0] sel , // 2 - bit select line
3 input [7:0] inputs [0:3] , // 4 input lines
4 output reg [7:0] output_data
5 );
6 always_comb begin
7 case ( sel )
8 2 ’ b00 : output_data = inputs [0];
9 2 ’ b01 : output_data = inputs [1];
10 2 ’ b10 : output_data = inputs [2];
11 2 ’ b11 : output_data = inputs [3];
12 default : output_data = 8 ’ b00000000 ;
13 endcase
14 end
15 endmodule

Answer:

• For sel = 2 (2’b10), the output output data will be 8’b11110000.

260
Chapter 16 Problems with Solutions

Difference Between Questions


1. Difference Between assign and always Block

• assign is used for continuous assignments, and it is evaluated continuously. It is


typically used for combinational logic.
• always block is used for procedural assignments and is evaluated at specified
times, such as the rising or falling edge of a clock.

2. Difference Between reg and wire Data Types

• 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.

3. Difference Between initial and always Blocks

• 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.

4. Difference Between posedge and negedge

• posedge refers to the rising edge of a signal (transition from 0 to 1).


• negedge refers to the falling edge of a signal (transition from 1 to 0).

5. Difference Between Blocking and Non-blocking Assignments

• 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.

6. Difference Between if-else and case Statements

• 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.

7. Difference Between for and while Loops

• 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.

8. Difference Between posedge clk and posedge reset

• posedge clk triggers actions on the rising edge of the clock signal.
• posedge reset triggers actions on the rising edge of the reset signal.

9. Difference Between parameter and localparam

• parameter can be overridden at the module instantiation level.


• localparam cannot be overridden and is used for internal parameters within the
module.

10. Difference Between always comb and always ff

• always comb is used to model combinational logic, automatically inferring sensi-


tivity lists.
• always ff is used to model sequential logic with flip-flops and latches, with ex-
plicit clocking events.

11. Difference Between assign and force

• 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.

12. Difference Between module and function

• 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.

13. Difference Between always @* and always @(x)

• 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.

14. Difference Between wire and tri

• wire is a general-purpose net that is used to connect combinational logic.


• tri is used for three-state logic, allowing a wire to be driven by multiple drivers
(typically used in bus systems).

262
Chapter 16 Problems with Solutions

15. Difference Between wait and @ (Event Control)

• wait is a blocking statement that halts execution until a specified condition is


true.
• @ is an event control used in always blocks, making the block sensitive to changes
in the specified signals.

16. Difference Between generate and for Loops

• generate is used for repetitive block instantiation at compile time.


• for loop is used for repeating logic at runtime and is typically used inside always
blocks.

17. Difference Between memory and reg

• 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.

18. Difference Between always and always comb

• always is used for procedural logic and requires an explicit sensitivity list.
• always comb is used for combinational logic, automatically creating a sensitivity
list.

19. Difference Between assign and deassign

• assign continuously drives a value to a wire.


• deassign removes the continuous assignment, leaving the wire undriven.

20. Difference Between posedge and negedge for Reset Behavior

• 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.

22. Difference Between initial Block and always Block with @*

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.

23. Difference Between posedge clk and posedge reset

• posedge clk refers to the rising edge of the clock signal.


• posedge reset refers to the rising edge of the reset signal.

24. Difference Between real and reg

• real is used for storing floating-point numbers.


• reg is used for storing binary values, typically integers.

25. Difference Between real and reg

• 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.

26. Difference Between fork and join

• 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.

27. Difference Between generate and for Loops in Hardware Design

• generate is used to create repetitive hardware structures during synthesis, which


are resolved at compile time.
• for loop is used in simulation or testbenches for repeating logic based on a con-
dition evaluated during runtime.

28. Difference Between always Block and always ff Block

• 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.

29. Difference Between case and casex Statements

• case performs exact matching, comparing each expression directly.

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.

30. Difference Between if and if-else in Verilog

• if is used to execute a block of code when a certain condition is true.


• if-else provides an alternative path of execution when the condition is false,
making it useful for two possible outcomes.

31. Difference Between module and task

• 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.

32. Difference Between posedge and negedge in Reset Logic

• 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).

33. Difference Between deassign and force

• 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.

34. Difference Between wire and logic

• 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.

35. Difference Between mem and reg Data Types

• 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.

36. Difference Between state and state next in FSM Design

• 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.

37. Difference Between casez and casex in Verilog

• 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.

38. Difference Between parameter and localparam

• parameter is a constant value that can be overridden at the time of module


instantiation.
• localparam is similar to parameter, but it cannot be overridden at instantiation
and is used for internal constant values within the module.

39. Difference Between initial Block and always Block in Verilog

• 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.

40. Difference Between assign and force in Verilog

• assign is used for continuous assignment, driving values to a signal.


• force is used to override the value of a signal during simulation for debugging
purposes.

41. Difference Between posedge and negedge for Clock Triggering

• posedge refers to the rising edge of a clock or signal.


• negedge refers to the falling edge of a clock or signal.

42. Difference Between forever and repeat Loops in Verilog

• 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.

43. Difference Between posedge and negedge for Triggering

• 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

Multiple Choice Questions


1. Which of the following data types is used to store a binary value in Verilog?

• A) real
• B) reg
• C) wire
• D) integer

Answer: B) reg

2. What is the default value of a reg in Verilog if it is not initialized?

• A) 0
• B) 1
• C) Unknown (X)
• D) Undefined

Answer: C) Unknown (X)

3. Which of the following is a correct way to declare a clock signal in Verilog?

• A) reg clk;
• B) wire clk;
• C) input clk;
• D) output clk;

Answer: B) wire clk;

4. What is the main purpose of a task in Verilog?

• A) To represent a hardware component


• B) To execute a block of code multiple times
• C) To declare an input port
• D) To store a value

Answer: B) To execute a block of code multiple times

267
Chapter 16 Problems with Solutions

True/False Questions
1. Verilog allows the declaration of integer variables for representing floating-point val-
ues. (False)

2. The always block in Verilog runs continuously in a simulation. (True)

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)

Predict the Output


1. What is the output of the following code?

module test;
reg a, b;
wire out;

assign out = a & b;

initial begin
a = 1;
b = 0;
#10;
$display("Out = %b", out);
end
endmodule

Answer: Out = 0

2. Predict the output of the following code:

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

Answer: b = 10001 (5 + 10 in binary)

3. Given the following code, predict the output.

module test;
reg [3:0] a;
reg b;
wire out;

assign out = (a > 4’b1010) ? b : ~b;

initial begin
a = 4’b1100;
b = 1;
#10;
$display("Out = %b", out);
end
endmodule

Answer: Out = 1

Code Writing/Fill in the Blanks


1. Write Verilog code to implement a 4-bit AND gate using assign.

module and_gate(input [3:0] a, input [3:0] b, output [3:0] out);


assign out = ____________;
endmodule

Answer: out = a & b;

2. Fill in the blanks to complete the Verilog code for a 2-to-1 multiplexer.

module mux2to1(input a, b, sel, output out);


assign out = ____________;
endmodule

Answer: out = (sel) ? b : a;

269
Chapter 16 Problems with Solutions

3. Complete the code to model a 4-bit counter using always block.

module counter(output [3:0] count, input clk, reset);


reg [3:0] count;
always @ (___________)
begin
if (reset)
count = 4’b0000;
else
count = count + 1;
end
endmodule

Answer: always @ (posedge clk)

Code Analysis and Debugging


1. Analyze the following Verilog code. What will be the value of out after the initial
block completes execution?

module test;
reg a, b;
wire out;

assign out = a & b;

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).

2. Identify the issue in the following Verilog code:

module test;
reg [3:0] a, b;

270
Chapter 16 Problems with Solutions

wire [3:0] out;

assign out = a + b; // Error: Undriven ’out’ in case of unknown a and b val

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).

2. In the following code, what is the issue?

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

Sholay Style Question


”Arre O Verilog ke master, yeh bata, always block ka use kab karna hai?”

Translation: ”Hey, Verilog expert, tell me, when should we use the always block?”

1. A) For continuous assignments

2. B) To specify a block that runs when signals change

3. C) To initialize a signal at the beginning of the simulation

4. D) Only when using initial blocks


Answer: B) To specify a block that runs when signals change

DDLJ Style Question


”Babu Moshai, yeh Verilog ka code kya hota hai? Ek baar jo hamne code likha,
toh phir usse kabhi samajh nahi aata!”

Translation: ”Babu, what is this Verilog code? Once we write the code, we never under-
stand it again!”

1. A) Verilog code is meant to specify the logic and structure of a circuit

2. B) Verilog code is written to design chips and SoCs

3. C) Verilog is only used for simulation, not for real hardware

4. D) Verilog code is written for testing only


Answer: A) Verilog code is meant to specify the logic and structure of a circuit

272
Chapter 16 Problems with Solutions

Don Style Question


”Don ka code agar galat ho, toh samajh jao, chhup jao! Verilog mein jab errors
aate hain, tab sab kuch hamesha ’X’ kyun dikhta hai?”

Translation: ”If Don’s code goes wrong, hide! Why does everything show ’X’ in Verilog
when errors occur?”

1. A) Because Verilog assumes ’X’ represents a logic error

2. B) ’X’ is the default value for wires when there is an undefined state

3. C) ’X’ indicates a syntax error in the code

4. D) ’X’ appears when the code has a missing semicolon


Answer: B) ’X’ is the default value for wires when there is an undefined state

Kabhi Khushi Kabhie Gham Style Question


”Mujhe yeh bata, Verilog ke andar reg aur wire mein kaunsa zyada khush hai?”

Translation: ”Tell me, which is happier between reg and wire in Verilog?”

1. A) reg is always happy because it stores values

2. B) wire is always happy as it connects things

3. C) reg is sad, but wire is happy

4. D) Both reg and wire are equally sad


Answer: A) reg is always happy because it stores values

Lagaan Style Question


”Arre bhai, yeh Verilog ka always block ka timing control kab lagana hai, batao
na!”

Translation: ”Hey friend, when do we apply timing control in the Verilog always block?”

1. A) Only during simulation

2. B) Whenever there is a change in input signals

3. C) During testbench creation

4. D) Never, it is not needed


Answer: B) Whenever there is a change in input signals

273
Chapter 16 Problems with Solutions

Yeh Jawaani Hai Deewani Style Question


”Jab tum apne initial block mein ’assign’ likhte ho, toh samajh lo, tumne kuch
bahut bada kaam kiya hai!”
Translation: ”When you write ’assign’ in your initial block, know that you’ve done
something big!”
1. A) assign is used to create combinational logic
2. B) assign is used only in sequential logic
3. C) assign is used to define output pins
4. D) assign is used to make variables constant
Answer: A) assign is used to create combinational logic

Taare Zameen Par Style Question


”Beta, yeh Verilog ka assign kabhi samajh nahi aata. Kaise tumne wire ko
assign kiya?”
Translation: ”Son, I never understand this Verilog assign. How did you assign a value to
the wire?”
1. A) You can assign values to wires using assign
2. B) Wires cannot have assigned values in Verilog
3. C) You need to use reg to assign values
4. D) Wires are automatically assigned values during synthesis
Answer: A) You can assign values to wires using assign

Om Shanti Om Style Question


”Om Shanti Om! Agar tumne Verilog ke testbenches mein ’fork’ aur ’join’ use
nahi kiya, toh tumhein kisne kaam diya!”
Translation: ”Om Shanti Om! If you haven’t used fork and join in Verilog testbenches,
who assigned you the work?”
1. A) fork and join are used for parallel processing in Verilog testbenches
2. B) fork and join are used to delay signal assignments
3. C) fork is used for sequential execution
4. D) fork and join have no use in Verilog
Answer: A) fork and join are used for parallel processing in Verilog testbenches

274
Appendix A

Commonly Used Verilog Syntax

Quick Reference
• module

• input, output, inout – Port declarations.

• assign – Continuous assignment (dataflow modeling).

• always @ (posedge clk) – Sequential logic block.

• initial – Initialization block (simulation only).

• if, else, case, for, while – Control flow.

• $display, $monitor, $dumpfile, $dumpvars – Simulation tools.

275
Appendix B

Tools and Simulators

Industry-Standard Tools
• ModelSim / QuestaSim – Comprehensive Verilog simulation.

• Vivado (Xilinx) – RTL to bitstream for FPGAs.

• Quartus Prime (Intel) – FPGA design environment.

Open Source Tools


• Icarus Verilog (iverilog) – Command-line simulator.

• GTKWave – Waveform viewer.

• EDA Playground – Browser-based online simulation.

276
Appendix C

Online Resources for Learning

Highly Recommended Platforms


• HDLBits – Practice platform for Verilog.

• EDA Playground – Online Verilog + waveform viewer.

• ASIC World – Verilog tutorials and basics.

• ChipVerify – SystemVerilog + verification articles.

277
Appendix D

Interview Preparation Tips

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.

Before the Interview


Prior to the interview, focus on sharpening core technical concepts and practical implemen-
tations.

• Review Verilog Modeling Styles: Understand the differences between Behavioral,


Structural, and Dataflow modeling. Be able to give examples of each.

• 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.

• Master Finite State Machines (FSMs): Be confident in designing and coding


Moore and Mealy machines. Prepare state diagrams and equivalent Verilog modules.

• Understand Testbenches and Verification: Learn to write simple testbenches


with various stimulus methods. If you know SystemVerilog/UVM, showcase your ver-
ification knowledge.

• Differentiate Synthesis vs Simulation: Clearly understand what constructs are


synthesizable. Know how delays (‘#‘) and initial blocks are treated differently in both.

• 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.

During the Interview


Your performance during the interview will depend not only on knowledge but also on how
you communicate and reason.

• 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.

• Highlight Internships/Certifications: Mention any VLSI training (Verilog/Sys-


temVerilog/UVM), MOOCs, or certifications you’ve done (like NPTEL, Coursera,
Udemy).

• Be Clear on Blocking vs Non-Blocking: Understand the difference between ‘=‘


and ‘¡=‘ operators and explain their use in sequential vs combinational logic.

• 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.

• Mock Interviews: Practice with friends or mentors. Join VLSI communities on


LinkedIn and WhatsApp for mock interview rounds.

• Research the Company: Understand whether the role is more synthesis-focused,


verification-oriented, or involves layout. Tailor your preparation accordingly.

• 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

Common Questions Asked


• What is the difference between blocking and non-blocking assignments?

• How do you design a synchronous reset in Verilog?

• Explain the difference between Mealy and Moore FSMs.

• How does synthesis differ from simulation in Verilog?

• Write a testbench for a 4-bit counter.

• How would you reduce power in your RTL design?

• How do you handle metastability in flip-flops?

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

1. Verilog HDL: A Guide to Digital Design and Synthesis – Samir Palnitkar

2. Digital Design and Verilog HDL – Zainalabedin Navabi

3. Advanced Digital Design with Verilog HDL – Michael D. Ciletti

4. FPGA Prototyping by Verilog Examples – Pong P. Chu

281
Appendix F

Final Note to Readers

A Personal Message from the Author


Dear Reader,
This book is more than just a collection of pages filled with Verilog syntax and simulation
diagrams — it’s a piece of my journey, my countless late nights of learning, unlearning, and
relearning. It is a reflection of the same struggles that many of you might be facing now —
the confusion when a waveform doesn’t match expectations, the frustration when synthesis
throws an unexpected warning, and the sheer joy when your first testbench finally works.
Whether you’re a student preparing for your dream company, a passionate engineer
building your own System-on-Chip, or a curious learner entering the world of digital logic
— this book was written for you. I sincerely hope it has made Verilog feel less intimidating
and more like a canvas where you can draw out your ideas in logic and timing.

This is more than just code. This is creativity in silicon.

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.

Keep exploring. Keep designing. Keep dreaming.

“Every chip begins not with a transistor, but with a dream.”

I would love to hear from you — your feedback, suggestions, or simply your thoughts after

282
Chapter 16 Problems with Solutions

reading this book. Every message matters to me.


Drop a note anytime: [email protected]

With gratitude and warmth,


The Author

283

You might also like