Fixed Point Multiplication with Saturation
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_nmust be asynchronous and active-low. - When
rst_nis asserted,pmust immediately evaluate to8'b0000_0000. - Reset has priority over
en. - The output
pis registered and must only update whenenis high. - Positive overflow must saturate to
8'b0111_1111(+7.9375). - Negative overflow must saturate to
8'b1000_0000(-8.0).
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.