processSsa method
override
Given existing currentMappings
, connects drivers and receivers
accordingly to SsaLogic
s and returns an updated set of mappings.
This function may add new Conditionals to existing Conditionals.
This is used for Combinational.ssa.
Implementation
@override
Map<Logic, Logic> processSsa(Map<Logic, Logic> currentMappings,
{required int context}) {
// add an empty else if there isn't already one, since we need it for phi
if (iffs.last is! Else) {
iffs.add(Else([]));
}
// first connect direct drivers into the if statements
for (final iff in iffs) {
Conditional.connectSsaDriverFromMappings(iff.condition, currentMappings,
context: context);
}
// calculate mappings locally within each if statement
final phiMappings = <Logic, Logic>{};
for (final conditionals in iffs.map((e) => e.then)) {
var localMappings = {...currentMappings};
for (final conditional in conditionals) {
localMappings = conditional.processSsa(localMappings, context: context);
}
for (final localMapping in localMappings.entries) {
if (!phiMappings.containsKey(localMapping.key)) {
phiMappings[localMapping.key] = Logic(
name: '${localMapping.key.name}_phi',
width: localMapping.key.width,
naming: Naming.mergeable,
);
}
conditionals.add(phiMappings[localMapping.key]! < localMapping.value);
}
}
final newMappings = <Logic, Logic>{...currentMappings}..addAll(phiMappings);
// find all the SSA signals that are driven by anything in this if block,
// since we need to ensure every case drives them or else we may create
// an inferred latch
final signalsNeedingInit = iffs
.map((e) => e.then)
.flattened
.map((e) => e.calculateReceivers())
.flattened
.whereType<SsaLogic>()
.toSet();
for (final iff in iffs) {
final alreadyDrivenSsaSignals = iff.then
.map((e) => e.calculateReceivers())
.flattened
.whereType<SsaLogic>()
.toSet();
for (final signalNeedingInit in signalsNeedingInit) {
if (!alreadyDrivenSsaSignals.contains(signalNeedingInit)) {
iff.then.add(signalNeedingInit < 0);
}
}
}
return newMappings;
}