`timescale 1ns/1ns module LIFO( reset, push, pop, push_data, pop_data, stack_empty, stack_full ); parameter LIFO_WIDTH = 8; parameter LIFO_DEPTH = 16; input reset; // async reset, active on 1 input push; // push input pop; // pop input [LIFO_WIDTH-1:0] push_data; output [LIFO_WIDTH-1:0] pop_data; output stack_empty; output stack_full; // interface wire reset; wire push; // push request wire pop; // pop request wire [LIFO_WIDTH-1:0] push_data; reg [LIFO_WIDTH-1:0] pop_data; reg stack_empty; reg stack_full; // internals reg [LIFO_WIDTH-1:0] lifo[LIFO_DEPTH-1:0]; reg [LIFO_WIDTH-1:0] stack_ptr; integer i; always @ (reset or stack_ptr) begin if (reset==1) stack_ptr = 0; case (stack_ptr) 0: stack_empty = 1'b1; LIFO_DEPTH: begin $display("Lifo full\n"); stack_full = 1'b1; end default: begin $display("Default reached\n"); stack_empty = 1'b0; stack_full = 1'b0; end endcase end always @ (posedge push or posedge pop) begin if ( pop == 1'b1 ) // pop begin stack_ptr = stack_ptr - 1; pop_data = lifo[stack_ptr]; $display("stack_ptr=%x, pop_data=%x\n",stack_ptr, pop_data); end else if (push == 1'b1) // push begin lifo[stack_ptr] = push_data; stack_ptr = stack_ptr + 1; $display("Pushed data=0x%x, lifo[stack_ptr]=0x%x\n", push_data, lifo[stack_ptr]); for (i = 0; i < LIFO_DEPTH ; i = i + 1) $display("lifo[%d]=0x%x, stack_ptr=0x%x\n", i, lifo[i], stack_ptr); end end endmodule