Retiming to Balance Logic Delay
Unbalanced pipelines severely limit the maximum clock frequency of a hardware design. When one pipeline stage contains multiple deep logic levels while subsequent stages act as simple pass-through registers, the entire system must slow down to accommodate the longest path. Retiming solves this by redistributing the registers across the combinational logic cloud, equalizing the delay between stages without altering the overall latency.
The module computes the mathematical expression y = (a * b) + (c * d) + e. An inexperienced engineer initially implemented this by performing all multiplications and additions in a single clock cycle, followed by two cycles of dummy pipeline delay to meet a 3-cycle latency requirement. This created a massive critical path.
The redesigned module must compute the exact same mathematical result with the exact same 3-cycle latency, but the logic must be retimed to balance the workload. Specifically, you must partition the logic into the following strict stages: • Stage 1: Perform the two multiplications (a * b and c * d). • Stage 2: Add the two resulting products together. • Stage 3: Add e to the running sum to produce the final output y.
Clocking and Reset Rules: • The clock edge is posedge. • The reset is asynchronous and active-low (rst_n). • On reset, every internal pipeline register and the final output y must clear to 0.
Worked Trace: Cycle 1: rst_n=0 → y=0, all internal registers hold 0. Cycle 2: rst_n=1, inputs a=2, b=3, c=4, d=5, e=6 are applied. Cycle 3: Stage 1 registers capture product1=6, product2=20, and a delayed copy of e=6. Output y remains 0. New inputs a=1, b=1, c=1, d=1, e=1 are applied. Cycle 4: Stage 2 registers capture sum=26 and a further delayed copy of e=6. Stage 1 captures product1=1, product2=1, and delayed e=1. Output y remains 0. Cycle 5: Stage 3 captures the final output y = 26 + 6 = 32. Stage 2 captures sum=2 and delayed e=1. Cycle 6: Stage 3 captures the next final output y = 2 + 1 = 3.
{ "signal": [
{ "name": "clk", "wave": "p........." },
{ "name": "rst_n", "wave": "01........" },
{ "name": "inputs (a-e)", "wave": "0.440.....", "data": ["TC1 (2,3,4,5,6)", "TC2 (1,1,1,1,1)"] },
{ "name": "stage1 (p1,p2)","wave": "0..440....", "data": ["6, 20", "1, 1"] },
{ "name": "stage2 (sum)", "wave": "0...440...", "data": ["26", "2"] },
{ "name": "y (output)", "wave": "0....440..", "data": ["32", "3"] }
], "head": { "text": "Pipeline retiming trace showing proper 3-cycle data propagation." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n| input | 1 | Asynchronous active-low reset; clears all pipeline state | | a | input | 8 | Unsigned 8-bit multiplicand | | b | input | 8 | Unsigned 8-bit multiplier | | c | input | 8 | Unsigned 8-bit multiplicand | | d | input | 8 | Unsigned 8-bit multiplier | | e | input | 8 | Unsigned 8-bit addend | | y | output | 17 | Unsigned 17-bit registered final result |
Constraints
- The module must have exactly 3 clock cycles of latency from inputs to the output
y. - The logic must be strictly partitioned as defined: multiplications in stage 1, first addition in stage 2, final addition in stage 3.
- The maximum possible value for
yis(255 * 255) + (255 * 255) + 255 = 130305, which fits perfectly within the 17-bit output width. Intermediate sums must be sized correctly to prevent overflow.
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.