# Finite state machines in verilog

I'm new to Verilog. I was trying to write the next Finite State Machines (miley machine) in Verilog:

this what I got:

// clk - clock, i - input, o - output
module test (clk,reset,i,o);

input   clk,reset,i;
output  o;
reg     o;
wire    clk,reset,i;

reg [2:0] present_state;
reg [2:0] next_state;

parameter A=2'b00, B=2'b01, C=2'b10;

always @(present_state,i)
begin
case (present_state)
A: if(i)        next_state = B;
else         next_state = A;
B: if(i)        next_state = A;
else         next_state = C;
C: if(i)        next_state = C;
else         next_state = B;
default:        next_state = A;
endcase
end

always @(posedge clk, posedge reset)
begin
if(reset)
present_state = 0'b0;
else
present_state = next_state;
end

always @(present_state)
begin
if(present_state == A)
o = 1'b0;
else if(present_state == C)
o = 1'b1;
else
o = i;
end

endmodule


I have a tester and every time I run it, I receive failure. What is the order of the block statement (which comes first?). Even thought my program compiled, It doesn't work.

• Could you share the compilation error? One of the error could be using a keyword "input" as a variable so might want to change it to "in" or something of your choice. Could you also share the test bench as well. May be there could be some errors in it. Nov 12 '17 at 17:44
• You can tidy up the case statement using a ternary construct, and also change to an always_comb block. But yes, a lot more info needed :) Nov 12 '17 at 17:47
• Also the code is bit confusing, as comment in top of the code, you show 'i' to be input, yet its not defined as input and also you dont initialise present_state. How is it supposed to next state when it doesnt know which state it is starting from? Nov 12 '17 at 17:49
• @rsg1710 the code doesn't have errors, it's just doesn't do what I need. About the input, I edited the code (while I was writing this post I have changed the syntax a little, that's the reason for the mistake) , it's should compile. Nov 12 '17 at 18:00
• Please share your testbench and the output you see at present. Nov 12 '17 at 18:02

I think the problem in your code is that the "present_state -> next_state" clocked block doesn't employ non-blocking assignment syntax.

Please study carefully the following articles,

and

and follow their advice and notation/syntax meticulously. You will get right results.

And another one, from the same expert Clifford E. Cummings.

// Testbench
timescale 1ns/1ns
module test;

reg clk   ;
reg reset ;
reg i     ;

// Instantiate design under test
test01 TST(.clk(clk),
.reset(reset),
.i(i),
.o(o));

initial begin
$dumpfile("dump.vcd");$dumpvars(1);
clk     =   1'b0;
reset   =   1'b1;
i       =   1'b0;
end

always begin
#10     reset   = 1'b0;
#15     i       = 1'b1;
#20     i       = 1'b0;
end

always
#5  clk = !clk;

endmodule


To this test bench I see it working fine :)

module test01 (clk,reset,i,o);

input   clk,reset,i;
output  o;
reg     o;
wire    clk,reset,i;

reg [2:0] present_state;
reg [2:0] next_state;

parameter A=2'b00, B=2'b01, C=2'b10;

always @(present_state,i)
begin
case (present_state)
A: if(i)        next_state = B;
else         next_state = A;
B: if(i)        next_state = A;
else         next_state = C;
C: if(i)        next_state = C;
else         next_state = B;
default:        next_state = A;
endcase
end

always @(posedge clk, posedge reset)
begin
if(reset)
present_state = 2'b00;
else
present_state = next_state;
end

always @(present_state)
begin
if(present_state == A)
o = 1'b0;
else if(present_state == C)
o = 1'b1;
else
o = i;
end

endmodule


Test 2: This works as well

// Testbench
module test;

reg clk   ;
reg reset ;
reg i     ;

// Instantiate design under test
test01 TST(.clk(clk),
.reset(reset),
.i(i),
.o(o));

initial begin
$dumpfile("dump.vcd");$dumpvars(1);
clk     =   1'b1;
reset   =   1'b1;
i       =   1'b1;
end

always begin
#10     reset   = 1'b0;
//#15   i       = 1'b1;
//#20       i       = 1'b0;
end

always
#5  clk = !clk;

endmodule


• The code still doesn't work for me, I think I have problem with the always clock block. Try the next test: clk=1,reset=1,i=1 the output should be 0 - this tests works fine, but if then I try reset=0 the output should still be 0` but it isn't. Nov 12 '17 at 22:08
• Check the edited answer, I did the test and it works, please consider to share your testbench to see what is going wrong in your code. Nov 13 '17 at 8:59
• can you provide an email or some other way of private communication so I could send you in private? (this site doesn't support private messages) Nov 13 '17 at 10:31
• you could edit your question and add the testbench or continue in chat Nov 13 '17 at 10:53
• I have edited my post, please take a look Nov 13 '17 at 11:15