在FSM模型中使用两态数据类型
1、使用两态类型和枚举类型对FSM复位
在仿真刚开始时,四态数据类型的值是逻辑X。类似有限状态机这样的模型中,四态变量的X逻辑值可以用来表示模型还没有复位,或复位逻辑的建模不正确。
仿真刚开始时,两态数据类型的缺省值是0而不是X。因为复位操作通常是将大部分变量清0,所以这样一来即使复位逻辑有缺陷,模型好像仍然是被复位了。
仿真开始时,枚举类型使用枚举类型的基类值作为缺省值。如果状态变量用默认基类和标签值定义并且复位操作也是将枚举值置为表中的第一个值,那么就会出现和两态变量类似的情况。默认基类是int,它是仿真时具有非初始值0。枚举列表中第一个标签的默认值是0,这与两态基类的非初始值相同。这样即使没有插入复位,或复位逻辑有错误,设计好像仍然是复位了。
enum{WAITE,LOAD,STORE}State,Next;
always@(posedge clock,negedge resetN)if(!resetN) State <= WAITE;else State <= Next;always@(State)case(State)WAITE:Next = LOAD;LOAD:Next = STORE;STORE:Next = WAITE;endcase
使用复位逻辑也不能解决这个状态锁定问题。因为复位会将State置为WAITE值,这仍然与开始仿真时的值一样。因此变量State还是没有变化,次态译码逻辑还是不能触发,Next仍然会保持起始值WAITE.
这种在仿真开始时出现的状态锁定问题可以通过两种方法解决。
第一种方法是用四态基类如logic显示声明枚举变量。然后仿真开始时State和Next会具有非初始值X。这清楚地表明了这些变量已经被复位了。它也准确反映了硬件特性,即触发器加电后处于一种中间状态。在RTL仿真中,当应用复位时,State变量将从X转变为它的复位值WAITE。这一转变将触发对Next译码以及将Next置为合适值LOAD的逻辑。
第二种解决使用默认基类和标签值的枚举类型时产生的FSM锁定问题的方法是用SystemVerilog是always_comb过程块代替always@(State)。即使其相关敏感表的变量没有变化,在仿真零时刻,always_comb过程块也会自动执行一次。通过在零时刻执行一次。通过在零时刻执行译码逻辑,初始State值将被译码,然后变量Next随之相应改变。