CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Memory Design

Simple LIFO Stack

MediumVerilog / SystemVerilogBuild

Processor call stacks, state saving mechanisms, and hardware parsers require a Last In First Out memory structure to temporarily hold and retrieve data in reverse order. This module implements a parameterized stack memory with a single pointer tracking the current fill level.

The module maintains an internal memory array of depth 2^ADDR_WIDTH. A stack pointer tracks the number of elements currently stored. On a valid push operation, the incoming data is written to the memory at the current pointer location, and the pointer increments. On a valid pop operation, the pointer decrements, and the data at the new pointer location is driven to the output register.

Timing and reset rules: • Clock edge: clk is positive edge triggered. • Reset type: rst_n is an asynchronous active low reset. • Reset behavior: On reset, the internal pointer is cleared to 0, empty is 1, full is 0, and data_out is 0. • Priority rules: If both push and pop are asserted on the same clock cycle, the operation is ignored and the state remains unchanged. • Boundary rules: A push when the stack is full is ignored. A pop when the stack is empty is ignored. • Output behavior: data_out is a registered output. It updates only on a valid pop operation. On all other cycles, including pushes and ignored operations, it holds its previous value.

Cycle by cycle trace: Cycle 1: rst_n=0 → empty=1, full=0, data_out=0 Cycle 2: rst_n=1, push=1, pop=0, data_in=10 → empty=0, full=0, data_out=0 Cycle 3: push=1, pop=0, data_in=20 → empty=0, full=0, data_out=0 Cycle 4: push=0, pop=1 → empty=0, full=0, data_out=20 Cycle 5: push=0, pop=1 → empty=1, full=0, data_out=10 Cycle 6: push=0, pop=1 → empty=1, full=0, data_out=10 (underflow ignored)

{ "signal": [
  { "name": "clk",      "wave": "p......" },
  { "name": "rst_n",    "wave": "01....." },
  { "name": "push",     "wave": "011000." },
  { "name": "pop",      "wave": "000111." },
  { "name": "data_in",  "wave": "x==xxxx", "data": ["10", "20"] },
  { "name": "data_out", "wave": "x...===", "data": ["20", "10", "10"] },
  { "name": "empty",    "wave": "10..1.." },
  { "name": "full",     "wave": "0......" }
], "head": { "text": "Pushing two elements, then popping three times to demonstrate underflow protection." } }

| Parameter | Default | Description | |-----------|---------|-------------| | DATA_WIDTH | 8 | Bit width of the data bus | | ADDR_WIDTH | 3 | Bit width of the memory address; stack depth is 2^ADDR_WIDTH |

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive edge triggered clock | | rst_n | input | 1 | Asynchronous active low reset | | push | input | 1 | Push enable; writes data_in to the stack | | pop | input | 1 | Pop enable; reads the top of the stack into data_out | | data_in | input | DATA_WIDTH | Data to be pushed onto the stack | | data_out | output | DATA_WIDTH | Data popped from the stack | | full | output | 1 | Asserted when the stack reaches its maximum capacity | | empty | output | 1 | Asserted when the stack contains zero elements |

Constraints

  • The pointer must have enough bits to represent the maximum capacity without wrapping to zero.
  • Pushing to a full stack must not overwrite existing data or increment the pointer.
  • Popping from an empty stack must not corrupt the pointer or update data_out.
  • Asserting both push and pop simultaneously results in no operation.

Topics

SequentialMemoryLIFOStack

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

  • Shift Register Based FIFOMedium
  • Asymmetric Data Width FIFOHard
  • True Dual Port RAM 2RWHard
  • Circular Buffer with OverwriteMedium
  • Synchronous Single Port RAMEasy
  • Stack Overflow and Underflow ProtectionMedium
  • Circular Buffer Pointer MathMedium
  • Read First Single Port RAMMedium

Browse all problems · Learning tracks