1
0
Fork 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
1 changed files with 25 additions and 10 deletions

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] = {
val pad = reg | UInt(0, width = 8*numBytes) 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 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 =>
def wrFn(i: Int): RegWriteFn = RegWriteFn((valid, data) => {
valids(i) := valid
when (valid) {newBytes(i) := data}
Bool(true)
})
val fullBytes = Seq.tabulate(numFullBytes) { i =>
val newDesc = desc.map {d => d.copy(name = d.name + s"_$i")} val newDesc = desc.map {d => d.copy(name = d.name + s"_$i")}
RegField(8, oldBytes(i), RegField(8, oldBytes(i), wrFn(i), newDesc)}
RegWriteFn((valid, data) => { val partialBytes = if (numPartialBytes > 0) {
valids(i) := valid val newDesc = desc.map {d => d.copy(name = d.name + s"_$numFullBytes")}
when (valid) { newBytes(i) := data } Seq(RegField(reg.getWidth % 8, oldBytes(numFullBytes), wrFn(numFullBytes), newDesc),
Bool(true) RegField(8 - (reg.getWidth % 8)))
}), newDesc)}} } 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