Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
    • Flip-Flops and Registers
    • Counters and Timers
    • Shift Registers and LFSRs
    • Pipelining
      • Throughput and Latency
      • A Three-Stage Arithmetic Pipeline
      • Valid/Ready Flow Control
      • Pipelined MAC
      • Precision Verification
    • Stalls, Bubbles and Hazards
    • Retiming
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Pipelining
  1. Topics
  2. RTL Design
  3. Sequential Design
  4. Pipelining
  5. Pipelined MAC

Part 3 · Sequential · Intermediate

Pipelined MAC

Pipeline multiplication and accumulation while keeping valid, reset, and numeric precision aligned.

Why this matters

Add a register after the multiplier without delaying the valid and frame signals, and every result is paired with the wrong transaction while each value is arithmetically correct. The accumulator loop also limits the clock.

After this lesson you can: build a pipelined MAC with a frame-aware valid, state which registers need reset, and name how to break the accumulator recurrence.

Pipelined multiply-accumulate with a valid product stage, frame counter, and final sum register.
Only the 1024th accepted product completes a frame; bubbles do not advance the count.

A frame is exactly 1024 accepted input pairs: in_valid = 1 at a rising edge accepts one pair, with no backpressure. Bubbles are ignored. The product is registered at that edge and accumulated at the next edge. out_valid pulses only when the final product is accumulated, alongside the full 42-bit frame sum; the accumulator clears on that same edge so the next frame can follow without an idle cycle. Reset discards any partial frame. Rounding and saturation consume this full-precision output later.

Continuous input, accepted at edge E0

Product stage after edge

Accumulator / output after edge

E0: accept pair 0

Product 0 valid

No old product to add

E1: accept pair 1

Product 1 valid

Add product 0

E1023: accept pair 1023

Final product valid

Sum contains products 0..1022

E1024: next frame may start

Next frame's first product, if offered

Publish all 1024 products; clear accumulator/count

E1025

Continue next frame

A clocked consumer can sample the preceding frame's valid result before this update

The end of a frame, cycle by cycle

Each slot is one clock cycle, sampled just after the edge that opens it: slot 0 follows E1021. Every pair is a = b = 1, so a full frame sums to 1024, hex 400.

  • Slot 2: the frame's last pair was accepted at E1023, but its product is still in the register (v1_q is 1), so count_q reads 3ff (1023).

  • Slot 3: at E1024 that product is added. out_valid pulses for one cycle with frame_sum = 400, and count_q clears on the same edge.

  • Slots 3 to 5: in_valid drops for one cycle. One edge later v1_q drops, and in slot 5 count_q holds at 1 instead of advancing.

  • Rule: the count follows accepted products, one register behind in_valid, not clock cycles.

frame_mac.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
module frame_mac (
  input  logic clk, rst_n, in_valid,
  input  logic signed [15:0] a_i, b_i,
  output logic out_valid,
  output logic signed [41:0] frame_sum
);
  logic v1_q;
  logic signed [31:0] product_q;
  logic signed [41:0] acc_q, next_sum;
  logic [9:0] count_q;

  assign next_sum = acc_q + product_q; // signed product extends to 42 bits
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      v1_q      <= 1'b0;
      out_valid <= 1'b0;
      acc_q     <= '0;
      count_q   <= '0;
      frame_sum <= '0;
    end else begin
      v1_q      <= in_valid;
      out_valid <= 1'b0;
      if (in_valid) product_q <= a_i * b_i;
      if (v1_q) begin
        if (count_q == 10'd1023) begin
          frame_sum <= next_sum;
          out_valid <= 1'b1;
          acc_q     <= '0;
          count_q   <= '0;
        end else begin
          acc_q   <= next_sum;
          count_q <= count_q + 1'b1;
        end
      end
    end
  end
endmodule

This is the implementation spine of the running sensor design: Q1.15 inputs produce a Q2.30 product, and the 42-bit accumulator keeps the same 30 fractional bits. The test first resets a 17-sample partial frame with a pending product, discards that reference epoch, then checks three fresh complete frames, including consecutive frames and bubbles. Every output-valid cycle must match the fresh model; no old partial completion is allowed.

  • Reset validity and frame state, not necessarily every wide data register.

  • Count accepted products, including the registered product latency, rather than clock cycles.

  • For variable-length frames, delay frame markers and tags with the product and define restart or abort explicitly.

  • Break feedback timing with partial sums or interleaved accumulators when one-cycle recurrence is too slow.

Common pitfall

Adding a pipeline register to the product but not delaying valid or frame control associates results with the wrong transaction even when every arithmetic value is individually correct.

Check yourself Why might a feedback accumulator limit clock frequency despite a pipelined multiplier?

The accumulator has a loop-carried dependency: each add needs the previous sum. Its adder and register-to-register path set the recurrence timing.

Remember

  • Delay valid and frame markers by the same number of stages as the data.

  • Count accepted products, not clock cycles. Reset validity and frame state, not every wide data register.

  • The accumulator is a loop-carried add, so its adder path sets the clock; partial sums or interleaving break it.

Keep going

  • Interview: run a mock interview on this topic

Related topics

  • Divider architectures

  • Pipelining

Previous

79 / 350

Next: Precision Verification

Up next

Up nextPrecision Verification

Sign in to save progress

Practice this lessonReport an error

See also

  • Throughput and Latency
  • A Three-Stage Arithmetic Pipeline
clkin_validv1_qcount_q3fd3fe3ff0123out_validframe_sum0400
Simulated end of one 1024-product frame in frame_mac, then a one-cycle bubble at the start of the next frame