one-hot Archives - Verilog Pro https://www.verilogpro.com/tag/one-hot/ Verilog and Systemverilog Resources for Design and Verification Mon, 27 Jun 2022 07:42:19 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.4 98068679 One-hot State Machine in SystemVerilog – Reverse Case Statement https://www.verilogpro.com/systemverilog-one-hot-state-machine/ https://www.verilogpro.com/systemverilog-one-hot-state-machine/#comments Wed, 14 Oct 2015 16:55:07 +0000 http://www.verilogpro.com/?p=167 Finite state machine (FSM) is one of the first topics taught in any digital design course, yet coding one is not as easy as first meets the eye. There are Moore and Mealy state machines, encoded and one-hot state encoding, one or two or three always block coding styles. Recently I was reviewing a coworker’s ... Read more

The post One-hot State Machine in SystemVerilog – Reverse Case Statement appeared first on Verilog Pro.

]]>
Finite state machine (FSM) is one of the first topics taught in any digital design course, yet coding one is not as easy as first meets the eye. There are Moore and Mealy state machines, encoded and one-hot state encoding, one or two or three always block coding styles. Recently I was reviewing a coworker’s RTL code and came across a SystemVerilog one-hot state machine coding style that I was not familiar with. Needless to say, it became a mini research topic resulting in this blog post.

When coding state machines in Verilog or SystemVerilog, there are a few general guidelines that can apply to any state machine:

  1. If coding in Verilog, use parameters to define state encodings instead of ‘define macro definition. Verilog ‘define macros have global scope; a macro defined in one module can easily be redefined by a macro with the same name in a different module compiled later, leading to macro redefinition warnings and unexpected bugs.
  2. If coding in SystemVerilog, use enumerated types to define state encodings.
  3. Always define a parameter or enumerated type value for each state so you don’t leave it to the synthesis tool to choose a value for you. Otherwise it can make for a very difficult ECO when it comes time to reverse engineer the gate level netlist.
  4. Make curr_state and next_state declarations right after the parameter or enumerated type assignments. This is simply clean coding style.
  5. Code all sequential always block using nonblocking assignments (<=). This helps guard against simulation race conditions.
  6. Code all combinational always block using blocking assignments (=). This helps guard against simulation race conditions.

SystemVerilog enumerated types are especially useful for coding state machines. An example of using an enumerated type as the state variable is shown below.

typedef enum {
  IDLE   = 2'b00,
  ACTIVE = 2'b01,
  DONE   = 2'b10,
  XX     = 'x
} state_t;
state_t curr_state, next_state;

Notice that enumerated types allow X assignments. Enumerated types can be displayed as names in simulator waveforms, which eliminates the need of a Verilog trick to display the state name in waveform as a variable in ASCII encoding.

One-hot refers to how each of the states is encoded in the state vector. In a one-hot state machine, the state vector has as many bits as number of states. Each bit represents a single state, and only one bit can be set at a time—one-hot. A one-hot state machine is generally faster than a state machine with encoded states because of the lack of state decoding logic.

SystemVerilog and Verilog has a unique (pun intended) and efficient coding style for coding one-hot state machines. This coding style uses what is called a reverse case statement to test if a case item is true by using a case header of the form case (1’b1). Example code is shown below:

enum {
  IDLE = 0,
  READ = 1,
  DLY  = 2,
  DONE = 3
//} state, next; // Original not completely correct code
} state_index_t;
logic [3:0] state, next; // Corrected. Thanks John!

// Sequential state transition
always_ff @(posedge clk or negedge rst_n)
  if (!rst_n) begin
    state       <= '0; // default assignment
    state[IDLE] <= 1'b1;
  end
  else
    state       <= next;

// Combinational next state logic
always_comb begin
  next = '0;
  unique case (1'b1)
    state[IDLE] : begin
      if (go)
        next[READ] = 1'b1;
      else
        next[IDLE] = 1'b1;
    end
    state[READ] : next[ DLY] = 1'b1;
    state[ DLY] : begin
      if (!ws)
        next[DONE] = 1'b1;
      else
        next[READ] = 1'b1;
    end
    state[DONE] : next[IDLE] = 1'b1;
  endcase
end

// Make output assignments
always_ff @(posedge clk or negedge rst_n)
...

In this one-hot state machine coding style, the state parameters or enumerated type values represent indices into the state and next vectors. Synthesis tools interpret this coding style efficiently and generates output assignment and next state logic that does only 1-bit comparison against the state vectors. Notice also the use of always_comb and always_ff SystemVerilog always statements, and unique case to add some run-time checking.

An alternate one-hot state machine coding style to the “index-parameter” style is to completely specify the one-hot encoding for the state vectors, as shown below:

enum {
  IDLE = 4'b0001,
  READ = 4'b0010,
  DLY  = 4'b0100,
  DONE = 4'b1000
} state, next;

According to Cliff Cummings’ 2003 paper, this coding style yields poor performance because the Design Compiler infers a full 4-bit comparison against the state vector, in effect defeating the speed advantage of a one-hot state machine. However, the experiments conducted in this paper were done in 2003, and I suspect synthesis tools have become smarter since then.

State machines may look easy on paper, but are often not so easy in practice. Given how frequently state machines appear in designs, it is important for every RTL designer to develop a consistent and efficient style for coding them. One-hot state machines are generally preferred in applications that can trade-off area for a speed advantage. This article demonstrated how they can be coded in Verilog and SystemVerilog using a unique and very efficient “reverse case statement” coding style. It is a technique that should be in every RTL designer’s arsenal.

What are your experiences with coding one-hot state machines? Do you have another coding style or synthesis results to share? Leave a comment below!

References

The post One-hot State Machine in SystemVerilog – Reverse Case Statement appeared first on Verilog Pro.

]]>
https://www.verilogpro.com/systemverilog-one-hot-state-machine/feed/ 14 167