# Finite State Machine in Verilog

So I am trying to make a basic FSM in verilog to turn on 3 different LEDs. I've looked at examples and other people's work, but I can't understand why mine wont work. Maybe someone can help me spot a bug in my code I can't see.

module blink( input rst, output reg [2:0] leds, output LED);

OSCH #("2.08") osc_int (                    //"2.03" specifies the operating frequency, 2.03 MHz. Other clock frequencies can be found in the MachX02's documentation
.STDBY(1'b0),                           //Specifies active state
.OSC(clk),                              //Outputs clock signal to 'clk' net
.SEDSTDBY());
wire clk_slow;              //this will be the slower clock wire

reg [21:0] cnt;                     //these two lines use the fast clock to increment a 21 bit register
always @(posedge clk) cnt <= cnt+1;

assign clk_slow = cnt[21];      //this is high whenever the 21st bit of the fast clock register is true, thus slowing the clock to about 1 Hz
assign LED = clk_slow ;         //status LED so I know my clock is working

reg [1:0] state;
reg [1:0] state_n;

parameter S0 = 2'b00;           //state paramenters
parameter S1 = 2'b01;
parameter S2 = 2'b10;

always @ (posedge clk_slow or posedge rst)  //state changer
begin
if(!rst)
state <= S0;
else
state <= state_n;

end

always @ (*)        //changes next state
begin
case(state)
S0: state_n = S1;
S1: state_n = S2;
S2: state_n = S0;
default state_n = S0;
endcase
end

always @ (*)        //decides what leds to light based on state
begin
if (state == S0)
leds = 3'b001;
else if(state == S1)
leds = 3'b010;
else if(state == S2)
leds = 3'b100;
end

endmodule


I'm not quite sure why it isn't working. The status LED I have hooked up is blinking at 1 Hz, which is correct. My other 3 LEDs seem to be stuck in State 0... or something. When I hit the reset button, it sometimes changes my LEDs to state 1, but I think that has to do with clock overlap. Any help is appreciated.

I am using a Lattice Diamond FPGA to program this. I am using the onboard clock to generate the initial clock, and I am using on board LEDs. My reset button is external and active low.

• If the reset is active low you need negedge rst. – copper.hat May 11 '15 at 4:30

always @ (posedge clk_slow or posedge rst)  //state changer
begin
if(!rst)
state <= S0;
else
state <= state_n;

end


If you want an asyncronous active-low reset, this always block should be sensitive to negedge rst instead of posedge rst.

If you want an active-high reset, then the condition in your if statement should be rst instead of !rst.

Edit

Other minor issues I see in the code (that shouldn't make your system nonfunctional):

• Your comment says cnt is a 21-bit register, but the actual code makes it a 22-bit register. This should just make the LEDs blink half as fast as you expected.

• There is no reset logic for cnt. This will make the code difficult to simulate (because cnt will be stuck in the 'x' state).

• Ah, yes thank you! However, my problem persists even after I have changed that. :( – Gigaxalus May 11 '15 at 3:32
• Hmm ok thanks. I'll try to implement that and see if that helps me find the problem. – Gigaxalus May 11 '15 at 4:39

Best practice is not to use clk_slow as your state machine clock. Use clk for your state machine and make clk_slow a sort of flag.

always @ (posedge clk or posedge rst)
begin
if(!rst)
state <= S0;
else if (clk_slow)
state <= state_n;
end


(I don't usually work in Verilog so please verify the syntax)