当前位置:网站首页>Understand the Chisel language. 30. Chisel advanced communication state machine (2) - FSMD: Take Popcount as an example
Understand the Chisel language. 30. Chisel advanced communication state machine (2) - FSMD: Take Popcount as an example
2022-08-02 07:53:00 【github-3rr0r】
Chisel进阶之通信状态机(二)——FSMD:以Popcount为例
The previous article used flash as an example,The writing method of the communication state machine is introduced,It is used to decompose a large complex state machine into small multiple state machines that communicate with each other,Less resources can be guaranteed to be used,维护、Modifications are also easier.However, the communication between the communication state machines in the previous article is all control signals,Data signals are not yet involved.This article will learn about state machines with data paths,并以PopcountThe counter is introduced as an example.
State machine with data path
A typical example of a communication state machine is a state machine with a data path,Such state machines have special names,即FSMD(Finite-State Machine with Datapath,Finite state machine with data path).The state machine controls the data path,The datapath performs the computation.FSMDThere are inputs from the environment and inputs from the datapath,Where input from the environment is fed into the datapath,The datapath in turn generates data.下图就是一个典型的FSMD:
Popcount的例子
The example above is actually a calculationPopcount的FSMD,这个Popcount也叫Hamming Weight(汉明权重),Refers to a binary string1
的数量.
PopcountCells contain data inputsdin
and the resulting outputpopCount
,Both are connected to the datapath.对于输入输出,我们使用ready-valid握手协议.When the sender data is valid,valid
信号被设置,When the receiver can accept the data,ready
信号被设置.when both signals are set,Data transfer happens.The handshake signal is connected toFSM上,FSMconnected to the data path,包括FSMControl signals to the datapath and datapath toFSM的状态信号.
Next we can design thisFSM了,Start with the state transition diagram first,That is, the example diagram given above.FSM从Idle
状态开始,等待输入.when the data arrives,会给出一个valid
信号,FSM会进入到Load
state to read a shift register.然后FSM进入下一个状态Count
,here in the binary string1
will be counted sequentially.Here we use a shift register,一个加法器,an accumulator register,and a down counter to complete the count.When the down counter reaches zero,计算就完成了,FSM进入下一个状态Done
,此时带valid
信号的FSMThe signal is given,FSMThe signal contains what will be usedpopCount
值.when received from the receiverready
信号后,FSM就转移到Idle
状态,准备计算下一个popCount
.
The code below is a description of the top-level module,会对FSMand the data section is initialized,并将他们连接起来:
class PopCount extends Module {
val io = IO(new Bundle {
// 输入数据有效
val dinValid = Input(Bool())
// 可以接收数据
val dinReady = Output(Bool())
// 输入数据
val din = Input(UInt(8.W))
// 输出结果有效
val popCountValid = Output(Bool())
// 可以输出数据
val popCountReady = Input(Bool())
// 输出结果
val popCount = Output(UInt(4.W))
})
// fsm部分
val fsm = Module(new PopCountFSM)
// 数据通路部分
val data = Module(new PopCountDataPath)
// fsmconnection to the top-level interface
fsm.io.dinValid := io.dinValid
io.dinReady := fsm.io.dinReady
io.popCountValid := fsm.io.popCountValid
fsm.io.popCountReady := io.popCountReady
// The connection between the datapath and the top-level interface
data.io.din := io.din
io.popCount := data.io.popCount
// 数据通路和fsm之间的连接
data.io.load := fsm.io.load
fsm.io.done := data.io.done
}
Comments simply state what the top-level module code means,这里就不多说了.Let's start by looking at the structure of the datapath,The following figure is a schematic diagram of the data path section:
数据din
首先输入到shf
寄存器中.在加载数据的时候,cnt
寄存器置零.为了统计1
的数量,regData
The deposit will be shifted to the right(图片中的shf
),The least significant bit is added every clock cycleregPopCount
上(图片中的cnt
).There is also a register map that is not drawn,It performs a countdown,until all bits in the input have been shifted out as least significant bits,计数器为0的时候就表明popCount
计算结束了.此时FSM会切换到Done
状态,在popCountReady
The resulting signal is output when the signal is set.when the result is read,通过设置popCountValid
Signal output data and letFSM切换回Idle
状态.The following is the data path sectionChisel代码实现:
class PopCountDataPath extends Module {
val io = IO(new Bundle {
val din = Input(UInt(8.W))
val load = Input(Bool())
val popCount = Output(UInt(4.W))
val done = Output(Bool())
})
val dataReg = RegInit(0.U(8.W))
val popCountReg = RegInit(0.U(4.W))
val counterReg = RegInit(0.U(4.W))
dataReg := 0.U ## dataReg(7, 1)
popCountReg := popCountReg + dataReg(0)
val done = counterReg === 0.U
when (!done) {
counterReg := counterReg - 1.U
}
when (io.load) {
dataReg := io.din
popCountReg := 0.U
counterReg := 8.U
}
// 调试用
printf("%b %d\t", dataReg, popCountReg)
io.popCount := popCountReg
io.done := done
}
在load
信号有效时,regData
The register is loaded with the input,regPopCount
registers will be reset to 0
,计数寄存器regCount
will be set to the number of bits to be shifted.否则,regData
register shift right,The least significant bits that were shifted out are added toregPopCount
寄存器上,倒数计数器regCount
自减一.当计数器为零时,regPopCount
The value of is to be calculatedpopCount
.
而PopCountFSM
有三种状态,从idle
开始.When the input data is valid signaldinValid
被设置时,FSM会切换到count
状态,and wait for the datapath to complete the computation,当popCount
有效时,FSM切换到done
状态,直到接收到popCntReady
signal and transmit the data,再切换为idle
状态,等待下一轮计算.FSM部分的Chisel实现如下:
class PopCountFSM extends Module {
val io = IO(new Bundle {
val dinValid = Input(Bool())
val dinReady = Output(Bool())
val popCountValid = Output(Bool())
val popCountReady = Input(Bool())
val load = Output(Bool())
val done = Input(Bool())
})
val idle :: count :: done :: Nil = Enum(3)
val stateReg = RegInit(idle)
io.load := false.B
io.dinReady := false.B
io.popCountValid := false.B
switch(stateReg) {
is(idle) {
io.dinReady := true.B
when(io.dinValid) {
io.load := true.B
stateReg := count
}
}
is(count) {
when(io.done) {
stateReg := done
}
}
is(done) {
io.popCountValid := true.B
when(io.popCountReady) {
stateReg := idle
}
}
}
// 调试用
printf("state: %b\n", stateReg)
}
The code in this part is similar to the previous state machine code,就不解释了.下面是测试代码:
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
class SimpleTestExpect extends AnyFlatSpec with ChiselScalatestTester {
"DUT" should "pass" in {
test(new PopCount) {
dut =>
dut.clock.step()
dut.io.din.poke("b10010011".U)
dut.io.dinValid.poke(true.B)
for (a <- 0 until 12) {
dut.clock.step()
}
dut.io.popCountReady.poke(true.B)
dut.clock.step()
dut.clock.step()
dut.clock.step()
dut.clock.step()
}
}
}
输出如下:
0 0 state: 0
0 0 state: 0
10010011 0 state: 1
1001001 1 state: 1
100100 2 state: 1
10010 2 state: 1
1001 2 state: 1
100 3 state: 1
10 3 state: 1
1 3 state: 1
0 4 state: 1
0 4 state: 10
0 4 state: 10
0 4 state: 10
0 4 state: 0
10010011 0 state: 1
1001001 1 state: 1
测试通过.
结语
这一篇文章以Popcount为例,Finite state machines with data paths are introducedFSMDwriting and implementation,It has a key guiding significance for writing complex systems later.我们可以注意到,在FSMD的实现中,Communication between state machines we useReady-Valid
握手协议,This is a common communication interface protocol,But it's obviously a bit complicated to write this every time.而Chisel中自带了Ready-Valid
相关的函数DecoupledIO
,for data signalsReady-Valid
协议的封装,In the next article we will learn about this important and convenient function.
边栏推荐
- 图腾柱和推挽电路介绍
- 带手续费买卖股票的最大利益[找DP的状态定义到底缺什么?]
- 初探形式化方法基本原理
- Introduction to mysql operation (4) ----- data sorting (ascending, descending, multi-field sorting)
- 逆变器绝缘检测检测功能及软件实现
- Ask a question, my Flinkcdc has run through, I can monitor the binlog of msql, and I can also send kafk
- FormData upload binary file, object, object array
- 替换ptmalloc,使用tcmalloc和jemalloc
- 跨阻放大器
- 【网络】IP、子网掩码
猜你喜欢
【云原生】如何快速部署Kubernetes
以训辅教,以战促学 | 新版攻防世界平台正式上线运营!
神经元网络
C#重点问题之Struct和Class的异同
MySQL-执行流程+缓存+存储引擎
The best interests of buying and selling stocks with handling fees [What is missing in the definition of DP status?]
替换ptmalloc,使用tcmalloc和jemalloc
【故障诊断分析】基于matlab FFT轴承故障诊断(包络谱)【含Matlab源码 2002期】
企业实训复现指导手册——基于华为ModelArts平台的OpenPose模型的训练和推理、基于关键点数据实现对攀爬和翻越护栏两种行为的识别、并完成在图片中只标注发生行为的人
条件构造器~wapper
随机推荐
Compact格式下MySQL的数据如何存储到磁盘
队列题目:无法吃午餐的学生数量
责任链模式(Chain Of Responsibility)
spark architecture
Gradle系列——Gradle插件(基于Gradle文档7.5)day3-2
查看僵尸进程
About the SQL concat () function problem, how to splice
论文阅读 (64):Weakly-supervised Video Anomaly Detection with Robust Temporal Feature Magnitude Learning
雷达人体存在感应器方案,智能物联网感知技术,实时感应人体存在
条件构造器~wapper
【机器学习】实验1布置:基于决策树的英雄联盟游戏胜负预测
jvm 二之 栈帧内部结构
【杂】pip换国内源教程及国内源地址
LeetCode刷题(7)
飞桨paddle技术点整理
自然语言处理 文本预处理(下)(张量表示、文本数据分析、文本特征处理等)
以训辅教,以战促学 | 新版攻防世界平台正式上线运营!
OC-Category
MySQL-多版本并发控制
2020美亚团队赛复盘