The Last In First Out (LIFO) or Stack is a data arrangement structure in which the data that enters the last is the one that is removed first. Let us see how to implement the concept of Stack using Verilog.
For a normal memory, we provide the address for reads and writes. But here we know where to write and what to read for stack operation. So address is not required to access a stack location.
Procedure to implement stack:
Testbench:
Simulation Result:
From the simulation result,
For a normal memory, we provide the address for reads and writes. But here we know where to write and what to read for stack operation. So address is not required to access a stack location.
Procedure to implement stack:
- Create a normal memory in Verilog.
- When the data and push signal is given, write to the memory starting from first address.
- When pop signal is given, read from the memory from last written address.
- When stack becomes empty, assert empty and if it becomes full, assert full signal.
We just require one index variable (internal variable) to control a stack because we are writing to and reading from the same address. However this is not the case for FIFO.
Verilog Code Logic:
Verilog Code:
Verilog Code Logic:
- Use a variable index to point to the memory location to read or write.
- During push signal, write to the memory and increment index.
- During pop, read from the memory from last written memory index and decrement index.
- Empty occurs when index equals 0.
- Full occurs when index equals depth.
For empty and full, I have used a shortcut logic to perform comparison as == operator will realize more hardware.
module Stack( clk, rstn, pop, push, empty, full, din, dout ); parameter WIDTH = 8; parameter DEPTH = 8; input clk; input rstn; input pop; input push; input [WIDTH-1:0]din; output [WIDTH-1:0]dout; output empty; output full; reg [WIDTH-1:0]stack[DEPTH-1:0]; //memory reg [WIDTH-1:0]index, next_index; reg [WIDTH-1:0]dout, next_dout; wire empty, full; always @ (posedge clk) //Sequential block begin if(!rstn) begin dout <= 8'd0; index <= 1'b0; end else begin dout <= next_dout; index <= next_index; end end assign empty = !(|index); assign full = !(|(index ^ DEPTH)); always @ (*) //Combinational Block begin if(push) //write begin stack[index] = din; next_index = index+1'b1; end else if(pop) //read begin next_dout = stack[index-1'b1]; next_index = index-1'b1; end else begin next_dout = dout; next_index = index; end end endmodule
Testbench:
module Stack_tb; // Inputs reg clk; reg rstn; reg pop; reg push; reg [7:0] din; // Outputs wire empty; wire full; wire [7:0] dout; // Instantiate the Unit Under Test (UUT) Stack uut ( .clk(clk), .rstn(rstn), .pop(pop), .push(push), .empty(empty), .full(full), .din(din), .dout(dout) ); always #5 clk = ~clk; task reset(); //reset task begin clk = 1'b1; rstn = 1'b0; pop = 1'b0; push = 1'b0; din = 8'd0; #30 rstn = 1'b1; end endtask task read_stack(); //read task begin pop = 1'b1; #10 pop = 1'b0; end endtask task write_stack([7:0]din_tb); //write task begin push = 1'b1; din = din_tb; #10 push = 1'b0; end endtask // Main code initial begin reset(); #10; repeat(2) begin write_stack(8'h11); #10; write_stack(8'h22); #10; write_stack(8'h33); #10; write_stack(8'h44); #40; end read_stack(); #20; read_stack(); #20; write_stack(8'hAA); #10; write_stack(8'hBB); #40; read_stack(); #20; $finish; end endmodule
Simulation Result:
From the simulation result,
- We see that the Stack is initially empty as there is no data.
- Data is pushed into it until it becomes full.
- Two data are popped and then two data are pushed again to make it full again
Thus we have verified the basic operation of a stack.
Hello, Thank you for the article. Could you please elaborate more on the shortcut you used for empty and full signal?
ReplyDeleteHello,
Deleteempty = (!(|index);
Here, we OR each bit of index whose result will be 0 only if all bits are zero. Invert it to make it 1 and assign to empty.
For the full case, EXOR result will be 0 when both variables are equal. So invert and assign to full.
Thank you so much :)
Deletehello can i get the algorithm and complete logic of the code
ReplyDeleteplzzzz.
Hi, I have mentioned the logic of the code on top. Can help if any portion is not clear.
Deletei want to know how many bytes or word this stack program
ReplyDeleteThe stack is configured as WIDTH=8 (8-bit data) and DEPTH=8 (8 locations).
DeleteIt can be modified as per requirement during instantiation.