Chisel で割り込みコントローラを作成しています。
次の関数は、最も優先度の高い保留中の割り込みを決定します。各割り込みソースは で表されIRQStatusReg
、組み合わされたレジスタ ファイルは ChiselVec
です。最も優先度の高い割り込みを決定するために、再帰的な分割統治戦略が使用されます。ハードウェアでは、これをマルチプレクサのツリーとして合成する必要があります。返されるタプルには、レジスターとその 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)))