Hello! In our last lesson, we wrapped up combinational logic by building a parameterized N-bit adder. This marked a major milestone, giving you the tools to create complex logic that calculates outputs based purely on its current inputs.
Today, we transition into the exciting world of sequential logic. Unlike combinational circuits, sequential circuits have memory. Their outputs depend not just on current inputs, but also on their past state. The fundamental building block for this memory is the flip-flop.
This lesson is your first step into modeling sequential logic in Verilog. Our goal is to model the most common sequential element: an edge-triggered D-type flip-flop with a synchronous reset. We'll use the always @(posedge clk) construct, which is the cornerstone of synchronous digital design.
1. The Heart of Sequential Logic: The Clocked always Block
In previous lessons, we used assign statements or always @(*) for combinational logic. To create logic that changes its state only at specific moments in time, we need a different construct.
In synchronous systems, all state changes are synchronized to a master clock signal. We model this in Verilog using an edge-sensitive always block.
This article from ChipVerify introduces the different uses of the always block.
Read the introduction, focusing on the section that starts with the comment // Edge-sensitive: Execute always block at positive edge of signal "clk". This shows the syntax for the clocked always block. Then, scroll down and read "Mistake #4: Forgetting to Declare Outputs as 'reg' in Always Blocks" to understand a key requirement for signals assigned within these blocks.
As you just read, the syntax always @(posedge clk) tells the simulator and synthesis tools to execute the code inside the block only on the rising (positive) edge of the clk signal. This is how we ensure our circuit's state updates synchronously.
A crucial point from the reading: any signal that gets a value assigned to it inside an always block (or any other procedural block) must be declared as type reg. This is a Verilog syntax rule. It can be confusing because reg does not always mean the hardware will be a register (as we saw with always @(*)), but in an edge-triggered always block, it almost always does.
2. Modeling a Basic D Flip-Flop
Let's start with the simplest D flip-flop. Its behavior is straightforward: on the rising edge of the clock, the output q takes the value of the input d. At all other times, q holds its value.
The Verilog code for this is remarkably simple and elegant.
module d_ff (
input clk,
input d,
output reg q
);
always @(posedge clk) begin
q <= d;
end
endmodule
Notice the <_=_ operator. This is the non-blocking assignment. For now, just know that you should always use non-blocking assignments (<=) for sequential logic inside a clocked always block. It correctly models how real flip-flops behave—all flip-flops in a system capture their inputs at the same time (the clock edge) and then update their outputs simultaneously. We will explore this topic in much more detail in our next lesson.
3. Adding a Synchronous Reset
In any real system, we need a way to put our circuits into a known, initial state. This is done with a reset signal. A synchronous reset is a reset that only takes effect on an active clock edge.
Synchronous Reset Asynchronous Reset in Sequential design with verilog code
This video from the Explore VLSI channel clearly explains and demonstrates the concept of a synchronous reset.
First, watch the conceptual explanation of synchronous vs. asynchronous reset. The key idea is that a synchronous reset is synchronized with the clock. Next, see how this is implemented in Verilog in the code example. Pay close attention to how the if (reset) check is placed inside the always @(posedge clk) block. Finally, watch the waveform analysis to see visually how the output q only goes to zero when the reset is active and a positive clock edge arrives.
As the video demonstrated, implementing the synchronous reset is a matter of adding an if-else statement inside our clocked always block. The reset condition is given priority. If the reset signal is active, the output is forced to a known value (usually 0). If the reset is not active, the flip-flop performs its normal operation.
This coding style directly describes the hardware that will be created.

The pattern for a D flip-flop with an active-high synchronous reset is a fundamental building block in RTL design.
Structural Design with Verilog
This guide from Harvey Mudd College provides concise examples of common Verilog structures.
Please read section 4.1, "Flip-Flops." Skim the basic flop example and focus on the module defined as flopr with the comment // synchronous reset. This provides another clear example of the exact structure we are implementing.
4. Your Turn: Code the D-FF Module
Now it's time to write the code yourself. Your task is to complete the Verilog module for a single-bit D flip-flop with an active-high synchronous reset.
Specifications:
- Module Name:
dff_sync_reset - Ports:
clk(input)reset(input, active-high)d(input)q(output)
- Behavior:
- On the positive edge of
clk, ifresetis high (1),qshould be driven to 0. - Otherwise, on the positive edge of
clk,qshould capture the value ofd.
- On the positive edge of
- Remember to declare
qasregand use non-blocking assignments (<=).
Fill in the always block below.
module dff_sync_reset (
input clk,
input reset,
input d,
output reg q
);
// Your always block goes here.
// It should be sensitive to the positive edge of the clock.
// Inside, it should check for the reset condition first.
endmodule
Solution
module dff_sync_reset (
input clk,
input reset,
input d,
output reg q
);
always @(posedge clk) begin
if (reset) begin
q <= 1'b0;
end else begin
q <= d;
end
end
endmodule
This is the standard, synthesizable template for a D flip-flop with a synchronous reset. It's one of the most common patterns you'll use in digital design.
Conclusion
In this lesson, we made the crucial leap from combinational to sequential logic. You learned how to model the fundamental memory element of digital design—the D-type flip-flop.
Key Takeaways:
- Sequential logic is modeled in Verilog using clocked
alwaysblocks, most commonlyalways @(posedge clk). - This construct creates synchronous logic that only changes state on a clock edge.
- A synchronous reset is implemented with an
ifstatement inside the clockedalwaysblock, giving the reset condition the highest priority. - Signals assigned inside an
alwaysblock must be declared as typereg. - Non-blocking assignments (
<=) are essential for correctly modeling the parallel nature of hardware in sequential blocks.
We've used non-blocking assignments (<=) throughout this lesson with the simple rule "always use them for sequential logic." In our next lesson, we will dive deep into the "why." You will learn the critical differences between blocking (=) and non-blocking (<=) assignments and see why using the wrong one can lead to simulations that don't match the real hardware.