(转帖) 有限狀態機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 ...
随机推荐
- BZOJ 3872 Ant colony
Description There is an entrance to the ant hill in every chamber with only one corridor leading int ...
- 【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】
鸡冻人心的2016,微软高产年. build 2016后 各种干货层出不穷. 1 Win10 集成了bash ,实现了纳德拉的成诺,Microsoft Love Linux!!! 2 跨平台 ,收 ...
- mysql中的group_concat函数的用法
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...
- 树形结构的维护:BZOJ 3991: [SDOI2015]寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...
- 后缀数组:HDU1043 Longest Common Substring
Longest Common Substring Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...
- 编写一个单独的Web Service for Delphi7(步骤)
1新建一个SOAP Server Application,在提示输入接口时输入MyHello,把所有文件保存在一个叫Ser的目录下,其中一个包含TWebModule1的文件保存为main.pas.在M ...
- GCD中有哪几种Queue?你自己建立过串行Queue吗?背后的线程模型是什么样的
一共有五种,看图 Paste_Image.png 主线程也就是那个main,一般后台处理数据就就用default那个.创建过一个queue,处理NSMutableArray的时候都在在这一个queue ...
- Jupyter Notebook 对LaTeX 的支持
Jupyter的Markdown模式比我原来想想的更加强大:它支持LaTeX! 支持的特性不多,应该能满足一般的需求了.
- Real-Rime Rendering (2) - 变换和矩阵(Translation and Matrics)
提要 在图形的计算中,比如旋转.缩放.平移.投影等操作,矩阵都扮演着极其重要的角色,它是操作图元的基本工具.虽然很多的图形API已经封装好了这些矩阵操作,但是理解这些矩阵操作的原理会非常非常有帮助,比 ...