三种不同状态机写法

一段式状态机:

 1 reg[3:0]  cs, ns;
 2 always @(posedge clk or negedge rst_n) begin
 3     if (!rst_n) begin
 4         cs    <=  IDLE;
 5         cmd <=  3‘b111;
 6     end
 7     else begin
 8         case (cs)
 9             IDLE :   if (wr_req) begin cs <= WR_S1; cmd <= 3‘b011; end
10                 else if (rd_req) begin cs <= RD_S1; cmd <= 3‘b011; end
11                 else             begin cs <= IDLE;  cmd <= 3‘b111; end
12             WR_S1:               begin cs <= WR_S2; cmd <= 3‘b101; end
13             WR_S2:               begin cs <= IDLE;  cmd <= 3‘b111; end
14             RD_S1:   if (wr_req) begin cs <= WR_S2; cmd <= 3‘b101; end
15                      else        begin cs <= RD_S2; cmd <= 3‘b110; end
16             RD_S2:   if (wr_req) begin cs <= WR_S1; cmd <= 3‘b011; end
17                      else        begin cs <= IDLE;  cmd <= 3‘b111; end
18             default :                  cs <= IDLE;
19         endcase
20     end
21 end

两段式状态机:

 1 reg[3:0]  cs, ns;
 2 //----------   时序逻辑   ------------------
 3 always @(posedge clk or negedge rst_n) begin
 4     if (!rst_n)
 5         cs    <=  IDLE;
 6     else
 7         cs    <=  ns;
 8 end
 9 //----------   组合逻辑   ------------------
10 always @(*) begin
11     case (cs)
12         IDLE :   if (wr_req) begin cs <= WR_S1; cmd <= 3‘b011; end
13             else if (rd_req) begin cs <= RD_S1; cmd <= 3‘b011; end
14             else             begin cs <= IDLE;  cmd <= 3‘b111; end
15         WR_S1:               begin cs <= WR_S2; cmd <= 3‘b101; end
16         WR_S2:               begin cs <= IDLE;  cmd <= 3‘b111; end
17         RD_S1:   if (wr_req) begin cs <= WR_S2; cmd <= 3‘b101; end
18                  else        begin cs <= RD_S2; cmd <= 3‘b110; end
19         RD_S2:   if (wr_req) begin cs <= WR_S1; cmd <= 3‘b011; end
20                  else        begin cs <= IDLE;  cmd <= 3‘b111; end
21         default :                  cs <= IDLE;
22     endcase
23 end

三段式状态机:

 1 reg[3:0]  cs, ns;
 2 //----------   时序逻辑   ------------------
 3 always @(posedge clk or negedge rst_n) begin
 4     if (!rst_n)
 5         cs    <=  IDLE;
 6     else
 7         cs    <=  ns;
 8 end
 9 //----------   组合逻辑   ------------------
10 always @(*) begin
11     case (cs)  //现态
12         IDLE :   if (wr_req) begin cs <= WR_S1; end
13             else if (rd_req) begin cs <= RD_S1; end
14             else             begin cs <= IDLE;  end
15         WR_S1:               begin cs <= WR_S2; end
16         WR_S2:               begin cs <= IDLE;  end
17         RD_S1:   if (wr_req) begin cs <= WR_S2; end
18                  else        begin cs <= RD_S2; end
19         RD_S2:   if (wr_req) begin cs <= WR_S1; end
20                  else        begin cs <= IDLE;  end
21         default :                  cs <= IDLE;
22     endcase
23 end
24 //----------   时序逻辑   ------------------
25 always @(posedge clk or negedge rst_n) begin
26     if (!rst_n)
27         cmd    <=  3‘b011;
28     else begin
29         case (ns)  //次态
30             IDLE :   if (wr_req) begin cmd <= 3‘b011; end
31                 else if (rd_req) begin cmd <= 3‘b011; end
32                 else             begin cmd <= 3‘b111; end
33             WR_S1:               begin cmd <= 3‘b101; end
34             WR_S2:               begin cmd <= 3‘b111; end
35             RD_S1:   if (wr_req) begin cmd <= 3‘b101; end
36                      else        begin cmd <= 3‘b110; end
37             RD_S2:   if (wr_req) begin cmd <= 3‘b011; end
38                      else        begin cmd <= 3‘b111; end
39             default : ;
40         endcase
41     end
42 end

三种写法对比:

(1)一段式状态机不利于维护(简单状态机可以用);

(2)两段式状态机是常见写法,时序逻辑进行状态切换,时序逻辑实现各个输入、输出以及状态判断,利于维护,不过组合逻辑容易出现毛刺等常见问题;

(3)三段式状态机推荐写法,代码易维护,时序逻辑输出解决了两段式写法种组合逻辑的毛刺问题,但是耗费资源多一些且三段式从输入到输出比一段式和两段式会延时一个时钟周期。

原文地址:https://www.cnblogs.com/yllinux/p/8641634.html

时间: 2024-10-06 20:22:39

三种不同状态机写法的相关文章

使用单例时的三种单例写法

单例:一个类只有一个实例,在外部创建对象时,不能用alloc.(只要alloc,就会在堆区开辟空间,就意味着有多个对象)所以我们要提供一个创建对象的方法: 1.加号方法 2.返回值类型为当前类 3.方法名以default ,standared,main,shared等开头 + 当前类名 下面以Person类为例 在.h文件中声明 + (Person *)sharePerson; 在.m文件实现 第一种模式(单线程使用这种模式) + (Person *)sharePerson { 声明为stati

JAVA Script 三种匿名函数写法

第一种匿名函数function f1(fn){alert('zheshi yigef1 hanshu'); fn ();}fn(f12);function f12( ){alert('12');}或者function f1(fn){alert('zheshi yigef1 hanshu'); fn( );} f1(function (){ alert('直接传递一个匿名函数'):}): 第二种匿名函数 (function(x,y){alert (x+y);})(10,50); 三种 匿名函数va

Egret中的三种单例写法

1 普通的单例写法 class Single{ private static instance:Single; public static getInstance():Single{ if(this.instance == null){ this.instance = new Single(); } return this.instance; } public run(){ } } Single.getInstance().run(); 2 Module写法.仿照的Egret中Res资源类写法.

android 三种定时器的写法

一. 使用Timer 和 TimerTask Timer timer = new Timer(); MyTimerTask timerTask = new MyTimerTask(); timer.schedule(timerTask, 3000, 1); // 延迟3秒钟,执行1次 //timer.cancel();// 取消 class MyTimerTask extends TimerTask { @Override public void run() { //这里不能处理UI操作 //

Remoting三种信道Http,Tcp,IPC和Web Service的访问速度比较(转)

Remoting和Web Service是.net中的重要技术,都可用来实现分布式系统开发,如果是不同的平台就只能选择Web Service,但如果是同一平台,就都可以选择了.到底选择那种,当然还有访问效率上的考虑,同时在Remoting中又有三中信道 Http,Tcp,Ipc,它们又各有差别.HTTP方式的信道在跨越防火墙上有优势:TCP方式的信道常用在局域网内通信,速度比HTTP快很 多:IPC信道用于同一台机器的进程间通信,通信不占用网络资源,速度又比TCP快很多.为了能够实际的比较一下这

测试Remoting三种信道Http,Tcp,Ipc和Web Service的访问速度 (转)

Remoting和Web Service是.net中的重要技术,都可用来实现分布式系统开发,如果是不同的平台就只能选择Web Service,但如果是同一平台,就都可以选择了.到底选择那种,当然还有访问效率上的考虑,同时在Remoting中又有三中信道Http,Tcp,Ipc,它们又各有差别.HTTP方式的信道在跨越防火墙上有优势:TCP方式的信道常用在局域网内通信,速度比HTTP快很多:IPC信道用于同一台机器的进程间通信,通信不占用网络资源,速度又比TCP快很多.为了能够实际的比较一下这四者

mysql不需要拷贝表的三种DDL

我们知道mysql5.6才支持部分的online ddl,但是以下三种ddl的写法是不需要拷贝表的: 字段注释alter table testtable change testcolumn testcolumn int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '修改后的字段的注释'; 表注释alter table testtable comment '修改后的表的注释'; 修改默认值alter table testtable alter colu

同一个逻辑的三种写法

同一个逻辑的三种写法: 我的写法 ? 林姐的写法 方法一 方法二 这种方法节省内存

for循环的三种写法

第一种写法  传统的方法,遍历数组 String[] arr = { "amy", "heinrich", "cindy", "git" }; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } 打印台 amy heinrich cindy git 这种方式最简单,对数组还有集合都可以 第二种 而对于遍历Collection对象,这个循