Reading Note of “SystemVerilog for Design” (Chapter 8: Modeling Finite State Machines with SystemVerilog)

This chapter gives some simple example of FSM code featuring SystemVerilog new keywords, such as “enum”, “always_comb”, “always_ff”, “unique case”.

Modeling FSM with “enum”

  • 3 blocks to model an FSM
    • Incrementing state
    • Determine the next state
    • Set output
  • Using “enum” without explicitly specified value
    • Cause mismatch in value between RTL and gate-level netlist
    • Cause difficulty with assertion to work for both RTL and gate-level netlist
    • So, DO specify value for “enum”
      • Can use “one-hot”, “one-cold”, “Gray code”, etc.
    • Synthesis compiler may try to optimize these explicitly defined values
  • Reversed case statement
    • The following example is seemly complicated (overkill), but actually have 2 advantages
      • Eliminate the possibility to define wrong one-hot/cold state value
      • Easier for future extension
  • Unique and parallel case (refer to Chapter 7)
module traffic_light (

output
logic    green_light,

                yellow_light,

                red_light,

input            sensor,

input [15:0]    green_downcnt,

                yellow_downcnt,

input            clk, rstb

);

// index of RED/GREEN/YELLOW bit in the state register

enum {     R_BIT = 0,

        G_BIT = 1,

        Y_BIT = 2

} state_bit;

// state register

enum
logic [2:0] {    RED        = 3’b001 << R_BIT,

                    GREEN    = 3’b001 << G_BIT,

                    YELLOW    = 3’b001 << Y_BIT

} state, next_state;

always_ff @ (posedge clk, negedge rstb) begin : step_forward

    if (!rstb) begin

        state <= RED;

    end

    else
begin

        state <= next_state;

    end

end : step_forward

always_comb
begin : set_next_state

    unique
case (1’b1)    // reversed case statement

    state[R_BIT]: begin

        if (sensor) begin

            next_state = GREEN;

        end

    end

    state[G_BIT]: begin

        if (green_downcnt == 0) begin

            next_state = YELLOW;

        end

    end

    state[Y_BIT]: begin

        if (yellow_downcnt == 0) begin

            next_state = RED;

        end

    end

    endcase

end : set_next_state

always_comb
begin : set_output

    unique
case (1’b1)

    state[R_BIT]: begin

        red_light         = 1’b1;

        green_light     = 1’b0;

        yellow_light     = 1’b0;

    end

    state[G_BIT]: begin

        red_light         = 1’b0;

        green_light     = 1’b1;

        yellow_light     = 1’b0;

    end

    state[Y_BIT]: begin

        red_light         = 1’b0;

        green_light     = 1’b0;

        yellow_light     = 1’b1;

    end

    endcase

end : set_output

endmodule

  • Specify unused state values
    • In Verilog, we used to have “default: next_state = 3’bxxx;” to tell synthesis compiler that the default case is an unused value.
    • In SystemVerilog, we can use either “unique case” or “parallel case” to state that this is a full case statement.
      • Better, because of runtime check
  • Always assign enumerated type variable with a label from its enumerated list, instead of a value or an expression, although sometimes they are legal after type casting.

2-state type in FSM

  • The idea is dangerous, because 2-state type variables initialize to logic 0 instead of logic X before applying reset. So it’s not how real circuit behave.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s