chisel - "for-loop" 减少 Chisel3.2 上的编码
问题描述
我想用 for-loop 编码冗余部分。
编码。
//Priority Encoder
class P_Encoder(NumInputs: UInt) extends Module {
val io = new Bundle {
val Req[NumInputs] = Bool(INPUT) //Requests
val Rls[NumInputs] = Bool(INPUT) //Releases
val Grant[NumInputs] = UInt(OUTPUT(log(NumInputs))) //Grants
}
val cnt = 0
for (i<-0 to NumInputs-1) {
when (io.Req[i] & !io.Rls[i]) {
cnt := cnt + 1.W
io.Grant[i] = cnt
}
else {
io.Grant[i] = 0.W
}
}
}
我想使用“for-loop”来编码冗余部分。
解决方案
这段代码有几个小问题:
- 通常我们在Scala中以小写字母开头命名变量,这主要是样式,但在某些情况下它确实具有语义意义(如模式匹配)
- 方括号仅用于类型参数(如 Java 泛型),索引在 Scala 中使用普通括号
- Bools 的输入 Vec 通常定义为:(
val req = Input(Vec(numInputs, Bool()))
假设import chisel3._
,但这也适用于Chisel._
Chisel 3.2) if
和else
用于静态参数化(即在硬件细化时),而when
和.otherwise
用于动态逻辑(例如,实际多路复用器)UInt
适用于硬件类型,如果您有静态参数(如numInputs
),请使用 ScalaInt
除了少量的语法内容之外,正确编写此代码最棘手的部分是了解仅在精化时(即 Scala 程序生成硬件时)运行的 Scala 构造与硬件中实际显示的构造之间的区别. 我建议从 chisel-users 邮件列表中阅读此线程,以了解有关其中一些内容的更多上下文:https ://groups.google.com/d/msg/chisel-users/gRoNnH-Y5hE/ynDCtmNPCAAJ
我对io.grant
应该获得什么值有点困惑,但我假设它应该是最高优先级的索引io.req
。这是您的代码的未经测试的版本,我认为它应该可以工作并做您想做的事情:
//Priority Encoder
class P_Encoder(numInputs: Int) extends Module {
// We wrap ports in IO
val io = IO(new Bundle {
val req = Input(Vec(numInputs, Bool()))
val rls = Input(Vec(numInputs, Bool()))
val grant = Output(UInt(log2Up(numInputs).W))
})
io.grant := 0.U // default grant value
// Due to Chisel last connect semantics, the last connection wins
// Thus the highest index will have priority
for (i <- 0 to numInputs - 1) {
when (io.req(i) && !io.rls(i)) {
io.grant := i.U
}
}
}
这段代码很棘手,因为它将精化时间for
循环与硬件when
和连接混合在一起,我将手动展开这个循环来说明它在做什么:
io.grant := 0.U
when (io.req(0) && !io.rls(0)) {
io.grant := 0.U
}
when (io.req(1) && !io.rls(1)) {
io.grant := 1.U
}
when (io.req(2) && !io.rls(2)) {
io.grant := 2.U
}
...
或者,如果我们愿意,我们可以重用内置的 PriorityEncoder 实用程序
import chisel3.util.PriorityEncoder
val enables = io.req.zip(io.rls).map { case (x, y) => x && !y }
// PriorityEncoder gives priority to *lowest* order bit
io.grant := PriorityEncoder(enables)
推荐阅读
- javascript - 我的画布上的签名在手机上不起作用
- mysql - 如何在一行中连接两个具有相同列名和不同 ID 的 SQL 表?
- junit4 - 如何为方法编写 Junit 测试用例
- python - WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:502
- r - 创建一个关于summarize+group by的函数
- javascript - 获取所有复选框并由前一个兄弟检查它们
- rabbitmq - 当我有持久队列并且消息传递模式是持久性时,RabbitMQ 集群中是否存在消息丢失的可能性?
- angular - 是否可以将现有的角度项目添加到新的角度多项目工作区?
- java - java.net.SocketTimeoutException:使用 Retrofit 和 OkHttp
- ios - iOS webView 没有使用整个屏幕