Deadlock Timeout Detector
Complex state machines, such as I2C or SPI controllers, can occasionally enter deadlocked states due to protocol glitches or missing peripheral responses. To prevent the entire system or simulation from hanging indefinitely, a watchdog timer circuit monitors the controller's active state and flags an error if an operation exceeds a safe time limit.
The deadlock detector monitors a controller's busy signal. When enable is high, the module counts the number of consecutive clock cycles the busy signal remains high. If the busy signal stays high for TIMEOUT consecutive clock cycles, the module asserts a timeout_err flag. If the busy signal drops low at any point, the internal counter resets to zero and the error flag is cleared. Disabling the detector (enable = 0) also resets the internal counter and clears the error flag immediately.
Timing and Reset Rules: • Clock: Positive-edge triggered (clk). • Reset: Asynchronous, active-low (rst_n). All outputs and internal state reset to 0. • Priority: rst_n has the highest priority, followed by enable == 0, followed by busy == 0. • The timeout_err signal must assert exactly on the TIMEOUT-th consecutive clock cycle where busy is sampled high (assuming enable remains high). • The module must accept a parameter TIMEOUT (default 1000) to allow testbenches to scale the threshold for simulation.
Worked Trace (assuming TIMEOUT = 4): • Cycle 1: rst_n=0 → timeout_err=0, count=0 • Cycle 2: rst_n=1, enable=1, busy=1 → timeout_err=0 (1st cycle high) • Cycle 3: enable=1, busy=1 → timeout_err=0 (2nd cycle high) • Cycle 4: enable=1, busy=1 → timeout_err=0 (3rd cycle high) • Cycle 5: enable=1, busy=1 → timeout_err=1 (4th cycle high) • Cycle 6: enable=1, busy=0 → timeout_err=0, count=0
{ "signal": [
{ "name": "clk", "wave": "p......" },
{ "name": "rst_n", "wave": "01....." },
{ "name": "enable", "wave": "01....." },
{ "name": "busy", "wave": "01...0." },
{ "name": "timeout_err", "wave": "0....10" }
], "head": { "text": "Timeout error asserts on the 4th consecutive cycle of busy being high (TIMEOUT=4)." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; all outputs go to 0 when asserted | | enable | input | 1 | Enable signal; when 0, counter and error flag are held at 0 | | busy | input | 1 | Monitored signal; must be high for TIMEOUT consecutive cycles to trigger error | | timeout_err | output | 1 | Error flag; asserts on the TIMEOUT-th consecutive cycle of busy being high |
Constraints
- The module must use a parameter named
TIMEOUTwith a default value of 1000. timeout_errmust be a registered output; do not use combinational logic for the output flag.- The internal counter must be sized safely to accommodate the
TIMEOUTparameter (e.g., at least a 32-bit register, or dynamically sized using$clog2). - If
busyorenabledrops to 0, the counter must reset immediately on the next clock edge.
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.