集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1509|回复: 1

Verilog HDL 的状态机设计的其他技巧

[复制链接]
afei6969 发表于 2021-4-26 17:53:51 | 显示全部楼层 |阅读模式
本节讨论 FSM 设计的其他技巧。
· FSM 的编码
Binary(二进制编码)、gray-code(格雷码)编码使用最少的触发器,较多
的组合逻辑,而 one-hot(独热码)编码反之。one-hot 编码的最大优势在于状
态比较时仅仅需要比较一个 bit,一定程度上从而简化了比较逻辑,减少了毛
刺产生的概率。由于 CPLD 更多地提供组合逻辑资源,而 FPGA 更多地提供触
发器资源,所以 CPLD 多使用 gray-code,而 FPGA 多使用 one-hot 编码。另一
方面,对于小型设计使用 gray-code 和 binary 编码更有效,而大型状态机使用
one-hot 更高效。
在代码中添加综合器的综合约束属性或者在图形界面下设置综合约束属性
可以比较方便地改变状态的编码。需要注意的是:Synplicity、Synopsys、
Exemplar 等综合工具关于 FSM 的综合约束属性的语法格式各不相同。
· FSM 初始化状态
一个完备的状态机(健壮性强)应该具备初始化状态和默认状态。当芯片
加电或者复位后,状态机应该能够自动将所有判断条件复位,并进入初始化状
态。需要注明的一点是,大多数 FPGA 有 GSR(Global Set/Reset)信号,当
FPGA 加电后,GSR 信号拉高,对所有的寄存器、RAM 等单元复位/置位,这
时配置于 FPGA 的逻辑并未生效,所以不能保证正确地进入初始化状态。所以
使用 GSR 企图进入 FPGA 的初始化状态,常常会产生种种不必要的麻烦。一
般的方法是采用异步复位信号,当然也可以使用同步复位,但是要注意同步复
位逻辑的设计。解决这个问题的另一种方法是将默认的初始状态的编码设为全
零,这样 GSR 复位后,状态机自动进入初始状态。如 6.2.3 节所示的编码方法
就是初始状态全零的 one-hot 编码方式。
· FSM 状态编码定义
状态机的定义可以用 parameter 定义,但是不推荐使用`define 宏定义的方
式,因为'define 宏定义在编译时自动替换整个设计中所定义的宏,而
parameter 仅仅定义模块内部的参数,定义的参数不会与模块外的其他状态机
混淆。例如一个工程里面有两个 module 各包含一个 FSM,如果设计时都有
IDLE 这一名称的状态,如果使用'define 宏定义就会混淆起来,如果使用
parameter 则不会造成任何不良影响。
· FSM 输出
如果使用 2 段式 FSM 描述 Mealy 状态机,输出逻辑可以用"?语句"描述,或
者使用 case 语句判断转移条件与输入信号即可。如果输出条件比较复杂,而且
多个状态共用某些输出,则建议使用 task/endtask 将输出封装起来,达到模块
复用的目的。
· 阻塞和非阻塞赋值
为了避免不必要的竞争冒险,不论是做两段式还是三段式 FSM 描述时,必须
遵循时序逻辑 always 模块使用非阻塞赋值“<=”,即当前状态向下一状态时序
转移,和寄存 FSM 输出等时序 always 模块中都要使用非阻塞赋值;而组合逻
辑 always 模块使用阻塞赋值“=”,即状态转移条件判断,组合逻辑输出等
always 模块中都要使用阻塞赋值。
· FSM 的默认状态
完整的状态机应该包含一个默认(default)状态,当转移条件不满足,或
者状态发生了突变时,要能保证逻辑不会陷入“死循环”。这是对状态机健壮
性的一个重要要求,也就是常说的要具备“自恢复”功能。对应于编码就是对
case 和 if…else 语句要特别注意,尽量使用完备的条件判断语句。Verilog 中,
使用 case 语句的时候要用 default 建立默认状态。读者可能注意到,在上节举
例中的 case 语句中,我们没有写 default 默认状态,其实我们可以将其中一个
状态不编码,指定其为 default 默认状态,则任何与所列状态机不匹配的状态
都会转到 default 状态,从而增强了 FSM 的健壮性,另外我们也可以添加一个
额外的 default 状态,这个一旦进入这个状态就会自动转到 IDLE 状态,从新
启动状态机,这样做也增强了状态机的健壮性。
case (CS)
IDLE: begin
IDLE_out;
if (~i1) NS = IDLE;
if (i1 && i2) NS = S1;
if (i1 && ~i2) NS = ERROR;
end
S1: begin
S1_out;
if (~i2) NS = S1;
if (i2 && i1) NS = S2;
if (i2 && (~i1)) NS = ERROR;
end
S2: begin
S2_out;
if (i2) NS = S2;
if (~i2 && i1) NS = IDLE;
if (~i2 && (~i1)) NS = ERROR;
end
ERROR: begin
ERROR_out;
if (i1) NS = ERROR;
if (~i1) NS = IDLE;
end
default: begin
IDLE_out;
NS = IDLE;
end
endcase
end
· Full Case 与 Parallel Case 综合属性
所谓 Full Case 是指:FSM 的所有编码向量都可以与 case 结构的某个分支
或 default 默认情况匹配起来。如果一个 FSM 的状态编码是 8bit,则对应的
256 个状态编码(全状态编码是2n 个)都可以与 case 的某个分支或者 default
映射起来。
所谓 Parallel Case 是指:在 case 结构中,每个 case 的判断条件表达式
(即本章 6.2.2 小节描述的 case_expression),有且仅有唯一的 case 语句的分
支(即本章 6.2.2 小节描述的每个 case_item)与之对应,即两者关系是一一对
应关系。
目前知名综合器如 Synplify Pro、Precision RTL 和 Synopys 综合工具等都
支持“ synthesis full_case”和“ synthesis parallel_case”这些综合约束属性,
合理使用 Full Case 约束属性,可以增强设计的安全性;合理使用 Parallel Case
约束属性,可以改善状态机译码逻辑。但是设计者必须具体情况具体分析,对
于有的设计,不当使用这两条语句,会占用大量逻辑资源,并恶化 FSM 的时
序表现。
zhangyukun 发表于 2021-4-27 10:21:26 | 显示全部楼层
Verilog HDL 的状态机设计的其他技巧
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-29 01:38 , Processed in 0.057121 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表