Stack with Peek Function
Parsers, expression evaluators, and microprocessors rely on stack data structures to manage execution state. Many algorithms require inspecting the top of the stack to make control flow decisions before committing to a pop operation. A dedicated peek function provides this visibility without requiring extra clock cycles to read memory.
The module maintains a 4-element deep, 8-bit wide stack. It supports synchronous push and pop operations. A dedicated combinational peek_data port continuously outputs the value at the top of the stack without modifying the internal pointer. Combinational empty and full flags indicate the current boundary state of the memory.
Timing and reset behaviour: • Clock edge: Positive edge of clk • Reset type: Asynchronous, active-low (rst_n) • Reset behaviour: The internal stack pointer clears to 0; empty asserts to 1; full and peek_data clear to 0 • Priority rules: If push and pop are asserted simultaneously, they cancel each other out and the state remains unchanged • Boundary rules: Pushing to a full stack or popping from an empty stack must be ignored
Cycle-by-cycle trace: Cycle 1: rst_n=0, push=0, pop=0, data_in=0 • empty=1, full=0, peek_data=0 Cycle 2: rst_n=1, push=1, pop=0, data_in=10 • empty=1, full=0, peek_data=0 Cycle 3: rst_n=1, push=1, pop=0, data_in=20 • empty=0, full=0, peek_data=10 Cycle 4: rst_n=1, push=1, pop=0, data_in=30 • empty=0, full=0, peek_data=20 Cycle 5: rst_n=1, push=1, pop=0, data_in=40 • empty=0, full=0, peek_data=30 Cycle 6: rst_n=1, push=0, pop=0, data_in=0 • empty=0, full=1, peek_data=40 Cycle 7: rst_n=1, push=0, pop=1, data_in=0 • empty=0, full=1, peek_data=40 Cycle 8: rst_n=1, push=0, pop=0, data_in=0 • empty=0, full=0, peek_data=30
{ "signal": [
{ "name": "clk", "wave": "p......." },
{ "name": "rst_n", "wave": "01......" },
{ "name": "push", "wave": "01111000" },
{ "name": "pop", "wave": "00000010" },
{ "name": "data_in", "wave": "x====xxx", "data": ["10", "20", "30", "40"] },
{},
{ "name": "empty", "wave": "1.0....." },
{ "name": "full", "wave": "0....1.0" },
{ "name": "peek_data", "wave": "=.====.=", "data": ["0", "10", "20", "30", "40", "30"] }
], "head": { "text": "Pushing 4 elements to reach full state, then popping one." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; clears pointer to 0 | | push | input | 1 | Push enable; writes data_in to stack on posedge clk | | pop | input | 1 | Pop enable; removes top element on posedge clk | | data_in | input | 8 | Data to be pushed onto the stack | | peek_data | output | 8 | Combinational output of current top element; 8'h00 if empty | | empty | output | 1 | Combinational flag asserted when stack holds 0 elements | | full | output | 1 | Combinational flag asserted when stack holds 4 elements |
Constraints
- The stack depth is exactly 4 elements.
peek_data,empty, andfullmust be combinational outputs reflecting the current state before the clock edge.- If
emptyis asserted,peek_datamust strictly output8'h00. - If
pushandpopare asserted simultaneously, they cancel out resulting in no state change. - Pushing to a full stack or popping from an empty stack must not modify the pointer or memory.
- Data inside the memory array does not need to be zeroed out on pop or reset; only the pointer state dictates valid data.
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.