Practice

Pipe Guard Kick Window

The electrical cabinet at Marsh Lane pushes a small protective current into 11 km of buried gas pipe. That current is what stops the pipe from corroding. The cabinet's controller board locks up in thunderstorms. A watchdog should catch that: a checker circuit that the firmware must pulse (kick) at regular intervals to prove it is alive. But the plain watchdog got fooled last autumn. A failed firmware update left the board in a boot loop, and the startup code pulses the kick line first thing. So the board kicked, crashed, and rebooted, around and around. After 6 weeks of that, the pipe's protective voltage was out of spec down the whole southern section. Corrosion does not send alarms.

Your task: build the replacement supervisor. It watches when the kick arrives, not just whether it arrives. A kick that lands too soon means the firmware is stuck in a loop, and that is as much a fault as silence. The service switch en_i disarms the supervisor for board swaps. Arming grants one full period of grace, because a freshly booted controller cannot hit a window it has never seen. The two fault flags, early_o and late_o, run to the telemetry dialer on separate wires. That way the repair crew knows whether to bring a firmware probe or a spare board.

Interface

PortDirectionTypeDescription
clk_iin1 bitClock
rst_iin1 bitSynchronous reset (active high)
en_iin1 bitService switch, high arms the supervisor
kick_iin1 bitKick line from the controller MCU
early_oout1 bitSticky fault: a kick landed in the closed half
late_oout1 bitSticky fault: the window closed without a kick

Behavior

  • Everything is sampled at rising clock edges
  • When en_i is sampled high while the supervisor is disarmed (after reset, or after any edge that sampled en_i low), that edge arms it. Call the edges that follow position 1, 2, 3 and so on
  • Arming opens the grace period: the first kick may land at any position 1 through 16 with no early fault possible. The arming edge itself does not sample the kick line
  • A kick sampled high at an allowed position is accepted, and position counting restarts at the following edge
  • After an accepted kick the window rules apply: positions 1 through 8 are closed, and a kick sampled at any of them sets early_o
  • Positions 9 through 16 are open, and a kick there is accepted
  • If position 17 is reached with nothing accepted since the last accept or arm, late_o sets at that edge
  • A kick arriving at position 17 does not rescue the period; the deadline has already passed
  • A kick held high across an accepted position is sampled again one edge later, at position 1 of the new period. That position is closed, so it sets early_o: a hung controller pinning the line high is a fault, not a heartbeat
  • early_o and late_o are sticky: once either is set the supervisor freezes, kicks are ignored, and the other flag can no longer set
  • en_i sampled low at any edge disarms and clears both flags at that edge. The next edge that samples en_i high arms afresh with a new grace period
  • rst_i = 1 at an edge clears both flags and disarms regardless of en_i; kicks are ignored while disarmed

What the bench checks

  • The testbench checks early_o and late_o on every cycle
  • The testbench drives kicks at positions 8, 9, 16 and 17 exactly, the grace period from both ends, and a held kick
  • It also drives a reset mid-period, re-arming after each kind of fault, and kicks while disarmed

Constraints

TIMING: everything is synchronous to clk_i; both outputs are registers.

SCOPE: this models the kick-window supervisor alone. The controller MCU, the telemetry dialer, and the pipe protection electronics are out of scope.

WINDOW: the numbers are the contract. Closed half 8 cycles, open half 8, deadline at the end of position 16, one full period of grace after arming.

Do not add ports.

Loading editor...

Click Run to execute your code. Output will appear here.