我想在一个时钟周期内多次重新分配变量hit_bits
。只要 io.bits_perf.bits(i)
为 true,hit_bits
就会增加。我收到“找到组合路径!”当我尝试编译代码时。
有什么想法吗?
val hit_bits = Bits()
hit_bits := Bits(0)
when(io.bits_perf.valid){
for(i<- 0 until 3){
when(io.bits_perf.bits(i)) { hit_bits := hit_bits + Bits(1)
}
}
}
最佳答案
对于此示例,请务必牢记 Chisel 和 Scala 之间的区别。更具体地说,when
是一个 Chisel 结构,映射到 Verilog 中的条件连接,而 for
是一个 Scala 结构,我们可以用它来生成硬件(类似于 generate
在 Verilog 中)。
让我们展开这个 for 循环,看看我们得到了什么:
when(io.bits_perf.valid){
when(io.bits_perf.bits(0)) { hit_bits := hit_bits + Bits(1) }
when(io.bits_perf.bits(1)) { hit_bits := hit_bits + Bits(1) }
when(io.bits_perf.bits(2)) { hit_bits := hit_bits + Bits(1) }
}
请注意,所有连接都是相同的,当 io.bits_perf.valid 为高且 io.bits_perf.bits 中的任何位为高时,您将把 hit_bits
连接到 hit_bits + Bits(1)
。这就是组合循环。
现在,让我们弄清楚如何表达您真正想要做的事情:当io.bits_perf.时如何将hit_bits连接到
为高。这也称为 popcount,Chisel 恰好有一个实用程序。你应该做的是使用它:io.bits_perf.bits
中的个数。有效
val hit_bits = Bits()
hit_bits := Bits(0)
when(io.bits_perf.valid) {
hit_bits := PopCount(io.bits_perf.bits)
}
但是,您编写的代码几乎是正确的,所以无论如何都要让它工作。我们想要做的是使用 Scala for 循环来生成一些代码。实现此目的的一种方法是使用 Scala var (允许重新分配)作为 Chisel 节点的“指针”,而不是使用仅允许单个分配的 val (因此不能更改为指向不同的 Chisel 节点)。
var hit_bits = Bits(0, 2) // We set the width because + does not expand width
when (io.bits_perf.valid) {
for (i <- 0 until 3) {
hit_bits = hit_bits + io.bits_perf.bits(i)
}
}
// Now hit_bits is equal to the popcount of io.bits_perf.bits (or 0 if not valid)
请注意,我还删除了内部条件条件,因为您可以直接添加位,而不是有条件地添加 1。这里发生的情况是 hit_bits
是对 Chisel 节点的引用,以 0
。然后,对于 for 循环中的每个索引,我们将 hit_bits 引用的节点更改为 Chisel 节点,该节点是前一个节点 hit_bits 引用的节点与 io.bits_perf.bits 的一位相加的输出>.
关于scala - 在一个时钟周期内多次重新分配变量 - Chisel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40935156/