diff --git a/src/main/scala/rocket/BusErrorUnit.scala b/src/main/scala/rocket/BusErrorUnit.scala index b2b95d2a..2c0d6e42 100644 --- a/src/main/scala/rocket/BusErrorUnit.scala +++ b/src/main/scala/rocket/BusErrorUnit.scala @@ -44,35 +44,43 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit }) val sources = io.errors.toErrorList - val mask = sources.map(_.nonEmpty.B).asUInt val cause = Reg(init = UInt(0, log2Ceil(sources.lastIndexWhere(_.nonEmpty) + 1))) val value = Reg(UInt(width = sources.flatten.map(_.bits.getWidth).max)) require(value.getWidth <= regWidth) - val enable = Reg(init = mask) - val interrupt = Reg(init = UInt(0, sources.size)) - val accrued = Reg(init = UInt(0, sources.size)) + val enable = Reg(init = Vec(sources.map(_.nonEmpty.B))) + val interrupt = Reg(init = Vec.fill(sources.size)(false.B)) + val accrued = Reg(init = Vec.fill(sources.size)(false.B)) - accrued := accrued | sources.map(_.map(_.valid).getOrElse(false.B)).asUInt - - for ((s, i) <- sources.zipWithIndex; if s.nonEmpty) { - when (s.get.valid && enable(i) && cause === 0) { - cause := i - value := s.get.bits + for ((((s, en), acc), i) <- (sources zip enable zip accrued).zipWithIndex; if s.nonEmpty) { + when (s.get.valid) { + acc := true + when (en && cause === 0) { + cause := i + value := s.get.bits + } } } val (int_out, _) = intNode.out(0) - io.interrupt := (accrued & interrupt).orR + io.interrupt := (accrued.asUInt & interrupt.asUInt).orR int_out(0) := io.interrupt - def reg(r: UInt) = RegField(regWidth, r) - def maskedReg(r: UInt, m: UInt) = RegField(regWidth, r, RegWriteFn((v, d) => { when (v) { r := d & m }; true })) + def reg(r: UInt) = RegField.bytes(r, (r.getWidth + 7)/8) + def reg(v: Vec[Bool]) = v.map(r => RegField(1, r)) + def numberRegs(x: Seq[Seq[RegField]]) = x.zipWithIndex.map { case (f, i) => (i * regWidth / 8) -> f } - node.regmap( - 0 -> Seq(reg(cause), - reg(value), - maskedReg(enable, mask), - maskedReg(interrupt, mask), - maskedReg(accrued, mask))) + node.regmap(numberRegs(Seq( + reg(cause), + reg(value), + reg(enable), + reg(interrupt), + reg(accrued))):_*) + + // hardwire mask bits for unsupported sources to 0 + for ((s, i) <- sources.zipWithIndex; if s.isEmpty) { + enable(i) := false + interrupt(i) := false + accrued(i) := false + } } }