1
0

regmapper: fix d_ready => d_bits loop in RegField.bytes

RegField.bytes updates only those bytes which are written every cycle.
However, there was a bug that it would try to return the updated value on reads.
This led to another TL-spec violating combinational path, just like the Debug module.
This commit is contained in:
Wesley W. Terpstra 2017-11-30 16:38:45 -08:00
parent fc1f5be316
commit 35506279af

View File

@ -113,13 +113,15 @@ object RegField
// 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): Seq[RegField] = { def bytes(reg: UInt, numBytes: Int): Seq[RegField] = {
val pad = reg | UInt(0, width = 8*numBytes) val pad = reg | UInt(0, width = 8*numBytes)
val bytes = Wire(init = 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 valids = Wire(init = Vec.fill(numBytes) { Bool(false) }) val valids = Wire(init = Vec.fill(numBytes) { Bool(false) })
when (valids.reduce(_ || _)) { reg := bytes.asUInt } when (valids.reduce(_ || _)) { reg := newBytes.asUInt }
bytes.zipWithIndex.map { case (b, i) => RegField(8, b, Seq.tabulate(numBytes) { i =>
RegWriteFn((valid, data) => { RegField(8, oldBytes(i),
RegWriteFn((valid, data) => {
valids(i) := valid valids(i) := valid
when (valid) { bytes(i) := data } when (valid) { newBytes(i) := data }
Bool(true) Bool(true)
}))}} }))}}