当前位置:网站首页>Understand the Chisel language. 29. Chisel advanced communication state machine (1) - communication state machine: take the flash as an example
Understand the Chisel language. 29. Chisel advanced communication state machine (1) - communication state machine: take the flash as an example
2022-07-30 14:30:00 【github-3rr0r】
ChiselAdvanced communication state machine(一)——Communication state machine:Take the flash for example
In the previous part we learned about a single finite state machineChisel描述方法,But a single finite state machine is often difficult to describe somewhat complex digital designs.在这种情况下,Divide the problem into two or more smaller ones、简单的FSM.这个FSMcommunicate using signals,某个FSM的输出是另一个FSM的输入,这个FSMObserve anotherFSM的输出.把一个大的FSMDivide into simple small onesFSMis called decompositionFSM.通信FSMUsually directly designed according to the design specification,Because if used first singleFSMIt's too big to implement the design.This article will learn the design and implementation of the communication state machine together.
通信FSM——Take the flash for example
To discuss communicationFSM,Our example using flash,This flash has an inputstart和一个输出light,The design specifications for this flash are as follows:
- 当
startwhen high for one cycle,闪烁开始; - will flash three times;
- flashing once,
light为on持续6个周期,为off持续4个周期; - 序列之后,FSM会将
light置为off并等待下一个start;
直接用一个FSMImplement this flash word,该FSM会有27中状态:1One is the initial state of waiting for input, 3 × 6 3\times 6 3×6个关于on状态的状态, 2 × 4 2\times 4 2×4个关于off状态的状态,共27中状态.We will not write the code for this implementation here.
Then we can make this bigFSMBreak it down into two small onesFSM:一个主FSMUsed to implement blinking logic,一个定时器FSM用于实现等待,The image below shows bothFSM之间的组合:

定时器FSMwill count down6cycle or4个周期,used to generate the desired timing,The specifications of the timer are as follows:
- 当
timerLoad被设置的时候,The timer loads a value into the countdown counter,Does not depend on state; timerSelectwill choose to load5或3;timerDoneWill be set when the counter has finished counting down and remains set;- 其他情况,The timer will count down.
The code below shows the timer for this flashFSM和主FSM实现:
val timerReg = RegInit(0.U)
// timer connection
val timerLoad = WireDefault(false.B) // 给loadStart the timer after the signal
val timerSelect = WireDefault(true.B) // 选择6cycle or4周期循环
val timerDone = Wire(Bool())
timerDone := timerReg === 0.U
timerLoad := timerDone
// 定时器FSM(倒数计数器)
when(!timerDone) {
timerReg := timerReg - 1.U
}
when(timerLoad) {
when(timerSelect) {
timerReg := 5.U
} .otherwise {
timerReg := 3.U
}
}
val off :: flash1 :: space1 :: flash2 :: space2 :: flash3 :: Nil = Enum(6)
val stateReg = RegInit(off)
val light = WireDefault(false.B) // FSM的输出
// 主FSM
switch(stateReg) {
is(off) {
timerLoad := true.B
timerSelect := true.B
when (start) {
stateReg := flash1}
}
is (flash1) {
timerSelect := false.B
light := true.B
when (timerDone) {
stateReg := space1}
}
is (space1) {
when (timerDone) {
stateReg := flash2}
}
is (flash2) {
timerSelect := false.B
light := true.B
when (timerDone) {
stateReg := space2}
}
is (space2) {
when (timerDone) {
stateReg := flash3}
}
is (flash3) {
timerSelect := false.B
light := true.B
when (timerDone) {
stateReg := off}
}
}
代码就不解释了,Just a hint,switchThere is no assignment in the statementwire都会赋默认值,所有space1和space2can be omitted insidetimerSelect和light的赋值,But it is best not to write that way.
But this solution is in the mainFSMThere is still redundant code,flash1、flash2和flash3The function of the state is the same,space1和space2也是如此.We can put these severalflashThe state is decomposed into a second counter,那么主FSMThere are only three statesoff、flash和space.The figure below shows the new communicationFSM设计:

Now there are two counts in the graphFSM了,一个用于计数on和offThe number of clock cycles in the interval,The other is used to count the restflash次数.The following code counts downFSM部分:
val cntReg = RegInit(0.U)
cntDone := cntReg === 0.U
// 向下计数FSM
when(cntLoad) {
cntReg := 2.U}
when(cntDecr) {
cntReg := cntReg - 1.U}
Note that the counter is loaded2to flash three times,Because it counts down the number of blinks left,and is decremented to when the timer finishesspace状态.The code below shows the complete new flashFSM实现:
import chisel3._
import chisel3.util._
class SimpleFsm extends Module {
val io = IO(new Bundle {
val start = Input(Bool())
val light = Output(Bool())
val state = Output(UInt()) // 用于调试
})
val light = WireDefault(false.B)
val timerLoad = WireDefault(false.B)
val timerSelect = WireDefault(true.B)
val timerDone = Wire(Bool())
val timerReg = RegInit(0.U)
timerDone := timerReg === 0.U
timerLoad := timerDone
when(!timerDone) {
timerReg := timerReg - 1.U
}
when(timerLoad) {
when(timerSelect) {
timerReg := 5.U
}.otherwise {
timerReg := 3.U
}
}
val cntLoad = WireDefault(false.B)
val cntDecr = WireDefault(true.B)
val cntDone = Wire(Bool())
val cntReg = RegInit(0.U)
cntDone := cntReg === 0.U
when(cntLoad) {
cntReg := 2.U }
when(cntDecr) {
cntReg := cntReg - 1.U }
val off :: flash :: space :: Nil = Enum(3)
val stateReg = RegInit(off)
switch(stateReg) {
is(off) {
timerLoad := true.B
timerSelect := true.B
cntLoad := true.B
when(io.start) {
stateReg := flash }
}
is(flash) {
cntLoad := false.B
timerSelect := false.B
light := true.B
when(timerDone & !cntDone) {
stateReg := space }
when(timerDone & cntDone) {
stateReg := off }
}
is(space) {
cntDecr := timerDone
when(timerDone) {
stateReg := flash }
}
}
io.light := light
io.state := stateReg
}
object MyModule extends App {
println(getVerilogString(new SimpleFsm()))
}
Except for the LordFSMThe status is reduced to 3中以外,Our new configuration is also more configurable.没有任何一个FSMWill need to change when we wanton、offtime is modified.
测试代码如下:
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
class SimpleTestExpect extends AnyFlatSpec with ChiselScalatestTester {
"DUT" should "pass" in {
test(new SimpleFsm) {
dut =>
dut.clock.step()
println(dut.io.state.peekInt(), dut.io.light.peekBoolean())
dut.io.start.poke(true.B)
for (a <- 0 until 50) {
dut.clock.step()
dut.io.start.poke(false.B)
println(a, dut.io.state.peekInt(), dut.io.light.peekBoolean())
}
}
}
}
Observe the output of the test,The test is known to pass.
结语
In this article, we take the flash circuit as an example,Communication circuits are explored,尤其是通信FSM的写法,FSMOnly control signals are exchanged between them.However, data can also be exchanged between circuits,For the coordinated exchange of data,We need to use the handshake signal,In the last article of this part, we will learn about control flow for one-way data exchangeready-valid接口.下一篇文章,We will learn about state machines with data paths,from manually specifiedready-valid信号开始.
边栏推荐
猜你喜欢

There is a risk of water ingress in the battery pack tray and there is a potential safety hazard. 52,928 Tang DMs are urgently recalled

LeetCode二叉树系列——144.二叉树的最大深度

如何在 TiDB Cloud 上使用 Databricks 进行数据分析 | TiDB Cloud 使用指南

我为何从开发人员转做测试,3年软件测试工程师,带你聊聊这其中的秘辛

【VMware虚拟机安装mysql5.7教程】

00 testers of seasoning after nearly a year, whether to change careers or to learn the software testing students summarized the following heart advice

无代码开发平台全部应用设置入门教程

Flask Framework - Flask-Mail Mail

No-code development platform all application settings introductory tutorial

A new generation of open source free terminal tools, so cool
随机推荐
权威推荐!腾讯安全DDoS边缘安全产品获国际研究机构Omdia认可
LeetCode二叉树系列——515.最每个树行中找最大值
BI-SQL丨WHILE
ARC115F Migration
sql中ddl和dml(sql与access的区别)
手把手教你写让人眼前一亮的软件测试简历,收不到面试邀请算我输
LeetCode二叉树系列——116.填充每个节点的下一个右侧指针
为什么做软件测试一定要学自动化?谈谈我眼中自动化测试的价值
CF780G Andryusha and Nervous Barriers
【Advanced Mathematics】【7】Double Integral
Remember an experience of interviewing an outsourcing company, should you go?
LeetCode二叉树系列——102.二叉树的层序遍历
JSON常用注解
跳槽前,把自己弄成卷王
BI-SQL丨WHILE
mongodb打破原则引入SQL,它到底想要干啥?
pytorch学习记录(五):卷积神经网络的实现
我为何从开发人员转做测试,3年软件测试工程师,带你聊聊这其中的秘辛
近两年激光雷达运动物体分割论文阅读小结
Study Notes - Becoming a Data Analyst in Seven Weeks "Week 2: Business": Business Analysis Metrics