状态机该怎么监控

状态机的可监控维度该如何考虑
》状态机该怎么监控     
最近遇到一个关于状态机的问题,具体的业务就不讲了。关于fsm怎么写这种初级问题在这里也不讲了。这里我们只关注下在真实的应用场景里,从监控的角度来看,该如何去看待fsm。         fpga设计里,除了功能实现之外,最重要的一部分就是dfx的设计。毕竟烧录完之后我们也只能通过dfx来去观测内部的状态(说jtag的请绕过,那顶多是开发阶段)。在考虑资源允许的情况下,我们要做的应当是有充分的dfx能够帮助我们去观测内部的状态。一个工程做下来往往是在补dfx时觉得要添加的太多了,而到真实需要定位问题的时候则又会感叹“当初怎么不多添加些dfx”~     回到对fsm的处理,一开始想到的可能是:
把fsm的当前状态添加到dfx中。
没毛病,我们能够清楚的观察到当前状态机处于什么状态。但当状态机如果处于卡死不动的状态,那我们所需要的就是导致当前状态卡住的信号的状态:
把fsm各条件跳转的判断信号添加到dfx中。
上面两条也基本是我们之前设计常常会做的内容。然而这里面只是对下面的场景做了监控:
状态机卡住的场景——通过状态跳转条件的dfx信号去判断卡住的原因
对于dfx信号,像我们通过pcie寄存器链路去读取dfx信号时不可能获取到每拍的结果,因而上面的dfx信号添加方式也就只能针对fsm卡死的情况进行定位判断。然而很不幸,这一次我遇到了一个状态机在跳转,只是没有跳转到一个需要响应某个动作的状态。由于代码从别人那里接手过来的,看代码也能对case场景进行一个判断。但回到监控的角度,只是没有跳转到一个需要响应某个动作的状态这个判断是我针对看到的dfx抓取信号来判断得到的结论,然而我并不能自证(当然可以通过仿真构造类似case来进行验证,这不提了),毕竟dfx不是每拍的结果都能看得到的,针对线上的问题,所有的判断应当都是有充足的证据的,而不是结合观测加推断。那么针对这种场景,有必要再增加一种监控手段:
记录各状态之间是否有过跳转发生,软件可清零。
通过记录各状态之间是否发生过跳转,那么我们可以结合dfx当前状态来充分说明某个状态没有到达。而记录各状态之间是否有过跳转发生,所消耗的资源也非常少。 》example
来看一个简单的状态机:
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))    }  }} 这里面会存在三个状态statea、stateb、statec:
statea——>stateb
stateb——>statec
statec——>statea
那么我们需要记录的就是:
statea_to_fsm_stateb_change
stateb_to_fsm_statec_change
statec_to_fsm_statea_change
在spinalhdl里,这种活儿还是不要手动的好,当然是自动化的处理好。下面给一个demo,可能有大神有更加优雅的解决方式,欢迎交流。
定义stateextend:
class stateextend(implicit statemachineaccessor: statemachineaccessor) extends state {  val nextstatebuffer=set[stateextend]()  def goto(state:stateextend)={    nextstatebuffer.add(state)    statemachineaccessor.goto(state)  }} 主要是在原有state的基础上重定义了goto函数,记录了每个状态会跳转的下一状态。
然后定义fsmmonitor:
case class fsmstate(monreg:bool,curstate:state,nextstate:state)case class fsmmonitor(implicit statemachineaccessor: statemachine ) extends area{  val statemonmap=map[state,arraybuffer[fsmstate]]()  val state_mon_clear=reginit(false) simpublic()  def generatefsmmonitor()={    val current_state_dly=regnext(statemachineaccessor.statereg)    val next_state_dly=regnext(statemachineaccessor.statenext)    for(state<-statemachineaccessor.states){      if(state.isinstanceof[stateextend]){        for (nextstate {      fsm_mon.generatefsmmonitor()    })  }} 差别点在于goto换成对应的statea.goto等显示调用的形式。通过例化fsmmonitor调用generatefsmmonitor即可注册所有的状态跳转信号:


华引芯半导体器件中心扩建项目竣工投产
发动机研发与制造企业全柴动力发布2022第一季度报告
国外80后牛人DIY创意便携式3D打印机(图文)
2016腾讯WE大会:AR、VR改变未来学习方式
日光灯常见故障的维修
状态机该怎么监控
RS485接口芯片
知名展商再聚一堂,谱写科技盛事
美国实行霸权主义将限制华为在美国销售设备
美国高防云服务器的硬件防御和软件防御的区别是什么
百度携手中国宝武推进AI在钢铁全产业链场景中的应用
可充锂金属电池中气体诱导的非活性锂形成机制
火爆无比!华为P10全面缺货:网友心痒
RealWear完成新一轮500万美元融资,用于扩展全球销售
Circuit Converts PWM Fan Drive
U-Boot介绍
小米在印度正式发布了红米7A该机搭载骁龙439处理器拥有三种配色
热导式流量开关介绍
武汉街头现手机无线充电路灯,可快速给手机充电
整流桥在电源中起什么作用?