Electrical – Designing a Moore sequence detector using three always blocks

electricalengineeringsequence-detectorstate-machines

Trying to implementing a Moore state machine using three always blocks. The Moore state machine has two inputs (ain[1:0]) and one output (yout). The output yout begins as 0 and remains a constant value unless one of the following input sequences occurs:

(i) The input sequence ain[1:0] = 01, 00 causes the output to become 0
(ii) The input sequence ain[1:0] = 11, 00 causes the output to become 1
(iii) The input sequence ain[1:0] = 10, 00 causes the output to toggle.

module moore_sequence_detector_3_blocks(
input clk,
input reset,
input [1:0] ain,
output reg yout
);
reg[2:0] state, nextstate;
parameter S0=0, S1=1, S2=2, S3=3, S1_To_S0=4, S2_To_S0=5, S3_To_S0=6;

always @(posedge clk or posedge reset) // always block to update state
    if(reset)
    begin
        state <= S0;
    end
    else
    begin
        state <= nextstate;
    end

always @(state or ain) // always block to compute nextstate
begin
    case (ain)
        2'b00:
            if(state == S1)
                nextstate = S1_To_S0;
            else if(state == S2)
                nextstate = S2_To_S0;
            else if(state == S3)
                nextstate = S3_To_S0;
            else
                nextstate = state;
        2'b01: nextstate = S1;
        2'b10: nextstate = S2;
        2'b11: nextstate = S3;
        default: nextstate = S0;
    endcase
end

always @(state) // always block to compute output
    begin
        case(state)
            S0: yout = 0;
            S1_To_S0: yout = 0;
            S2_To_S0: yout = ~yout;
            S3_To_S0: yout = 1;
            default:
                yout = yout;
        endcase
    end endmodule

I cant seem to figure out what is wrong. The states should work as follows
enter image description here

sout0 yout = 0
sout1 yout = 1

swait1 yout = 0
swait2 yout = 0
swaitInv0 yout = 0

swait3 yout = 1
swait4 yout = 1
swaitInv1 yout = 1

swaitInv0 -> sout1

Best Answer

You state machine coding is rather weird.

You normally start with looking which state you are in and then respond to the input to go to a new state. Also you should give your states better names.

case (state)
SEEN_00: 
    case (ain)
    2'b00 : next_state = SEEN_00;
    2'b01 : next_state = SEEN_01;
    2'b10 : next_state = ..
    2'b11 : next_state = ..
    endcase
SEEN_01 : 
    case (ain)
    2'b00 : next_state = ..
    2'b01 : next_state = ..
    2'b10 : next_state = ..
    2'b11 : next_state = ..
    endcase
SEEN_10 :
    ...
SEEN_11 :
    ...
endcase

Now here is a nice trick if you need to react to state transitions. You look at the current state and the next state:

if (state==SEEN_01 && next_state==SEEN_00) 
   yout <= ...
else
   if (state==SEEN_10 && next_state==SEEN_00) 

This is an example where the coding using a state and next_state gives you a huge advantage against just writing state <= SEEN_..;

With this the state machine code becomes regular and thus trivial.

Now here is a nice GOTCHA:

Note that the output yout is registered and is not combinatorial depending on an input.

Thus this is NOT a Mealy machine.

At the same time the output is NOT dependent on the state as in state SEEN_00 the yout can be 0 or 1 depending on the previous state. Thus if you take the definition of a Moore machine literally "a Moore machine is a finite-state machine whose output values are determined only by its current state. "

This is NOT a Moore machine either.