Skip to content

Commit 1b7f6e8

Browse files
committed
[internal] Add Builder state save/restore fns
Add the ability to save and restore the Builder state in a sane way. This is intended for advanced generator APIs that want to create hardware in another location and need to change the Builder state to something else temporarily. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 1eaaa91 commit 1b7f6e8

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

core/src/main/scala/chisel3/internal/Builder.scala

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)