Course Companion
Building the Capstone Datapath
A concept-level guide to turning a datapath plan into named-port connections, worked on a different datapath.
3 min read · Updated
In the capstone's datapath step, every block is supplied and already instantiated. What is left is translation: turning the Lesson 7.2 design plan into named-port connections. This page works the method on a different datapath, a running total, so the capstone's own connections stay yours to trace.
The method: trace each input back to its driver
For every port you have to connect, start at the port and follow the plan backwards to the block that drives it. The wire to write is whatever that block's output port is connected to in the surrounding module. Two cases need care.
- A MUX sits between a source and a port. The port receives the MUX's output wire, never one of the MUX's data inputs. The source reaches the port only through the MUX.
- A wire leaves the module and also feeds a block inside it. A module may read its own output port, so one wire can do both jobs.
Worked on a running total
This top level adds either a sample or a fixed 1 to a stored total. It uses Lesson 3.6's register and the Module 2 ALU under different names:
module running_sum(input clk, input rst, input add_en, input count_mode,
input [3:0] sample, output [3:0] sum);
wire [3:0] held, step;
assign step = count_mode ? 4'd1 : sample; // the MUX
reg4 u_hold(.clk(clk), .rst(rst), .en(add_en),
.d(sum), .q(held)); // stores the total
alu4 u_add(.a(held), .b(step), .op(2'b00),
.y(sum)); // adds
endmoduleTrace it. The adder's b port is fed by the MUX, so it takes step, not sample. The adder's a port is fed by the register, so it takes held. The register's d port is fed by the adder, whose output sum is also the module's output, read inside the module. With held at 6, count_mode at 0 and sample at 3, sum shows 9 at once; the register stores 9 at the next rising edge with add_en at 1.
Why that loop is safe
sum feeds the register, and the register feeds the adder that makes sum. That is not a combinational loop (Lesson 6.6): a new value enters the register only at a rising edge with add_en at 1, so within one cycle sum never depends on itself. A loop is legal when it passes through a clocked register.
The controller stub
The capstone's datapath checker acts as a controller stub: it drives every control input directly, the write enable, the addresses, the ALU operation and the immediate select. From Lesson 7.5 onward the controller FSM drives some of those and the top-level module drives the rest. The stub lets you prove the datapath in isolation, before the real FSM exists.
The capstone ALU adds SUB to the Lesson 2.13 ALU, so its codes shift: SUB takes 01, and AND and OR move to 10 and 11.
A register file with no other bootstrap path starts every register at an unknown value after power-on. The stub testbench resets first, then writes each seed value through the ALU's own ADD-with-immediate path (0 + value) — a pattern worth remembering any time a testbench needs a known starting state without a dedicated load port.