0
在使用「scanLeft」生成分接移位寄存器時,我需要使用IndexedSeq寄存器並將scanLeft的結果顯式複製到輸出線。以下是四個示例(使用測試臺)。只有第一個工作。 我最喜歡第二個,並想知道爲什麼它不正確。chisel3:想要使用Vec,但需要使用IndexedSeq
package tsr
import chisel3._
import chisel3.util._
import chisel3.iotesters._
import org.scalatest.{Matchers, FlatSpec}
object TappedShiftRegister {
def apply[ T <: Data](d : T, n : Int) : Vec[T] = {
val rs = IndexedSeq.tabulate(n){ (i) => Reg(d.cloneType)}
val rs0 = rs.scanLeft(d){ case (x, r) => r := x; r}
val ys = Wire(Vec(n+1, d.cloneType))
(ys zip rs0).foreach{ case (y,r) => y := r}
ys
}
def apply1[ T <: Data](d : T, n : Int) : Vec[T] = { // ChiselException
val rs = Vec.tabulate(n){ (i) => Reg(d.cloneType)}
Vec(rs.scanLeft(d){ case (x, r) => r := x; r})
}
def apply2[ T <: Data](d : T, n : Int) : Vec[T] = { // ChiselException
val rs = IndexedSeq.tabulate(n){ (i) => Reg(d.cloneType)}
Vec(rs.scanLeft(d){ case (x, r) => r := x; r})
}
def apply3[ T <: Data](d : T, n : Int) : Vec[T] = { // Wrong values
val rs = Vec.tabulate(n){ (i) => Reg(d.cloneType)}
val rs0 = rs.scanLeft(d){ case (x, r) => r := x; r}
val ys = Wire(Vec(n+1, d.cloneType))
(ys zip rs0).foreach{ case (y,r) => y := r}
ys
}
}
class TappedShiftRegisterIfc extends Module {
val io = IO(new Bundle {
val inp = Input(UInt(8.W))
val out = Output(Vec(5, UInt(8.W)))
})
}
class GenericTSRTest(factory :() => TappedShiftRegisterIfc) extends FlatSpec with Matchers {
it should "meet all PeekPokeTester expectations" in {
chisel3.iotesters.Driver(factory, "firrtl") { c => new PeekPokeTester(c) {
val N = 4
val off = 47
for { i <- 0 until 100} {
poke(c.io.inp, off+i)
expect(c.io.out(0), off+i) // mealy output
step(1)
for { j <- 0 until N if i > j} {
expect(c.io.out(j+1), off+i-j) // moore outputs
}
}
}} should be (true)
}
}
class TSRTest extends GenericTSRTest(() => new TappedShiftRegisterIfc { io.out := TappedShiftRegister(io.inp, 4) })
class TSRTest1 extends GenericTSRTest(() => new TappedShiftRegisterIfc { io.out := TappedShiftRegister.apply1(io.inp, 4)})
class TSRTest2 extends GenericTSRTest(() => new TappedShiftRegisterIfc { io.out := TappedShiftRegister.apply2(io.inp, 4)})
class TSRTest3 extends GenericTSRTest(() => new TappedShiftRegisterIfc { io.out := TappedShiftRegister.apply3(io.inp, 4)})
'val rs = Reg(Vec(n,d.cloneType))'也適用。舊的「使用註冊Vecs而不是註冊Vec」規則 –
謝謝。如果我們不應該使用功能,我們是否應該有棄用消息(或編譯器錯誤)? –
這很好,但理查德說這很難。我的目標是暫時改善文檔。 –