I am working on a project wherein I need to convert a Finite State Machine coded in Verilog into a ROM. In order to do this I need to create a memory file for the ROM version of the FSM which stores the Next State and Output Values at Addresses comprised of the Current State and Input Values. My thought for how to build this file was to take the FSM in question and add "current_state" input, and "next_state" outputs, and then to make small modification to the fsm such that it uses those. However, I have had multiple issues with this tesbench that I can't seem to figure out so I figured I would throw together a smaller fsm to show what I am doing and hopefully get some insight as to what I am doing incorrectly. I believe my main issue is that the clock signal doesn't appear to be triggering at all (at least when I debug, the block which should be activiating at the posedge clock doesn't appear to ever trigger). The FSM in question I am attempting to model has something like 15 Current State and Input bits, and 76 Next State and Output bits, so rather than use any of the code from that I just threw together this smaller FSM (I get the same behavior so the issue isn't state machine specific and is likely more just due to my bad testbench).
So here is the FSM unit under test. It's a basic FSM I lifted from an old textbook:
module mealy_traditional(input wire clk,
input wire reset,
input wire a,
input wire b,
output wire y);
//Symbollic State Definition
localparam [1:0] state0 = 2'b00,
state1 = 2'b01,
state2 = 2'b10;
//signal declaration
reg [1:0] stateCurrent,
stateNext;
//state register
always @(posedge clk, posedge reset)
if(reset)
stateCurrent <= state0;
else
stateCurrent <= stateNext;
//_______________________________________________________Next State Logic
always @* begin
stateNext = stateCurrent
//______________________________________________________START_CASE
case(stateCurrent)
//___________________________________________________state0
state0:
if(a)
if(b)
stateNext = state2;
else
stateNext = state1;
else
stateNext = state0;
//___________________________________________________state1
state1:
if(a)
stateNext = state0;
else
stateNext = state1;
//___________________________________________________state2
state2: stateNext = state0;
//__________________________________________________default
default: stateNext = state0;
endcase
end
//Mealy Output Logic, function of both current state and current inputs
assign y = (stateCurrent == state0) & a & b;
endmodule
And here is the same FSM modified (I believe) to accept the current state as an input and to assign the next state output to a wire output.
module mealy_traditional(input wire clk,
input wire reset,
input wire [1:0] state_current,
input wire a,
input wire b,
output wire [1:0] state_next,
output wire y);
//Symbollic State Definition
localparam [1:0] state0 = 2'b00,
state1 = 2'b01,
state2 = 2'b10;
//signal declaration
reg [1:0] stateCurrent,
stateNext;
//state register
always @(posedge clk, posedge reset)
if(reset)
stateCurrent <= state0;
else
stateCurrent <= state_current;
//_______________________________________________________Next State Logic
always @* begin
stateNext = stateCurrent;
//______________________________________________________START_CASE
case(stateCurrent)
//___________________________________________________state0
state0:
if(a)
if(b)
stateNext = state2;
else
stateNext = state1;
else
stateNext = state0;
//___________________________________________________state1
state1:
if(a)
stateNext = state0;
else
stateNext = state1;
//___________________________________________________state2
state2: stateNext = state0;
//__________________________________________________default
default: stateNext = state0;
endcase
end
//Mealy Output Logic, function of both current state and current inputs
assign y = (stateCurrent == state0) & a & b;
assign state_next = stateNext;
endmodule
So here's where the issue almost certainly lies, the testbench. Now I know that given this FSM's limited inputs it would be very easy to just manually hit the fsm with each input combination and display the output, however, obviously with the other FSM that has close to 100 bits of IO, that's not really an option. Therefore I decided to create a for loop to just iterate through all possible input bit combinations and then generate the outputs to save into the memory file. The problem I run into is that it doesn't appear that the clock input cycles at all. Currently I am trying the following testbench code
`timescale 1ns / 1ns
module mealy_traditional_tb;
reg clk = 1'b0;
reg reset = 1'b0;
reg [3:0] in;
wire [2:0] out;
integer i = 0;
integer maxValue = 16;
//Instantiation
mealy_traditional
uut(.clk(clk),
.reset(reset),
.state_current(in[3:2]),
.a(in[1]),
.b(in[0]),
.state_next(out[2:1]),
.y(out[0]));
initial begin
reset = 1;
#10
reset = 0;
#10
for(i = 0; i < maxValue; i = i + 1) begin
in = i;
clk = 1;
clk = 0;
clk = 1;
clk = 0;
$display("%b : %b", in, out);
end
$finish;
end
endmodule
initially I had tried to create a standalone clock cycle by using an
always #10 clk = ~clk;
And then putting delays inside the for loop, which verilog did NOT like (wouldn't even compile, threw syntax errors).
So as it stands right now, this testbench code does compile and the simulator fires up, however it's pretty clear that the else branch of the state register update in the FSM is not getting accessed as when I set break points in there they never trigger and the output of the state machine appears to be just the baseline state from a system reset. (as follows)
# 0000 : 00x
# 0001 : 00x
# 0010 : 00x
# 0011 : 00x
# 0100 : 00x
# 0101 : 00x
# 0110 : 00x
# 0111 : 00x
# 1000 : 00x
# 1001 : 00x
# 1010 : 00x
# 1011 : 00x
# 1100 : 00x
# 1101 : 00x
# 1110 : 00x
# 1111 : 00x
I would have thought manually forcing the clock cycle in the for loop would have cause the finite state machine to update but it appears to not have. Is there a way for me to ensure that the clock cycle fires in such a way?