SystemVerilog FSM enum states

207 views Asked by At

I'm trying to implement the following state diagram in SV:

fsm example

With these output logic:

enter image description here

With the following code:

`timescale 1ns / 1ps

 module fsm_example2(input logic clk,
                input logic reset,
                input logic TA,TB,
                output logic [1:0]LA,LB);
         
typedef enum logic [2:0] {S0, S1, S2, S3} statetype;
statetype state, nextstate;     

// state register
always_ff @(posedge clk, posedge reset)
    if (reset) state <= S0;
    else state <= nextstate;            
    
// next state logic
always_comb 
    case (state)
        S0: if(TA) nextstate = S0;
        else nextstate = S1;
        S1: if(TB) nextstate = S0;
        else nextstate = S1;
        default: nextstate = S0;

    endcase

// output logic
assign LA[0] = ~S1 | S0;
assign LA[1] = S1;
assign LB[0] = S1 | S0;
assign LB[1] = ~S1;
endmodule

But the RTL schematic doesnt appear to have the right circuitry.

RTL schematic

My guess is on the typedef enum definition on the states.

2

There are 2 answers

2
dave_59 On BEST ANSWER

A couple of problems. S0-S3 are constants, so LA and LB are being assigned constant expressions.

Also, your output expressions are 2-bits, yet you are assigning them to 1-bit wires.

You probably need something like this:

assign LA[1] = state==S1;

You should be able to figure out the other assignments.

0
toolic On

Always start with simulation.

One problem is that your next-state logic does not match the FSM diagram for states S1 and S2.

Another problem is that you use strange syntax to drive the outputs. I recommend using an enum for those as well.

I created a testbench with example input stimulus:

module fsm_example2(input logic clk,
                input logic reset,
                input logic TA,TB,
                output logic [1:0] LA,LB);
         
typedef enum logic [1:0] {S0, S1, S2, S3} statetype;
statetype state, nextstate;     

typedef enum logic [1:0] {RED, GREEN, YELLOW} outtype;
outtype la, lb;

// state register
always_ff @(posedge clk, posedge reset)
    if (reset) state <= S0;
    else state <= nextstate;            
    
// next state logic
always_comb 
    case (state)
        S0 : nextstate = (TA) ? S0 : S1;
        S1 : nextstate = S2;
        S2 : nextstate = (TB) ? S2 : S3;
        S3 : nextstate = S0;
    endcase

always_comb 
    case (state)
        S0 : begin la = GREEN ; lb = RED   ; end
        S1 : begin la = YELLOW; lb = RED   ; end
        S2 : begin la = RED   ; lb = GREEN ; end
        S3 : begin la = RED   ; lb = YELLOW; end
    endcase

assign LA = la;
assign LB = lb;

endmodule

module tb;
    bit TA;
    bit TB;
    bit clk;
    bit reset = 1;
    wire [1:0] LA;
    wire [1:0] LB;

fsm_example2 dut (
    .TA     (TA),
    .TB     (TB),
    .clk    (clk),
    .reset  (reset),
    .LA     (LA),
    .LB     (LB)
);

always #5 clk++;

initial begin
    #15 reset = 0;
    repeat (3) @(posedge clk); TA <= 1;
    repeat (3) @(posedge clk); TA <= 0;
    repeat (3) @(posedge clk); $finish;
end

endmodule

Simulation output:

waves

You can adjust the 2-bit output decoding as needed.