0

I'm trying to write a simple 4-bit stack of depth 8 with push/pop signals but it's behaving in a very odd manner. One of my if statements works fine and the other one does not run at all. Here's my code:

module Stack_8x4(
    input wire clk,
    input wire reset,
    input wire push,
    input wire pop,
    input wire [3:0] data_in,
    output reg [3:0] data_out,
    output reg empty,
    output reg full
    );
    
    reg [3:0] index;
    reg [3:0] stack [7:0];
    
    always @(posedge reset) begin
        index <= -1;
        data_out = 4'd0;
        empty = 1;
        full = 0;
    end
    always @(posedge clk) begin
        if (push & !pop) begin
            empty = 0;
            if(!full) begin
                index = index + 1;
                stack[index] = data_in;
                if(index > 6) full = 1;
            end
        end
        if (pop & !push) begin
            full = 0;
            if(!empty) begin
                data_out = stack[index];
                index = index - 1;
                if(index < 0) empty= 1;
            end else data_out = 0;
        end
    end
endmodule

As you can see, the logic for push and pop is almost the same. My question is why does the line if(index < 0) empty= 1; does not work while if(index > 6) full = 1; works just fine?

Here's a test bench and simulation for more details:

module sim();

reg clk;
reg reset;
reg push;
reg pop;
reg [3:0] data_in;
wire [3:0] data_out;
wire full;
wire empty;
//wire [3:0]i;

always begin
clk = 0;
#5
clk = 1;
#5
clk = 0;
end

initial begin
// setup
reset = 1;
push = 0;
pop = 0;
data_in = 0;
#10
reset = 0;

// idle
#20

// push 1, 2, 3, 4, 5, 6, 7, 8, 9 to fill the module and test for idling at full
push = 1;
data_in = 1;
#10
data_in = 2;
#10
data_in = 3;
#10
data_in = 4;
#10
data_in = 5;
#10
data_in = 6;
#10
data_in = 7;
#10
data_in = 8;
#10
data_in = 9;
#10
data_in = 10;
#10
data_in = 11;
#10
pop = 1;
#10
push = 0;
#30
pop = 0;
push = 1;
#30
push = 0;
#20
pop = 1;
// pop
//pop = 1;

end

Stack_8x4 S (
    .clk(clk),
    .push(push),
    .pop(pop),
    .reset(reset),
    .data_in(data_in),
    .data_out(data_out),
    .full(full),
    .empty(empty)
);

endmodule

enter image description here

1 Answer 1

2

Your main issue is in the attempt to use signed data with unsigned variables. So, index <= -1;, index < 0 just do not work as you expect. My suggestion is to forget about signed arithmetic and do unsigned only.

Other issues:

  1. you should use only a single always block to do reset and non-reset work.
  2. you should use non-blocking assignments everywhere in your always @posedge blocks
  3. for some reason you do not use 2 elements in your stack (6, 7) due to 'index < 6'.

So, here is my re-write of your code:

   always @(posedge clk) begin
      if (reset) begin
         index <= 0;
         data_out <= 4'd0;
         empty <= 1;
         full <= 0;
      end      
      else if (push & !pop) begin
          if(index < 8) begin
            full<= 0;
            stack[index] <= data_in;
            index <= index + 1;
         end
         else 
           full <= 1;
      end
      else if (pop & !push) begin
         if(index == 0) begin
            empty <= 1;
            data_out <= 0;
         end
         else begin
            empty <= 0;
            index <= index - 1;
            data_out <= stack[index];
         end
      end // if (pop & !push)
   end // always @ (posedge clk)
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.