我想实现一个通用的addr解码器。这是一个后续问题to this post。
class AddrDecoder[T <: Data with Num[T]] (dType:T, n:Int) extends Module {
val io = IO (new Bundle {
val mmap = Map(BigInt, BigInt) // base, size ranges
val addr = Input (dType)
val en = Input (Bool())
//val sel = Output(Vec(n,Bool())) // $onehot0 selector
val sel = Output(Bool():_*) // $onehot0 selector
})
// Curried function which accepts a tuple and an input addr
// Use map to apply it to inputs
def inside (range:(T,T))(addr:T):Bool = {
addr >= range._1 && addr < range._1 + range._2
}
// MUX output
for (i <- 0 until n) {
io.sel(i) := false.B
}
// Check addr range and assert high if matches
var idx = 0 // yes, variable
for ((k,v) <- io.mmap) {
when (io.en) {
io.sel(idx) := (k + v) (inside(_)(io.addr))
idx := idx + 1.U
}
}
// $onehot0 output encoding check
assert (PopCount(io.sel) >= 1.U, "Invalid addr decoding")
}
我得到一个编译错误:
[error] found : math.BigInt.type
[error] required: (?, ?)
[error] val mmap = Map(BigInt, BigInt) // base, size ranges
...
[error] found : chisel3.core.Bool
[error] required: Seq[?]
[error] val sel = Output(Bool():_*) // $onehot0 selector
我可以使用Map和可变的Bool数组作为IO端口吗?如果没有,该如何正确重写?
谢谢!
答案 0 :(得分:1)
好的,这是我的解决方案。不是通用的,因为我无法将其专门用于BigInt,但是现在对我有用:
class AddrDecoder (addrWidth:Int, mmap:Map[UInt, UInt]) extends Module {
val size = mmap.size
val io = IO (new Bundle {
val addr = Input (UInt(addrWidth.W))
val en = Input (Bool())
val sel = Output(Vec(size,Bool())) // $onehot0 selector
})
// Curried function which accepts a tuple and an input addr
def inside (range:(UInt,UInt))(addr:UInt):Bool = {
addr >= range._1 && addr < range._1 + range._2
}
// MUX output
for (i <- 0 until size) {
io.sel(i) := false.B
}
// Loop thru the Memory Map, pair with index and evaluate logic value for io.sel
mmap.zipWithIndex foreach { case (entry,idx) =>
when (io.en && inside(entry)(io.addr)) {
io.sel(idx) := true.B
} .otherwise {
io.sel(idx) := false.B
}
}
// $onehot0 output encoding check
assert (PopCount(io.sel) <= 1.U, "Invalid addr decoding")
}