Skip to content

Commit 0ee2dc8

Browse files
Optimize .readOnly to only create views when necessary (#4271) (#4273)
(cherry picked from commit 478eaef) Co-authored-by: Jack Koenig <koenig@sifive.com>
1 parent db47e0d commit 0ee2dc8

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

core/src/main/scala/chisel3/Data.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,12 @@ object Data {
10151015
* This Data this method is called on must be a hardware type.
10161016
*/
10171017
def readOnly(implicit sourceInfo: SourceInfo): T = {
1018-
self.viewAsReadOnly(_ => "Cannot connect to read-only value")
1018+
val alreadyReadOnly = self.isLit || self.topBindingOpt.exists(_.isInstanceOf[ReadOnlyBinding])
1019+
if (alreadyReadOnly) {
1020+
self
1021+
} else {
1022+
self.viewAsReadOnly(_ => "Cannot connect to read-only value")
1023+
}
10191024
}
10201025
}
10211026
}

src/test/scala/chiselTests/ReadOnlySpec.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import chisel3.probe._
99
import chisel3.properties._
1010
import chisel3.experimental.SourceInfo
1111
import chisel3.experimental.dataview._
12+
import chisel3.experimental.BundleLiterals._
13+
import chisel3.experimental.VecLiterals._
1214

1315
import org.scalactic.source.Position
1416

@@ -364,4 +366,31 @@ class ReadOnlySpec extends ChiselFlatSpec with Utils {
364366
})
365367
}
366368
}
369+
370+
it should "NOT create a view for literals" in {
371+
ChiselStage.emitCHIRRTL(new RawModule {
372+
val a = 123.U
373+
val b = -27.S
374+
val c = (new BiggerBundle).Lit(_.fizz -> 123.U, _.buzz -> 456.U)
375+
val d = Vec.Lit(0.U, 23.U)
376+
// Use referential equality to check they are the same objects (no view introduced)
377+
assert(a.readOnly eq a)
378+
assert(b.readOnly eq b)
379+
assert(c.readOnly eq c)
380+
assert(d.readOnly eq d)
381+
})
382+
}
383+
384+
it should "NOT create a view for op results" in {
385+
ChiselStage.emitCHIRRTL(new RawModule {
386+
val a = IO(Input(UInt(8.W)))
387+
val b = IO(Input(new BiggerBundle))
388+
389+
val x = a + 1.U
390+
val y = b.asUInt
391+
// Use referential equality to check they are the same objects (no view introduced)
392+
assert(x.readOnly eq x)
393+
assert(y.readOnly eq y)
394+
})
395+
}
367396
}

0 commit comments

Comments
 (0)