This chapter transitions from combinational to sequential logic. It starts with the basic SR latch built from cross-coupled NOR or NAND gates, then introduces the gated SR latch, gated D latch, and the crucial edge-triggered D flip-flop (master-slave configuration). T flip-flops and JK flip-flops are also covered 1. Gated SR Latch — adds a clock/enable input to the basic SR latch. The cross-coupled NOR loop only responds when CLK=1. The S=R=1 input is still forbidden. Gated SR latch — Q sets/resets only while CLK=1 2. Gated D Latch — eliminates the forbidden state by deriving R from D̄. With one D input, S = D·CLK and R = D̄·CLK, so Q always follows D when the latch is enabled. Still level-sensitive: while CLK=1, every change of D propagates through. Gated D latch — Q transparently follows D while CLK=1; holds when CLK=0 3. Edge-Triggered D Flip-Flop (master-slave) — two D-latches in series with inverted clock to the second. While CLK=0 the master tracks D (slave is locked); when CLK rises, the master locks and the slave opens — capturing exactly one snapshot of D per rising edge. This is true edge-triggering: D can change freely between edges without affecting Q. Edge-triggered D FF — Q samples D only on rising edge of CLK 4. T Flip-Flop — toggle FF: when T=1, Q flips on each clock edge; when T=0, Q holds. Built from a D-FF with D = T ⊕ Q. Used as the building block of binary counters (each FF divides clock by 2). T flip-flop — Q toggles on rising edge when T=1, holds when T=0 5. JK Flip-Flop — the most general single-bit storage element: hold (00), reset (01), set (10), and toggle (11). Effectively combines SR and T behavior. Historically common in TTL designs; modern FPGAs prefer D-FFs because synthesis is simpler. JK flip-flop — JK = 00 hold, 01 reset, 10 set, 11 toggle Summary: latches are level-sensitive (transparent while enabled); flip-flops are edge-sensitive (sample on a clock edge, hold otherwise). The master-slave construction is the bridge — two latches with opposite clock phases turn level-sensitivity into edge-sensitivity. In Verilog/SystemVerilog, the choice between The core distinction: Classic shift-register example — same code, different hardware: Why the blocking version "collapses": synthesizers see that Why non-blocking matches hardware: physical flip-flops sample their D input at the clock edge and propagate to Q after a small delay (Tco). They can't see each other's new outputs within the same edge. Non-blocking semantics (evaluate-then-update) capture this exactly. Two-rule guideline that prevents almost all assignment bugs: Mixing them in a single Visual tour: latches → flip-flops
always @(posedge clk) for sequential logic, blocking vs. non-blocking assignmentsWhat is blocking vs. non-blocking?
= (blocking) and <= (non-blocking) is fundamental. The difference matters most inside always @(posedge clk) blocks — getting it wrong silently changes your hardware.
=): Executes sequentially, like software. Each statement finishes before the next begins.<=): All right-hand sides are evaluated first using the old values, then all left-hand sides update simultaneously at the end of the time step — modeling how real flip-flops work.
Non-blocking (correct: 3-stage shift) Blocking (collapses to 1 flip-flop) always @(posedge clk) begin
b <= a;
c <= b;
d <= c;
end
// → a → [FF] → b → [FF] → c → [FF] → d
// Three flip-flops, true shift registeralways @(posedge clk) begin
b = a;
c = b;
d = c;
end
// b, c, d all = a after the edge
// Synthesizer collapses to one FFb, c, d always end the clock edge with the same value, so they share storage. You get one flip-flop, not three. The simulation result depends on statement ordering, which is exactly what real hardware does not do.
always @(posedge clk) — always use <=always @* (combinational) — always use =always block is where simulation/synthesis mismatches creep in. If your testbench passes but the synthesized netlist behaves differently on FPGA, this is usually the culprit.
UpDown. When UpDown=1 the counter counts up; when 0 it counts down. Give the Verilog code.=) and non-blocking (<=) assignments in Verilog. Show a code example where using the wrong type produces incorrect hardware.Enable=0, the flip-flop holds its current value.D_latch with inputs D and Clk and output Q that uses an always block sensitive to D and Clk with an if (Clk) assignment, so that a level-sensitive gated D latch is inferred.always @(posedge Clock).always @(posedge Clock) block, two blocking assignments Q1 = D; Q2 = Q1; appear. Explain why this does NOT synthesize cascaded flip-flops, and draw the circuit that is actually inferred.Q1 <= D; Q2 <= Q1;) produces a two-stage shift register. Explain the semantic difference.Recap of Example 5.3 (blocking — wrong for cascading). The textbook starts with this code:
module example5_3 (D, Clock, Q1, Q2);
input D, Clock;
output reg Q1, Q2;
always @(posedge Clock) begin
Q1 = D; // blocking
Q2 = Q1; // blocking — Q1 already updated
end
endmoduleBlocking assignments evaluate sequentially. After Q1 = D;, the variable Q1 already holds the new value D, so Q2 = Q1; reads D as well. Both FFs latch the same input on every clock edge:
Problem 5.16 — non-blocking (right): swap = for <=:
always @(posedge Clock) begin Q1 <= D; // non-blocking Q2 <= Q1; // reads OLD Q1 (value at block entry) end
Non-blocking assignments all sample their right-hand sides at the moment the always block fires, then commit new values together at the end. So Q2 <= Q1; reads the previous value of Q1 — exactly what a real cascaded FF does. The synthesized hardware is a true 2-stage shift register:
Side-by-side semantics for one rising edge. Suppose before the edge: $D=1, Q_1=0, Q_2=0$.
| Style | $Q_1$ after edge | $Q_2$ after edge |
|---|---|---|
Blocking = | $D = 1$ | new $Q_1 = 1$ |
Non-blocking <= | $D = 1$ | old $Q_1 = 0$ |
After the second clock edge with non-blocking, $Q_2$ finally becomes 1 — the input has propagated through two stages, hence "shift register".
Rule of thumb. Use non-blocking (<=) for everything inside a clocked always @(posedge clk) block. Use blocking (=) only in combinational always @(*) blocks where sequential evaluation matches gate-level dataflow. Mixing the two in the same block is the most common source of synthesis-vs-simulation mismatches.
always @(posedge Clock) block with blocking assignments f = x1 & x2; g = f | x3;, draw the circuit that is synthesized. Explain why an AND gate appears between the input and the OR gate that feeds the g flip-flop.g is now driven by the previous-cycle output of the f flip-flop instead of the AND-gate output.— example 5.5Resetn) using a sensitivity list of negedge Resetn, posedge Clock.posedge Clock only.regn for an $n$-bit register with asynchronous clear, where $n$ is a parameter with a default value.Four requirements:
1. parameterized Verilog module regn — module name is regn ("register, parameterized n"). Must use Verilog's parameter mechanism so the bit width is not hard-coded — the same module file works for any width by passing a different value at instantiation.
2. for an $n$-bit register — a bank of $n$ D flip-flops in parallel: input bus D[n-1:0], output bus Q[n-1:0], one shared clock. On each rising clock edge, the $n$ inputs latch into the $n$ outputs simultaneously.
3. with asynchronous clear — a reset signal that clears all $n$ bits to 0 immediately when asserted, not waiting for the next clock edge. Implementation-wise, the reset signal goes into the always-block sensitivity list along with the clock (always @(posedge Clock or negedge Resetn)), so the block fires the moment reset asserts. Contrast: a synchronous clear would only take effect on the next rising clock edge.
4. where $n$ is a parameter with a default value:
n declared with parameter (not localparam, not a hard-coded number).What the grader checks: one module file that supports regn r1(); (default), regn #(.n(16)) r2(); (16-bit), regn #(32) r3(); (32-bit) — all without editing the source. Asserting Resetn drops Q to 0 between clock edges (visible in waveform). All $n$ bits load D on the rising clock edge when Resetn is inactive.
muxdff subcircuit (a D flip-flop with a 2-to-1 multiplexer on its D input). Inputs: R (parallel data), L (load), w (serial in), Clock; output Q.muxdff?A muxdff is the workhorse cell of a parallel-load / shift register: a single D flip-flop preceded by a 2-to-1 multiplexer that selects between two next-state values. The MUX's select line is usually called L (load):
w; the FF clocks in the bit coming from a neighbour cell. The chain shifts.R; the FF clocks in a fresh data bit from outside. The register loads.It's the smallest building block that lets a register do both jobs (shift OR load) under a single control bit.
Verilog for the muxdff cell:
module muxdff (
input R, w, L, Clock,
output reg Q
);
always @(posedge Clock)
Q <= L ? R : w; // L=1 → load R; L=0 → shift in w
endmodule
Building a 4-bit parallel-load shift register by chaining four muxdff cells:
Each cell's MUX bottom input is wired to the previous cell's Q. With L=0, bits ripple through the chain (shift). With L=1, every cell loads its corresponding R[i] in parallel.
Hierarchical Verilog (problem 5.22's task):
module shift_load_4 ( input [3:0] R, input L, w, Clock, output [3:0] Q ); muxdff bit3 (.R(R[3]), .w(w), .L(L), .Clock(Clock), .Q(Q[3])); muxdff bit2 (.R(R[2]), .w(Q[3]), .L(L), .Clock(Clock), .Q(Q[2])); muxdff bit1 (.R(R[1]), .w(Q[2]), .L(L), .Clock(Clock), .Q(Q[1])); muxdff bit0 (.R(R[0]), .w(Q[1]), .L(L), .Clock(Clock), .Q(Q[0])); endmodule
Why the muxdff abstraction matters: almost every register in a real design needs more than just "clock D into Q on each edge". Adding load, shift, hold, and reset capabilities can pile up ifs and edge cases. Capturing each combination as a tiny named cell (muxdff, plus enable/reset variants) and instantiating n copies for an n-bit register is the cleanest way to scale — verify the cell once, reuse everywhere.
always @(posedge Clock) block with non-blocking assignments to perform the load or shift action.for loop to express the bit-by-bit shift in the else branch.Resetn and enable input E. The count increments on the positive edge of Clock when E=1.L and a 4-bit data input R, so that the counter loads $R$ on the next clock edge when $L=1$.— example 5.13L=1 load R; otherwise if E=1 decrement.up_down that selects whether the counter increments or decrements.Figure 5.70a — two cascaded inverters tap-off internal nodes A and B
So $A = \overline{C}$ delayed by $\Delta$, and $B = C$ delayed by $2\Delta$ (i.e. $A$ further inverted).
The circuit. Two edge-triggered JK flip-flops share clock input $w$ and a common asynchronous Clear. Both K inputs are tied to logic 1, so each FF either holds (when $J=0$) or toggles (when $J=1$). The combinational wiring is:
JK behavior recap. On each rising edge of $w$:
| $J$ | $K$ | $Q^{+}$ | name |
|---|---|---|---|
| 0 | 0 | $Q$ | hold |
| 0 | 1 | 0 | reset |
| 1 | 0 | 1 | set |
| 1 | 1 | $\overline{Q}$ | toggle |
State walk-through. Start from Clear $\Rightarrow Q_1Q_0=00$:
| before | $J_1K_1$ | $J_0K_0$ | FF1 action | FF0 action | after |
|---|---|---|---|---|---|
| $Q_1Q_0=00$ | $0,1$ | $1,1$ | reset → 0 | toggle → 1 | $01$ |
| $Q_1Q_0=01$ | $1,1$ | $1,1$ | toggle → 1 | toggle → 0 | $10$ |
| $Q_1Q_0=10$ | $0,1$ | $0,1$ | reset → 0 | reset → 0 | $00$ |
The cycle closes after three pulses: $00 \to 01 \to 10 \to 00 \to \ldots$ — exactly the count sequence 0, 1, 2, 0, 1, 2, … so the circuit is a modulo-3 (divide-by-3) counter.
Timing diagram (matches Figure 5.72; both FFs are positive-edge-triggered on $w$):
Why this wiring works. State $11$ is excluded by construction: from state $10$, $J_0=\overline{Q_1}=0$ keeps $Q_0$ at 0, so the next state can never be $11$. With only three reachable states, three clock pulses return to the start — the defining property of a mod-3 counter.
Connection to Chapter 6. This is a hand-crafted FSM. In §6.7 the same mod-3 counter is re-derived systematically: pick a state assignment, build the excitation table for JK FFs (using the inverse of the JK characteristic table), and read $J_i$, $K_i$ off K-maps. The wiring above is the optimal result of that procedure.
Coin, and the output expression $Z = s_5 + s_4 s_3 s_2 s_1$.— example 5.20