This chapter shows how to combine building blocks into complete digital systems. The key concept of separating a system into a datapath and a control unit (FSM) is central. Bus structures are explained using tri-state drivers and multiplexers. A simple processor design serves as the main example, including a register file, ALU, and a control FSM. Several algorithmic designs are presented: a bit-counting circuit, a shift-and-add multiplier, a restoring divider, an arithmetic mean calculator, and a sorting network. Each is designed using ASM charts for control and datapath diagrams. The chapter concludes with practical considerations: clock distribution networks, flip-flop timing at the chip level, asynchronous input handling (synchronizers), and switch debouncing circuits.
本章說明如何將各個基礎元件組合成完整的數位系統。核心概念是把系統拆分為資料路徑 (datapath)與控制單元 (control unit, FSM)。匯流排結構則以三態驅動器 (tri-state driver) 與多工器 (multiplexer) 來實現。本章的主要範例是一個簡單處理器,包含暫存器檔 (register file)、ALU 與控制 FSM。此外還介紹幾個演算法設計:位元計數電路、移位加法乘法器、還原除法器 (restoring divider)、算術平均計算器,以及排序網路。每個範例都以 ASM 圖描述控制流,搭配資料路徑圖。最後則討論實務考量:時脈分佈網路 (clock distribution)、晶片層級的正反器時序、非同步輸入處理 (同步器, synchronizer),以及開關彈跳消除 (switch debouncing) 電路。
An ASM (Algorithmic State Machine) chart is a flowchart-style notation for describing the control flow of a finite-state machine. It plays the same role as a state diagram, but is closer to algorithm pseudocode — easier to read for complex FSMs that branch on many conditions, easier to translate directly into Verilog case statements, and easier to align visually with the datapath actions it controls.
The three building blocks of an ASM chart:
Each box has a specific role:
An ASM block is a state box together with all the decision and conditional-output boxes that follow it before the next state box. One ASM block = one clock cycle's worth of behavior.
Tiny worked example — "001" detector (Moore):
Three state boxes (A, B, C — C drawn with a double border to mark Moore z=1), two decision boxes testing input w, no conditional outputs needed since this version is pure Moore.
Mealy variant — "01" detector with a conditional output oval: the same job done with one fewer state. z is asserted only on the transition that actually completes the pattern, so it lives inside an oval on that branch (Mealy = output depends on state and input).
Two state boxes (A, B), two decision boxes on input w, and one conditional output oval on the B → A branch where w=1 completes the "01" pattern. Mealy fires z for one cycle on that transition only — strictly fewer states than the Moore version of the same detector, at the cost of an output that follows the input combinationally.
How it maps to Verilog: each state box becomes one branch of a case in the FSM's combinational always block; each decision box becomes a nested if; each conditional output box becomes an output assignment inside that if branch.
ASM chart vs. state diagram:
| State diagram | ASM chart | |
|---|---|---|
| Visual style | circles + arrows (graph) | flowchart (boxes + flow lines) |
| Best for | small FSMs, conceptual understanding | large FSMs with many input branches, datapath-aware design |
| Output placement | inside the state circle (Moore) or on the arrow (Mealy) | inside the state box (Moore) or in a conditional output oval (Mealy) |
| Translation to Verilog | manual case + transitions | direct mapping: each box → one Verilog construct |
| Datapath alignment | separate (you draw the datapath elsewhere) | often shown side-by-side with the datapath actions in each state |
Bottom line: ASM chart = state diagram for engineers. Same information, organized as a flowchart that lines up cleanly with Verilog code and with the datapath operations the FSM is controlling. The textbook uses ASM charts throughout chapter 7 because every example involves a datapath whose register transfers must be choreographed cycle-by-cycle.
A canonical small-FSM example: compute $\gcd(a, b)$ by repeated subtraction. The 3-state controller (IDLE / RUN / DONE) drives a tiny datapath of two registers, one subtractor, and one comparator — exactly the kind of pattern covered throughout this chapter.
Algorithm. Load $A \leftarrow a$, $B \leftarrow b$ on start. While $A \neq B$, subtract the smaller from the larger ($A \leftarrow A-B$ if $A>B$, else $B \leftarrow B-A$). When $A = B$ that common value is the GCD.
module gcd #(parameter N = 8) (
input clk, rst, start,
input [N-1:0] a, b,
output reg [N-1:0] gcd_out,
output reg done
);
reg [N-1:0] A, B;
reg [1:0] state;
parameter IDLE = 2'b00, RUN = 2'b01, DONE = 2'b10;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
done <= 1'b0;
end else case (state)
IDLE: if (start) begin
A <= a;
B <= b;
done <= 1'b0;
state <= RUN;
end
RUN: if (A == B) begin
gcd_out <= A; // result
done <= 1'b1;
state <= DONE;
end else if (A > B) begin
A <= A - B;
state <= RUN; // explicit: stay in RUN
end else begin
B <= B - A;
state <= RUN; // explicit: stay in RUN
end
DONE: if (!start) state <= IDLE; // wait for start to deassert
endcase
end
endmodule
Latency & variants. Subtraction-based GCD is worst-case O(max(a, b)) cycles — slow for very different operands (e.g. $\gcd(1, 2^{31})$). The mod-based variant $\gcd(A, B) = \gcd(B, A \bmod B)$ reaches O(log min(a, b)) cycles but requires an integer divider in the datapath. The repeated-subtraction form is the standard textbook example because it needs only a subtractor + comparator + 2 registers + a 3-state FSM controller.