I'm trying to program an 8 level stack register for a Program Counter. It is working well enough, but for some reason, when I test it, some combinations of inputs produce unexpected results. This is leading me to believe that I don't really understand the underlying logic behind the "if(condition1 && condition2)" statement or the always@ statement (Statement? I'm not really sure how to call it). I don't care if it is synthesizable. I just feel that I'm missing something.
Here is the code:
module Stack(
// Buses
inout [12:0] BUS_Stack, // Bus used to exchange data between Stack and PC
// Inputs
input logic WE_Stack, // Write Enable. WE = 1 Stack sends data to PC
input logic RE_Stack // Read Enable. RE = 1 Receives data from PC
);
// Internal variables
integer i; // Variable used for "for loops"
reg [12:0] Stack [0:7]; // Stack matrix. A registry is used for it to have "memory"
logic [12:0] Data_To_PC; // Internal variable that manages the writing process to BUS_Stack
parameter Height = 7; // Constant for the number of layers that the stack has. Given in (N-1) bits
// The bus between PC and Stack is set to Z when WE_Stack = 0;
assign BUS_Stack = (WE_Stack && !RE_Stack) ? Data_To_PC : 13'bz;
always @(BUS_Stack or WE_Stack == 1'b1 or RE_Stack)
begin
// Receive data from PC
if (!WE_Stack && RE_Stack)
begin
// Downward PUSH to all elements in the Stack register
for (i = Height; i > 0 ; i = i - 1) Stack [i][12:0] = Stack [i-1][12:0];
// First Stack address <- Bus
Stack [0][12:0] = BUS_Stack;
end
// Send data to PC
else if (WE_Stack && !RE_Stack)
begin
// Stack's first row is asigned to the Bus
Datos_A_PC = Stack [0][12:0];
// Upwards PUSH to all elements inside the stack register
for (i = 0; i < Height ; i = i + 1) Stack [i][12:0] = Stack [i+1][12:0];
Stack[Height][12:0] = 13'bx;
end
end
endmodule
Here is the testbench I'm using:
//----------------------------TESTBENCH--------------------------------
module testbench();
// Inputs and Outputs
logic WE_Stack, RE_Stack;
logic [12:0] PC;
wire [12:0] BUS_Stack;
// Connection to module
Stack STK (.WE_Stack(WE_Stack), .BUS_Stack(BUS_Stack), .RE_Stack(RE_Stack));
// Assign statement used to simulate the Stack bus receiving data
assign BUS_Stack = (!WE_Stack && RE_Stack) ? PC : 13'bz;
initial
begin
$monitor("WE_Stack: %b \t RE_Stack: %b", WE_Stack, RE_Stack);
#1 WE_Stack = 0; RE_Stack = 1;
#1 PC = 13'd7;
#1 PC = 13'd21;
#1 PC = 13'd1;
#1 PC = 13'd144;
#1 PC = 13'd5;
#3 WE_Stack = 1; RE_Stack = 0;
#1 WE_Stack = 1; RE_Stack = 1;
#1 WE_Stack = 1; RE_Stack = 0;
#1 WE_Stack = 0; RE_Stack = 0;
#1 PC = 13'd4;
#1 PC = 13'd68;
end
initial
begin
#120 $finish;
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
The problem appears after the line
#3 WE_Stack = 1; RE_Stack = 0;
The program is supposed to write to PC only once, but when simulated, it produces about 7 write operations to the PC.