You are on page 1of 13

A SystemVerilog Class Template for Finite State Machine Design

Swapnajit Mitra

Project VeriPage Inc. swapnajit@project-veripage.com

ABSTRACT This paper proposes an object oriented methodology for hardware implementation of finite state machines using SystemVerilog. The paper has two broad parts. In the first part, using already existing SystemVerilog syntax, the paper proposes a coding methodology for finite state machines that is portable across designs and is in tune with rest of the object oriented nature of SystemVerilog language. In the second part, it proposes new extensions for class datatype that will even further streamline the hardware centric object oriented nature of SystemVerilog. The paper concludes with an appeal to the EDA vendors for their support of these extensions.

Table of Contents
1.0 Finite State Machine ........................................................................................................... 3 2.0 Coding FSM in Verilog ...................................................................................................... 3 3.0 An Object Oriented Approach for Hardware...................................................................... 5 4.0 A Class Template for FSM Design..................................................................................... 5 4.1 The Base Class for any FSM .............................................................................................. 6 4.2 The Sub Class for a Specific FSM...................................................................................... 7 4.3 The Main Body of the Module ........................................................................................... 8 5.0 Implementation Issues and Reducing Redundancy ............................................................ 9 6.0 A Proposal for Syntax Extension of SystemVerilog Class Datatype to Allow Automated, Temporal and Conditional Execution of Methods........................................................................ 10 7.0 A Complete Example........................................................................................................ 10 8.0 Conclusions....................................................................................................................... 12 9.0 Acknowledgements........................................................................................................... 13 10.0 References......................................................................................................................... 13 11.0 Author Biography ............................................................................................................. 13

Table of Figures
Figure 1 State Diagram of an example FSM ............................................................................... 3 Figure 2 - Verilog code for the state machine of Figure 1.............................................................. 4 Figure 3 - A base class for any FSM .............................................................................................. 7 Figure 4 - A sub class example for the FSM of Figure 2................................................................ 8 Figure 5 The main body of the FSM module............................................................................... 9 Figure 6 Alteration of task syntax.............................................................................................. 10 Figure 7 Alteration of function syntax....................................................................................... 10 Figure 8 The complete code for the FSM module using the extended syntax........................... 12
SNUG San Jose 2006 2 A SystemVerilog Class Template for Finite State Machine Design

1.0 Finite State Machine


A Finite State Machine (FSM) is a modified Turings machine with support for finite number of automata [2]. An FSM calculates outputs and the next state based on the current state and/or the inputs. It is a basic building block of any sequential digital logic. Figure 1 shows the state diagram for an FSM and Table 1 shows the state table showing the same state transition information [1]. Note that, for simplicity, this FSM produces only the next state, and does not produce any output.
0

00 1 11 0

01 0 10

Figure 1 State Diagram of an example FSM

2.0 Coding FSM in Verilog


Coding FSM in Verilog, just as any other coding methodology, vastly varies based 0 00 00 on a designers personal coding style and 0 01 10 preferences, objectives (such as, whether the code will be synthesized or not), tool support, 0 10 10 and corporate guidance. Accordingly, there are 0 11 11 several ways of coding the same state machine, 1 00 01 and many of these often result in the same goal, 1 01 01 for instance the number of gates used if the code is synthesized. Recommending a particular 1 10 11 coding style often viewed as equivalent of 1 11 00 religious preaching in the design community. Table 1: State Table for FSM For this reason, without recommending a specific coding style, this paper selects an example that contains the central theme of many other variants. The following code in Figure 2 shows one of the various possible methodologies that yield synthesizable one-hot state machine for the FSM described in Figure 1 and Table 1. The input to the FSM is named x in the code. The current and next states of the FSM are named current_state and next_state. The reset signal reset is assumed to be active high and synchronous to clock clk.
Input Current State Next State SNUG San Jose 2006 3 A SystemVerilog Class Template for Finite State Machine Design

module fsm ( input clk , input reset , input x ); // variable declaration reg [1:0] current_state; reg [1:0] next_state; // parameter declaration parameter ONE = 4b1; parameter STATE_00_BIT = parameter STATE_00 = ONE parameter STATE_01_BIT = parameter STATE_01 = ONE parameter STATE_10_BIT = parameter STATE_10 = ONE parameter STATE_11_BIT = parameter STATE_11 = ONE

0; << 1; << 2; << 3; <<

STATE_00_BIT; STATE_01_BIT; STATE_10_BIT; STATE_11_BIT;

// combinatorial assignment of next_state always @* begin next_state = current_state; case (1b1) // synthesis full_case parallel_case current_state[STATE_00_BIT]: if (x) next_state = STATE_01; current_state[STATE_01_BIT]: if (~x) next_state = STATE_10; current_state[STATE_10_BIT]: if (x) next_state = STATE_11; current_state[STATE_11_BIT]: if (x) next_state = STATE_00; endcase end // sequential assignment of current_state always @(posedge clk) if (reset) current_state <= STATE_00; else current_state <= next_state; endmodule
Figure 2 - Verilog code for the state machine of Figure 1

There are few salient points to note in the above implementation that will help analysis of the later parts of this paper. Observation-1: There are two always blocks in the module that clearly separates the generation of the variables next_state and current_state. Observation-2: The variable next_state is generated through an all-combinatorial block. Anytime any of the signals (in this case, x and current_state) changes, next_state is re-evaluated through a combinatorial logic using Verilog blocking assignment (=).
SNUG San Jose 2006 4 A SystemVerilog Class Template for Finite State Machine Design

Observation-3: The evaluation of current_state is always done at an edge of a clock (in the example of Figure 2, at the positive edge of the clock). Thus, the value of next_state may change any number of times in between two clock edges, but current_state is evaluated only at the edge using Verilog non-blocking assignment (<=) that mimics the behavior of a flip-flop. Observation-4: A critical part of the previous observation is that the logic corresponding to the assignment of current_state does not change regardless of what the FSM does (as long as the logic works at the positive edge of the clock and the reset is synchronous and active high). We will further explore the implication of this observation on our discussion in Section 4. Although this particular example does not have any, an output produced by an FSM will be generated by a sequential or combinatorial combination of the current_state or next_state variables and other inputs. Thus, their generation is not related to the main body of the FSM.

3.0 An Object Oriented Approach for Hardware


While the methodology described in Section 2 above works well (and has worked well for last two decades) for smaller designs, it poses several challenges for a large design. For instance, for a hardware logic that has several such FSMs designed by a large team, maintaining a coherent design methodology is not only just desirable, it is an absolute essential. Yet, it is extremely difficult to enforce. For lack of a centralized data structure or library, the above methodology can not easily enforce such a coherency. Moreover, the approach described in Section 2 is procedural and not object oriented. An object oriented methodology has many significant advantages over a procedural one. By pairing related data and operations together into an object, the object oriented methodology reduces the chance of two unrelated object data to interfere with each other. In large designs developed procedurally, unintended interactions between different parts of the designs are a major cause of bugs and errors. The approach shown in Section 2 has further disadvantage of maintenance. It can vastly increase the difficulty of design modifications and upgrades. While object oriented methodology is not a panacea for these problems, it does make the designers life a lot easier. As a matter of fact, object oriented approach for designing an FSM has been followed for a long time in software designs [5], where object oriented languages such as C++ and Java have made significant in-roads. This approach for FSM design is widely followed even with newer languages, such as C#. The advantages of object oriented methodology, which were so far available to only traditional software-centric object oriented languages, are to a large degree making their way into newer hardware description and verification languages, such as SystemVerilog. SystemVerilog provides full support of the basic object oriented data types, such as class [6], and additional language support for object oriented features extended class, inheritance, polymorphism, virtual class to name a few [3]. With these feature sets available, it will be unwise for a design not to take advantage of them and shy away from using them in places that have been known to be effective and productive, such as in an FSM design. In the next section, this paper describes a methodology for FSM design that does just that by defining a class template for an FSM.

4.0 A Class Template for FSM Design


In order to develop a class template for FSM, it is easy to see from observations made in Section 2, that any such template can be divided into two parts. The first part will contain the
SNUG San Jose 2006 5 A SystemVerilog Class Template for Finite State Machine Design

generic properties (i.e., data inside that class) and methods (i.e., task and functions inside the class that work on those data) for the class that will be applicable for any FSM. The other part will have to be customized for a specific FSM. Also, the first part can be described in a base class and the other part can be a sub class of this base class. 4.1 The Base Class for any FSM To define the base class for an FSM, we must define its properties and methods. Since current_state and next_state are the only two variables that the code in Figure 2 generates, the base class for an FSM should have those variables as its properties1. The methods of this base class, by definition, must be those which modify the above properties. The only external variable that the assignment of current_state depends on is reset. The task `current_state_transition performs this. It is important to note here that the task itself does not specify when the assignment takes place (i.e. the positive edge of the clock). The assignment of next_state depends on a specific FSM, but again separating the events that change next_state from the change itself, the task next_state_transition performs this operation. From these, here is the code for the base class named genericFSM in Figure 3. The width of the state bits here is made parameterized to make it generic for any FSM.
class genericFsm #(int FSM_WIDTH = 7); // properties bit [FSM_WIDTH:0] current_state; bit [FSM_WIDTH:0] next_state; // methods task next_state_transition ( input int state_to_bit ); // combinatorial begin // { next_state = 0; next_state [state_to_bit] = 1'b1; end // } endtask task current_state_transition ( input logic reset ); // flopped begin // { if (reset) current_state <= IDLE; else current_state <= next_state; end // } endtask endclass
1

Moreover, no other part of the code needs to modify or read these variables, except perhaps some sub classes. So, these variables can be marked as protected, if the designer so wishes. 6 A SystemVerilog Class Template for Finite State Machine Design

SNUG San Jose 2006

Figure 3 - A base class for any FSM

4.2 The Sub Class for a Specific FSM The next state transition rules are always specific to a particular FSM. Thus, they need a sub class of genericFSM that particularly caters to that FSM. The sub class specificFSM in Figure 4 below shows how to do this for the example of Figure 2. There are few things to notice in this implementation. First, the sub class specificFSM alters the width of the state bits of the base class (from 8 to 4) for this particular example. It then defines a separate task for each of the state transitions without specifying, once again, when the state transition occurs. Each of these tasks calls the task next_state_transition of the base class, either to move to a new state or simply to stay in the current state. Needless to say, though the basic structure of the sub class (parameter declarations, method definitions for the next state and the combinatorial logic) remains the same, their implementation will change from one FSM to another.
class specificFSM extends genericFSM #(3); // parameter declaration localparam ONE = 4b1; localparam STATE_00_BIT = localparam STATE_00 = ONE localparam STATE_01_BIT = localparam STATE_01 = ONE localparam STATE_10_BIT = localparam STATE_10 = ONE localparam STATE_11_BIT = localparam STATE_11 = ONE // methods task from_state_00; begin // { if (x) next_state_transition (STATE_01_BIT); else next_state_transition (STATE_00_BIT); end // } endtask task from_state_01; begin // { if (~x) next_state_transition (STATE_10_BIT); else next_state_transition (STATE_01_BIT); end // } endtask task from_state_10; begin // {
SNUG San Jose 2006 7 A SystemVerilog Class Template for Finite State Machine Design

0; << 1; << 2; << 3; <<

STATE_00_BIT; STATE_01_BIT; STATE_10_BIT; STATE_11_BIT;

if (x) next_state_transition (STATE_11_BIT); else next_state_transition (STATE_10_BIT); end // } endtask task from_state_11; begin // { if (x) next_state_transition (STATE_00_BIT); else next_state_transition (STATE_11_BIT); end // } endtask task main_comb; begin // { case (1'b1) current_state[STATE_00_BIT]: current_state[STATE_01_BIT]: current_state[STATE_10_BIT]: current_state[STATE_11_BIT]: endcase end // } endtask endclass

from_state_00; from_state_01; from_state_10; from_state_11;

Figure 4 - A sub class example for the FSM of Figure 2

4.3 The Main Body of the Module Once the base and the sub class are defined, the main body of the module for an FSM just needs to instantiate the corresponding objects. This is shown in Figure 5 below.
module fsm_class ( input clk , input reset , input x ); class genericFsm #(int FSM_WIDTH = 7); ... // contents of Figure 3 goes here endclass class specificFSM extends genericFSM #(3); ... // contents of Figure 4 goes here endclass specificFSM #(3) P; always @(posedge clk) P.current_state_transition(); always @*
SNUG San Jose 2006 8 A SystemVerilog Class Template for Finite State Machine Design

P.main_comb; endmodule
Figure 5 The main body of the FSM module

The main body of the module contains an object instance P of the sub class specificFSM. The main body also contains two blocks, one sequential and another combinatorial similar to the traditional FSM of Figure 2, that triggers events for generating the current and the next state respectively. For generating current_state, the module calls the task current_state_transition (that P has inherited from genericFSM). For generating next_state, the module calls the main combinatorial logic task main_comb.

5.0 Implementation Issues and Reducing Redundancy


There are few important points to note about the implementation presented in Figure 5. First, it is important to discuss the synthesizability of this implementation. SystemVerilog 3.1A LRM allows class declaration in a module, program block or in a package. From simulation point of view, this does not really matter, as a class declaration and its use anywhere in those three scopes will result in the same simulation result. But from a synthesis point of view, this is important as a program block is not supposed to be synthesizable (adding to the challenges of implementing a synthesizable test bench). Yet, a class type variable has nothing that prevents it from being synthesizable if the purely simulation related constructs (e.g., virtual class, protected versus local bits) are ignored during synthesis. This is certainly something that can be easily accommodated by synthesis tool vendors. The more important aspect of the implementation is the redundancy of code. It is apparent from Figure 5 that the main body of the FSM module does not have any substantial amount of code. As a matter of fact, the only codes it has are generic sequential and combinatorial design structures (always @ (posedge clk) and always @*) that invoke various class methods at different temporal locations. Had there been a way in the class definition in addition to what a method does to specify when that method is triggered, the entire main body of the module would have been redundant. For instance, if there were ways to specify in the definition of specificFSM that the task main_comb is triggered whenever any of the variables in its sensitivity list changes, or the task current_state_transition is triggered on all positive edges of the clock, then the main body of the module will become unnecessary. Moreover, the resultant code would have been concise and true to the spirit of object oriented paradigm. It seems this inability of the SystemVerilog class definitions to trigger execution of a method temporally is a handicap that SystemVerilog has acquired from other software-centric object oriented languages. When class definition in a software-centric object oriented language does not have any notion of time and hence does not need this feature, it will be extremely convenient for a hardware-centric language like SystemVerilog to have this feature. Yet, automatic execution of a method in SystemVerilog is not a new concept. For example, a constructor method (whether explicitly called or through its implicit super.new constructor method) executes every time an object is instantiated. Also, in SystemVerilog, an implied destructor method executes every time an objects lifecycle is completed. In a sense, letting a method to execute over time conditional to a set of rules will be similar to a constructor or a destructor method.
SNUG San Jose 2006 9 A SystemVerilog Class Template for Finite State Machine Design

In the next section, this paper proposes an extension of the syntax of SystemVerilog to allow such features.

6.0 A Proposal for Syntax Extension of SystemVerilog Class Datatype to Allow Automated, Temporal and Conditional Execution of Methods
This proposal introduces no new keyword, and extends the SystemVerilog grammar in two places of the language, namely the syntaxes of tasks and functions (i.e., the methods) within a class. Outside the scope of a class (excluding out of block extern methods), these extensions have no meaning2. A parser may generate an implementation dependent error message or simply ignore these extensions if they are encountered outside the scope of a class. A triggering of a method only occurs when an object instance is available for the class. The EBNF for these extensions are shown in Figure 6 and 7 below [3] [4].
task_declaration ::= task [lifetime] [task_sensitivity_list] task_body_declaration // Section 10.2, SV3.1A task_sensitivity_list ::= ([procedural_timing_control_statement]) // Annex A.6, IEEE 1364-2001
Figure 6 Alteration of task syntax

function_declaration ::= function [lifetime] [function_sensitivity_list] function_body_declaration // Section 10.3, SV3.1A function_sensitivity_list ::= ([procedural_timing_control_statement]) // Annex A.6, IEEE 1364-2001
Figure 7 Alteration of function syntax

The main change in the existing syntax is the introduction of optional task_sensitivity_list (or, function_sensitivity_list in case of function. All of the following discussion is valid for functions as well). This is a parenthesized, optional list that describes the sensitivity list for triggering the task. An empty list is permitted and will imply unconditional triggering of the task. The use of the wildcard * is allowed. For an out of block extern method declaration, the variables declared in the task_sensitivity_list will follow the same SystemVerilog scoping rules that apply to variables used inside the method.

7.0 A Complete Example


Using the extended syntax, Figure 8 below shows the code for an FSM (with the extended syntax highlighted). It is interesting to note that the main body of the module this time only contains the object instance for specificFSM.
module fsm_class ( input clk , input reset
2 Or, at least so for the current proposal. Interested readers are invited to explore the possibilities of what it will mean to have this new construct for tasks outside the scope of a class. SNUG San Jose 2006 10 A SystemVerilog Class Template for Finite State Machine Design

, input );

class genericFsm #(int FSM_WIDTH = 7); // properties bit [FSM_WIDTH:0] current_state; bit [FSM_WIDTH:0] next_state; // methods task next_state_transition ( input int state_to_bit ); // combinatorial begin // { next_state = 0; next_state [state_to_bit] = 1'b1; end // } endtask task (@(posedge clk)) current_state_transition ( input logic reset ); // flopped begin // { if (reset) current_state <= IDLE; else current_state <= next_state; end // } endtask endclass class specificFSM extends genericFSM #(3); // parameter declaration localparam ONE = 4b1; localparam STATE_00_BIT = localparam STATE_00 = ONE localparam STATE_01_BIT = localparam STATE_01 = ONE localparam STATE_10_BIT = localparam STATE_10 = ONE localparam STATE_11_BIT = localparam STATE_11 = ONE // methods task from_state_00; begin // { if (x) next_state_transition (STATE_01_BIT); else next_state_transition (STATE_00_BIT); end // }
SNUG San Jose 2006 11 A SystemVerilog Class Template for Finite State Machine Design

0; << 1; << 2; << 3; <<

STATE_00_BIT; STATE_01_BIT; STATE_10_BIT; STATE_11_BIT;

endtask task from_state_01; begin // { if (~x) next_state_transition (STATE_10_BIT); else next_state_transition (STATE_01_BIT); end // } endtask task from_state_10; begin // { if (x) next_state_transition (STATE_11_BIT); else next_state_transition (STATE_10_BIT); end // } endtask task from_state_11; begin // { if (x) next_state_transition (STATE_00_BIT); else next_state_transition (STATE_11_BIT); end // } endtask task (@*) main_comb; begin case (1'b1) current_state[STATE_00_BIT]: current_state[STATE_01_BIT]: current_state[STATE_10_BIT]: current_state[STATE_11_BIT]: endcase end endtask endclass specificFSM #(3) P; // The module body is pretty much empty endmodule
Figure 8 The complete code for the FSM module using the extended syntax

from_state_00; from_state_01; from_state_10; from_state_11;

8.0 Conclusions
This paper proposes an object oriented structure for an FSM, one of the most widely used hardware elements in a digital design, using standard SystemVerilog constructs. It further

SNUG San Jose 2006

12

A SystemVerilog Class Template for Finite State Machine Design

proposes extensions in the current SystemVerilog syntax to implement a finite state machine even more concisely by Allowing class type variables as synthesizable component inside a module. Allowing extended syntax for task and function definition that automates their execution. At the time of writing this paper, the current trend of increasing support for the newer SystemVerilog datatypes, including class type, in simulation, synthesis and other EDA tools is indeed encouraging. This provides a good opportunity for the EDA vendors to support the new constructs proposed in this paper, and also for the standard committees, such as IEEE P1800 and Accellera, to consider these new extensions for inclusion in a future revision of the language.

9.0 Acknowledgements
The author would like to thank SNUG reviewers of this paper for their feedback. The author is also indebted to Haihui Chen of Synopsys Inc. for his meticulous comments and suggestions on this paper.

10.0 References
[1] M Morris Mano. Digital Logic and Computer Design. Englewood Cliffs, NJ: Prentice Hall Inc., 1987. [2] Zvi Kohavi. Switching and Finite Automata Theory. New Jersey, NJ: McGraw Hill, 1978. [3] SystemVerilog 3.1a Language Reference Manual . Napa, CA: Accellera Organization, 2004. [4] IEEE Std.1364-2001 Verilog Hardware Description Language. Piscataway, NJ: IEEE Press, 2001. [5] SCO Group, Using Simple Finite State Machines. http://ou800doc.caldera.com/en/SDK_c++/_Using_Simple_Finite_State_Machi.html, July, 2005 [6] Project VeriPage, SystemVerilog Class Datatype. http://www.projectveripage.com/sv_class_1.php, July 2005.

11.0 Author Biography


Swapnajit Mitra is the CEO of Project VeriPage Inc. (http://www.project-veripage.com), a design and verification resource center on the web including articles on SystemVerilog and Verilog PLI. He is the author of the book Principles of Verilog PLI and the chairman of Accellera SystemVerilog C/C++ committee. The views expressed in this paper are his own.

SNUG San Jose 2006

13

A SystemVerilog Class Template for Finite State Machine Design

You might also like