CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Arithmetic

Fixed Point Multiplication with Saturation

HardVerilog / SystemVerilogBuild

Digital signal processing algorithms frequently rely on fixed-point arithmetic to maintain precision without the hardware cost of floating-point units. Multiplying two fixed-point numbers doubles the bit width; returning this product to the original bus width requires careful scaling and clamping to prevent catastrophic integer wrapping.

This module multiplies two 8-bit two's complement numbers formatted in Q4.4 (4 integer bits, 4 fractional bits). The 16-bit intermediate Q8.8 product is truncated to drop the lower 4 fractional bits, keeping the result in Q4.4 format. If the resulting value exceeds the maximum positive (+7.9375) or minimum negative (-8.0) representable values in Q4.4, the output clamps to the respective maximum (0111_1111) or minimum (1000_0000) value instead of wrapping around.

The module updates its output on the positive edge of the clock when the enable signal is asserted. An asynchronous active-low reset clears the output to zero.

Worked Trace

Cycle 1: rst_n=0 → p=0 (Reset clears output) Cycle 2: rst_n=1, en=1, a=16 (1.0), b=32 (2.0) → p=0 (Evaluating 1.0 * 2.0) Cycle 3: en=1, a=64 (4.0), b=64 (4.0) → p=32 (2.0 latched from Cycle 2) Cycle 4: en=1, a=-128 (-8.0), b=64 (4.0) → p=127 (16.0 exceeds +7.9375, clamps to max positive) Cycle 5: en=1, a=-128 (-8.0), b=-128 (-8.0) → p=-128 (-32.0 exceeds -8.0, clamps to min negative) Cycle 6: en=0, a=0, b=0 → p=127 (+64.0 exceeds +7.9375, clamps to max positive) Cycle 7: en=0 → p=127 (Enable de-asserted, holds previous value)

{ "signal": [
  { "name": "clk",   "wave": "p......" },
  { "name": "rst_n", "wave": "01....." },
  { "name": "en",    "wave": "x1...0." },
  { "name": "a",     "wave": "x====x.", "data": ["16", "64", "-128", "-128"] },
  { "name": "b",     "wave": "x====x.", "data": ["32", "64", "64", "-128"] },
  {},
  { "name": "p",     "wave": "=======", "data": ["0", "0", "32", "127", "-128", "127", "127"] }
], "head": { "text": "Multiplication, saturation clamping, and enable hold behaviour." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n| input | 1 | Asynchronous active-low reset; clears p to 8'b0000_0000 | | en | input | 1 | Enable signal; output p updates on clock edge when en=1 | | a | input | 8 | Multiplicand in two's complement Q4.4 format | | b | input | 8 | Multiplier in two's complement Q4.4 format | | p | output | 8 | Registered product in two's complement Q4.4 format |

Constraints

  • The design must be triggered on the positive edge of clk.
  • The reset rst_n must be asynchronous and active-low.
  • When rst_n is asserted, p must immediately evaluate to 8'b0000_0000.
  • Reset has priority over en.
  • The output p is registered and must only update when en is high.
  • Positive overflow must saturate to 8'b0111_1111 (+7.9375).
  • Negative overflow must saturate to 8'b1000_0000 (-8.0).

Topics

datapathfixed-pointdspsaturation

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.

Sign in to solveSee what Pro unlocks

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.

Related problems

  • Binary to Gray Code DatapathEasy
  • 16-bit Arithmetic Barrel ShifterHard
  • Twos Complement Overflow in SubtractionMedium
  • 8-bit Combinational PopcountMedium
  • 8-bit Logical Barrel ShifterMedium
  • Absolute Value with Bit GrowthMedium
  • 8 bit Basic ALU with FlagsEasy
  • Parameterized ALU with Safe DefaultsMedium

Browse all problems · Learning tracks