2

我正在用 Chisel 编写一个中断控制器。

以下函数确定最高优先级的挂起中断。每个中断源由 a 表示,IRQStatusReg组合的寄存器文件是 Chisel Vec。为了确定具有最高优先级的中断,使用递归分治策略。在硬件中,这应该被合成为多路复用器树。返回的元组包含寄存器及其 ID。

def select_highest_prio_irq(vec: Vec[IRQStatusReg], start: Int, len: Int) : (IRQStatusReg, UInt) = {
    if(len == 1){
        return (vec(start), UInt(width=0))
    }
   else{
       val left_len = len / 2
       val right_len = len - left_len
       val (left, l0) = select_highest_prio_irq(vec, start, left_len)
       val (right, r0) = select_highest_prio_irq(vec, start+ left_len, right_len)
       val select_left = left.irq_pending && !left.irq_masked && left.irq_prio > right.irq_prio
       printf("val: %x\n", select_left)
       printf("expr: %x\n", left.irq_pending && !left.irq_masked && left.irq_prio > right.irq_prio)
       (Mux(select_left, left, right), 
        Cat(!select_left, Mux(select_left, l0, r0)))  
    }
 } 

val (highest_prio_reg, irq_nr) = select_highest_prio_irq(irq_status_regfile, 0, intSources)

但是,当使用某些寄存器配置和 4 个中断源时,此函数无法确定正确的结果。原因在于对 select_left 的赋值:右侧表达式的值与赋值后 select_left 的值不同(见第 3/4 行):

val:0
expr: 0
val:0
expr: 1
val: 1
expr: 1

这怎么可能?赋值后 val 如何具有与表达式不同的值?

作为参考,这里是 IRQStatusReg Vec 的定义:

class IRQStatusReg(priorityLevels: Int) extends Bundle {
  val irq_prio = UInt(width = log2Up(priorityLevels))
  val irq_masked = Bool()
  val irq_pending = Bool()
  override def cloneType: this.type =
      new IRQStatusReg(priorityLevels).asInstanceOf[this.type]
}
 val irq_status_regfile = Reg(init = Vec(intSources, new IRQStatusReg(priorityLevels)))
4

0 回答 0