1746025839080
1746025839080
Preface
Introduction
Verilog is a Hardware Description Language (HDL) widely used in the design and veri-
fication of digital circuits, including FPGAs and ASICs. It enables designers to model,
simulate, and synthesize hardware systems from simple gates to complex SoCs. Under-
standing Verilog is a critical skill for any aspiring VLSI or embedded systems engineer.
Target Audience
This book is crafted for:
2
VeriCore VLSI Design
Salient Features
• 100+ conceptual explanations with real-world analogies.
3
VeriCore VLSI Design
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: infoex31@gmail.com
“From RTL to your first real job—this book is your companion in silicon success.”
4
Contents
Preface 2
5
Contents VeriCore VLSI Design
6
Contents VeriCore VLSI Design
7
Contents VeriCore VLSI Design
8
Chapter 1 : Overview of Digital Design
with Verilog
Introduction
Verilog is a Hardware Description Language (HDL) that provides a means to describe,
simulate, and synthesize digital systems such as microprocessors, memory units, and cus-
tom 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.
9
Chapter 1 Overview of Digital Design with Verilog
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.
6. Fabrication: Manufac-
ture chip or burn into FPGA
10
Chapter 1 Overview of Digital Design with Verilog
Pro Tip
Mnemonic Trick: “Smart Men Simulate Systems In Fabricated
Factories” — One word per step in the design flow.
Pro Tip
Career Tip: Verilog is your ticket to internships and full-time VLSI roles. Start projects
and share them on GitHub and LinkedIn!
11
Chapter 1 Overview of Digital Design with Verilog
Output-Based
1. Predict the behavior of a Verilog ‘always‘ block with blocking assignment.
Summary
• Verilog is a widely used HDL for modeling digital systems.
12
Chapter 1 Overview of Digital Design with Verilog
Pro Tip
Final Insight: Focus on simulation and modeling first. Don’t rush into synthesis—get
your logic right!
13
Chapter 2: Hierarchical Modeling
Introduction
Hierarchical modeling is a foundational concept in digital design, where systems are bro-
ken down into smaller, manageable components called modules. This enables the de-
signer to approach complex problems with modular design principles, enhancing readabil-
ity, reusability, and scalability of Verilog code.
Verilog’s support for hierarchy allows us to:
Learning Objectives
• Understand the principle and benefits of hierarchical modeling.
14
Chapter 2 Hierarchical Modeling
• Bottom-up design: Smaller blocks are designed first, then integrated to form the
complete system.
Top-Level System
Module A Module C
Module B
Pro Tip
Pro Tip: Modularize your code as early as possible! This helps you simulate and debug
each block independently.
Analogy:
Imagine you’re building a car. You wouldn’t design it as one massive blueprint—you’d
create separate designs for the engine, wheels, and electronics, then assemble them. That’s
hierarchical modeling in action!
15
Chapter 2 Hierarchical Modeling
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
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.
16
Chapter 2 Hierarchical Modeling
Pro Tip
Pro Tip: Prefix your instance names (like u1, inst_) to track them easily during
simulation and debugging.
Best Practices
• Keep each module focused on a single function.
17
Chapter 2 Hierarchical Modeling
Top Module
Decoder Adder
2. Testbench
A non-synthesizable module that drives the inputs to the DUT and monitors the outputs.
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.
18
Chapter 2 Hierarchical Modeling
Pro Tip
Pro Tip: Break your testbench into generator, monitor, and checker blocks
for better modularity and reuse.
Testbench DUT
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.
19
Chapter 2 Hierarchical Modeling
‘timescale 1ns/1ps
Common Use-Cases
• Apply stimulus to DUT
Pro Tip
Pro Tip: Use waveform viewers (like GTKWave) to visualize the simulation time-
line—great for debugging!
20
Chapter 2 Hierarchical Modeling
Code-Based Questions
1. Write a Verilog code for a 4-bit ripple carry adder using hierarchical modules.
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:
Pro Tip
Trick: Always begin designing from the bottom-up (build modules) or top-down (de-
fine structure first)—but never both at the same time!
21
Chapter 3 Basic Concepts
Learning Outcomes
• Understand and use hierarchical modeling in Verilog.
“Think modular, code reusable, simulate always — that’s the Verilog way!”
22
Chapter 3: Basic Concept
Introduction
In digital design, mastering Verilog begins with understanding its basic building blocks.
This chapter covers the essential syntax, data types, variables, and structures used to write
functional and efficient code. A solid grasp of these concepts is vital before diving into
more complex design styles.
Learning Objectives
• Understand the lexical rules and conventions used in Verilog.
• \t – Horizontal Tab
• \b – Backspace
23
Chapter 3 Basic Concepts
Pro Tip
Use escape sequences while printing strings using system tasks like $display for
formatting output.
24
Chapter 3 Basic Concepts
• \n – Newline
• \t – Tab
• \b – Backspace
Pro Tip
Use whitespace generously to improve code readability. Although Verilog ignores it,
humans don’t!
25
Chapter 3 Basic Concepts
3.2.2 Comments
Verilog supports two types of comments:
• // Single-line comment
• /* Multi-line comment */
// Valid identifiers:
reg clk_1;
wire _enable;
integer \abc$def; // Escape identifier
3.2.4 Literals
Verilog literals can be signed or unsigned, and may also include undefined or high-impedance
states.
Examples:
Pro Tip
Unsigned numbers roll over on overflow. Use signed when dealing with negative values!
26
Chapter 3 Basic Concepts
Ignore Whitespace
Parse Identifiers
Parse Literals
Handle Comments
27
Chapter 3 Basic Concepts
reg clk;
reg [7:0] count;
Pro Tip
Use reg inside procedural blocks and wire outside them for connections!
integer i;
Note: Can be used in loops but not synthesizable for hardware mapping.
real pi;
initial pi = 3.14159;
28
Chapter 3 Basic Concepts
time delay;
delay = $time;
—
Difference Table
Pro Tip
Always assign reg in initial or always blocks. Use assign only for wire
types.
Input Signal
Wire
Output
29
Chapter 3 Basic Concepts
3.4 Vectors
In Verilog, vectors are used to represent buses or multi-bit signals. A vector groups multi-
ple scalar wires or regs into a single entity.
3.4.1 Syntax
wire [3:0] data; // 4-bit vector (data[3] down to data[0])
reg [7:0] count; // 8-bit register
Note: The index is specified as [MSB:LSB]. Verilog supports both big-endian (MSB
to LSB) and little-endian declarations.
Pro Tip
Tip: When using vectors, always double-check bit ordering. [7:0] counts from 7
down to 0!
3.5 Arrays
Verilog supports arrays of regs or nets (from Verilog-2001 onward). Arrays help in orga-
nizing repetitive hardware like registers, memory banks, etc.
Access:
30
Chapter 3 Basic Concepts
register_file[2] = 8’hFF;
mem_2d[1][2] = 4’b1010;
Pro Tip
Analogy: Think of a 2D array like an Excel sheet with rows and columns storing digital
data.
3.6 Memories
In Verilog, a memory is essentially a one-dimensional array of vectors.
3.6.1 Declaration
reg [7:0] memory [0:255]; // 256 locations, each 8-bit wide
Pro Tip
Pro Tip: Verilog memories do not support multi-port access by default — you must
model it!
—
Block Diagram – Memory Block Access
31
Chapter 3 Basic Concepts
Clock
3.7.1 Syntax
parameter WIDTH = 8;
reg [WIDTH-1:0] data_bus;
32
Chapter 3 Basic Concepts
Pro Tip
Pro Tip: Always prefer named parameter overriding. Avoid using defparam in mod-
ern Verilog for better readability and tool support.
initial begin
$display("Simulation starts at time %t", $time);
$monitor("a = %b, b = %b, out = %b", a, b, out);
end
33
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
34
Chapter 3 Basic Concepts
// Q2
parameter WIDTH = 4;
reg [WIDTH-1:0] b;
initial begin
b = 4’b1010;
$display("b = %b", b);
end
—
Summary
• Memories store multiple data locations and are used for RAM/ROM models.
• System tasks like $display, $monitor are essential for simulation output.
Learning Outcome:
• You can now differentiate between data types and storage styles in Verilog.
“In Verilog, simplicity lies in structure — think in modules, wires, and clocks.”
35
Chapter 4: Modules and Ports
Introduction
Verilog’s design structure is fundamentally based on the use of modules. Each design unit
is modeled as a module, containing ports for communication, and internal logic to define
its functionality. This modularity promotes reuse, readability, and scalability in digital
system design.
Learning Objectives
• Understand the structure and importance of Verilog modules.
4.1.1 Syntax
verilog module (module name) (port list);
// Declarations
// Functionality
36
Chapter 4 Modules and Ports
endmodule
37
Chapter 4 Modules and Ports
Input Output
Module
Inout
Pro Tip
Pro Tip: Always declare port directions explicitly! Verilog infers wires by default —
which may cause synthesis issues if not declared correctly.
• Positional Association: The ports are connected in the order they are defined.
38
Chapter 4 Modules and Ports
Pro Tip
Pro Tip: Prefer named associations for better readability and error prevention, espe-
cially in large designs.
Example:
1
2 module top;
3 wire d, clk, q;
4 dff d1 (.d(d), .clk(clk), .q(q));
5 endmodule
If you want to monitor signal q inside dff, you can refer to it as:
verilog top.d1.q
39
Chapter 4 Modules and Ports
Pro Tip
Pro Tip: Avoid writing to hierarchical signals. Hierarchical referencing is best used for
monitoring, not design.
Practice Questions
Theoretical:
Summary
• Modules are the building blocks of Verilog designs.
40
Chapter 4 Modules and Ports
Learning Outcome:
41
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 under-
standing how synthesized logic maps onto physical gates.
Learning Objectives
• Understand the different types of logic gates available in Verilog.
• not – Inverter
• buf – Buffer
42
Chapter 5 Gate Level Modelling
Pro Tip
Pro Tip: Think of gates as mathematical functions. An AND gate is like multiplication:
1 * 1 = 1, everything else is 0.
Pro Tip
Trick to Remember:
Think of AND as "both must be true", OR as "either can be true", XOR as "only
one must be true", and NAND as "AND but inverted".
43
Chapter 5 Gate Level Modelling
• NOR Gate: Inverted output of OR. Output is high only when both inputs are low.
• XNOR Gate: Inverted output of XOR. True when inputs are equal.
Pro Tip
Hardware Hint:
NAND and NOR gates are known as Universal Gates — any digital logic can be im-
plemented using just these two!
Explanation
The output will update 5 time units after both inputs become valid. Use this in
testbenches to visualize delays.
44
Chapter 5 Gate Level Modelling
Pro Tip
Use multiple delay values to model real-world rise and fall transitions of gates.
2. What are the possible values that a signal can take in Verilog?
2. Given a NOT gate connected to a wire initialized to 1, what will be the delayed
output?
3. Trace the waveform of a 2-input NAND gate over a 10-time unit simulation.
45
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:
“Logic gates are the atoms of digital design — master them to build anything!”
46
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 behav-
ioral modeling, dataflow emphasizes *how data flows* between signals based on logical
or arithmetic operations, without explicitly describing how it’s implemented.
47
Chapter 6 Data Flow Modelling
48
Chapter 6 Data Flow Modelling
Gate-Level Modeling
Dataflow Modeling
Behavioral Modeling
Comparison Table:
Real-World Analogy
Think of dataflow modeling like water pipelines: you don’t worry about each pipe’s
structure but just how water (data) flows from tank (input) to faucet (output) through
connections (assignments).
49
Chapter 6 Data Flow Modelling
Learning Objectives
• Understand the purpose and application of dataflow modeling in Verilog.
• Learn about the ‘assign‘ statement and how continuous assignments work.
“Flow the logic, not the gates — that’s the dataflow mindset.”
Definition
A continuous assignment describes a logic expression that is continuously evaluated and
assigned to a net. Any change in the right-hand-side variables automatically triggers re-
evaluation and updates the output.
50
Chapter 6 Data Flow Modelling
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.
Explanation: This implements a simple 2-to-1 multiplexer. When sel=1, y=b; oth-
erwise, y=a.
51
Chapter 6 Data Flow Modelling
52
Chapter 6 Data Flow Modelling
Interview Insight
Pro Tip
Always remember that assign statements work best for modeling combinational
logic. They’re synthesizable and resemble actual gate-level hardware more closely
than procedural logic.
Practice Questions
1. What is the main difference between continuous and procedural assignments?
Key Takeaways:
“With assign, you define how data flows — no clocks, no waits, just logic.”
53
Chapter 6 Data Flow Modelling
If input changes last less than 5 units, the output remains unchanged.
54
Chapter 6 Data Flow Modelling
• A single delay
Real-World Examples
Example 1: Basic Delay
1 assign #3 y = a ^ b;
Pro Tip
Delays are ignored during synthesis but are vital in simulation. Use them in testbenches
to accurately test real-time behavior.
55
Chapter 6 Data Flow Modelling
• Multiple delay types are supported: single, rise/fall, and full delays.
• Always simulate with delays to visualize waveform behaviors, but avoid them in
synthesis code.
Learning Outcome
• Understand different types of delays and their syntax in Verilog.
Syntax:
1 assign out = expression;
56
Chapter 6 Data Flow Modelling
Operands in Verilog
Operands are the basic data items on which operations are performed. They may include
constants, wires, or even another expression.
Types of Operators
Verilog offers various operators, categorized as:
57
Chapter 6 Data Flow Modelling
1 assign sum = a + b;
2 assign diff = a - b;
3 assign prod = a * b;
4 assign div = a / b;
2. Relational Operator:
1 assign is_greater = (a > b);
2 assign is_equal = (a == b);
3. Logical Operator:
1 assign logic_result = (a && b) || (!c);
4. Bitwise Operator:
1 assign and_op = a & b;
2 assign xor_op = a ^ b;
5. Shift Operator:
1 assign left_shift = a << 2;
2 assign right_shift = b >> 1;
7. Reduction Operator:
1 assign any_bit_high = |a;
2 assign all_bits_low = ~|a;
8. Conditional Operator:
58
Chapter 6 Data Flow Modelling
• Multiplicative: *, /, %
• Additive: +, -
• Equality: ==, !=
• Bitwise: &, |, ˆ
• Logical: &&, ||
• Conditional: ? :
Pro Tip
Always use parentheses to clarify precedence in complex expressions. It not only
reduces bugs but makes your code more readable.
59
Chapter 6 Data Flow Modelling
“Think of dataflow modeling as plumbing logic—where signals flow like water through
gates and pipes!”
Explanation: This is the simplest form of logic gate. Think of it like a door that only
opens when both switches (inputs) are ON.
Analogy: Like a streetlight system where light turns ON if any one sensor detects motion.
60
Chapter 6 Data Flow Modelling
Analogy: Like a train junction that decides which track to follow based on a lever (selec-
tor).
Explanation: Adds two 1-bit values, just like primary school math.
Example 8: Comparator
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
61
Chapter 6 Data Flow Modelling
62
Chapter 6 Data Flow Modelling
63
Chapter 6 Data Flow Modelling
Pro Tip
You can simulate all the above examples using tools like ModelSim or EDA Playground.
Try changing input values to visualize how logic flows!
Q5. Design a 4-input OR gate and simulate it with all combinations of inputs.
64
Chapter 6 Data Flow Modelling
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 ‘*‘.
Q14. Implement a parity generator using the reduction XOR (ˆ) operator.
Q18. Concatenate two 4-bit inputs and store the result in an 8-bit output.
Q19. Create a barrel shifter using assign statements (hint: use shifts).
Q22. Implement a 4-bit full adder using four 1-bit full adders.
65
Chapter 6 Data Flow Modelling
Pro Tip
Tip: Start writing these on simulation platforms like ModelSim or EDA Playground to
test your syntax and logic. Simulating is the best way to validate and learn!
66
Chapter 6 Data Flow Modelling
67
Chapter 6 Data Flow Modelling
6.7 Summary
In this chapter, we explored the foundations of Dataflow Modeling in Verilog, one of the
most intuitive and efficient ways to describe hardware behavior using continuous assign-
ments. Below is a recap of all important concepts covered:
68
Chapter 6 Data Flow Modelling
• Continuous Assignments: Defined using the assign keyword, suitable for com-
binational logic.
• Delay Types:
• Expression Components:
• Operator Types: Covered in depth with syntax, examples, and application tips.
• Pro Tips: Coding best practices, synthesis tips, and simulation advice were pro-
vided to guide both beginners and advanced learners.
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.
69
Chapter 6 Data Flow Modelling
Dataflow Modeling
70
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.
71
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 em-
powers 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.”
72
Chapter 7 Behavioral Modeling
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
abstraction.
3. Apply timing controls like delay control (#), event control (@), and level-sensitive
constructs.
5. Use sequential and parallel blocks to describe concurrent and ordered logic flows.
73
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!
74
Chapter 7 Behavioral Modeling
Key Points:
• Not synthesizable.
75
Chapter 7 Behavioral Modeling
Key Points:
76
Chapter 7 Behavioral Modeling
Pro Tip
Use initial blocks in testbenches to apply stimulus or set default values. Use
always blocks when describing logic based on clocks or input changes.
7.1.5 Summary
• initial blocks run only once and are perfect for stimulus generation in test-
benches.
• always blocks run continuously and form the backbone of synthesizable RTL.
• Understanding when and where to use each block is key to effective Verilog model-
ing.
77
Chapter 7 Behavioral Modeling
Key Characteristics:
• Easier to debug.
78
Chapter 7 Behavioral Modeling
• Executes in parallel.
79
Chapter 7 Behavioral Modeling
Start Clock Edge Evaluate RHS (b) Start Clock Edge Evaluate RHS (b, a)
End of Blocking
Pro Tip
Golden Rule: Never mix blocking and non-blocking assignments in the same always
block. It may cause unpredictable simulation results!
7.2.6 Summary
• Blocking (=) executes sequentially — best for combinational logic.
80
Chapter 7 Behavioral Modeling
• 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!
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
differently depending on inputs or internal states. In Verilog, the most commonly used
conditional statement is the ‘if‘ statement.
Analogy
Think of conditional statements like a traffic signal system. If the light is green, ve-
hicles move. If it’s red, they stop. This simple decision-making mechanism governs
how the circuit reacts to different situations.
81
Chapter 7 Behavioral Modeling
Start
Is condition true?
Yes No
Execute Execute
True Block False Block
Continue
• Control units
• Priority encoders
82
Chapter 7 Behavioral Modeling
Quick Recap:
83
Chapter 7 Behavioral Modeling
84
Chapter 7 Behavioral Modeling
Comparison Table
Statement Ignores ‘x‘ Ignores ‘z‘
case No No
casex Yes Yes
casez No Yes
Pro Tip
Use casex and casez with caution in synthesis as they may result in unexpected
logic due to wildcard matching.
• casex treats ‘x‘ and ‘z‘ as wildcards — good for simulation, not synthesis.
• casez ignores only ‘z‘ — better than casex for synthesis use.
Analogy
Think of loops like an assembly line machine: you instruct it to stamp a part multiple
times until the job is complete. In Verilog, loops allow similar repetition of tasks in
code.
85
Chapter 7 Behavioral Modeling
• for loop
• while loop
• repeat loop
• forever loop
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] pat-
tern; 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
synthesizable 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
86
Chapter 7 Behavioral Modeling
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 genera-
tion.
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.
Quick Checklist:
87
Chapter 7 Behavioral Modeling
Pro Tip
Use case for synthesis-safe design. Avoid casex unless you fully understand
how X/Z values propagate in simulation.
88
Chapter 7 Behavioral Modeling
89
Chapter 7 Behavioral Modeling
Best Practices
• Always include a default case to avoid latches.
Pro Tip
Always initialize your output in a case structure or use a default path to prevent
latch inference during synthesis.
Learning Outcome
After completing this section, students should be able to:
90
Chapter 7 Behavioral Modeling
• while loop
• repeat loop
• forever loop
91
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
Pro Tip
Use forever loops only with proper delay elements like # or (posedge clk) to
prevent simulation from hanging.
92
Chapter 7 Behavioral Modeling
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.
Syntax
initial begin
statement1;
statement2;
statement3;
end
93
Chapter 7 Behavioral Modeling
Example
Output:
Time 0: Start
Time 10: Middle
Time 20: End
Parallel blocks execute all the enclosed statements simultaneously and wait for all of them
to complete.
Syntax
initial fork
statement1;
statement2;
statement3;
join
94
Chapter 7 Behavioral Modeling
Example
Output:
Time 2: C
Time 5: A
Time 10: B
95
Chapter 7 Behavioral Modeling
• Use fork ... join when multiple events need to occur simultaneously (e.g.,
generating multiple signals).
Pro Tip
Pro Tip
Always ensure to use fork...join with care inside testbenches, especially when
one of the processes never terminates — it can cause the simulation to hang!
Output:
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 simu-
lation may get stuck.
96
Chapter 7 Behavioral Modeling
Learning Objectives
• Understand the difference between delay control and event control.
\item Use ‘#‘, ‘@‘, and ‘wait‘ for controlling simulation time and eve
Syntax
#time; // Waits for ’time’ units
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.
97
Chapter 7 Behavioral Modeling
Syntax
@(event_expression); // Waits until event_expression becomes true
Syntax
wait(condition); // Suspends execution until condition is true
Output:
Explanation: This waits until ‘clk‘ becomes ‘1‘, regardless of how long it takes.
98
Chapter 7 Behavioral Modeling
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.
99
Chapter 7 Behavioral Modeling
• Loops available:
• Grouping statements:
100
Chapter 7 Behavioral Modeling
• Avoid using ‘fork ... join‘ in synthesizable code. Use only for testbenches.
101
Chapter 8: Task and Function
Introduction
In Verilog, reusable blocks of code are essential for improving readability, modularity, and
scalability of complex designs. Tasks and functions serve this purpose by encapsulating
frequently used operations. While both can be invoked from procedural blocks, they differ
significantly in their usage and capabilities.
This chapter covers both in detail, helping you distinguish when and how to use them
effectively in real-world Verilog projects.
Learning Objectives
• Understand the purpose and syntax of tasks and functions.
Why It Matters
Tasks and functions help you avoid repetition, reduce errors, and improve code
maintainability in Verilog. Whether writing RTL or testbenches, mastering these
will boost your efficiency and skillset.
102
Chapter 8 Task and Function
Syntax of a Task
Task Syntax
task task_name;
input [bit_width] input_name;
output [bit_width] output_name;
inout [bit_width] inout_name;
// Task body
begin
// Statements
end
endtask
Key Features
• Can include delays (#) and event control (@).
103
Chapter 8 Task and Function
initial begin
print_number(4);
end
initial begin
multiply(3, 4, res);
$display("Result: %d", res);
end
Output: Result: 12
104
Chapter 8 Task and Function
#delay_time;
$display("Waited %d time units", delay_time);
end
endtask
initial begin
delay_print(5);
end
Pro Tips
• Tasks are powerful in testbenches and can simplify repeated sequences.
• Avoid using tasks with delays in RTL blocks intended for synthesis.
105
Chapter 8 Task and Function
Task Call
Execute Statements
Return Control
End
What is a Function?
A function in Verilog is a reusable block of code that returns a single value. Functions are
primarily used for combinational logic without any timing delays.
• They cannot include time-consuming operations like delays (#), event controls
(@), or wait statements.
• All inputs must be passed by value — there are no output or inout ports.
106
Chapter 8 Task and Function
Syntax of a Function
Function Syntax
function [bit_width] function_name;
input [bit_width] arg1;
input [bit_width] arg2;
begin
function_name = expression;
end
endfunction
—
Examples of Functions in Verilog
initial begin
$display("Sum = %d", add(2, 3));
end
Output: Sum = 5
107
Chapter 8 Task and Function
initial begin
$display("Max = %d", max_val(8, 12));
end
Output: Max = 12
initial begin
$display("AND = %b", and_func(4’b1101, 4’b1011));
end
108
Chapter 8 Task and Function
Pro Tips
• Use functions to simplify combinational logic like arithmetic, comparisons,
and encoding.
• Best suited for hardware logic that’s fast, predictable, and simple.
initial begin
$display("Sum = %d", adder(5, 10)); // Output: 15
end
109
Chapter 8 Task and Function
initial begin
show_msg("Hello");
end
110
Chapter 8 Task and Function
begin
for (i = 0; i < 4; i = i + 1)
reverse_bits[i] = data[3 - i];
end
endfunction
111
Chapter 8 Task and Function
begin
begin
$display("Inner Block Value: %d", a);
end
end
endtask
112
Chapter 8 Task and Function
113
Chapter 8 Task and Function
temp = a;
a = b;
b = temp;
end
endtask
114
Chapter 8 Task and Function
115
Chapter 8 Task and Function
4. How are input, output, and inout ports used differently in tasks and functions?
116
Chapter 8 Task and Function
initial begin
$display("%d", sum(4’d3, 4’d5));
end
task show_delay;
input [3:0] x;
begin
#x;
$display("Delayed by %d", x);
end
endtask
initial begin
show_delay(4);
end
function add_numbers;
input [3:0] a, b;
add_numbers = a + b;
endfunction
117
Chapter 8 Task and Function
task invalid_delay;
input [3:0] a;
begin
$display("Waiting...");
wait(a == 1);
end
endfunction
Design Questions
9. Design a function that counts the number of 1’s in an 8-bit input.
10. Design a task that swaps two 8-bit values using ‘inout‘.
11. Implement a function that performs a logical AND operation on two inputs and
returns the result.
12. Write a task that accepts an input and displays whether it is odd or even.
13. Design a function that performs a priority encoding for 4-bit input.
16. Create a task to generate a PWM signal (simulate with delay and display).
18. Design a task to loop through an array and print each value.
118
Chapter 8 Task and Function
• Use task when you need delays, multiple outputs, or procedural operations.
• Never insert a delay (#), event, or wait statement in a function — this violates
synthesizable code rules.
• Always verify that your task ends (no infinite waits) — to avoid simulation
hang.
• Remember: A task can call another task or function, but a function can
**only** call another function.
8.6 Summary
• Verilog provides two primary subprograms: task and function, to modularize
repeated logic.
• Tasks:
• Functions:
119
Chapter 8 Task and Function
• While functions are preferred in RTL design (synthesizable logic), tasks are mainly
used in testbenches.
• Both are reusable, modular constructs that improve code clarity, testability, and
maintenance.
120
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 model-
ing methods are frequently used. These include procedural assignments, conditional com-
pilation, 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).
121
Chapter 9 Useful Modelling Technique
9.0.1 assign-deassign
The ‘assign‘ statement in a procedural context behaves similarly to a continuous assign-
ment, 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
122
Chapter 9 Useful Modelling Technique
Pro Tip
Pro Tip
Avoid using assign-deassign and force-release in RTL. These constructs are meant
only for simulation and can create undefined behaviors if mixed with synthesizable
logic.
Common Directives
• \‘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.
123
Chapter 9 Useful Modelling Technique
Syntax
Syntax
‘define DEBUG
module example;
...
‘ifdef DEBUG
initial $display("Debug Mode Enabled");
‘endif
endmodule
module tb;
initial begin
‘ifdef SIMULATION
$display("This is a simulation-only block.");
‘endif
$display("Testbench running...");
end
endmodule
module check;
initial begin
‘ifdef ASIC
$display("ASIC flow selected.");
124
Chapter 9 Useful Modelling Technique
‘else
$display("FPGA flow selected.");
‘endif
end
endmodule
Output:
Pro Tips
Pro Tips
• Always end conditional compilation blocks with ‘endif to avoid errors.
• Never include hardware logic inside ‘ifdef blocks that are excluded during
synthesis.
• Group macro definitions at the top of the file for better readability.
125
Chapter 9 Useful Modelling Technique
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.
• 1ps is the time precision: how accurate the simulator tracks time events.
module test;
initial begin
#1 $display("1ns passed");
#2 $display("2ns more passed");
end
endmodule
Output:
126
Chapter 9 Useful Modelling Technique
127
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Always define ‘timescale at the top of every Verilog file for consistency.
• Use higher precision (e.g., 1ps) in testbenches for more accurate timing con-
trol.
• For FPGA/ASIC flow, timescale has no synthesis impact — it’s for simulation
only.
1. $display
Formats:
• %b - binary
• %d - decimal
• %h - hexadecimal
128
Chapter 9 Useful Modelling Technique
2. $monitor
Continuously prints whenever any variable in the list changes.
129
Chapter 9 Useful Modelling Technique
Pro Tips
Pro Tips
• Prefer $display for static messages and $monitor for tracking changes
over time.
• System tasks are non-synthesizable; they are used only for simulation and
debugging.
130
Chapter 9 Useful Modelling Technique
Purpose
The VCD file stores simulation signal changes in a time-stamped format, allowing the user
to examine transitions, glitches, or timing issues.
Example
module tb;
reg clk, rst;
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, tb);
end
initial begin
clk = 0;
forever #5 clk = ~clk;
131
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.
132
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 de-
signs.
• VCD does not capture memories or variables by default — use tools like
$dumpvars deeply or switch to FST or other formats if needed.
initial begin
assign data = clk;
#5 clk = 1;
#10 clk = 0;
deassign data;
end
endmodule
Explanation: The ‘data‘ net is connected to ‘clk‘ temporarily using ‘assign‘. Once
‘deassign‘ is executed, ‘data‘ becomes undriven.
133
Chapter 9 Useful Modelling Technique
initial begin
a = 0;
force b = a;
#5 a = 1;
#10 release b;
end
endmodule
Explanation: The value of ‘b‘ is forcibly tied to ‘a‘. Even if ‘a‘ changes, ‘b‘ follows
until ‘release‘ is issued.
Explanation: Every delay (e.g., #10) is interpreted in nanoseconds with 1ps precision.
134
Chapter 9 Useful Modelling Technique
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, vcd_test);
a = 0; b = 1;
#5 a = 1;
#5 b = 0;
end
endmodule
initial begin
x = 0; y = 0;
#10 x = 1;
#10 y = 1;
end
endmodule
135
Chapter 9 Useful Modelling Technique
assign b = a;
initial begin
a = 0;
force b = 1; // overrides the assign
#10 release b; // returns to original assignment
end
endmodule
initial begin
136
Chapter 9 Useful Modelling Technique
clk = 0;
assign out = clk;
$display("Assigned out to clk");
#5 clk = 1;
#5 deassign out;
$display("Deassigned out");
end
endmodule
Code-Based Questions
11. Write a code to demonstrate conditional compilation using ‘ìfdef‘ and ‘èlse‘.
137
Chapter 9 Useful Modelling Technique
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?
Pro Tip 2
Always pair ‘assign‘ with ‘deassign‘ and ‘force‘ with ‘release‘. Forgetting to undo
forced assignments can cause inconsistent simulations.
138
Chapter 9 Useful Modelling Technique
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
behavior and waveform transitions in time.
Summary
• Procedural continuous assignments include ‘assign-deassign‘ and ‘force-release‘,
used primarily in simulation for overriding signal values.
• ‘force-release‘ can be used on both nets and variables, giving more flexibility during
testing.
• Timescale affects how delays are interpreted in simulation — using it correctly en-
sures proper timing behavior.
• System tasks like ‘display‘, ‘monitor‘, ‘time‘, and‘dumpvars‘ help monitor and de-
bug simulation behavior.
• Value Change Dump (VCD) files store simulation transitions and are visualized us-
ing tools like GTKWave.
139
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.
140
Chapter 10 Finite State Machines (FSM) in Verilog
141
Chapter 10 Finite State Machines (FSM) in Verilog
Structure
• Next-State Logic: Determines next state based on current state and input.
142
Chapter 10 Finite State Machines (FSM) in Verilog
// State transition
always_ff @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next-state logic
always_comb begin
case(state)
IDLE: next_state = in ? S1 : IDLE;
S1: next_state = in ? S2 : IDLE;
S2: next_state = in ? S2 : IDLE;
default: next_state = IDLE;
endcase
end
143
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
144
Chapter 10 Finite State Machines (FSM) in Verilog
// State transition
always_ff @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
145
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
combinational next-state/output logic. Keep output logic separate to avoid synthesis
mismatches 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.
146
Chapter 10 Finite State Machines (FSM) in Verilog
Description: All states are declared as individual bits, and only one bit is active at a time.
• State Register
• Next-State Logic
• Output Logic
147
Chapter 10 Finite State Machines (FSM) in Verilog
// 2. Next-State Logic
always_comb begin
case (state)
IDLE: next_state = (in) ? S1 : IDLE;
...
endcase
end
// 3. Output Logic
always_comb begin
case (state)
...
endcase
end
Description: Common in simpler FSMs. Combines all logic in one always block.
148
Chapter 10 Finite State Machines (FSM) in Verilog
149
Chapter 10 Finite State Machines (FSM) in Verilog
Pro Tip
Pro Tip
Use 3-block FSMs for clean synthesis and easier maintenance. Flat FSMs are pre-
ferred in high-speed design where latency is critical, especially for Mealy-style ma-
chines.
• Binary Encoding
• One-Hot Encoding
• Gray Encoding
• Johnson Encoding
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.
150
Chapter 10 Finite State Machines (FSM) in Verilog
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
applications.
Example: 3-bit Gray Code
Pros: Reduces glitches in transitions. Cons: More complex to decode and implement.
4. Johnson Encoding
A twist on Gray encoding. It uses shift register logic with feedback.
Example: For 4 bits:
Pros: Suitable for counters and FSM sequencing. Cons: Less popular in general FSM
designs.
151
Chapter 10 Finite State Machines (FSM) in Verilog
Pro Tip
Pro Tip
Use Binary encoding for large FSMs to save area. Use One-Hot for speed-critical
paths or when FSMs are small. Gray coding is ideal for crossing clock domains or
reducing switching noise.
152
Chapter 10 Finite State Machines (FSM) in Verilog
Verilog Code:
153
Chapter 10 Finite State Machines (FSM) in Verilog
Problem: Detect whether the incoming serial bit stream has even parity using a Mealy
FSM.
States:
Output:
• y = 1 if even parity
• y = 0 if odd parity
Verilog Code:
154
Chapter 10 Finite State Machines (FSM) in Verilog
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.
155
Chapter 10 Finite State Machines (FSM) in Verilog
A. Conceptual Questions
1. What is the key difference between Mealy and Moore state machines?
2. Why is the output of a Moore FSM more stable than that of a Mealy FSM?
B. Coding/Verilog-Oriented Questions
11. Write a Verilog code for a Moore FSM to detect the sequence “101”.
12. Write a Verilog code for a Mealy FSM that detects “110” and resets after detection.
14. Design a FSM in Verilog that generates a pulse every third clock cycle.
15. Code an FSM with three states: IDLE, LOAD, and DONE. Transition upon specific
inputs.
156
Chapter 10 Finite State Machines (FSM) in Verilog
19. What are the best practices to define parameters for states?
20. Implement a traffic light controller FSM in Verilog using case statements.
22. Your FSM works in simulation but not in synthesis. What would you check?
24. Explain the difference between blocking and non-blocking assignments in FSMs.
26. What debugging strategy would you apply if the FSM is unstable after reset?
27. In which cases would you prefer a Mealy FSM over a Moore FSM?
30. How would you implement a lock/unlock FSM using a combination of state and
input verification?
157
Chapter 10 Finite State Machines (FSM) in Verilog
• Avoid Latches: Ensure that all state transitions and outputs are defined for
every possible condition to prevent unintended latch inference.
• One-Hot for Speed, Binary for Area: Choose one-hot encoding for faster
FSMs when area isn’t a concern. Prefer binary/gray encoding for area-
sensitive designs.
• Avoid Unused States: Ensure all defined states are reachable. Unreachable
states increase area and can cause simulation warnings.
158
Chapter 10 Finite State Machines (FSM) in Verilog
Verilog
Testbenches
Case Model
Debug/Simulation Reset/Clocking
FSM
State
Moore
Encoding
State
Mealy
Diagrams
159
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:
Memory elements are non-synthesizable unless properly mapped with synthesis direc-
tives or inferred using coding styles recognized by tools.
Understanding memory modeling allows designers to:
160
Chapter 11 Memory Modeling in Verilog
Learning Objectives
After completing this chapter, you will be able to:
reg [7:0] mem_array [0:255]; // 256 memory locations, each 8 bits wide
Explanation:
These types are used for LUTs, register files, or basic RAM/ROM simulation.
161
Chapter 11 Memory Modeling in Verilog
initial begin
rom[0] = 8’hAA;
rom[1] = 8’hBB;
rom[2] = 8’hCC;
// ... initialize all
end
162
Chapter 11 Memory Modeling in Verilog
module sync_write_async_read (
input wire clk,
input wire [7:0] data_in,
163
Chapter 11 Memory Modeling in Verilog
Key points:
• Write happens on the positive clock edge.
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
);
reg [7:0] memory [0:255];
164
Chapter 11 Memory Modeling in Verilog
Note: Read and write are controlled through a clock cycle and are mutually exclusive.
—
module dual_port_mem (
input wire clk,
input wire wr_en,
input wire [7:0] wr_addr,
input wire [7:0] data_in,
input wire [7:0] rd_addr,
output reg [7:0] data_out
);
reg [7:0] memory [0:255];
Advantage: Improves performance when simultaneous read and write are required.
—
165
Chapter 11 Memory Modeling in Verilog
Pros:
• Extremely scalable
166
Chapter 11 Memory Modeling in Verilog
Explanation:
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
);
// Write Operation
always @(posedge clk) begin
if (we) begin
reg_array[w_addr] <= w_data;
end
end
endmodule
167
Chapter 11 Memory Modeling in Verilog
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
);
168
Chapter 11 Memory Modeling in Verilog
• Avoid reading and writing the same location in the same clock cycle.
• For multi-port register files, prioritize arbitration logic to prevent data hazards.
‘timescale 1ns/1ps
module tb_register_file;
// Inputs
reg clk;
reg we;
reg [1:0] w_addr;
reg [1:0] r_addr1, r_addr2;
reg [7:0] w_data;
// Outputs
wire [7:0] r_data1;
wire [7:0] r_data2;
// Clock generation
initial clk = 0;
169
Chapter 11 Memory Modeling in Verilog
initial begin
// Initialize inputs
we = 0; w_addr = 0; w_data = 8’h00;
r_addr1 = 0; r_addr2 = 1;
// Disable write
we = 0;
170
Chapter 11 Memory Modeling in Verilog
$display("Test Completed.");
$stop;
end
endmodule
• 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
addresses.
• 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.
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.
• Use meaningful parameter names and labels for register widths and counts — it
enhances code reusability.
• Avoid using blocking assignments in sequential blocks when designing register files.
171
Chapter 11 Memory Modeling in Verilog
• Remember that simultaneous write and read to the same address in the same cycle
may require special handling (read-after-write hazard).
• For synthesizable RTL, avoid initializing memory inside the definition — use an
initial block for simulation only.
• Use one-hot encoding or binary encoding for state machines interfacing with register
files depending on power and area constraints.
172
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.
173
Chapter 12 User Defined Primitive (UDP)
• Sequential UDP: Has memory element, output depends on both current input and
previous state.
Syntax
table
// input1 input2 : output;
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
174
Chapter 12 User Defined Primitive (UDP)
table
// a b : out
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
table
// clk d : q : q_next
r 0 : ? : 0;
r 1 : ? : 1;
f ? : ? : -;
endtable
endprimitive
Practice Examples
1. XNOR Gate Using UDP
table
0 0 : 1;
0 1 : 0;
1 0 : 0;
1 1 : 1;
175
Chapter 12 User Defined Primitive (UDP)
endtable
endprimitive
table
0 0 : 0;
0 1 : 1;
1 0 : 1;
1 1 : 1;
endtable
endprimitive
table
// en d : q : q_next
1 0 : ? : 0;
1 1 : ? : 1;
0 ? : q : -;
endtable
endprimitive
176
Chapter 12 User Defined Primitive (UDP)
Practical/Verilog-Based
1. Create a UDP for a 3-input majority function.
Pro Tips
Pro Tips
• Use UDPs for modeling gate-level primitives only.
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.
177
Chapter 12 User Defined Primitive (UDP)
178
Chapter 13: Event Scheduler
Introduction
In Verilog, the **event scheduler** is the internal mechanism that determines the exe-
cution order of events within a simulation time step. Since multiple statements can be
scheduled for the same time, understanding how Verilog handles their execution is crucial
for accurate modeling and debugging.
It divides simulation time into four main regions for handling scheduled events:
• Active Region
• Inactive Region
• Monitor/Reactive Region
Each region has its own specific role in maintaining simulation integrity and race-free
behavior.
Learning Objectives
• Understand the internal working of the Verilog simulator’s event scheduler.
179
Chapter 13 Event Scheduler
2. Inactive Region: Events postponed from the active region (usually from zero-delay
assignments).
4. Monitor Region: Executes monitoring tasks (‘monitor‘, ‘strobe‘) after all values are
updated.
Active Region
(Blocking, Eval RHS)
Inactive Region
(Zero-delay Scheduled)
NBA Region
(Non-blocking Assignments)
Monitor Region
($monitor, $strobe)
This flow ensures a clean and deterministic simulation order, minimizing unintended
interactions and race conditions.
180
Chapter 13 Event Scheduler
Simulation Walkthrough
• Time 0: a and b set to 0 in the initial block.
initial begin
a = 0;
b = 0;
end
always @(a)
b = a;
181
Chapter 13 Event Scheduler
always @(a)
a = 1;
endmodule
module zero_delay_fix;
reg clk, a, b;
module delay_order;
reg x, y;
initial begin
x = 0;
y = 0;
#5 x = 1;
y = 1;
end
endmodule
182
Chapter 13 Event Scheduler
Summary
Concept Description
Event Scheduler Controls execution timing and order of Verilog code
Regions of Execution Active, Inactive, Non-blocking active (NBA), NBA inactive
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 is-
sues
Event Control Triggers execution on signal events using @, posedge,
negedge
Delta Cycle Zero time step used for simulation ordering at same time
instant
Pro Tips
• Use <= for sequential logic inside clocked always blocks to avoid race conditions.
• Delta delays help ensure all operations at the same time are handled sequentially
without time progression.
• Explain the event scheduler using real-life analogies like a traffic signal (Red = Wait,
Green = Execute, Yellow = Prepare).
• Use simulation waveforms and flowcharts to analyze and debug timing behavior.
183
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 veri-
fication.
184
Chapter 14 Efficient Testbench Writing
Testbench:
1 module tb_mux2to1;
2 reg a, b, sel;
3 wire y;
4
5 mux2to1 uut (.a(a), .b(b), .sel(sel), .y(y));
6
7 initial begin
8 a = 0; b = 0; sel = 0;
9 #10 a = 1;
10 #10 sel = 1;
11 #10 b = 1;
12 #10 sel = 0;
13 end
14 endmodule
Explanation: This testbench initializes inputs and applies different test cases using
time delays to test how the multiplexer behaves with different combinations of inputs.
Testbench:
1 module tb_dff;
2 reg clk, d;
3 wire q;
4
185
Chapter 14 Efficient Testbench Writing
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
Explanation: The ‘always‘ block toggles the clock every 5 time units. The ‘initial‘
block changes the ‘d‘ value at specific times to simulate input behavior.
Testbench:
1 module tb_adder4bit;
2 reg [3:0] a, b;
3 wire [4:0] sum;
4
5 adder4bit uut (.a(a), .b(b), .sum(sum));
6
7 initial begin
8 a = 4’b0000; b = 4’b0000;
9 #10 a = 4’b0101; b = 4’b0011;
10 #10 a = 4’b1111; b = 4’b1111;
11 #10 a = 4’b1010; b = 4’b0101;
12 end
13 endmodule
Explanation: This testbench applies different sets of 4-bit values to check overflow
and proper addition functionality.
186
Chapter 14 Efficient Testbench Writing
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
10 clk = 0; reset = 1;
11 #10 reset = 0;
12 #50 reset = 1;
13 #10 reset = 0;
14 #30;
15 end
16 endmodule
Explanation: Clock toggling and reset control demonstrate synchronous behavior and
reset mechanism of the counter.
Testbench:
1 module tb_and_gate;
2 reg a, b;
3 wire y;
4
5 and_gate uut (.a(a), .b(b), .y(y));
6
187
Chapter 14 Efficient Testbench Writing
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.
188
Chapter 14 Efficient Testbench Writing
// Testbench
module tb_seq_detector;
reg clk, reset, in_bit;
wire detected;
initial begin
clk = 0; forever #5 clk = ~clk;
end
initial begin
reset = 1; in_bit = 0;
#10 reset = 0;
#10 in_bit = 1; #10 in_bit = 0; #10 in_bit = 1; #10 in_bit = 1;
#20 $finish;
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 cor-
rectly detects “1011”. The use of ‘$monitor‘ is efficient for observing signal values over
189
Chapter 14 Efficient Testbench Writing
time.
// Testbench
module tb_edge_detector;
reg clk, sig;
wire edge;
initial begin
clk = 0; forever #5 clk = ~clk;
end
initial begin
sig = 0;
#12 sig = 1; #10 sig = 0; #10 sig = 1; #20;
$stop;
end
initial begin
190
Chapter 14 Efficient Testbench Writing
module tb_mux2x1();
reg a, b, sel;
wire y;
initial begin
a = 0; b = 1;
sel = 0; #10;
sel = 1; #10;
$finish;
end
endmodule
module tb_adder_4bit();
reg [3:0] a, b;
wire [4:0] sum;
191
Chapter 14 Efficient Testbench Writing
initial begin
a = 4’d9; b = 4’d5; #10;
a = 4’d10; b = 4’d15; #10;
a = 4’d7; b = 4’d2; #10;
$finish;
end
endmodule
2. How does a testbench differ from the design under test (DUT)?
192
Chapter 14 Efficient Testbench Writing
13. Write a testbench that checks both synchronous and asynchronous reset behavior.
17. Use ‘for‘ loop and arrays to automate test cases in a testbench.
19. Write a testbench for a finite state machine (FSM) that detects ‘1011‘.
21. Your testbench runs but shows ‘X‘ outputs. What could be wrong?
23. How would you log all testbench events with timestamps?
24. Your simulation output is stuck. What would be your approach to debug it?
30. Create a testbench for a memory block that tests read and write functionality.
193
Chapter 14 Efficient Testbench Writing
• Use ‘timescale‘: Define timing precision and unit clearly to avoid simulation
mismatch.
• Automation: Automate test vectors using ‘for‘, ‘repeat‘, and ‘case‘ state-
ments to reduce manual errors.
• Task and Function Reuse: Create reusable test routines with ‘task‘ and
‘function‘ blocks to avoid redundancy.
• Stimulus Timing: Ensure proper delay between stimulus events to allow the
DUT to process inputs.
• Coverage Plan: Think about all edge cases while preparing stimulus (reset,
boundary inputs, illegal states).
• Initial and Always Balance: Use ‘initial‘ for one-time stimulus and ‘always‘
for continuous signal generation.
194
Chapter 14 Efficient Testbench Writing
14.4 Summary
Chapter Summary
• Testbenches are essential for validating digital designs before hardware im-
plementation.
• A testbench should ideally include input generators, clock logic, reset logic,
and output monitors.
• Simulation tools and waveform viewers like GTKWave are crucial for debug-
ging.
195
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, test-
bench development, FSMs, and real-world debugging scenarios. These are designed to
test both theoretical understanding and practical coding ability.
196
Chapter 15 200 Verilog Interview Questions
15. Define and differentiate between combinational and sequential logic in Verilog.
19. What are ‘initial‘ and ‘always‘ blocks used for in simulations?
28. How does a ‘for‘ loop differ from a ‘repeat‘ loop in Verilog?
197
Chapter 15 200 Verilog Interview Questions
198
Chapter 15 200 Verilog Interview Questions
70. What are the design issues with deeply nested ‘if‘ statements?
73. Describe the purpose and syntax of ‘always_comb‘, ‘always_ff‘, and ‘always_latch‘
in SystemVerilog.
74. What happens if multiple assignments are made to the same wire?
199
Chapter 15 200 Verilog Interview Questions
87. Can we write an ‘always‘ block inside a module more than once?
200
Chapter 15 200 Verilog Interview Questions
102. What are Verilog attributes and where are they used?
201
Chapter 15 200 Verilog Interview Questions
124. What is the difference between a blocking and non-blocking assignment in terms of
simulation results?
137. What are some best practices in Verilog coding for synthesis?
138. How do you check whether your design meets timing constraints?
202
Chapter 15 200 Verilog Interview Questions
146. What is a gray code counter and how would you implement it?
152. Describe how a ring counter works and its Verilog implementation.
159. What are asynchronous FIFO and how are they implemented?
164. How can you ensure a testbench covers all corner cases?
165. What are synthesis directives and how are they used?
203
Chapter 15 200 Verilog Interview Questions
168. How does a ‘for‘ loop behave differently in simulation vs. synthesis?
173. What are synthesis warnings, and how should you handle them?
174. What is a latch? How can you avoid unintentional latch inference?
183. What is the difference between hierarchical and flat design in Verilog?
204
Chapter 15 200 Verilog Interview Questions
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?
202. Describe a real-world project where you wrote Verilog code and verified it.
205
Chapter 16 : Problems with Solutions
Project Levels
Project Categories
• Beginner
• Intermediate
• Advanced
206
Chapter 16 Problems with Solutions
Verilog Code
module and_gate (input A, input B, output Y);
assign Y = A & B;
endmodule
Pro Tip
Pro Tip: Use ModelSim to simulate this with 4 test cases to verify all input combina-
tions.
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.
207
Chapter 16 Problems with Solutions
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!
208
Chapter 16 Problems with Solutions
Objective: Implement a Full Adder using two Half Adders and an OR gate.
Verilog Code
module full_adder (
input A, B, Cin,
output Sum, Cout
);
wire Sum1, Carry1, Carry2;
Pro Tip
Pro Tip: Use structural modeling to wire up submodules like in this example!
Objective: Design a 4-bit Ripple Carry Adder using four Full Adders.
209
Chapter 16 Problems with Solutions
Verilog Code
module ripple_adder_4bit (
input [3:0] A, B,
input Cin,
output [3:0] Sum,
output Cout
);
wire C1, C2, C3;
Pro Tip
Pro Tip: Great first project to test on waveform viewers and learn carry propagation
delays.
Verilog Code
module comparator_4bit (
input [3:0] A, B,
output A_gt_B, A_eq_B, A_lt_B
);
assign A_gt_B = (A > B);
assign A_eq_B = (A == B);
assign A_lt_B = (A < B);
endmodule
210
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Expand this into a 16-bit comparator with pipelining later.
Verilog Code
module decoder_3to8 (
input [2:0] A,
input En,
output [7:0] Y
);
assign Y = En ? (1 << A) : 8’b0;
endmodule
Pro Tip
Pro Tip: Decoders are widely used in address decoding in SoC.
211
Chapter 16 Problems with Solutions
Verilog Code
module encoder_8to3 (
input [7:0] D,
output reg [2:0] Y
);
always @(*) begin
casez(D)
8’b1???????: Y = 3’d7;
8’b01??????: Y = 3’d6;
8’b001?????: Y = 3’d5;
8’b0001????: Y = 3’d4;
8’b00001???: Y = 3’d3;
8’b000001??: Y = 3’d2;
8’b0000001?: Y = 3’d1;
8’b00000001: Y = 3’d0;
default: Y = 3’dx;
endcase
end
endmodule
Pro Tip
Pro Tip: Try replacing ‘casez‘ with ‘casex‘ and explore behavior.
Project 9: D Flip-Flop
212
Chapter 16 Problems with Solutions
Verilog Code
module d_flip_flop (
input D, clk,
output reg Q
);
always @(posedge clk)
Q <= D;
endmodule
Pro Tip
Pro Tip: Always use non-blocking assignments inside sequential logic!
Verilog Code
module t_flip_flop (
input T, clk,
output reg Q
);
always @(posedge clk)
if (T)
Q <= ~Q;
else
Q <= Q;
endmodule
Pro Tip
Pro Tip: Used in counters – combine 3 of these to make a 3-bit counter.
213
Chapter 16 Problems with Solutions
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
Pro Tip
Pro Tip: Experiment with ‘assign‘ statement for structural style too.
Verilog Code
module demux_1to4 (
input D,
input [1:0] Sel,
output reg [3:0] Y
);
always @(*) begin
Y = 4’b0000;
Y[Sel] = D;
end
endmodule
214
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Test on waveform viewer — only one output line should be HIGH at a time.
Verilog Code
module register_4bit (
input clk, rst, en,
input [3:0] D,
output reg [3:0] Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 4’b0000;
else if (en)
Q <= D;
end
endmodule
Pro Tip
Pro Tip: Useful for pipeline registers in processor design.
215
Chapter 16 Problems with Solutions
Verilog Code
module counter_up_4bit (
input clk, rst,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 4’d0;
else
count <= count + 1;
end
endmodule
Pro Tip
Pro Tip: Try adding enable and direction signals to upgrade it!
Verilog Code
module counter_down_4bit (
input clk, rst,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 4’d15;
else
count <= count - 1;
end
endmodule
216
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Set initial value from input instead of hardcoding.
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.
217
Chapter 16 Problems with Solutions
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
Pro Tip
Pro Tip: Gray code is useful in encoder applications to avoid glitches.
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.
218
Chapter 16 Problems with Solutions
Verilog Code
module seq_detect_1011 (
input clk, rst, X,
output reg Z
);
reg [2:0] state;
Pro Tip
Pro Tip: Try Moore version for a better understanding of FSMs.
219
Chapter 16 Problems with Solutions
Verilog Code
module majority_voter (
input A, B, C,
output Y
);
assign Y = (A & B) | (B & C) | (A & C);
endmodule
Pro Tip
Pro Tip: Expand to 5-input and 7-input majority logic – useful in fault-tolerant systems.
Verilog Code
module dff_async_reset (
input D, clk, rst,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else
Q <= D;
end
endmodule
Pro Tip
Pro Tip: Asynchronous resets can be dangerous in CDC designs. Use sync resets for
FPGA.
220
Chapter 16 Problems with Solutions
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
Pro Tip
Pro Tip: Use such flip-flops in data latches or gated registers in FSMs.
221
Chapter 16 Problems with Solutions
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.
222
Chapter 16 Problems with Solutions
Verilog Code
module t_flip_flop (
input T, clk, rst,
output reg Q
);
always @(posedge clk or posedge rst) begin
if (rst)
Q <= 0;
else if (T)
Q <= ~Q;
end
endmodule
Pro Tip
Pro Tip: T flip-flops are often used in frequency dividers.
Verilog Code
module counter_sync_en (
input clk, rst, en,
output reg [3:0] count
);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 0;
else if (en)
count <= count + 1;
end
endmodule
223
Chapter 16 Problems with Solutions
Pro Tip
Pro Tip: Use ‘en‘ to control state transition in FSMs as well.
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.
224
Chapter 16 Problems with Solutions
Verilog Code
module clk_div4 (
input clk, rst,
output reg clk_out
);
reg [1:0] count;
225
Chapter 16 Problems with Solutions
Verilog Code
module clk_div_n #(parameter N = 10)(
input clk, rst,
output reg clk_out
);
reg [$clog2(N)-1:0] count;
Pro Tip
Pro Tip: Use ‘clog2‘ to make the design more scalable.
226
Chapter 16 Problems with Solutions
Verilog Code
module priority_encoder_4to2 (
input [3:0] D,
output reg [1:0] Y
);
always @(*) begin
casez (D)
4’b1???: Y = 2’b11;
4’b01??: Y = 2’b10;
4’b001?: Y = 2’b01;
4’b0001: Y = 2’b00;
default: Y = 2’bxx;
endcase
end
endmodule
Solution:
1 module edge_detector (
2 input clk,
3 input signal,
4 output reg edge_detected
5 );
6 reg signal_d;
7
8 always @(posedge clk) begin
9 signal_d <= signal;
10 edge_detected <= signal & ~signal_d;
11 end
12 endmodule
227
Chapter 16 Problems with Solutions
Solution:
1 module pulse_gen (
2 input clk,
3 input trigger,
4 output reg pulse
5 );
6 reg trigger_d;
7
8 always @(posedge clk) begin
9 trigger_d <= trigger;
10 pulse <= trigger & ~trigger_d;
11 end
12 endmodule
Solution:
1 module decoder_2to4 (
2 input [1:0] in,
3 input en,
4 output reg [3:0] out
5 );
6 always @(*) begin
7 if (en)
8 out = 4’b0001 << in;
9 else
10 out = 4’b0000;
11 end
12 endmodule
228
Chapter 16 Problems with Solutions
Solution:
1 module d_ff (
2 input clk,
3 input rst,
4 input en,
5 input d,
6 output reg q
7 );
8 always @(posedge clk or posedge rst) begin
9 if (rst)
10 q <= 0;
11 else if (en)
12 q <= d;
13 end
14 endmodule
Solution:
1 module sync_counter (
2 input clk,
3 input rst,
4 input en,
5 output reg [3:0] count
6 );
7 always @(posedge clk or posedge rst) begin
8 if (rst)
9 count <= 0;
10 else if (en)
11 count <= count + 1;
12 end
13 endmodule
229
Chapter 16 Problems with Solutions
Solution:
1 module up_counter (
2 input clk,
3 input rst,
4 output reg [2:0] count
5 );
6 always @(posedge clk or posedge rst) begin
7 if (rst)
8 count <= 3’b000;
9 else
10 count <= count + 1;
11 end
12 endmodule
Solution:
1 module t_ff (
2 input clk,
3 input rst,
4 input t,
5 output reg q
6 );
7 always @(posedge clk or posedge rst) begin
8 if (rst)
9 q <= 0;
10 else if (t)
11 q <= ~q;
12 end
13 endmodule
230
Chapter 16 Problems with Solutions
Solution:
1 module sync_dff (
2 input clk,
3 input rst,
4 input d,
5 output reg q
6 );
7 always @(posedge clk) begin
8 if (rst)
9 q <= 0;
10 else
11 q <= d;
12 end
13 endmodule
Solution:
1 module comparator_1bit (
2 input a, b,
3 output gt, lt, eq
4 );
5 assign gt = a & ~b;
6 assign lt = ~a & b;
7 assign eq = ~(a ^ b);
8 endmodule
231
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [7:0] in,
3 output reg [2:0] out,
4 output reg valid
5 );
6 always @(*) begin
7 valid = 1’b1;
8 casex (in)
9 8’b1xxxxxxx: out = 3’b111;
10 8’b01xxxxxx: out = 3’b110;
11 8’b001xxxxx: out = 3’b101;
12 8’b0001xxxx: out = 3’b100;
13 8’b00001xxx: out = 3’b011;
14 8’b000001xx: out = 3’b010;
15 8’b0000001x: out = 3’b001;
16 8’b00000001: out = 3’b000;
17 default: begin
18 out = 3’b000;
19 valid = 1’b0;
20 end
21 endcase
22 end
23 endmodule
232
Chapter 16 Problems with Solutions
Solution:
1 module up_down_counter (
2 input clk,
3 input rst,
4 input up_down, // 1 for up, 0 for down
5 output reg [3:0] count
6 );
7 always @(posedge clk or posedge rst) begin
8 if (rst)
9 count <= 4’b0000;
10 else if (up_down)
11 count <= count + 1;
12 else
13 count <= count - 1;
14 end
15 endmodule
Solution:
1 module binary_to_gray (
2 input [3:0] bin,
3 output reg [3:0] gray
4 );
5 always @(*) begin
6 gray[3] = bin[3];
7 gray[2] = bin[3] ^ bin[2];
8 gray[1] = bin[2] ^ bin[1];
9 gray[0] = bin[1] ^ bin[0];
10 end
11 endmodule
233
Chapter 16 Problems with Solutions
Solution:
1 module decoder_3to8 (
2 input [2:0] in,
3 output reg [7:0] out
4 );
5 always @(*) begin
6 case (in)
7 3’b000: out = 8’b00000001;
8 3’b001: out = 8’b00000010;
9 3’b010: out = 8’b00000100;
10 3’b011: out = 8’b00001000;
11 3’b100: out = 8’b00010000;
12 3’b101: out = 8’b00100000;
13 3’b110: out = 8’b01000000;
14 3’b111: out = 8’b10000000;
15 default: out = 8’b00000000;
16 endcase
17 end
18 endmodule
Solution:
1 module binary_subtractor (
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
234
Chapter 16 Problems with Solutions
Solution:
1 module binary_adder (
2 input [3:0] a, b,
3 output reg [3:0] sum,
4 output reg carry_out
5 );
6 always @(*) begin
7 {carry_out, sum} = a + b;
8 end
9 endmodule
Solution:
1 module multiplier_8bit (
2 input [7:0] a, b,
3 output reg [15:0] product
4 );
5 always @(*) begin
6 product = a * b;
7 end
8 endmodule
235
Chapter 16 Problems with Solutions
Solution:
1 module magnitude_comparator (
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
236
Chapter 16 Problems with Solutions
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
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
237
Chapter 16 Problems with Solutions
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
238
Chapter 16 Problems with Solutions
Solution:
1 module counter_with_enable (
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
239
Chapter 16 Problems with Solutions
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
240
Chapter 16 Problems with Solutions
Solution:
1 module comparator_8bit (
2 input [7:0] a, b,
3 output reg greater, equal, less
4 );
5 always @(*) begin
6 if (a > b) begin
7 greater = 1;
8 less = 0;
9 equal = 0;
10 end else if (a < b) begin
11 greater = 0;
12 less = 1;
13 equal = 0;
14 end else begin
15 greater = 0;
16 less = 0;
17 equal = 1;
18 end
19 end
20 endmodule
241
Chapter 16 Problems with Solutions
Solution:
1 module bin_to_bcd (
2 input [3:0] bin,
3 output reg [7:0] bcd
4 );
5 always @(*) begin
6 case(bin)
7 4’b0000: bcd = 8’b00000000; // BCD for 0
8 4’b0001: bcd = 8’b00000001; // BCD for 1
9 4’b0010: bcd = 8’b00000010; // BCD for 2
10 4’b0011: bcd = 8’b00000011; // BCD for 3
11 4’b0100: bcd = 8’b00000100; // BCD for 4
12 4’b0101: bcd = 8’b00000101; // BCD for 5
13 4’b0110: bcd = 8’b00000110; // BCD for 6
14 4’b0111: bcd = 8’b00000111; // BCD for 7
15 4’b1000: bcd = 8’b00001000; // BCD for 8
16 4’b1001: bcd = 8’b00001001; // BCD for 9
17 default: bcd = 8’b00000000; // Default BCD for
invalid input
18 endcase
19 end
20 endmodule
242
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [3:0] in,
3 output reg [1:0] out
4 );
5 always @(*) begin
6 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
Solution:
1 module up_counter_enable (
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
243
Chapter 16 Problems with Solutions
Solution:
1 module down_counter_enable (
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
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
244
Chapter 16 Problems with Solutions
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
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
245
Chapter 16 Problems with Solutions
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
246
Chapter 16 Problems with Solutions
Solution:
1 module up_down_counter_enable (
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
247
Chapter 16 Problems with Solutions
Solution:
1 module d_flip_flop (
2 input clk, rst,
3 input [3:0] d,
4 output reg [3:0] q
5 );
6 always @(posedge clk or posedge rst) begin
7 if (rst)
8 q <= 4’b0000;
9 else
10 q <= d;
11 end
12 endmodule
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
248
Chapter 16 Problems with Solutions
Solution:
1 module sync_reset_counter (
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
Solution:
1 module frequency_divider (
2 input clk,
3 output reg divided_clk
4 );
5 always @(posedge clk) begin
6 divided_clk <= ~divided_clk;
7 end
8 endmodule
249
Chapter 16 Problems with Solutions
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
Solution:
1 module even_parity_generator (
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
250
Chapter 16 Problems with Solutions
Solution:
1 module even_parity_checker (
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
Solution:
1 module odd_parity_generator (
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
251
Chapter 16 Problems with Solutions
Solution:
1 module odd_parity_checker (
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
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
252
Chapter 16 Problems with Solutions
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
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
253
Chapter 16 Problems with Solutions
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
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
254
Chapter 16 Problems with Solutions
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
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
255
Chapter 16 Problems with Solutions
Solution:
1 module multiplier (
2 input [3:0] a, b,
3 output [7:0] product
4 );
5 assign product = a * b;
6 endmodule
Solution:
1 module divider (
2 input [3:0] a, b,
3 output [3:0] quotient,
4 output [3:0] remainder
5 );
6 assign quotient = a / b;
7 assign remainder = a % b;
8 endmodule
256
Chapter 16 Problems with Solutions
Solution:
1 module and_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = a & b;
6 endmodule
Solution:
1 module or_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = a | b;
6 endmodule
257
Chapter 16 Problems with Solutions
Solution:
1 module xor_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = a ^ b;
6 endmodule
Solution:
1 module xnor_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = ~(a ^ b);
6 endmodule
258
Chapter 16 Problems with Solutions
Solution:
1 module not_gate (
2 input [3:0] a,
3 output [3:0] out
4 );
5 assign out = ~a;
6 endmodule
Solution:
1 module nand_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = ~(a & b);
6 endmodule
259
Chapter 16 Problems with Solutions
Solution:
1 module nor_gate (
2 input [3:0] a, b,
3 output [3:0] out
4 );
5 assign out = ~(a | b);
6 endmodule
Solution:
1 module comparator (
2 input [3:0] a, b,
3 output reg equal
4 );
5 always @(*) begin
6 if (a == b)
7 equal = 1;
8 else
9 equal = 0;
10 end
11 endmodule
260
Chapter 16 Problems with Solutions
Solution:
1 module decoder (
2 input [1:0] in,
3 output reg [3:0] out
4 );
5 always @(*) begin
6 case (in)
7 2’b00: out = 4’b0001;
8 2’b01: out = 4’b0010;
9 2’b10: out = 4’b0100;
10 2’b11: out = 4’b1000;
11 default: out = 4’b0000;
12 endcase
13 end
14 endmodule
Solution:
1 module up_counter (
2 input clk, reset,
3 output reg [3:0] count
4 );
5 always @(posedge clk or posedge reset) begin
6 if (reset)
7 count <= 4’b0000;
8 else
9 count <= count + 1;
10 end
11 endmodule
261
Chapter 16 Problems with Solutions
Solution:
1 module down_counter (
2 input clk, reset,
3 output reg [3:0] count
4 );
5 always @(posedge clk or posedge reset) begin
6 if (reset)
7 count <= 4’b1111;
8 else
9 count <= count - 1;
10 end
11 endmodule
262
Chapter 16 Problems with Solutions
• 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
263
Chapter 16 Problems with Solutions
Solution:
1 module shift_register (
2 input clk, reset, shift_left, shift_right,
3 input [15:0] data_in,
4 output reg [15:0] data_out
5 );
6 always @(posedge clk or posedge reset) begin
7 if (reset)
8 data_out <= 16’b0;
9 else if (shift_left)
10 data_out <= data_out << 1;
11 else if (shift_right)
12 data_out <= data_out >> 1;
13 end
14 endmodule
Solution:
1 module multiplier (
2 input [7:0] a, b,
3 output [15:0] product
4 );
5 assign product = a * b;
6 endmodule
264
Chapter 16 Problems with Solutions
Solution:
1 module priority_encoder (
2 input [3:0] in,
3 output reg [1:0] out
4 );
5 always @(*) begin
6 casez(in)
7 4’b0001: out = 2’b00;
8 4’b001x: out = 2’b01;
9 4’b01xx: out = 2’b10;
10 4’b1xxx: out = 2’b11;
11 default: out = 2’b00;
12 endcase
13 end
14 endmodule
Solution:
1 module counter (
2 input clk, reset, enable,
3 output reg [15:0] count
4 );
5 always @(posedge clk or posedge reset) begin
6 if (reset)
7 count <= 16’b0;
8 else if (enable)
9 count <= count + 1;
10 end
11 endmodule
265
Chapter 16 Problems with Solutions
Solution:
1 module barrel_shifter (
2 input [7:0] data_in,
3 input [2:0] shift_amount,
4 input shift_left, shift_right,
5 output reg [7:0] data_out
6 );
7 always @(*) begin
8 if (shift_left)
9 data_out = data_in << shift_amount;
10 else if (shift_right)
11 data_out = data_in >> shift_amount;
12 else
13 data_out = data_in;
14 end
15 endmodule
Solution:
1 module full_adder (
2 input [7:0] a, b,
3 input carry_in,
4 output [7:0] sum,
5 output carry_out
6 );
7 assign {carry_out, sum} = a + b + carry_in;
8 endmodule
266
Chapter 16 Problems with Solutions
Solution:
1 module reg_file (
2 input clk, we,
3 input [1:0] addr,
4 input [3:0] data_in,
5 output reg [3:0] data_out
6 );
7 reg [3:0] registers [3:0]; // 4 registers of 4 bits each
8
9 always @(posedge clk) begin
10 if (we)
11 registers[addr] <= data_in;
12 data_out <= registers[addr];
13 end
14 endmodule
Solution:
1 module comparator (
2 input [7:0] a, b,
3 output reg equal
4 );
5 always @(*) begin
6 if (a == b)
7 equal = 1;
8 else
9 equal = 0;
10 end
11 endmodule
267
Chapter 16 Problems with Solutions
268
Chapter 16 Problems with Solutions
16 if (we_b)
17 memory[addr_b] <= data_in_b; // Write to port B
18 else
19 data_out_b <= memory[addr_b]; // Read from port B
20 end
21 endmodule
269
Chapter 16 Problems with Solutions
270
Chapter 16 Problems with Solutions
271
Chapter 16 Problems with Solutions
272
Chapter 16 Problems with Solutions
273
Chapter 16 Problems with Solutions
274
Chapter 16 Problems with Solutions
275
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 con-
trol 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
276
Chapter 16 Problems with Solutions
277
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
278
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
279
Chapter 16 Problems with Solutions
280
Chapter 16 Problems with Solutions
281
Chapter 16 Problems with Solutions
282
Chapter 16 Problems with Solutions
283
Chapter 16 Problems with Solutions
Project 117: Dynamic Memory Allocation with Alloc and Free Operations
Problem: Implement a dynamic memory allocation system that supports mem-
ory 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
284
Chapter 16 Problems with Solutions
285
Chapter 16 Problems with Solutions
286
Chapter 16 Problems with Solutions
288
Chapter 16 Problems with Solutions
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
289
Chapter 16 Problems with Solutions
22 always_comb begin
23 case(state)
24 FLOOR0: next_state = (floor_request == 2’b01) ? FLOOR1
:
25 (floor_request == 2’b10) ?
FLOOR2 :
26 (floor_request == 2’b11) ?
FLOOR3 : FLOOR0;
27 FLOOR1: next_state = (floor_request == 2’b00) ? FLOOR0
:
28 (floor_request == 2’b10) ?
FLOOR2 :
29 (floor_request == 2’b11) ?
FLOOR3 : FLOOR1;
30 FLOOR2: next_state = (floor_request == 2’b00) ? FLOOR0
:
31 (floor_request == 2’b01) ?
FLOOR1 :
32 (floor_request == 2’b11) ?
FLOOR3 : FLOOR2;
33 FLOOR3: next_state = (floor_request == 2’b00) ? FLOOR0
: 291
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
Chapter 16 Problems with Solutions
23 always_comb begin
24 case(state)
25 S0: next_state = (user_input) ? S1 : S0;
26 S1: next_state = (user_input) ? S2 : S0;
27 S2: next_state = (user_input) ? S3 : S0;
28 S3: next_state = (user_input) ? S4 : S0;
29 S4: next_state = S4; // Stay in valid password state
30 default: next_state = S0;
31 endcase
32 end
33
292
Chapter 16 Problems with Solutions
294
Chapter 16 Problems with Solutions
Answer:
• AND_out = 0
• OR_out = 1
• XOR_out = 1
Answer:
295
Chapter 16 Problems with Solutions
Answer:
296
Chapter 16 Problems with Solutions
Answer:
297
Chapter 16 Problems with Solutions
Answer:
• Starting value Q = 3.
298