Randomized Stimulus with Golden Model
Verifying complex arithmetic blocks exhaustively is often impossible; a 32-bit multiplier has $2^{64}$ possible input combinations. Hardware engineers use randomized stimulus generation and behavioral golden models to gain confidence in the design. In this problem, you will design a Built-In Self-Test (BIST) checker module that acts as an automated testbench for an external pipelined multiplier.
The module generates deterministic pseudo-random operands, drives them to the multiplier, waits for the result, and compares the hardware output against its own internal behavioral calculation (A * B). To keep the simulation brief, this BIST completes when exactly 4 successful checks are performed.
- Clock and Reset: The module is driven by a positive-edge triggered clock
clk. It has an active-low asynchronous resetrst_n. - Reset State: On reset,
mult_en,done, anderrorare0. The stimulus registersmult_aandmult_breset to16'd1and16'd2, respectively. - Operation:
- When the
startinput is asserted high (a 1-cycle pulse), the module transitions out of idle and begins testing. - It asserts
mult_en = 1and waits for the external multiplier to assertmult_valid = 1. - On the cycle
mult_validis high, the module compares the external productmult_pagainst the expected productmult_a * mult_b. - Match: If the product matches, the module increments its internal successful check counter. On the following cycle, it updates the operands using the formulas
mult_a = mult_a * 16'd5 + 16'd1andmult_b = mult_b * 16'd9 + 16'd3, and continues testing. - Mismatch: If the product does not match, the module transitions to an ERROR state on the next cycle, setting
error = 1andmult_en = 0. It remains in this state indefinitely. - Completion: When the 4th successful match occurs, the module transitions to a DONE state on the next cycle, setting
done = 1andmult_en = 0. It remains in this state indefinitely. - Holding Values: Upon entering either the DONE or ERROR state,
mult_aandmult_bmust freeze and hold the values they had during the final check.
Worked Trace
Cycle 1: rst_n=0 → en=0, err=0, done=0, a=1, b=2
Cycle 2: rst_n=1, start=1 → en=0, err=0, done=0, a=1, b=2 (State: IDLE)
Cycle 3: start=0, vld=0 → en=1, err=0, done=0, a=1, b=2 (State: STIMULUS)
Cycle 4: vld=1, p=2 → en=1, err=0, done=0, a=1, b=2 (Match! count=1)
Cycle 5: vld=0, p=0 → en=1, err=0, done=0, a=6, b=21 (a updated to 1*5+1, b to 2*9+3)
Cycle 6: vld=1, p=126 → en=1, err=0, done=0, a=6, b=21 (Match! count=2)
Cycle 7: vld=0, p=0 → en=1, err=0, done=0, a=31, b=192 (a updated to 6*5+1, b to 21*9+3)
Cycle 8: vld=1, p=9999 → en=1, err=0, done=0, a=31, b=192 (Mismatch!)
Cycle 9: vld=0, p=0 → en=0, err=1, done=0, a=31, b=192 (State: ERROR, a/b frozen)State Diagram
flowchart LR
RESET(( )) -->|reset| IDLE
IDLE((IDLE)) -->|start=1| STIMULUS
IDLE -->|start=0| IDLE
STIMULUS((STIMULUS)) -->|vld=1, p!=A*B| ERROR
STIMULUS -->|vld=1, p==A*B, count==3| DONE
STIMULUS -->|vld=1, p==A*B, count<3| STIMULUS
STIMULUS -->|vld=0| STIMULUS
ERROR(["ERROR ★"]):::err --> ERROR
DONE(["DONE ★"]):::done --> DONE
classDef err fill:#FF7675,stroke:#D63031,color:#fff
classDef done fill:#55EFC4,stroke:#00B894,color:#fffTiming Diagram (First two matches)
{ "signal": [
{ "name": "clk", "wave": "p......" },
{ "name": "rst_n", "wave": "01....." },
{ "name": "start", "wave": "010...." },
{ "name": "mult_valid", "wave": "0..1010" },
{ "name": "mult_p", "wave": "=..=.=.", "data": ["0", "2", "0", "126", "0"] },
{},
{ "name": "mult_en", "wave": "0.1...." },
{ "name": "mult_a", "wave": "=...=..", "data": ["1", "6", "31"] },
{ "name": "mult_b", "wave": "=...=..", "data": ["2", "21", "192"] },
{ "name": "error", "wave": "0......" }
]}Port Table
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Active-low asynchronous reset | | start | input | 1 | 1-cycle pulse to begin testing | | mult_valid | input | 1 | High when the DUT provides a valid product | | mult_p | input | 32 | The product returned by the DUT | | mult_a | output | 16 | Operand A driven to the DUT; resets to 16'd1 | | mult_b | output | 16 | Operand B driven to the DUT; resets to 16'd2 | | mult_en | output | 1 | High when testing is active (STIMULUS state) | | done | output | 1 | High when 4 successful checks have completed | | error | output | 1 | High if a mismatch is detected |
Constraints
- The behavioral calculation
mult_a * mult_bmust be evaluated combinationally or on the cyclemult_validis high. - The operands
mult_aandmult_bmust only update on the cycle *after* a successful match. - Upon entering the DONE or ERROR states,
mult_aandmult_bmust hold the values they had during the final check. - The
startsignal should be ignored if the module is not in the IDLE state.
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.