chisel手册中对状态机中代码的学习记录、心得体会、理解与解释

13 篇文章 0 订阅
6 篇文章 0 订阅

https://www.chisel-lang.org/docs/cookbooks/cookbook#how-do-i-create-a-finite-state-machine-fsm

chisel手册,状态机中的理解

代码

import chisel3._
import chisel3.util.{switch, is}

object DetectTwoOnes {
  object State extends ChiselEnum {
    val sNone, sOne1, sTwo1s = Value
  }
}

/* This FSM detects two 1's one after the other */
class DetectTwoOnes extends Module {
  import DetectTwoOnes.State
  import DetectTwoOnes.State._

  val io = IO(new Bundle {
    val in = Input(Bool())
    val out = Output(Bool())
    val state = Output(State())
  })

  val state = RegInit(sNone)

  io.out := (state === sTwo1s)
  io.state := state

  switch (state) {
    is (sNone) {
      when (io.in) {
        state := sOne1
      }
    }
    is (sOne1) {
      when (io.in) {
        state := sTwo1s
      } .otherwise {
        state := sNone
      }
    }
    is (sTwo1s) {
      when (!io.in) {
        state := sNone
      }
    }
  }
}

代码理解:

这段代码是用Chisel硬件设计语言实现的一个简单的有限状态机(FSM),用于检测连续两个逻辑“1”。以下是对代码的详细中文解释:

导入模块和工具

  • import chisel3._: 导入Chisel库,这是使用Chisel进行硬件设计的基础。
  • import chisel3.util.{switch, is}: 导入Chisel的switchis工具,这些工具用于构建条件分支,类似于其他编程语言中的switch-case语句。

定义状态机的状态

  • DetectTwoOnes对象中定义一个名为State的枚举类型,用于表示状态机的状态。这里定义了三个状态:
    • sNone:初始状态,表示到目前为止没有检测到“1”。
    • sOne1:第一状态,表示已经检测到一个“1”。
    • sTwo1s:第二状态,表示连续检测到两个“1”。

状态机的实现

  • class DetectTwoOnes是一个Chisel模块,实现了上述定义的状态机。
  • 定义了一个名为io的接口,包括:
    • in:输入信号,类型为Bool(),表示接收外部的逻辑信号。
    • out:输出信号,类型为Bool(),当状态机处于sTwo1s状态时输出为true,表示已经检测到两个连续的“1”。
    • state:输出当前状态机的状态,用于调试或测试。

状态机逻辑

  • 使用switch语句来根据当前的状态执行不同的操作:
    • is(sNone): 当状态为sNone时,如果输入为true(即检测到“1”),则状态转移到sOne1
    • is(sOne1): 当状态为sOne1时,如果再次输入为true,则状态转移到sTwo1s,表示连续检测到两个“1”。如果输入为false,则返回到sNone状态。
    • is(sTwo1s): 当状态为sTwo1s时,如果输入为false,则状态返回到sNone,等待下一次连续两个“1”的检测。

功能描述

  • 该状态机启动时在sNone状态,等待输入信号。
  • 当检测到一个“1”后,进入sOne1状态。
  • 如果在sOne1状态下再次检测到“1”,则进入sTwo1s状态,并通过out输出信号表示检测到连续两个“1”。
  • 如果在任何状态下检测到“0”,状态机将重置回sNone状态。

这种类型的状态机在数字电路设计中常用于序列检测,如网络数据流中特定模式的检测等。

细节理解:

import的部分理解

  import DetectTwoOnes.State
  import DetectTwoOnes.State._

在的代码中,使用了两个import语句来引入DetectTwoOnes.State,这些语句的作用和含义如下:

1. import DetectTwoOnes.State

这条语句导入了DetectTwoOnes对象中定义的State枚举类型。通过这种导入,您可以在当前作用域中直接使用State来引用这个枚举类型,而不需要每次都使用完整的路径DetectTwoOnes.State。这样做的好处是简化了代码的书写,提高了代码的可读性。

2. import DetectTwoOnes.State._

这条语句进一步导入了DetectTwoOnes.State枚举中定义的所有值(成员),如sNonesOne1sTwo1s。这意味着您可以直接在代码中使用这些枚举值,而无需每次都加前缀State.

实际应用

这样的导入方式使得在定义和操作状态机时代码更为简洁明了。例如,当您需要检查或设置状态机的状态时,可以直接写:

state := sNone

而不是:

state := DetectTwoOnes.State.sNone

这两条import语句共同使得代码更为简洁,提高了开发效率,同时保持了代码的易读性。在复杂的项目中,适当地使用这种导入策略可以大大减少代码的冗余,并且使得来自同一模块或包的不同部分更加紧密地协作。

状态相关

  io.out := (state === sTwo1s)
  io.state := state

在代码片段中,io.outio.state是两个与输入/输出相关的接口定义,它们是状态机DetectTwoOnes的关键部分,用于与外部系统交互。这些行如何工作及其意义如下:

1. io.out := (state === sTwo1s)

这行代码设置了输出信号io.out的值。具体来说,io.out是一个布尔类型的输出(Bool()),该输出依赖于状态机的当前状态是否为sTwo1s

  • 表达式解释(state === sTwo1s)是一个条件表达式,检查当前的状态(由寄存器state保存)是否等于sTwo1s状态。这里使用的===是Chisel中的相等比较运算符,用于比较两个数据元素是否相等。
  • 行为:如果状态机当前处于sTwo1s状态,表明已经连续检测到两个逻辑“1”,这时表达式(state === sTwo1s)的结果为true,因此io.out将输出true。如果不是sTwo1s状态,io.out输出false

这种设计使得外部系统可以通过检查io.out的值来知道是否检测到了连续的两个“1”。

2. io.state := state

这行代码将内部状态寄存器state的当前值直接输出到io.stateio.state是一个枚举类型的输出,与内部的state寄存器类型相同。

  • 功能:通过将内部状态直接输出,可以方便地进行调试或监控状态机的行为。外部系统或测试设备可以读取这个值,了解状态机在任意时刻的状态。
  • 用途:在实际应用中,这可以用于系统的状态监测、故障诊断或者系统行为的验证。

这两行代码共同定义了状态机与外部世界的接口行为,一方面通过io.out提供业务逻辑所需的信号输出,另一方面通过io.state提供系统状态信息,以便进行监控和调试。这样的设计不仅增强了模块的功能完整性,也便于模块的集成和测试。

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值