Make BusErrorUnit support 32-bit stores
Otherwise it isn't too useful for RV32!
This commit is contained in:
		| @@ -44,35 +44,43 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit | |||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     val sources = io.errors.toErrorList |     val sources = io.errors.toErrorList | ||||||
|     val mask = sources.map(_.nonEmpty.B).asUInt |  | ||||||
|     val cause = Reg(init = UInt(0, log2Ceil(sources.lastIndexWhere(_.nonEmpty) + 1))) |     val cause = Reg(init = UInt(0, log2Ceil(sources.lastIndexWhere(_.nonEmpty) + 1))) | ||||||
|     val value = Reg(UInt(width = sources.flatten.map(_.bits.getWidth).max)) |     val value = Reg(UInt(width = sources.flatten.map(_.bits.getWidth).max)) | ||||||
|     require(value.getWidth <= regWidth) |     require(value.getWidth <= regWidth) | ||||||
|     val enable = Reg(init = mask) |     val enable = Reg(init = Vec(sources.map(_.nonEmpty.B))) | ||||||
|     val interrupt = Reg(init = UInt(0, sources.size)) |     val interrupt = Reg(init = Vec.fill(sources.size)(false.B)) | ||||||
|     val accrued = Reg(init = UInt(0, sources.size)) |     val accrued = Reg(init = Vec.fill(sources.size)(false.B)) | ||||||
|  |  | ||||||
|     accrued := accrued | sources.map(_.map(_.valid).getOrElse(false.B)).asUInt |     for ((((s, en), acc), i) <- (sources zip enable zip accrued).zipWithIndex; if s.nonEmpty) { | ||||||
|  |       when (s.get.valid) { | ||||||
|     for ((s, i) <- sources.zipWithIndex; if s.nonEmpty) { |         acc := true | ||||||
|       when (s.get.valid && enable(i) && cause === 0) { |         when (en && cause === 0) { | ||||||
|           cause := i |           cause := i | ||||||
|           value := s.get.bits |           value := s.get.bits | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     val (int_out, _) = intNode.out(0) |     val (int_out, _) = intNode.out(0) | ||||||
|     io.interrupt := (accrued & interrupt).orR |     io.interrupt := (accrued.asUInt & interrupt.asUInt).orR | ||||||
|     int_out(0) := io.interrupt |     int_out(0) := io.interrupt | ||||||
|  |  | ||||||
|     def reg(r: UInt) = RegField(regWidth, r) |     def reg(r: UInt) = RegField.bytes(r, (r.getWidth + 7)/8) | ||||||
|     def maskedReg(r: UInt, m: UInt) = RegField(regWidth, r, RegWriteFn((v, d) => { when (v) { r := d & m }; true })) |     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( |     node.regmap(numberRegs(Seq( | ||||||
|       0 -> Seq(reg(cause), |       reg(cause), | ||||||
|       reg(value), |       reg(value), | ||||||
|                maskedReg(enable, mask), |       reg(enable), | ||||||
|                maskedReg(interrupt, mask), |       reg(interrupt), | ||||||
|                maskedReg(accrued, mask))) |       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 | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user