状态机设计(共7页)_第1页
状态机设计(共7页)_第2页
状态机设计(共7页)_第3页
状态机设计(共7页)_第4页
状态机设计(共7页)_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上状态机设计 FSM简介: FSM 分两大类:米里型和摩尔型,组成要素有输入(包括复位),状态(包括当前状态的操作),状态转移条件,状态的输出条件,图1为状态机结构图。设计FSM 的方法和技巧多种多样,但是总结起来有两大类:第一种,将状态转移和状态的操作和判断等写到一个模块(process、block)中。另一种是将状态转移单独写成一个模块,将状态的操作和判断等写到另一个模块中(在Verilog代码中,相当于使用两个“always” block)。其中较好的方式是后者。其原因如下: 首先FSM 和其他设计一样,最好使用同步时序方式设计,好处不再赘述。而状态机实现后,状态

2、转移是用寄存器实现的,是同步时序部分。状态的转移条件的判断是通过组合逻辑判断实现的,之所以第二种比第一种编码方式合理,就在于第二种编码将同步时序和组合逻辑分别放到不同的程序块(process,block)中实现。这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。图1为状态机结构图 显式的FSM 描述方法可以描述任意的FSM(参考Verilog 第四版P181 有限状态机的说明)。两个always 模块。其中一个是时序模块,一个为组合逻辑。时序模块设计与书上完全一致,表示状态转移,可分为同步与异步复位。 同步: alw

3、ays (posedge clk) if (!reset) 异步: always (posedge clk or negedge reset) if (!reset) 专心-专注-专业组合逻辑用case 语句,sensitive list 包括当然状态(current state)和输入(a,b,c)。 编者注:以下是编者从“State Machine Coding Styles for Synthesis”一文中摘取的程序代码,是一个简单状态机的示例,采用两个always块的方法: module bm1_s (err, n_o1, o2, o3, o4,i1, i2, i3, i4, clk

4、, rst); output err, n_o1, o2, o3, o4; input i1, i2, i3, i4, clk, rst; reg err, n_o1, o2, o3, o4; parameter 2:0 /可以在此处添加综合约束属性来限定状态机的编码:binary,one-hot,gray,etc IDLE = 3'd0, S1 = 3'd1, S2 = 3'd2, S3 = 3'd3, ERROR = 3'd4; reg 2:0 state, next; always (posedge clk or posedge rst)/异步复位

5、,时序逻辑 if (rst) state <= IDLE; else state <= next; always (state or i1 or i2 or i3 or i4) begin /组合逻辑,敏感列表包含当前状态以及所有的状态机输入 next = 3'bx;/设置默认值,以便防止因为if或者case语句不完整综合生成锁存器 err = 0; n_o1 = 1; o2 = 0; o3 = 0; o4 = 0; case (state) IDLE: begin next = ERROR;/如果下面所有的if条件都不符合,则对next赋该默认值 if (!i1) nex

6、t = IDLE; if (i1 & i2) next = S1; if (i1 & !i2 & i3) next = S2; end S1: begin next = ERROR; if (!i2) next = S1; if (i2 & i3) next = S2; if (i2 & !i3 & i4) next = S3; n_o1 = 0; o2 = 1; end S2: begin next = ERROR; if (i3) next = S2; if (!i3 & i4) next = S3; o2 = 1; o3 = 1;

7、end S3: begin next = S3; if (!i1) next = IDLE; if (i1 & i2) next = ERROR; o4 = 1; end endmodule 对于状态机的输出可以通过寄存器寄存一下,消除毛刺,这将另外需要一个always块,也就是状态机三个always块的写法。 编码风格: 1. 避免生成锁存器 一个完备的状态机(健壮性强)应该具备初始化(reset)状态和默认(default)状态。当芯片加电或者复位后,状态机应该能够自动将所有判断条件复位,并进入初始化状态。需要注 明的一点是,大多数FPGA 有GSR(Global Set/Rese

8、t)信号,当FPGA 加电后,GSR 信号拉高,对所有的寄存器,RAM 等单元复位/置位,这时配置于FPGA 的逻辑并未生效,所以不能保证正确的进入初始化状态。所以使用GSR 进入FPGA 的初始化状态,常常会产生种种不必一定的麻烦。一般简单方便的方法是采用异步复位信号,当然也可以使用同步复位,但是要注意同步复位的逻辑设计。状态机也应该有一个默认(default)状态,当转移条件不满足,或者状态发生了突变时,要能保证逻辑不会陷入“死循环”。这是对状态机健壮性的一个重要要求,也就是常说的要具备“自恢复”功能。对应于编码就是对case,ifelse 语句要特别注意,要写完备的条件判断语句。VHDL

9、 中,当使用CASE 语句的时候,要使用“When Others”建立默认状态。使用“IF.THEN.ELSE”语句的时候,要在“ELSE”指定默认状态。Verilog 中,使用“case”语句的时候要用“default”建立默认状态,使用“if.else”语句的注意事项相似。 另外有一个技巧:大多数综合器都支持Verilog 编码状态机的完备状态属性“full case”。这个属性用于指定将状态机综合成完备的状态,如Synplicity 的综合工具(Synplify/Synplify Pro)支持的命令格式如下: case (current_state) / synthesis full_c

10、ase 2b00 : next_state <= 2b01; 2b01 : next_state <= 2b11; 2b11 : next_state <= 2b00; /这两段代码等效 case (current_state) 2b00 : next_state <= 2b01; 2b01 : next_state <= 2b11; 2b11 : next_state <= 2b00; default : next_state <= 2bx; Synplicity 还有一个关于状态机的综合属性,叫“/ synthesis parallel_case”

11、其功能是检查所有的状态是“并行的”(parallel),也就是说在同一时间只有一个状态能够成立。 编者注:使用上述两个综合约束属性会造成综合前后仿真结果的不一致,请慎重使用。 2. 参数定义用parameter 状态的定义用parameter 定义,不推荐使用define 宏定义的方式,因为define 宏定义在编译时自动替换整个设计中所定义的宏,而parameter 仅仅定义模块内部的参数,定义的参数不会与模块外的其他状态机混淆。 3. 时序电路中一定要使用”<=”非阻塞赋值方式 Verilog的非阻塞行赋值模拟的是实际硬件中串行寄存器的行为,排除了很多潜在的竞争冒险。在使用非阻塞赋值

12、的时候,很多设计者采用"intra-assignment timing delay"(在非阻塞赋值前人为加入一个很小单位的延时)。如下例: always (posedge clk or posedge rst) if (rst) state <= #1 IDLE; else state <= #1 nextstate; 关于这种写法的阐释有下面几点: I. 首先,这种描述是行为级描述方式,仅仅在仿真时起作用,在综合时会自动被综合器忽略。也就是通常所说的延时描述是不可综合的。 II. 这种描述的好处之一是:它简单模拟了赋值过程寄存器内部的clock-to-outp

13、ut 的延时,在做行为级功能仿真的时候,也可以发现一些由于寄存器固有延迟造成的时序和功能问题。 III. 避免了由RTL 级代码向门级描述转变过程中的一些潜在错误,如保持时间带来的问题。 4 不论是二进制编码的FSM,还是独热码FSM,复位时状态寄存器应该赋值为IDLE状态,如下: always( posedge clk or posedge rst ) if( rst ) state <= #1 IDLE; else state <= #1 next; 如果实现简化的独热码FSM,复位时状态寄存器首先赋值为全零,然后再立即置位状态寄存器的IDLE位。注意:两个非阻塞性赋值作用在同

14、一位上。这完全符合Verilog标准 规定,在此情况下,最后的非阻塞性赋值会代替前面所有的非阻塞性赋值,即更新状态机的IDLE位,如下所示: always( posedge clk or posedge rst ) if( rst ) begin state <= 5'b0; stateIDLE <= 1'b1; end else state <= next; 5 状态机中组合逻辑块的赋值 在组合always块中只能使用阻塞性赋值。来自同步always块的状态寄存器和状态机的所有输入触发组合always块,该块更新下一状态。应该在组合always块的最前面为下

15、一状态赋一个默认值,块内的case语句会更新该默认值。通常下一状态有三种默认值:全x;预定的恢复状态,如IDLE;状态寄存器的当前值。如果默认值为全x,那么前仿真模型会使状态机在没有任何明确的状态转移时,输出未知。这不仅有利于状态机的调试,还有利于综合,因为综合工具将x作为"无关"。一些设计(如卫星应用,媒体应用,需要使用FSM触发器作为检测扫描链的设计和使用正规验证工具做等价检测的设计)要求下一状态是已知的,而不是全x。通常这些设计下一状态的默认值应该是IDLE或全零,才能满足设计的要求。将下一状态初始化为默认值,可能比在每个case语句中指定明确的状态转移更简单。 6

16、Synplify中状态机设计: 可以在Synplify中添加在state定义时添加如下约束属性来限定状态机的编码: reg 2:0 state /* synthesis syn_encoding = "onehot" */; Synplify中包含一个强大的FSM编辑器,可以产生在时间和面积上均得到优化的状态机设计,但这将忽略一些状态机中未定义的状态(invalid state),如果必须在状态机进入了未定义的状态后能自动回到有效状态,可以在状态机生成时添加一个安全属性(safe),使得到达无效状态时能回到初始状态,这对电路的时间和面积产生很小的影响:reg 2:0 sta

17、te /* synthesis syn_encoding = "safe,onehot" */; 这种方法可能与源代码中实际描述的不一致,对于大多数设计来说这不会产生问题,但如果必须与源代码中描述的状态机流程图相吻合,可以通过约束属性关掉FSM编辑器:reg 4:0 state /* synthesis syn_preserve=1 */;但这将严重影响电路的时间和面积特性,下表是将三种方法应用在Altera Flex10k 和 Xilinx Virtex上的比较:编者注:对第5条和第6条在Synplicity公司的Application Note ”Designing S

18、afe Verilog State Machines with Synplify”中有更详细的说明。 7 几种状态机编码比较: 状态机编码有gray、binary、onehot 等,其中Binary、gray-code 编码使用最少的触发器,较多的组合逻辑。而one-hot 编码反之。由于CPLD 更多的提供组合逻辑资源,而FPGA 更多的提供触发器资源,所以CPLD 多使用gray-code,而FPGA 多使用one-hot 编码。另一方面,对于小型设计使用gray-code 和binary 编码更有效,而大型状态机使用one-hot更高效。看synplicity 的文档,推荐在24 个状态

19、以上会用格雷码,在524 个状态会用独热码,在4 个状态以内用二进制码,肯定独热码比二进制码在实现FSM 部分会占更多资源,但是译码输出控制简单,所以如果状态不是太多,独热码较好。状态太少译码不会太复杂,二进制就可以了。状态太多,前面独热码所占资源太多,综合考虑就用格雷码了。在代码中添加综合器的综合约束属性或者在图形界面下设置综合约束属性可以比较方便的改变状态的编码。在synplify 综合时,把FSM compile 勾上,就算用binary 表示,综合器会自动综合成one-hot 模式。 也可在coding 时直接添加描述:VHDL attribute TYPE_ENCODING_styl

20、e of <typename> : type is ONEHOT; Verilog Reg2:0 state; / synthesis syn_encoding = "value"(onehot) 其中onehot编码又分为几种:verbose one-hot 、simplified one-hot、one-hot with zero-idle,关于其具体区别请参考“State Machine Coding Styles for Synthesis“一文。 8 同步状态机输入变量的处理 所有的输入变量都必须与状态机时钟同步,否则,状态机的实际运行可能出现奇怪的现

21、 象,会莫名其妙地出现非法状态。所有的状态机都不可避免地可能死锁,在运行中间歇地中止。为什么呢?这是因为,实际上所有的物理状态机是用物理门实现的,而物理门的传播延时不为0。输入信号经过不同的物理门组合到不同的状态触发器输入端D的传播延时有细微的差别。如果输入信号正好在错误的时间改变,那么较快的通路会探测到变化,而较慢的通路则不会。时钟是不变的,所以必定有一个触发器会出现错误的电平。这样就导致状态转移错 误,整个状态机电路就会误动作。这种设计错误通常不被人注意,因为误动作的几率很小。所以,一定要注意异步输入。解决异步输入的办法是同步器,通常二级同步器能够预防错误的状态入口。虽然可能性很小,还是必须注意一个统计问题,即异步输入还是有可能传播通过同步器。因为两个同步阶段的出现,这种可能性被大大地减小了。一些空间或军事设计需要使用三级同步器,但是对于商业和工业级设计,二级同步器已经足够了。为了最大的减小延迟,第一级使用下降沿触发,第二级使用上升沿触发。 9 FSM输出产生 FSM的输出逻辑可以编码为一个独立的连续赋值块,也可以编码为一个组合逻辑always块。如果输出赋值编码到组合always块中,那么输出赋值就可以放到Verilog的task中,每 个case语句调用task。将输出赋值与组合always块分开,不仅有利于在需要更改时改变输出逻辑,还

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论