Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Multiplier

Design

The multiplier is a 3-stage pipelined 32×32-bit signed/unsigned multiplier. Instead of implementing a custom shift-and-add state machine, the module relies on the synthesizer to infer DSP slices from the native multiplication expression.

sequenceDiagram
    participant Stage1 as Stage 1<br/>(Sign-Extend)
    participant Stage2 as Stage 2<br/>(Multiply)
    participant Stage3 as Stage 3<br/>(Select Output)

    Note over Stage1: rs1_in, rs2_in, multiplier_op_in
    Stage1->>Stage1: ext_rs1 = {sign_rs1, rs1_in}<br/>ext_rs2 = {sign_rs2, rs2_in}
    Stage1->>Stage2: reg1 values valid
    Stage2->>Stage2: product = rs1_reg1 * rs2_reg1<br/>(DSP inference)
    Stage2->>Stage3: reg2 values valid
    Stage3->>Stage3: case(mul_op):<br/>MUL → product[31:0]<br/>default → product[63:32]
    Note over Stage3: result + valid_out

Stage 1: Sign Extension

The 33-bit sign extension depends on the opcode:

Oprs1rs2
MULSignedSigned
MULHSignedSigned
MULHSUSignedUnsigned
MULHUUnsignedUnsigned

For unsigned operands, the MSB is extended with 0 instead of the sign bit. The extended values are stored in pipeline registers rs1_reg1 and rs2_reg1.

Stage 2: Multiplication

The actual multiplication is expressed natively in HDL:

(* use_dsp = "yes" *) logic signed [65:0] product;
product <= rs1_reg1 * rs2_reg1;

The use_dsp attribute guides the synthesizer to map the multiplication onto DSP48E1 slices. On the XC7A100T, three DSP blocks are inferred for this operation. The multiplication is performed on 33-bit signed values (one bit wider than the inputs to accommodate the sign extension), producing a 66-bit result. The intermediate values are retained in flip-flops for the pipeline.

Stage 3: Output Selection

The final stage selects either the lower or upper 32 bits of the product:

  • MUL: returns product[31:0] (the standard 32-bit multiplication result)
  • MULH / MULHSU / MULHU: returns product[63:32] (the high half, implementing multiply-high)

The 3-cycle latency means the result of a multiplication is available on the third clock cycle after issue. During these cycles, the pipeline is stalled to prevent dependent instructions from reading stale register values.

Verification

The multiplier testbench (rtl/tb_multiplier.sv) uses a dynamic scoreboard queue to handle the pipeline latency. Test vectors include:

  • Basic signed and unsigned multiplications with known results
  • Edge inputs (zero, one, maximum values, sign flips)
  • Hazard chains where MUL results feed directly into subsequent operations
  • Full coverage of all four MUL/MULH/MULHSU/MULHU variants