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:
parent
0fcacd37df
commit
e0c3c63826
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user