合格状态机的条件
1. 表示状态机的信号或变量必须为枚举类型;
2. 状态机的状态转换必须由时钟信号触发,并且由if语句检测上升沿进行转移;
3. 状态机转换到下一个状态由case语句判断;
4. 所有的信号或变量赋值都应该在状态机的进程中进行;
5. 状态机的状态必须大于两个
以下为QuatusII handbook的原话
The compiler recognizes states machines and repert them as such in the states machines,section of the report window only if all of the following conditions are met
1. The type of signal or variable that represent the machine must be an enumerated type
2. The process statement that describle that state machine must be clocked and must contain an if statement that checks for a positive edge of the clk control signal;
3. The state machine behavior,that is,the next-state logic is defined with case statement at the top level,
4. All assignments to the signal or variable that represents the state machine are within the process
5. The states machine must have more than two states.
Altera推荐的状态机设计原则
1. 合适的状态机编码方式
各种状态编码对比
编码方式 | 优缺点 | 适用场合 |
Johnson | 使用较少的触发器、较多的组合逻辑 | CPLD,应用于小型设计 |
Gray | 使用较少的触发器、较多的组合逻辑 | CPLD,应用于小型设计 |
Minimal bits |
|
|
Sequential |
|
|
One-hot | 使用较多的触发器、较少的组合逻辑 | FPGA,应用于大型设计 |
在QuartusII中Assignments/Setting/Analysis & Synthesis Settings/More Setting/State machine processing中设置合适的状态机编码
2. 同步mealy型状态机
同步mealy型状态机是最佳的状态机表示方法,因为他的同步更加彻底,所有的输出由寄存器直接驱动,状态寄存器与输出信号之间无需任何组合逻辑
3. 两段或三段式状态机
不采用一段式的目的是“可能会导致综合工具优化困难”。一段式状态机往往存在时序约束等问题,而且不能很好的表示同步mealy型状态机的输出,容易产生Latches,应该避免。
通常把状态转移写在一个进程中,而状态的操作、判断写在另一个进程中,这样做的好处是:不仅便于阅读、理解,更重要的是有利于综合器优化代码,有利于用户添加合适的时序约束,有利于布局布线器实现设计。
4. 初始化和处理剩余状态
一个完整的健壮的状态机应该具备初始化状态和默认状态,当系统上电或复位后,状态机应该能够自动地把所有的判断条件复位,并进入初始化状态,这里关于复位,由一些技巧,可以参考Kevin的博文FPGA复位问题
一般状态机的初始化状态设置为全零,避免一些不必要的麻烦。
处理剩余状态很重要,当条件不满足或者状态发生突变时,保证系统不会进入死循环,要能从非法的状态中自动恢复,也就是数电中提到的“自恢复电路”。又称“捕弊束缚电路(Booby trap)”。其实状态机从非法状态回到合法状态,从电路运行这个微观的角度上看是“安全的”,但从状态机的行为上这个宏观上看,回到合法状态不等于状态机可以继续正常工作,其实并不正常,这就好像生病了,要治病一样,我们应该锻炼身体,避免生病,这样就不用治病了。在设计系统的时候,应该考虑怎样不让状态机进入非法状态,让系统按照我们的意愿去运行,而不是只采取事后补救措施!
5. 指定默认的输出值
对状态机的所有输出变量指定一个默认的输出值,防止无意生成的Latch,另外,输出时最好采用时钟同步,使得系统的时序性能更好。
6. 逻辑复用
对于状态机中的多个状态都会执行某个操作,可以把这个操作的具体内容放在状态机之外,在状态机中只调用最终的输出值即可。在有些状态里循环执行的,可以放在或定义另一个状态,如
when mac_chk_head =>
fifo_en <= ‘1’;
if phy_data = X”7E” then
mac_state <= mac_packet;
else
mac_state <= mac_chk_head;
end if;
fifo_en <= ‘1’在这个状态中循环执行,可以把它放在上个状态中的条件判断中,只需执行一次,节省逻辑资源。
7. 输出采用寄存器驱动可以优化状态机的时序性能
上面已经介绍
8. 在QuartusII做一些设置
在QuartusII中Assignments/Setting/Analysis & Synthesis Settings/More Setting/Soft State Machine中设置为On,但是可能会带来状态机使用资源的增长和速度的下降。
用户3717572 2016-4-30 23:34