(转帖) 有限狀態機FSM coding style整理 (SOC) (Verilog)
来源:http://www.codesoso.net/Record/101092_95120_21.html
来源:http://www.cnblogs.com/oomusou/archive/2011/06/05/fsm_coding_style.html
Moore FSM架构
一般在写FSM时,会以Moore FSM为主,所以先讨论Moore。由上图可知,Moore FSM内部由3个block所构成:Next state logic,State register与Output logic。
Next state logic:纯粹的组合逻辑,以整个module的input与目前的state为输入,目的在产生下一个state值存入state register。
State register:由D-FF所构成,将Next state logic所产生的state存入register。
Output logic:纯粹的组合逻辑,根据目前的state产生整个module的output。
所以可以发现,整个Moore FSM事实上是由2块的组合逻辑与1块D-FF所构成,我们常听到所谓的一段式、二段式与三段式FSM,事实上就是由这3个block排列组合而成。
Moore FSM各种coding style比较

Moore FSM各种coding style比较
为了要实际比较各种coding style,在此举一个简单的例子,若input w_i为连续2个clk为high,则output会在下1个clk产生周期为1 T的high pulse,timing diagram如下图所示。


因此设计了Moore FSM,state diagram如上图所示,接下来要做的就是用各种coding style来实现这个Moore FSM。
simple_fsm_moore_3_always_best.v / Verilog
/*
(C) OOMusou 2011 http://oomusou.cnblogs.com Filename : simple_fsm_moore_3_always_best.v
Synthesizer : Quartus II 8.1
Description : 3 always block for moore fsm (BEST)
Release : Jun.05,2011 1.0
*/ module simple_fsm (
clk,
rst_n,
w_i,
z_o
); input clk;
input rst_n;
input w_i;
output z_o; parameter IDLE = 'b00;
parameter S0 = 'b01;
parameter S1 = 'b10; reg [:] curr_state;
reg [:] next_state;
reg z_o; // state reg
always@(posedge clk or negedge rst_n)
if (~rst_n) curr_state <= IDLE;
else curr_state <= next_state; // next state logic
always@(*)
case (curr_state)
IDLE : if (w_i) next_state = S0;
else next_state = IDLE;
S0 : if (w_i) next_state = S1;
else next_state = IDLE;
S1 : if (w_i) next_state = S1;
else next_state = IDLE;
default : next_state = IDLE;
endcase // output logic
always@(*)
case (curr_state)
IDLE : z_o = 'b0;
S0 : z_o = 'b0;
S1 : z_o = 'b1;
default : z_o = 'b0;
endcase endmodule
個always是一個推薦的寫法。
Testbench
simple_fsm_tb.v / Verilog
/*
(C) OOMusou 2011 http://oomusou.cnblogs.com Filename : simple_fsm_tb.v
Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
Description : testbench for FSM
Release : Jun.05,2011 1.0
*/ module simple_fsm_tb; reg clk = 'b1;
reg rst_n = 'b1;
reg w_i = 'b0;
wire z_o; // clk
always # clk = ~clk; event after_rst; // rst_n
initial begin
#; // 6ns
rst_n = 'b0;
#; // 36ns
rst_n = 'b1;
->after_rst;
end // w_i
initial begin
@(after_rst);
repeat()@(posedge clk); // 60ns
w_i <= 'b1;
@(posedge clk); // 80 ns
w_i <= 'b0;
@(posedge clk); // 100 ns
w_i <= 'b1;
repeat()@(posedge clk); // 140 ns
w_i <= 'b0;
@(posedge clk); // 160 ns
w_i <= 'b1;
repeat()@(posedge clk); // 220 ns
w_i <= 'b0;
end initial begin
$fsdbDumpfile("simple_fsm.fsdb");
$fsdbDumpvars(, simple_fsm_tb);
end simple_fsm u_simple_fsm (
.clk (clk),
.rst_n (rst_n),
.w_i (w_i),
.z_o (z_o)
); endmodule
/*
(C) OOMusou 2011 http://oomusou.cnblogs.com Filename : simple_fsm_moore_3_always_best.v
Synthesizer : Quartus II 8.1
Description : 3 always block for moore fsm (BEST)
Release : Jun.05,2011 1.0
*/ module simple_fsm (
clk,
rst_n,
w_i,
z_o
); input clk;
input rst_n;
input w_i;
output z_o; parameter IDLE = 'b00;
parameter S0 = 'b01;
parameter S1 = 'b10; reg [:] curr_state;
reg [:] next_state;
reg z_o; // state reg
always@(posedge clk or negedge rst_n)
if (~rst_n) curr_state <= IDLE;
else curr_state <= next_state; // next state logic
always@(*)
case (curr_state)
IDLE : if (w_i) next_state = S0;
else next_state = IDLE;
S0 : if (w_i) next_state = S1;
else next_state = IDLE;
S1 : if (w_i) next_state = S1;
else next_state = IDLE;
default : next_state = IDLE;
endcase // output logic
always@(*)
case (curr_state)
IDLE : z_o = 'b0;
S0 : z_o = 'b0;
S1 : z_o = 'b1;
default : z_o = 'b0;
endcase endmodule
simple_fsm_moore_3_always_best.v / Verilog
/*
(C) OOMusou 2011 http://oomusou.cnblogs.com Filename : simple_fsm_tb.v
Simulator : ModelSim SE 6.3e + Debussy 5.4 v9
Description : testbench for FSM
Release : Jun.05,2011 1.0
*/ module simple_fsm_tb; reg clk = 'b1;
reg rst_n = 'b1;
reg w_i = 'b0;
wire z_o; // clk
always # clk = ~clk; event after_rst; // rst_n
initial begin
#; // 6ns
rst_n = 'b0;
#; // 36ns
rst_n = 'b1;
->after_rst;
end // w_i
initial begin
@(after_rst);
repeat()@(posedge clk); // 60ns
w_i <= 'b1;
@(posedge clk); // 80 ns
w_i <= 'b0;
@(posedge clk); // 100 ns
w_i <= 'b1;
repeat()@(posedge clk); // 140 ns
w_i <= 'b0;
@(posedge clk); // 160 ns
w_i <= 'b1;
repeat()@(posedge clk); // 220 ns
w_i <= 'b0;
end initial begin
$fsdbDumpfile("simple_fsm.fsdb");
$fsdbDumpvars(, simple_fsm_tb);
end simple_fsm u_simple_fsm (
.clk (clk),
.rst_n (rst_n),
.w_i (w_i),
.z_o (z_o)
); endmodule
Testbench
1.使用3个always (三段式)
使用1个always描述state register,因为是D-FF且含clk,所以使用nonblocking。
由于state register区块并不包含任何逻辑,所以不会因为不同FSM而有不同写法,不同FSM只会改变next state logic与output logic的写法。
使用1个always描述output logic,因为是纯粹组合逻辑,所以使用blocking。
根据Moore FSM架构图所示,output logic的结果只与目前state有关,所以只需用case对state做一次分类即可。
使用3个always写法有几个优点:
1.可忠实地反映出原本的Moore FSM硬件架构
2.可轻易地将state diagram改用Verilog表示
3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护。
Mealy FSM架构

谈完了Moore FSM,接下来谈Mealy FSM,与Moore FSM的差别只在于Moore FSM的output logic只由目前state决定,但是Mealy FSM可由目前state与input共同决定。
将之前的例子用Mealy FSM重新改写,原本在Moore FSM下,若input w_i为连续2个clk为high,则output会在下1个clk产生周期为1 T的high pulse,若改用Mealy FSM,则output会提早1个clk出现,如下图所示。
原本Moore FSM需要3个state,若改用Mealy FSM后,会只剩下2个state,接下来要用各种coding style来实现Mealy FSM。
1.使用3个always (三段式)
simple_fsm_mealy_3_always_best.v / Verilog
之前提到使用Mealy FSM会少Moore FSM 1个state,且output会早Moore FSM 1个clk,所以最后特别将output在敲一级delay 1个clk,这样Mealy FSM就会完全与Moore FSM一样。
使用3个always写法有几个优点:
1.可忠实地反映出原本的Mealy FSM硬件架构
2.可轻易地将state diagram改用Verilog表示
3.将Next state logic与output logic分开,可降低code的复杂度,便于日后维护
/*
(C) OOMusou 2011 http://oomusou.cnblogs.com Filename : simple_fsm_mealy_3_always_best.v
Synthesizer : Quartus II 8.1
Description : 3 always block for mealy fsm (BEST)
Release : Jun.05,2011 1.0
*/ module simple_fsm (
clk,
rst_n,
w_i,
z_o
); input clk;
input rst_n;
input w_i;
output z_o; parameter IDLE = 'b00;
parameter S0 = 'b01; reg [:] curr_state;
reg [:] next_state;
reg z;
reg z_o; // state reg
always@(posedge clk or negedge rst_n)
if (~rst_n) curr_state <= IDLE;
else curr_state <= next_state; // next state logic
always@(*)
case (curr_state)
IDLE : if (w_i) next_state = S0;
else next_state = IDLE;
S0 : if (w_i) next_state = S0;
else next_state = IDLE;
default : next_state = IDLE;
endcase // output logic
always@(*)
case (curr_state)
IDLE : if (w_i) z = 'b0;
else z = 'b0;
S0 : if (w_i) z = 'b1;
else z = 'b0;
default : z = 'b0;
endcase // mealy output to delay 1 clk for moore
always@(posedge clk or negedge rst_n)
if (~rst_n) z_o <= 'b0;
else z_o <= z; endmodule
simple_fsm_mealy_3_always_best.v / Verilog
Conclusion
1.3个always与2个always (state register与next state logic合一)是两种推荐的写法,而且这两种写法无论要描述Moore FSM或者Mealy FSM都没问题,其他写法都不推荐,个人是比较喜欢2个always写法(state register + next state logic),因为这种写法最精简,各种需求都可描述,也不用担心是否要提前一个clk判断,最为直觉不易错。
2.实务上不会特别拘泥使用Moore或者Mealy,只要符合需求即可,一般会以Moore FSM为正宗。
3.实务上为了timing更好,会在Moore FSM的output logic多敲一级。
4.Mealy会比Moore少1个state,且output会比Moore早1个clk。
5.Moore与Mealy之间可以互换,只要在Mealy的output多敲一级即可。
(转帖) 有限狀態機FSM coding style整理 (SOC) (Verilog)的更多相关文章
- 有限狀態機FSM coding style整理 (SOC) (Verilog)
AbstractFSM在數位電路中非常重要,藉由FSM,可以讓數位電路也能循序地執行起演算法.本文將詳細討論各種FSM coding style的優缺點,並歸納出推薦的coding style. In ...
- [Gem] AASM 狀態機
@(Ruby on Rails)[rails, gem] 1234 # AASM is a continuation of the acts-as-state-machine rails plugin ...
- Linux 内核Coding Style整理
转载:http://www.cnblogs.com/wang_yb/p/3532349.html 总结linux内核开发的coding style, 便于以后写代码时参考. 下面只是罗列一些规则, 具 ...
- 有限状态机FSM(自动售报机Verilog实现)
有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 FSM Coding Goals
1.the fsm coding style should be easily modifiable to change state encoding and FSM styles. FSM 的的 状 ...
- SSIS 無法將保護的 XML 節點 "DTS:Password" 解密,錯誤為 0x8009000B "機碼用在特定狀態時無效
发现之前部署的SSIS,执行失败,查看日志 來源: 描述: 無法將保護的 XML 節點 -- ::-- ::-- :: DataReader 來源 [] 描述: System.Exception: S ...
- Win10還原成最乾淨的狀態 不必重灌
系統不穩定時我們想到的第一個選擇就是重灌,如果你的作業系統是win10將會有另外一個新選擇,就是透過程式進行還原,讓你的電腦回到剛安裝時的清爽. 工具資訊 [軟體名稱]微軟 Refresh Windo ...
- Win10還原成最乾淨的狀態
系統不穩定時我們想到的第一個選擇就是重灌,如果你的作業系統是win10將會有另外一個新選擇,就是透過程式進行還原,讓你的電腦回到剛安裝時的清爽. 工具資訊 [軟體名稱]微軟 Refresh Windo ...
- 檢查RAC狀態
1.使用srvctl工具檢查RAC當前配置和狀態 $ srvctl config database -h Displays the configuration for the database. Us ...
随机推荐
- hibernate 一张数据表的流程
1. 写一个domain类来映射数据库表 2. 写一个*.hbm.xml文件来配置映射 <?xml version="1.0"?> <!DOCTYPE hiber ...
- 大用处--PowerShell Management Library for Hyper-V.
http://pshyperv.codeplex.com/releases 用脚本来收集及集成HYPER-V管理. 越来越似KVM,LIBVIRT啦.
- 【HDOJ】3220 Alice’s Cube
状态压缩+逆向BFS.方向数组就是任意相邻的两点(初始化时减1),每个顶点均有4个相邻点.因此,共有16*4/2=32个方向.按序排列即可找到. /* 3220 */ #include <ios ...
- WordPress Citizen Space插件跨站请求伪造漏洞
漏洞名称: WordPress Citizen Space插件跨站请求伪造漏洞 CNNVD编号: CNNVD-201307-463 发布时间: 2013-07-23 更新时间: 2013-07-23 ...
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- HDOJ 2053 Switch Game
Problem Description There are many lamps in a line. All of them are off at first. A series of operat ...
- How to distribute your own Android library through jCenter and Maven Central from Android Studio
In Android Studio, if you wish to include any library to your application. You could just simply add ...
- qemu kvm 虚拟化
虚拟化: KVM是一个基于Linux内核的虚拟机,属于完全虚拟化.虚拟机监控的实现模型有两类:监控模型(Hypervisor)和宿主机模型(Host-based).由于监控模型需要进行处理器调度,还需 ...
- android快捷简单的实现音乐播放器
自己做了一个相对完整的音乐播放器,现在把播放模块提取出来,分享给大家.音乐播放器基本功能都实现了的,可能有些BUG,希望谅解. 播放器功能如下: 1.暂停,播放 2.拖动条实现,快进,快退 3.歌词同 ...
- 356. Line Reflection
首先找到X方向的中点,如果中点是一个点,那么分别从这个点开始往左右找就行:如果是一个区间,比如1 2之间,那么首先总点数得是偶数,然后以1和2往左右两边找就行.. 找的时候,有3种情况: 同时没找到, ...