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

Randomized Stimulus with Golden Model

HardVerilog / SystemVerilogBuild

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 reset rst_n.
  • Reset State: On reset, mult_en, done, and error are 0. The stimulus registers mult_a and mult_b reset to 16'd1 and 16'd2, respectively.
  • Operation:
  • When the start input is asserted high (a 1-cycle pulse), the module transitions out of idle and begins testing.
  • It asserts mult_en = 1 and waits for the external multiplier to assert mult_valid = 1.
  • On the cycle mult_valid is high, the module compares the external product mult_p against the expected product mult_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'd1 and mult_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 = 1 and mult_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 = 1 and mult_en = 0. It remains in this state indefinitely.
  • Holding Values: Upon entering either the DONE or ERROR state, mult_a and mult_b must 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:#fff

Timing 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_b must be evaluated combinationally or on the cycle mult_valid is high.
  • The operands mult_a and mult_b must only update on the cycle *after* a successful match.
  • Upon entering the DONE or ERROR states, mult_a and mult_b must hold the values they had during the final check.
  • The start signal should be ignored if the module is not in the IDLE state.

Topics

FSMArithmeticVerificationBIST

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

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks