Stack Overflow and Underflow Protection
Hardware accelerators and embedded processors rely on stacks to manage local variables, state contexts, and return addresses. A hardware stack must protect its contents from invalid operations; pushing to a full stack destroys valid data, while popping from an empty stack returns undefined garbage.
The safe_stack module maintains an internal 4-deep by 8-bit memory array and a stack pointer. It processes push and pop commands to store and retrieve data. When a push is requested but the stack is at maximum capacity, the module ignores the write and asserts an overflow flag. When a pop is requested but the stack contains no data, the module ignores the read and asserts an underflow flag. Simultaneous push and pop requests cancel each other out, resulting in no memory changes and no error flags.
Timing and Reset Rules
- Clock edge:
posedge clk - Reset type: Asynchronous active-low
rst_n - Reset state:
empty=1,full=0,overflow=0,underflow=0,rdata=8'h00. The internal pointer resets to 0. - Priority rules: If
pushandpopare asserted simultaneously, they cancel out. The pointer remains unchanged, memory is not written, and no error flags assert. An activerst_ntakes priority over any memory operation. - Registered outputs:
overflowandunderfloware registered and assert for exactly one clock cycle immediately following the invalid request.rdatais registered and updates on the clock edge of a validpopoperation.
Worked Trace
Cycle 1: rst_n=0 → empty=1, full=0, overflow=0, underflow=0, rdata=8'h00 Cycle 2: rst_n=1, pop=1 → empty=1, underflow=0 (Invalid pop requested) Cycle 3: push=1, wdata=8'hAA → empty=0, underflow=1 (Underflow asserts for 1 cycle) Cycle 4: push=1, wdata=8'hBB → empty=0, full=0, underflow=0 Cycle 5: push=1, wdata=8'hCC → empty=0, full=0 Cycle 6: push=1, wdata=8'hDD → empty=0, full=1 (Stack is now full) Cycle 7: push=1, wdata=8'hEE → empty=0, full=1, overflow=0 (Invalid push requested) Cycle 8: pop=1 → empty=0, full=0, overflow=1, rdata=8'h00 (Overflow asserts for 1 cycle, valid pop requested) Cycle 9: push=0, pop=0 → empty=0, full=0, overflow=0, rdata=8'hDD (rdata updates from pop)
{ "signal": [
{ "name": "clk", "wave": "p........" },
{ "name": "rst_n", "wave": "01......." },
{ "name": "push", "wave": "001111100" },
{ "name": "pop", "wave": "010000010" },
{ "name": "wdata", "wave": "x.====x..", "data": ["AA", "BB", "CC", "DD", "EE"] },
{},
{ "name": "empty", "wave": "1.0......" },
{ "name": "full", "wave": "0.....1.0" },
{ "name": "overflow", "wave": "0......10" },
{ "name": "underflow", "wave": "0.10....." },
{ "name": "rdata", "wave": "2.......2", "data": ["00", "DD"] }
], "head": { "text": "Underflow and overflow flag generation with registered read data." } }Port Table
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | push | input | 1 | Push command; writes wdata to stack if not full | | pop | input | 1 | Pop command; reads top of stack to rdata if not empty | | wdata | input | 8 | Data to be pushed onto the stack | | rdata | output | 8 | Data popped from the stack; updates on valid pop; resets to 0 | | full | output | 1 | Asserted when stack contains exactly 4 elements | | empty | output | 1 | Asserted when stack contains 0 elements | | overflow | output | 1 | Registered flag; asserts for 1 cycle after a push to a full stack | | underflow | output | 1 | Registered flag; asserts for 1 cycle after a pop from an empty stack |
Constraints
- Internal memory must be exactly 4 entries deep and 8 bits wide.
overflowandunderflowmust be exactly one clock cycle wide.rdatamust hold its value until the next validpopor a reset.- Simultaneous
pushandpopmust be treated as a no-op (no memory change, no pointer change, no error flags).
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.