@@ -1199,6 +1199,85 @@ private[chisel3] object Builder extends LazyLogging {
11991199 }
12001200
12011201 initializeSingletons()
1202+
1203+ /** The representation of the state of the [[Builder ]] at a current point in
1204+ * time. This is intended to capture _enough_ information to insert hardware
1205+ * at another point in the circuit.
1206+ *
1207+ * @see [[chisel3.Placeholder ]]
1208+ */
1209+ case class State (
1210+ currentModule : Option [BaseModule ],
1211+ whenStack : List [WhenContext ],
1212+ blockStack : List [Block ],
1213+ layerStack : List [layer.Layer ],
1214+ prefix : Prefix ,
1215+ clock : Option [Delayed [Clock ]],
1216+ reset : Option [Delayed [Reset ]],
1217+ enabledLayers : List [layer.Layer ]
1218+ )
1219+
1220+ object State {
1221+
1222+ /** Return a [[State ]] suitable for doing module construction.
1223+ */
1224+ def default : State = State (
1225+ currentModule = Builder .currentModule,
1226+ whenStack = Nil ,
1227+ blockStack = Builder .blockStack,
1228+ layerStack = layer.Layer .Root :: Nil ,
1229+ prefix = Nil ,
1230+ clock = None ,
1231+ reset = None ,
1232+ enabledLayers = Nil
1233+ )
1234+
1235+ /** Capture the current [[Builder ]] state.
1236+ */
1237+ def save : State = {
1238+ State (
1239+ currentModule = Builder .currentModule,
1240+ whenStack = Builder .whenStack,
1241+ blockStack = Builder .blockStack,
1242+ layerStack = Builder .layerStack,
1243+ prefix = Builder .getPrefix,
1244+ clock = Builder .currentClockDelayed,
1245+ reset = Builder .currentResetDelayed,
1246+ enabledLayers = Builder .enabledLayers.toList
1247+ )
1248+ }
1249+
1250+ /** Set the [[Builder ]] state to that provided by the parameter.
1251+ *
1252+ * @param state the state to set the [[Builder ]] to
1253+ */
1254+ def restore (state : State ) = {
1255+ Builder .currentModule = state.currentModule
1256+ Builder .whenStack = state.whenStack
1257+ Builder .blockStack = state.blockStack
1258+ Builder .layerStack = state.layerStack
1259+ Builder .setPrefix(state.prefix)
1260+ Builder .currentClock = state.clock
1261+ Builder .currentReset = state.reset
1262+ Builder .enabledLayers = enabledLayers
1263+ }
1264+
1265+ /** Run the `thunk` with the context provided by `state`. Save the [[Builder ]]
1266+ * state before the thunk and restore it afterwards.
1267+ *
1268+ * @param state change the [[Builder ]] to this state when running the thunk
1269+ * @param thunk some hardware to generate
1270+ * @return whatever the `thunk` returns
1271+ */
1272+ def guard [A ](state : State )(thunk : => A ): A = {
1273+ val old = save
1274+ restore(state)
1275+ val result = thunk
1276+ restore(old)
1277+ result
1278+ }
1279+
1280+ }
12021281}
12031282
12041283/** Allows public access to the naming stack in Builder / DynamicContext, and handles invocations
0 commit comments