来源: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.使用3always (三段式)

使用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.使用3always (三段式)

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)的更多相关文章

  1. 有限狀態機FSM coding style整理 (SOC) (Verilog)

    AbstractFSM在數位電路中非常重要,藉由FSM,可以讓數位電路也能循序地執行起演算法.本文將詳細討論各種FSM coding style的優缺點,並歸納出推薦的coding style. In ...

  2. [Gem] AASM 狀態機

    @(Ruby on Rails)[rails, gem] 1234 # AASM is a continuation of the acts-as-state-machine rails plugin ...

  3. Linux 内核Coding Style整理

    转载:http://www.cnblogs.com/wang_yb/p/3532349.html 总结linux内核开发的coding style, 便于以后写代码时参考. 下面只是罗列一些规则, 具 ...

  4. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  5. 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 的的 状 ...

  6. SSIS 無法將保護的 XML 節點 "DTS:Password" 解密,錯誤為 0x8009000B "機碼用在特定狀態時無效

    发现之前部署的SSIS,执行失败,查看日志 來源: 描述: 無法將保護的 XML 節點 -- ::-- ::-- :: DataReader 來源 [] 描述: System.Exception: S ...

  7. Win10還原成最乾淨的狀態 不必重灌

    系統不穩定時我們想到的第一個選擇就是重灌,如果你的作業系統是win10將會有另外一個新選擇,就是透過程式進行還原,讓你的電腦回到剛安裝時的清爽. 工具資訊 [軟體名稱]微軟 Refresh Windo ...

  8. Win10還原成最乾淨的狀態

    系統不穩定時我們想到的第一個選擇就是重灌,如果你的作業系統是win10將會有另外一個新選擇,就是透過程式進行還原,讓你的電腦回到剛安裝時的清爽. 工具資訊 [軟體名稱]微軟 Refresh Windo ...

  9. 檢查RAC狀態

    1.使用srvctl工具檢查RAC當前配置和狀態 $ srvctl config database -h Displays the configuration for the database. Us ...

随机推荐

  1. BZOJ 3872 Ant colony

    Description There is an entrance to the ant hill in every chamber with only one corridor leading int ...

  2. 【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】

    鸡冻人心的2016,微软高产年. build 2016后 各种干货层出不穷. 1 Win10 集成了bash  ,实现了纳德拉的成诺,Microsoft Love Linux!!! 2 跨平台  ,收 ...

  3. mysql中的group_concat函数的用法

    本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...

  4. 树形结构的维护:BZOJ 3991: [SDOI2015]寻宝游戏

    Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...

  5. 后缀数组:HDU1043 Longest Common Substring

    Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  6. 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  7. 编写一个单独的Web Service for Delphi7(步骤)

    1新建一个SOAP Server Application,在提示输入接口时输入MyHello,把所有文件保存在一个叫Ser的目录下,其中一个包含TWebModule1的文件保存为main.pas.在M ...

  8. GCD中有哪几种Queue?你自己建立过串行Queue吗?背后的线程模型是什么样的

    一共有五种,看图 Paste_Image.png 主线程也就是那个main,一般后台处理数据就就用default那个.创建过一个queue,处理NSMutableArray的时候都在在这一个queue ...

  9. Jupyter Notebook 对LaTeX 的支持

    Jupyter的Markdown模式比我原来想想的更加强大:它支持LaTeX! 支持的特性不多,应该能满足一般的需求了.

  10. Real-Rime Rendering (2) - 变换和矩阵(Translation and Matrics)

    提要 在图形的计算中,比如旋转.缩放.平移.投影等操作,矩阵都扮演着极其重要的角色,它是操作图元的基本工具.虽然很多的图形API已经封装好了这些矩阵操作,但是理解这些矩阵操作的原理会非常非常有帮助,比 ...