当前位置:网站首页>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:
- 当
start
when 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; timerSelect
will choose to load5或3;timerDone
Will 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
和space2
can 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
和flash3
The function of the state is the same,space1
和space2
也是如此.We can put these severalflash
The 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
和off
The 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
、off
time 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
信号开始.
边栏推荐
猜你喜欢
Still saying software testing doesn't have a midlife crisis?9 years of test engineers were eliminated
Huawei's 7-year-experienced software testing director, gives some advice to all friends who want to change careers to learn software testing
LoRaWAN网关源码分析(V1.0.2)
手把手教你写让人眼前一亮的软件测试简历,收不到面试邀请算我输
LeetCode二叉树系列——144.二叉树的最大深度
接口自动化框架,lm-easytest内测版发布,赶紧用起来~
跳槽前,把自己弄成卷王
桌面软件开发框架大赏
自动化测试之数据驱动DDT详细篇
记面试外包公司的一次经历,到底该不该去?
随机推荐
新一代开源免费的终端工具,太酷了
Before quitting, make yourself a roll king
Allure进阶-动态生成报告内容
记面试外包公司的一次经历,到底该不该去?
关于String的一些思考
Cookie simulation login "recommended collection"
pytorch与keras的相互转换(代码以LeNet-5为例)
Synology system installation related file sharing
八年测试经验,为何惨遭领导痛批:你写的测试文档还不如刚来的应届生
数据中台建设(五):打破企业数据孤岛和提取数据价值
MIMO雷达波形设计
Huawei's 7-year-experienced software testing director, gives some advice to all friends who want to change careers to learn software testing
AT4108 [ARC094D] Normalization
43.【list链表的定义及初始化】
No-code development platform application visible permission setting introductory tutorial
Flask框架——Flask-SQLite数据库
LeetCode二叉树系列——144.二叉树的最大深度
机器学习在竞赛和工业界应用区别
开源工具推荐:高性能计算辅助工具MegPeak
Why do software testing have to learn automation?Talk about the value of automated testing in my eyes