• spinal HDL - 10 - 状态机


    状态机

    介绍

    在 SpinalHDL 中,您可以通过使用枚举和 switch/case 语句来定义您的状态机,就像在 VHDL/Verilog 中一样。但在 SpinalHDL 中,您也可以使用专用语法。

    下面的状态机在以下示例中实现:

    image-20220815160551864

    风格一:

    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))
        }
      }
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    风格二:

    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))
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    状态机

    StateMachine是基类。它管理 FSM 的逻辑。

    val myFsm = new StateMachine {
      // Definition of states
    }
    
    • 1
    • 2
    • 3

    StateMachine还提供了一些访问器:

    姓名返回描述
    isActive(state)BoolTrue当状态机处于给定状态时返回
    isEntering(state)BoolTrue当状态机进入给定状态时返回

    入口点

    通过扩展 EntryPoint trait,可以将状态定义为状态机的入口点:

    val stateA = new State with EntryPoint
    
    • 1

    或通过使用setEntry(state)

    val stateA = new State
    setEntry(stateA)
    
    • 1
    • 2

    过渡

    • 转换由 表示goto(nextState),它将状态机安排nextState在下一个周期。
    • exit()安排状态机在下一个周期处于启动状态(或者,在 中StateFsm,退出当前嵌套状态机)。

    这两个函数可以在状态定义中使用(见下文)或 using ,它始终适用,优先于状态。always { yourStatements }``yourStatements

    状态

    可以使用多种状态:

    • State(基地之一)
    • StateDelay
    • StateFsm
    • StateParallelFsm

    它们中的每一个都提供了以下函数来定义与它们关联的逻辑:

    姓名描述
    state.onEntry {```你的声明```}yourStatements状态机不在时应用state,将state在下一个周期
    state.onExit {```你的声明```}yourStatements在状态机处于状态时应用,state并将在下一个周期处于另一个状态
    state.whenIsActive {```你的声明```}yourStatements当状态机处于state
    state.whenIsNext {```你的声明```}yourStatements当状态机将state进入下一个周期时执行(即使它已经在其中)

    state.隐含在块中:new State

    image-20220815163101706

    val stateB : State = new State {
      onEntry(counter := 0)
      whenIsActive {
        counter := counter + 1
        when(counter === 4) {
          goto(stateC)
        }
      }
      onExit(io.result := True)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    状态延迟

    StateDelay 允许创建一个状态,该状态在执行语句之前等待固定数量的周期。使用它的首选方法是:whenCompleted {...}

    val stateG : State = new StateDelay(cyclesCount=40) {
      whenCompleted {
        goto(stateH)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    也可以写成一行:

    val stateG : State = new StateDelay(40) { whenCompleted(goto(stateH)) }
    
    • 1

    状态机

    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
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在上面的示例中,exit()使状态机跳转到启动状态(内部隐藏状态)。这通知StateFsm了内部状态机的完成。

    StateParallelFsm

    StateParallelFsm允许处理多个嵌套状态机。当所有嵌套状态机都完成后,执行中的语句。whenCompleted { ... }

    例子:

    val stateD = new StateParallelFsm (internalFsmA(), internalFsmB()) {
      whenCompleted{
        goto(stateE)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    进入状态注意事项

    上面定义的进入状态的方式使得在复位和第一次时钟采样之间,状态机处于启动状态。只有在第一次时钟采样之后,定义的进入状态才会激活。这允许正确进入入口状态(在 中应用语句onEntry),并允许嵌套状态机。

    虽然它很有用,但也可以绕过该功能并直接让状态机引导到用户状态。

    为此,请使用makeInstantEntry()而不是定义。该函数返回开机状态,复位后直接激活。new State

  • 相关阅读:
    UE4/UE5 设置widget中text的字体Outline
    day08_分类品牌管理&商品规格管理&商品管理
    Matlab:Matlab软件之Simulink的简介、特点、使用方法、界面介绍之详细攻略
    【字符】压缩文本文件
    24张图攻克border-image
    coreldraw2022新版本新功能介绍cdr2022
    综合案例:学成在线案例
    多目标优化算法:基于非支配排序的麻雀搜索算法(Non-Dominated Sorting Sparrow Search Algorithm,NSSSA)
    医院敏感文件交互 如何保障安全和效率?
    leetCode 30.串联所有单词的子串
  • 原文地址:https://blog.csdn.net/weixin_41445387/article/details/126373991