Anda di halaman 1dari 6

10/16/2014

How to write FSM in Verilog?

How to write FSM in Verilog?


Feb-9-2014

Introduction
Basically a FSM consists of combinational, sequential and output logic.
Combinational logic is used to decide the next state of the FSM, sequential
logic is used to store the current state of the FSM. The output logic is a
mixture of both combo and seq logic as shown in the figure below.

Types of State Machines


There are many ways to code these state machines, but before we get into
the coding styles, let's first understand the basics a bit. There are two types
of state machines:
Mealy State Machine : Its output depends on current state and
current inputs. In the above picture, the blue dotted line makes the
circuit a mealy state machine.
Moore State Machine : Its output depends on current state only. In
the above picture, when blue dotted line is removed the circuit
becomes a Moore state machine.
Depending on the need, we can choose the type of state machine. In
general, or you can say most of the time, we end up using Mealy FSM.
Encoding Style
Since we need to represent the state machine in a digital circuit, we need
to represent each state in one of the following ways:
Binary encoding : each state is represented in binary code (i.e. 000,
001, 010....)
Gray encoding : each state is represented in gray code (i.e. 000,
001, 011,...)
One Hot : only one bit is high and the rest are low (i.e. 0001, 0010,
0100, 1000)
One Cold : only one bit is low, the rest are high (i.e.
1110,1101,1011,0111)
Most of the time we use one hot encoding.
Example
To help you follow the tutorial, I have taken a simple arbiter as the
example; this has got two request inputs and two grant outputs, as shown
in the signal diagram below.
When req_0 is asserted, gnt_0 is asserted
When req_1 is asserted, gnt_1 is asserted
When both req_0 and req_1 are asserted then gnt_0 is asserted i.e.
higher priority is given to req_0 over req_1.

http://www.asic-world.com/tidbits/verilog_fsm.html

1/6

10/16/2014

How to write FSM in Verilog?

We can symbolically translate into a FSM diagram as shown in figure


below, here FSM has got following states.
IDLE : In this state FSM waits for the assertion of req_0 or req_1 and
drives both gnt_0 and gnt_1 to inactive state (low). This is the default
state of the FSM, it is entered after the reset and also during fault
recovery condition.
GNT0 : FSM enters this state when req_0 is asserted, and remains
here as long as req_0 is asserted. When req_0 is de-asserted, FSM
returns to the IDLE state.
GNT1 : FSM enters this state when req_1 is asserted, and remains
there as long as req_1 is asserted. When req_1 is de-asserted, FSM
returns to the IDLE state.

Coding Methods
Now that we have described our state machine clearly, let's look at various
methods of coding a FSM.
We use one-hot encoding, and all the FSMs will have the following code in
common, so it will not be repeated again and again.

Using A Function For Combo Logic


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

//----------------------------------------------------// This is FSM demo program using function


// Design Name : fsm_using_function
// File Name : fsm_using_function.v
//----------------------------------------------------module fsm_using_function (
clock
, // clock
reset
, // Active high, syn reset
req_0
, // Request 0
req_1
, // Request 1
gnt_0
, // Grant 0
gnt_1
);

//-------------Input Ports----------------------------input clock,reset,req_0,req_1;


//-------------Output Ports---------------------------output gnt_0,gnt_1;
//-------------Input ports Data Type------------------wire
clock,reset,req_0,req_1;
//-------------Output Ports Data Type-----------------reg
gnt_0,gnt_1;
//-------------Internal Constants-------------------------parameter SIZE = 3
;
parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
//-------------Internal Variables---------------------------

http://www.asic-world.com/tidbits/verilog_fsm.html

2/6

10/16/2014

How to write FSM in Verilog?


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

reg [SIZE-1:0]
state
;// Seq part of the FSM
wire [SIZE-1:0]
next_state
;// combo part of FSM
//----------Code startes Here-----------------------assign next_state = fsm_function(state, req_0, req_1);
//----------Function for Combo Logic----------------function [SIZE-1:0] fsm_function;
input [SIZE-1:0] state ;
input
req_0 ;
input
req_1 ;
case(state)
IDLE : if (req_0 == 1'b1) begin
fsm_function = GNT0;
end else if (req_1 == 1'b1) begin
fsm_function= GNT1;

end else begin


fsm_function = IDLE;
end
GNT0 : if (req_0 == 1'b1) begin
fsm_function = GNT0;
end else begin
fsm_function = IDLE;
end
GNT1 : if (req_1 == 1'b1) begin
fsm_function = GNT1;
end else begin
fsm_function = IDLE;
end
default : fsm_function = IDLE;
endcase
endfunction
//----------Seq Logic----------------------------always @ (posedge clock)
begin : FSM_SEQ
if (reset == 1'b1) begin
state <= #1 IDLE;
end else begin
state <= #1 next_state;
end
end
//----------Output Logic----------------------------always @ (posedge clock)
begin : OUTPUT_LOGIC
if (reset == 1'b1) begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
end
else begin
case(state)
IDLE : begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
end
GNT0 : begin
gnt_0 <= #1 1'b1;
gnt_1 <= #1 1'b0;
end
GNT1 : begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b1;
end
default : begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
end
endcase
end
end // End Of Block OUTPUT_LOGIC
endmodule // End of Module arbiter

You could download file fsm_using_function.v here

Using Two Always Blocks


http://www.asic-world.com/tidbits/verilog_fsm.html

3/6

10/16/2014

How to write FSM in Verilog?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

//----------------------------------------------------// This is FSM demo program using always block


// Design Name : fsm_using_always
// File Name : fsm_using_always.v
//----------------------------------------------------module fsm_using_always (
clock
, // clock
reset
, // Active high, syn reset
req_0
, // Request 0
req_1
, // Request 1
gnt_0
, // Grant 0
gnt_1
);

//-------------Input Ports----------------------------input clock,reset,req_0,req_1;


//-------------Output Ports---------------------------output gnt_0,gnt_1;
//-------------Input ports Data Type------------------wire
clock,reset,req_0,req_1;
//-------------Output Ports Data Type-----------------reg
gnt_0,gnt_1;
//-------------Internal Constants-------------------------parameter SIZE = 3
;
parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
//-------------Internal Variables--------------------------reg [SIZE-1:0]
state
;// Seq part of the FSM
reg [SIZE-1:0]
next_state
;// combo part of FSM
//----------Code startes Here-----------------------always @ (state or req_0 or req_1)
begin : FSM_COMBO
next_state = 3'b000;
case(state)
IDLE : if (req_0 == 1'b1) begin
next_state = GNT0;
end else if (req_1 == 1'b1) begin
next_state= GNT1;

end else begin


next_state = IDLE;
end
GNT0 : if (req_0 == 1'b1) begin
next_state = GNT0;
end else begin
next_state = IDLE;
end
GNT1 : if (req_1 == 1'b1) begin
next_state = GNT1;
end else begin
next_state = IDLE;
end
default : next_state = IDLE;
endcase
end
//----------Seq Logic----------------------------always @ (posedge clock)
begin : FSM_SEQ
if (reset == 1'b1) begin
state <= #1 IDLE;
end else begin
state <= #1 next_state;
end
end
//----------Output Logic----------------------------always @ (posedge clock)
begin : OUTPUT_LOGIC
if (reset == 1'b1) begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
end
else begin
case(state)
IDLE : begin
gnt_0 <= #1 1'b0;

http://www.asic-world.com/tidbits/verilog_fsm.html

4/6

10/16/2014

How to write FSM in Verilog?


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

gnt_1

<= #1 1'b0;

end
GNT0

: begin
gnt_0
gnt_1

<= #1 1'b1;
<= #1 1'b0;

end
GNT1

: begin
gnt_0
gnt_1

<= #1 1'b0;
<= #1 1'b1;

end
default : begin
gnt_0
gnt_1

<= #1 1'b0;
<= #1 1'b0;

end
endcase
end
end // End Of Block OUTPUT_LOGIC
endmodule // End of Module arbiter

You could download file fsm_using_always.v here

Using Single Always For Sequential, Combo And Output Logic


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

//====================================================
// This is FSM demo program using single always
// for both seq and combo logic
// Design Name : fsm_using_single_always
// File Name : fsm_using_single_always.v
//=====================================================
module fsm_using_single_always (
clock
, // clock
reset
, // Active high, syn reset
req_0
, // Request 0
req_1
, // Request 1
gnt_0
, // Grant 0
gnt_1
);

//=============Input Ports=============================
input clock,reset,req_0,req_1;
//=============Output Ports===========================
output gnt_0,gnt_1;
//=============Input ports Data Type===================
wire
clock,reset,req_0,req_1;
//=============Output Ports Data Type==================
reg
gnt_0,gnt_1;
//=============Internal Constants======================
parameter SIZE = 3
;
parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
//=============Internal Variables======================
reg [SIZE-1:0]
state
;// Seq part of the FSM
reg [SIZE-1:0]
next_state
;// combo part of FSM
//==========Code startes Here==========================
always @ (posedge clock)
begin : FSM
if (reset == 1'b1) begin
state <= #1 IDLE;
gnt_0 <= 0;
gnt_1 <= 0;
end else
case(state)
IDLE : if (req_0 == 1'b1) begin
state <= #1 GNT0;
gnt_0 <= 1;
end else if (req_1 == 1'b1) begin
gnt_1 <= 1;
state <= #1 GNT1;
end else begin
state <= #1 IDLE;
end
GNT0 : if (req_0 == 1'b1) begin
state <= #1 GNT0;
end else begin

http://www.asic-world.com/tidbits/verilog_fsm.html

5/6

10/16/2014

How to write FSM in Verilog?


50
51
52
53
54
55
56
57
58
59
60
61
62
63

gnt_0
state

<= 0;
<= #1 IDLE;

end
: if (req_1 == 1'b1) begin
state <= #1 GNT1;
end else begin
gnt_1 <= 0;
state <= #1 IDLE;
end
default : state <= #1 IDLE;
endcase
end
GNT1

endmodule // End of Module arbiter

You could download file fsm_using_single_always.v here

Copyright 1998-2014
Deepak Kumar Tala - All rights reserved
Do you have any Comment? mail me at:deepak@asic-world.com

http://www.asic-world.com/tidbits/verilog_fsm.html

6/6

Anda mungkin juga menyukai