我想使用for循环来编写冗余部分。
编码。
//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”进行编码,以对冗余部分进行编码。
答案 0 :(得分:2)
此代码存在一些小问题:
val req = Input(Vec(numInputs, Bool()))
(假设import chisel3._
,但对于凿子3.2,这也应在Chisel._
中起作用)if
和else
用于静态参数化(即,在硬件制造时),而when
和.otherwise
用于动态逻辑(例如,实际的多路复用器) UInt
用于硬件类型,如果您有静态参数(例如numInputs
),请使用Scala Int
除了少量的语法问题外,正确编写代码的最棘手的部分是了解仅在阐述时间(即,当Scala程序生成硬件时)运行的Scala构造之间的区别。 ,以及实际显示在硬件中的内容。我建议您从凿子用户的邮件列表中阅读此线程,以获取有关以下内容的更多上下文: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)
答案 1 :(得分:1)
我同意@jkoenig所说的一切。
在另一个假设杰克的IO结构的示例中,有时候我喜欢
将foldLeft
与when
/ elsewhen
结合使用
io.rel.zip(io.req).zipWithIndex.foldLeft(when(false.B){}) { case (lastWhen,((req, rel), index)) =>
lastWhen.elsewhen(req && !rel) {
io.grant := index.U
}
} otherwise {
io.grant := 0.U
}
when
和elsewhen
都返回一个WhenClause
,可以将其与foldLeft一起使用以继续添加子句。