Универсальный декодер адресов - PullRequest
0 голосов
/ 13 января 2019

Я хотел бы реализовать универсальный addr-декодер. Это следующий вопрос к этому сообщению .

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 в качестве портов ввода-вывода? Если нет, то как правильно переписать это?

Спасибо!

1 Ответ

0 голосов
/ 13 января 2019

Хорошо, вот мое решение. Не такой общий, так как я не мог специализировать его на 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")
}
...