状态机
介绍
在 SpinalHDL 中,您可以通过使用枚举和 switch/case 语句来定义您的状态机,就像在 VHDL/Verilog 中一样。但在 SpinalHDL 中,您也可以使用专用语法。
下面的状态机在以下示例中实现:
风格一:
import spinal.lib.fsm._ class TopLevel extends Component { val io = new Bundle { val result = out Bool() } val fsm = new StateMachine { val counter = Reg(UInt(8 bits)) init (0) io.result := False val stateA : State = new State with EntryPoint { whenIsActive(goto(stateB)) } val stateB : State = new State { onEntry(counter := 0) whenIsActive { counter := counter + 1 when(counter === 4) { goto(stateC) } } onExit(io.result := True) } val stateC : State = new State { whenIsActive(goto(stateA)) } } }
风格二:
import spinal.lib.fsm._ class TopLevel extends Component { val io = new Bundle { val result = out Bool() } val fsm = new StateMachine{ val stateA = new State with EntryPoint val stateB = new State val stateC = new State val counter = Reg(UInt(8 bits)) init (0) io.result := False stateA .whenIsActive(goto(stateB)) stateB .onEntry(counter := 0) .whenIsActive { counter := counter + 1 when(counter === 4) { goto(stateC) } } .onExit(io.result := True) stateC .whenIsActive(goto(stateA)) } }
状态机
StateMachine
是基类。它管理 FSM 的逻辑。
val myFsm = new StateMachine { // Definition of states }
StateMachine
还提供了一些访问器:
姓名 | 返回 | 描述 |
isActive(state) |
Bool |
True 当状态机处于给定状态时返回 |
isEntering(state) |
Bool |
True 当状态机进入给定状态时返回 |
入口点
通过扩展 EntryPoint trait,可以将状态定义为状态机的入口点:
val stateA = new State with EntryPoint
或通过使用setEntry(state)
:
val stateA = new State setEntry(stateA)
过渡
- 转换由 表示
goto(nextState)
,它将状态机安排nextState
在下一个周期。 exit()
安排状态机在下一个周期处于启动状态(或者,在 中StateFsm
,退出当前嵌套状态机)。
这两个函数可以在状态定义中使用(见下文)或 using ,它始终适用,优先于状态。always { yourStatements }``yourStatements
状态
可以使用多种状态:
State
(基地之一)StateDelay
StateFsmStateParallelFsm
它们中的每一个都提供了以下函数来定义与它们关联的逻辑:
state.
隐含在块中:new State
val stateB : State = new State { onEntry(counter := 0) whenIsActive { counter := counter + 1 when(counter === 4) { goto(stateC) } } onExit(io.result := True) }
状态延迟
StateDelay
允许创建一个状态,该状态在执行语句之前等待固定数量的周期。使用它的首选方法是:whenCompleted {...}
val stateG : State = new StateDelay(cyclesCount=40) { whenCompleted { goto(stateH) } }
也可以写成一行:
val stateG : State = new StateDelay(40) { whenCompleted(goto(stateH)) }
状态机
StateFsm
允许描述包含嵌套状态机的状态。当嵌套状态机完成(退出)时,执行中的语句。whenCompleted { ... }
有一个 StateFsm 定义的例子:
// internalFsm is a function defined below val stateC = new StateFsm(fsm=internalFsm()) { whenCompleted { goto(stateD) } } def internalFsm() = new StateMachine { val counter = Reg(UInt(8 bits)) init (0) val stateA : State = new State with EntryPoint { whenIsActive { goto(stateB) } } val stateB : State = new State { onEntry (counter := 0) whenIsActive { when(counter === 4) { exit() } counter := counter + 1 } } }
在上面的示例中,exit()使状态机跳转到启动状态(内部隐藏状态)。这通知StateFsm了内部状态机的完成。
StateParallelFsm
StateParallelFsm允许处理多个嵌套状态机。当所有嵌套状态机都完成后,执行中的语句。whenCompleted { ... }
例子:
val stateD = new StateParallelFsm (internalFsmA(), internalFsmB()) { whenCompleted{ goto(stateE) } }
进入状态注意事项
上面定义的进入状态的方式使得在复位和第一次时钟采样之间,状态机处于启动状态。只有在第一次时钟采样之后,定义的进入状态才会激活。这允许正确进入入口状态(在 中应用语句onEntry),并允许嵌套状态机。
虽然它很有用,但也可以绕过该功能并直接让状态机引导到用户状态。
为此,请使用makeInstantEntry()而不是定义。该函数返回开机状态,复位后直接激活。new State