Time Multiplexing a Heavy Combinational Block
Area-constrained ASICs and FPGAs often cannot afford to instantiate multiple large combinational blocks like DSP slices or multipliers. A spatial design that computes four multiplications in parallel consumes four times the area of a temporal design that reuses a single multiplier over four clock cycles. Converting a parallel algorithm into a time-multiplexed sequential state machine is a fundamental skill for hardware optimization.
This module computes the sum of four products: (d1 * c1) + (d2 * c2) + (d3 * c3) + (d4 * c4). Instead of computing this in a single clock cycle with four multipliers, it time-multiplexes a single 8-bit by 8-bit multiplier over four clock cycles. When start is asserted, the module begins the multiply-accumulate sequence. On the fourth cycle of computation, it asserts done and outputs the final 18-bit accumulated result.
Timing and Reset Rules: • Clock edge: posedge clk • Reset: negedge rst_n (asynchronous, active-low) • On reset, done and result must be 0. The internal accumulator and state must also reset. • start is asserted for exactly one clock cycle. The inputs d1 through c4 are guaranteed to remain stable for the entire 4-cycle computation. • done must be asserted for exactly one clock cycle when the final result is ready, simultaneously with the valid result. • The module must return to the idle state immediately after asserting done, ready to accept a new start pulse on the very next cycle.
Worked Trace: • Cycle 1: rst_n=0 → state=IDLE, acc=0, done=0, result=0 • Cycle 2: rst_n=1, start=1 → state=IDLE. Multiplier computes d1*c1. • Cycle 3: start=0 → state=S1, acc=(d1*c1). Multiplier computes d2*c2. • Cycle 4: start=0 → state=S2, acc=(d1*c1)+(d2*c2). Multiplier computes d3*c3. • Cycle 5: start=0 → state=S3, acc=(d1*c1)+(d2*c2)+(d3*c3). Multiplier computes d4*c4. • Cycle 6: start=0 → state=IDLE, done=1, result=(d1*c1)+(d2*c2)+(d3*c3)+(d4*c4). • Cycle 7: start=0 → state=IDLE, done=0.
flowchart LR
IDLE((IDLE)) -->|start=1| S1
IDLE -->|start=0| IDLE
S1((S1)) --> S2
S2((S2)) --> S3
S3((S3)) -->|done=1| IDLE{ "signal": [
{ "name": "clk", "wave": "p......." },
{ "name": "rst_n", "wave": "01......" },
{ "name": "start", "wave": "010....." },
{ "name": "state", "wave": "=.====.=", "data": ["IDLE","IDLE","S1","S2","S3","IDLE"] },
{ "name": "done", "wave": "0....10." },
{ "name": "result","wave": "0....=0.", "data": ["sum"] }
], "head": { "text": "Time-multiplexed MAC execution over 4 cycles." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | start | input | 1 | 1-cycle pulse to begin computation | | d1, d2, d3, d4 | input | 8 | Data inputs | | c1, c2, c3, c4 | input | 8 | Coefficient inputs | | done | output | 1 | 1-cycle pulse when computation is complete | | result | output | 18 | Accumulated result, valid when done=1 |
Constraints
- Clock is positive-edge triggered; reset is asynchronous and active-low.
- All outputs and internal registers must be initialized to 0 on reset.
- You must use exactly one
*operator in your RTL. Instantiating multiple multipliers violates the core area-saving constraint of this problem. - The
resultoutput must be exactly 18 bits wide to prevent overflow. donemust assert for exactly one cycle.- The computation must take exactly 4 cycles from
starttodone.
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.