@@ -3,11 +3,27 @@ package chisel3.simulator
33import svsim ._
44import chisel3 ._
55
6+ import chisel3 .experimental .{SourceInfo , SourceLine , UnlocatableSourceInfo }
7+ import chisel3 .internal .ExceptionHelpers
8+
69object PeekPokeAPI extends PeekPokeAPI
710
811trait PeekPokeAPI {
912 case class FailedExpectationException [T ](observed : T , expected : T , message : String )
1013 extends Exception (s " Failed Expectation: Observed value ' $observed' != $expected. $message" )
14+ object FailedExpectationException {
15+ def apply [T ](
16+ observed : T ,
17+ expected : T ,
18+ message : String ,
19+ sourceInfo : SourceInfo ,
20+ extraContext : Seq [String ]
21+ ): FailedExpectationException [T ] = {
22+ val fullMessage = s " $message ${sourceInfo.makeMessage(x => x)}" +
23+ (if (extraContext.nonEmpty) s " \n ${extraContext.mkString(" \n " )}" else " " )
24+ new FailedExpectationException (observed, expected, fullMessage)
25+ }
26+ }
1127
1228 implicit class testableClock (clock : Clock ) {
1329 def step (cycles : Int = 1 ): Unit = {
@@ -56,25 +72,47 @@ trait PeekPokeAPI {
5672 }
5773
5874 final def peek (): T = encode(data.peekValue())
59- final def expect (expected : T ): Unit = {
75+ // Added for binary compatibility, not callable directly but can be called if compiled against old Chisel
76+ private [simulator] final def expect (expected : T ): Unit = _expect(expected, UnlocatableSourceInfo )
77+ final def expect (expected : T )(implicit sourceInfo : SourceInfo ): Unit = _expect(expected, sourceInfo)
78+ // Added to avoid ambiguity errors when using binary compatibility shim
79+ private def _expect (expected : T , sourceInfo : SourceInfo ): Unit = {
6080 data.expect(
6181 expected.litValue,
6282 encode(_).litValue,
63- (observed : BigInt , expected : BigInt ) => s " Expectation failed: observed value $observed != $expected"
83+ (observed : BigInt , expected : BigInt ) => s " Expectation failed: observed value $observed != $expected" ,
84+ sourceInfo
6485 )
6586 }
66- final def expect (expected : T , message : String ): Unit = {
67- data.expect(expected.litValue, encode(_).litValue, (_ : BigInt , _ : BigInt ) => message)
87+ // Added for binary compatibility, not callable directly but can be called if compiled against old Chisel
88+ private [simulator] def expect (expected : T , message : String ): Unit =
89+ _expect(expected, message, UnlocatableSourceInfo )
90+ final def expect (expected : T , message : String )(implicit sourceInfo : SourceInfo ): Unit =
91+ _expect(expected, message, sourceInfo)
92+ // Added to avoid ambiguity errors when using binary compatibility shim
93+ private def _expect (expected : T , message : String , sourceInfo : SourceInfo ): Unit = {
94+ data.expect(expected.litValue, encode(_).litValue, (_ : BigInt , _ : BigInt ) => message, sourceInfo)
6895 }
69- final def expect (expected : BigInt ): Unit = {
96+ // Added for binary compatibility, not callable directly but can be called if compiled against old Chisel
97+ private [simulator] def expect (expected : BigInt ): Unit = _expect(expected, UnlocatableSourceInfo )
98+ final def expect (expected : BigInt )(implicit sourceInfo : SourceInfo ): Unit = _expect(expected, sourceInfo)
99+ // Added to avoid ambiguity errors when using binary compatibility shim
100+ private def _expect (expected : BigInt , sourceInfo : SourceInfo ): Unit = {
70101 data.expect(
71102 expected,
72103 _.asBigInt,
73- (observed : BigInt , expected : BigInt ) => s " Expectation failed: observed value $observed != $expected"
104+ (observed : BigInt , expected : BigInt ) => s " Expectation failed: observed value $observed != $expected" ,
105+ sourceInfo
74106 )
75107 }
76- final def expect (expected : BigInt , message : String ): Unit = {
77- data.expect(expected, _.asBigInt, (_ : BigInt , _ : BigInt ) => message)
108+ // Added for binary compatibility, not callable directly but can be called if compiled against old Chisel
109+ private [simulator] def expect (expected : BigInt , message : String ): Unit =
110+ _expect(expected, message, UnlocatableSourceInfo )
111+ final def expect (expected : BigInt , message : String )(implicit sourceInfo : SourceInfo ): Unit =
112+ _expect(expected, message, sourceInfo)
113+ // Added to avoid ambiguity errors when using binary compatibility shim
114+ private def _expect (expected : BigInt , message : String , sourceInfo : SourceInfo ): Unit = {
115+ data.expect(expected, _.asBigInt, (_ : BigInt , _ : BigInt ) => message, sourceInfo)
78116 }
79117
80118 }
@@ -122,17 +160,40 @@ trait PeekPokeAPI {
122160 val simulationPort = module.port(data)
123161 simulationPort.get(isSigned = isSigned)
124162 }
163+ @ deprecated(" Use version that takes a SourceInfo" , " Chisel 6.5.0" )
125164 def expect [T ](
126165 expected : T ,
127166 encode : (Simulation .Value ) => T ,
128167 buildMessage : (T , T ) => String
168+ ): Unit = expect(expected, encode, buildMessage)
169+ def expect [T ](
170+ expected : T ,
171+ encode : (Simulation .Value ) => T ,
172+ buildMessage : (T , T ) => String ,
173+ sourceInfo : SourceInfo
129174 ): Unit = {
130175 val module = AnySimulatedModule .current
131176 module.willPeek()
132177 val simulationPort = module.port(data)
178+
133179 simulationPort.check(isSigned = isSigned) { observedValue =>
134180 val observed = encode(observedValue)
135- if (observed != expected) throw FailedExpectationException (observed, expected, buildMessage(observed, expected))
181+ if (observed != expected) {
182+ val extraContext =
183+ sourceInfo match {
184+ case sl : SourceLine =>
185+ ExceptionHelpers .getErrorLineInFile(Seq (), sl)
186+ case _ =>
187+ Seq ()
188+ }
189+ throw FailedExpectationException (
190+ observed,
191+ expected,
192+ buildMessage(observed, expected),
193+ sourceInfo,
194+ extraContext
195+ )
196+ }
136197 }
137198 }
138199 }
0 commit comments