1
0

RegFieldDesc: Update the .bytes method to emit reserved register fields

instead of applying the same description to the registers that it doesn't
actually do anything with (the padding registers)
This commit is contained in:
Megan Wachs 2018-03-09 15:10:43 -08:00
parent 0fcacd37df
commit e0c3c63826

View File

@ -173,23 +173,38 @@ object RegField
}), desc) }), desc)
// Create byte-sized read-write RegFields out of a large UInt register. // Create byte-sized read-write RegFields out of a large UInt register.
// It is updated when any of the bytes are written. Because the RegFields // It is updated when any of the (implemented) bytes are written, the non-written
// are all byte-sized, this is also suitable when a register is larger // bytes are just copied over from their current value.
// Because the RegField are all byte-sized, this is also suitable when a register is larger
// than the intended bus width of the device (atomic updates are impossible). // than the intended bus width of the device (atomic updates are impossible).
def bytes(reg: UInt, numBytes: Int, desc: Option[RegFieldDesc]): Seq[RegField] = { def bytes(reg: UInt, numBytes: Int, desc: Option[RegFieldDesc]): Seq[RegField] = {
require(reg.getWidth * 8 >= numBytes, "Can't break a ${reg.getWidth}-bit-wide register into only ${numBytes} bytes.")
val numFullBytes = reg.getWidth/8
val numPartialBytes = if ((reg.getWidth % 8) > 0) 1 else 0
val numPadBytes = numBytes - numFullBytes - numPartialBytes
val pad = reg | UInt(0, width = 8*numBytes) val pad = reg | UInt(0, width = 8*numBytes)
val oldBytes = Vec.tabulate(numBytes) { i => pad(8*(i+1)-1, 8*i) } val oldBytes = Vec.tabulate(numBytes) { i => pad(8*(i+1)-1, 8*i) }
val newBytes = Wire(init = oldBytes) val newBytes = Wire(init = oldBytes)
val valids = Wire(init = Vec.fill(numBytes) { Bool(false) }) val valids = Wire(init = Vec.fill(numBytes) { Bool(false) })
when (valids.reduce(_ || _)) { reg := newBytes.asUInt } when (valids.reduce(_ || _)) { reg := newBytes.asUInt }
Seq.tabulate(numBytes) { i =>
val newDesc = desc.map {d => d.copy(name = d.name + s"_$i")} def wrFn(i: Int): RegWriteFn = RegWriteFn((valid, data) => {
RegField(8, oldBytes(i),
RegWriteFn((valid, data) => {
valids(i) := valid valids(i) := valid
when (valid) {newBytes(i) := data} when (valid) {newBytes(i) := data}
Bool(true) Bool(true)
}), newDesc)}} })
val fullBytes = Seq.tabulate(numFullBytes) { i =>
val newDesc = desc.map {d => d.copy(name = d.name + s"_$i")}
RegField(8, oldBytes(i), wrFn(i), newDesc)}
val partialBytes = if (numPartialBytes > 0) {
val newDesc = desc.map {d => d.copy(name = d.name + s"_$numFullBytes")}
Seq(RegField(reg.getWidth % 8, oldBytes(numFullBytes), wrFn(numFullBytes), newDesc),
RegField(8 - (reg.getWidth % 8)))
} else Nil
val padBytes = Seq.fill(numPadBytes){RegField(8)}
fullBytes ++ partialBytes ++ padBytes
}
def bytes(reg: UInt, desc: Option[RegFieldDesc]): Seq[RegField] = { def bytes(reg: UInt, desc: Option[RegFieldDesc]): Seq[RegField] = {
val width = reg.getWidth val width = reg.getWidth