import net.mograsim.logic.model.verilog.converter.VerilogEmulatedModelPin.Type;
import net.mograsim.logic.model.verilog.helper.IdentifierGenerator;
import net.mograsim.logic.model.verilog.helper.UnionFind;
-import net.mograsim.logic.model.verilog.helper.UnionFind.UnionFindElement;
import net.mograsim.logic.model.verilog.model.Assign;
import net.mograsim.logic.model.verilog.model.ComponentReference;
import net.mograsim.logic.model.verilog.model.Constant;
"Can only convert SubmodelComponents, tried to convert " + modelID + " with params " + params);
SubmodelComponent modelComponentC = (SubmodelComponent) modelComponent;
- ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponentC, modelID, params);
+ UnionFind<PinBit> connectedPins = findConnectedPins(modelComponentC);
+
+ ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponentC, connectedPins, modelID, params);
componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, mapping);
for (ModelComponent subcomponent : modelComponentC.submodel.getComponentsByName().values())
- if (!subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
+ if (!(subcomponent instanceof ModelSplitter) && !subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
convert(subcomponent);
- verilogComponents.add(mapImplementation(modelComponentC, mapping));
+ verilogComponents.add(mapImplementation(modelComponentC, connectedPins, mapping));
+ }
+
+ private static UnionFind<PinBit> findConnectedPins(SubmodelComponent modelComponent)
+ {
+ UnionFind<PinBit> connectedPins = new UnionFind<>();
+ for (ModelWire w : modelComponent.submodel.getWiresByName().values())
+ for (int bit = 0; bit < w.getPin1().logicWidth; bit++)
+ connectedPins.union(new PinBit(w.getPin1(), bit), new PinBit(w.getPin2(), bit));
+
+ for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
+ if (subcomponent instanceof ModelSplitter)
+ {
+ ModelSplitter splitter = (ModelSplitter) subcomponent;
+ for (int bit = 0; bit < splitter.logicWidth; bit++)
+ connectedPins.union(new PinBit(splitter.getInputPin(), bit), new PinBit(splitter.getOutputPin(bit), 0));
+ }
+
+ // TODO connected pins of subcomponents
+
+ return connectedPins;
}
- private ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(ModelComponent modelComponent, String modelID,
- JsonElement params)
+ private ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(SubmodelComponent modelComponent,
+ UnionFind<PinBit> connectedPins, String modelID, JsonElement params)
{
- return generateCanonicalDeclarationMapping(modelComponent, modelID, params,
+ // TODO this is probably slow
+ Map<PinBit, PinNameBit> representantMapping = new HashMap<>();
+ UnionFind<PinNameBit> connectedPinsByName = new UnionFind<>();
+ for (Pin p : modelComponent.getSubmodelPins().values())
+ for (int bit = 0; bit < p.logicWidth; bit++)
+ {
+ PinNameBit pinnamebit = new PinNameBit(p.name, bit);
+ PinNameBit representative = representantMapping.computeIfAbsent(connectedPins.find(new PinBit(p, bit)), q -> pinnamebit);
+ connectedPinsByName.union(pinnamebit, representative);
+ }
+
+ return generateCanonicalDeclarationMapping(modelComponent, connectedPinsByName, modelID, params,
verilogComponentIDGen.generateID(verilogComponentIDPrefix + modelID + (params.isJsonNull() ? "" : "_" + params)));
}
public static ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping(ModelComponent modelComponent,
- String modelID, JsonElement params, String verilogID)
+ UnionFind<PinNameBit> connectedPins, String modelID, JsonElement params, String verilogID)
{
IdentifierGenerator ioPortIDGen = new IdentifierGenerator(ModelComponentToVerilogConverter::sanitizeVerilogID);
List<IOPort> ioPorts = new ArrayList<>();
- Set<VerilogEmulatedModelPin> pinMapping = new HashSet<>();
+ Map<Type, Map<PinNameBit, VerilogEmulatedModelPinBuilder>> pinMapping = new HashMap<>();
+ for (Type t : Type.values())
+ pinMapping.put(t, new HashMap<>());
for (Pin modelPin : modelComponent.getPins().values())
for (int bit = 0; bit < modelPin.logicWidth; bit++)
{
- addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Input::new, Type.PRE, "pre");
- addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Output::new, Type.OUT, "out");
- addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Input::new, Type.RES, "res");
+ PinNameBit pinbit = new PinNameBit(modelPin.name, bit);
+ addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Input::new, Type.PRE, "pre");
+ addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Output::new, Type.OUT, "out");
+ addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Input::new, Type.RES, "res");
}
VerilogComponentDeclaration declaration = new VerilogComponentDeclaration(verilogID, ioPorts);
- return new ModelComponentToVerilogComponentDeclarationMapping(modelID, params, declaration, pinMapping);
+ Set<VerilogEmulatedModelPin> finalPinMapping = pinMapping.values().stream().map(Map::values).flatMap(Collection::stream)
+ .map(VerilogEmulatedModelPinBuilder::build).collect(Collectors.toSet());
+ return new ModelComponentToVerilogComponentDeclarationMapping(modelID, params, declaration, finalPinMapping);
}
- private static void addPinMapping(IdentifierGenerator ioPortIDGen, List<IOPort> ioPorts, Set<VerilogEmulatedModelPin> pinMapping,
- Pin modelPin, int bit, BiFunction<String, Integer, IOPort> constr, Type type, String suffix)
+ private static void addPinMapping(IdentifierGenerator ioPortIDGen, List<IOPort> ioPorts, UnionFind<PinNameBit> connectedPins,
+ Map<Type, Map<PinNameBit, VerilogEmulatedModelPinBuilder>> pinMapping, PinNameBit pinbit,
+ BiFunction<String, Integer, IOPort> constr, Type type, String suffix)
{
- String portID = ioPortIDGen.generateID(modelPin.name + "_" + bit + "_" + suffix);
- IOPort ioPort = constr.apply(portID, 2);
- int index = ioPorts.size();
- ioPorts.add(ioPort);
- pinMapping.add(new VerilogEmulatedModelPin(ioPort, index, new PinNameBit(modelPin.name, bit), type));
+ Map<PinNameBit, VerilogEmulatedModelPinBuilder> pinMappingCorrectType = pinMapping.get(type);
+ pinMappingCorrectType.computeIfAbsent(connectedPins.find(pinbit), p ->
+ {
+ String portID = ioPortIDGen.generateID(p.getName() + "_" + p.getBit() + "_" + suffix);
+ IOPort ioPort = constr.apply(portID, 2);
+ int index = ioPorts.size();
+ ioPorts.add(ioPort);
+ return new VerilogEmulatedModelPinBuilder(ioPort, index, type);
+ }).addPinbit(pinbit);
}
- private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent,
- ModelComponentToVerilogComponentDeclarationMapping declarationMapping)
+ private static class VerilogEmulatedModelPinBuilder
{
- UnionFind<PinBit> connectedPins = new UnionFind<>();
- for (ModelWire w : modelComponent.submodel.getWiresByName().values())
- for (int bit = 0; bit < w.getPin1().logicWidth; bit++)
- connectedPins.union(new PinBit(w.getPin1(), bit), new PinBit(w.getPin2(), bit));
+ private final IOPort verilogPort;
+ private final int portIndex;
+ private final Set<PinNameBit> pinbits;
+ private final Type type;
- Map<UnionFindElement<PinBit>, Signal> currentPreSignals = new HashMap<>();
- Map<UnionFindElement<PinBit>, NamedSignal> finalOutSignals = new HashMap<>();
- Map<UnionFindElement<PinBit>, NamedSignal> resSignals = new HashMap<>();
+ public VerilogEmulatedModelPinBuilder(IOPort verilogPort, int portIndex, Type type)
+ {
+ this.verilogPort = verilogPort;
+ this.portIndex = portIndex;
+ this.pinbits = new HashSet<>();
+ this.type = type;
+ }
+
+ public void addPinbit(PinNameBit pinbit)
+ {
+ pinbits.add(pinbit);
+ }
+
+ public VerilogEmulatedModelPin build()
+ {
+ return new VerilogEmulatedModelPin(verilogPort, portIndex, pinbits, type);
+ }
+ }
+
+ private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, UnionFind<PinBit> connectedPins,
+ ModelComponentToVerilogComponentDeclarationMapping declarationMapping)
+ {
+ Map<PinBit, Signal> currentPreSignals = new HashMap<>();
+ Map<PinBit, NamedSignal> finalOutSignals = new HashMap<>();
+ Map<PinBit, NamedSignal> resSignals = new HashMap<>();
for (Pin submodelPin : modelComponent.getSubmodelPins().values())
for (int bit = 0; bit < submodelPin.logicWidth; bit++)
{
PinBit pinbit = new PinBit(submodelPin, bit);
PinNameBit pinnamebit = pinbit.toPinNameBit();
- UnionFindElement<PinBit> root = UnionFind.find(connectedPins.getElement(pinbit));
+ PinBit root = connectedPins.find(pinbit);
resSignals.put(root, declarationMapping.getResPinMapping().get(pinnamebit).getVerilogPort());
finalOutSignals.put(root, declarationMapping.getOutPinMapping().get(pinnamebit).getVerilogPort());
Signal prePort = declarationMapping.getPrePinMapping().get(pinnamebit).getVerilogPort();
Signal previousPrePort = currentPreSignals.put(root, prePort);
- if (previousPrePort != null)
- // TODO implement this
- throw new IllegalArgumentException("Can't convert components with connected pins");
+ assert previousPrePort != null && !previousPrePort.equals(prePort);
}
IdentifierGenerator idGen = new IdentifierGenerator(
for (int bit = 0; bit < pin.logicWidth; bit++)
{
PinBit pinbit = new PinBit(pin, bit);
- UnionFindElement<PinBit> root = UnionFind.find(connectedPins.getElement(pinbit));
+ PinBit root = connectedPins.find(pinbit);
Wire outSignal = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit), 2);
internalWires.add(outSignal);
Signal preSignal = currentPreSignals.put(root, outSignal);
}
Set<Assign> assigns = new HashSet<>();
- for (Entry<UnionFindElement<PinBit>, NamedSignal> e : finalOutSignals.entrySet())
+ for (Entry<PinBit, NamedSignal> e : finalOutSignals.entrySet())
assigns.add(new Assign(currentPreSignals.get(e.getKey()), e.getValue()));
return new VerilogComponentImplementation(declarationMapping.getVerilogComponentDeclaration(), internalWires, assigns,
import net.mograsim.logic.model.model.components.atomic.ModelClock.ModelClockParams;
import net.mograsim.logic.model.model.components.atomic.ModelFixedOutput;
import net.mograsim.logic.model.model.components.atomic.ModelNandGate;
-import net.mograsim.logic.model.model.components.atomic.ModelSplitter;
-import net.mograsim.logic.model.model.components.atomic.ModelSplitter.SplitterParams;
import net.mograsim.logic.model.model.components.atomic.ModelTextComponent;
import net.mograsim.logic.model.model.components.atomic.ModelTriStateBuffer;
import net.mograsim.logic.model.model.components.atomic.ModelTriStateBuffer.ModelTriStateBufferParams;
import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogComponentDeclarationMapping;
import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogConverter;
+import net.mograsim.logic.model.verilog.helper.UnionFind;
import net.mograsim.logic.model.verilog.model.VerilogComponentImplementation;
public class ExportAm2900
public static void main(String[] args) throws IOException
{
Am2900Loader.setup();
+ Path target;
+ String rootComponentID;
try (Scanner sysin = new Scanner(System.in))
{
System.out.print("Directory to export Verilog into >");
- Path target = Paths.get(sysin.nextLine());
+ target = Paths.get(sysin.nextLine());
if (!Files.exists(target))
Files.createDirectories(target);
else if (!Files.isDirectory(target))
throw new IllegalArgumentException("Target exists and is not a directory");
System.out.print("Component ID to serialize recursively >");
- String rootComponentID = sysin.nextLine();
- {
- if (!Files.exists(target))
- Files.createDirectories(target);
- else if (!Files.isDirectory(target))
- throw new IllegalArgumentException("Target exists and is not a directory");
+ rootComponentID = sysin.nextLine();
+ }
- LogicModelModifiable model = new LogicModelModifiable();
+ if (!Files.exists(target))
+ Files.createDirectories(target);
+ else if (!Files.isDirectory(target))
+ throw new IllegalArgumentException("Target exists and is not a directory");
- Set<ModelComponentToVerilogComponentDeclarationMapping> atomicComponentMappings = Stream.of(//
- new ModelNandGate(model, 1), //
- new ModelFixedOutput(model, BitVector.SINGLE_0, null), //
- new ModelFixedOutput(model, BitVector.SINGLE_1, null), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.RIGHT)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.RIGHT_ALT)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.DOWN)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(4, Orientation.RIGHT)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(12, Orientation.RIGHT_ALT)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(12, Orientation.DOWN)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(16, Orientation.LEFT)), //
- new ModelTriStateBuffer(model, new ModelTriStateBufferParams(16, Orientation.RIGHT_ALT)), //
- new ModelWireCrossPoint(model, 1), //
- new ModelWireCrossPoint(model, 2), //
- new ModelWireCrossPoint(model, 4), //
- new ModelWireCrossPoint(model, 9), //
- new ModelWireCrossPoint(model, 12), //
- new ModelWireCrossPoint(model, 16), //
- new ModelSplitter(model, new SplitterParams(2, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(2, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(2, Orientation.UP)), //
- new ModelSplitter(model, new SplitterParams(2, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(3, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(3, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(3, Orientation.UP)), //
- new ModelSplitter(model, new SplitterParams(3, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(3, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(4, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(4, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(4, Orientation.UP)), //
- new ModelSplitter(model, new SplitterParams(4, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(4, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(5, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(5, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(6, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(6, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(6, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(6, Orientation.UP)), //
- new ModelSplitter(model, new SplitterParams(6, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(8, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(8, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(9, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(9, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(12, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(12, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(12, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(12, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(13, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(13, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(16, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(16, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(16, Orientation.UP)), //
- new ModelSplitter(model, new SplitterParams(16, Orientation.DOWN)), //
- new ModelSplitter(model, new SplitterParams(16, Orientation.DOWN_ALT)), //
- new ModelSplitter(model, new SplitterParams(80, Orientation.LEFT)), //
- new ModelSplitter(model, new SplitterParams(80, Orientation.RIGHT)), //
- new ModelSplitter(model, new SplitterParams(80, Orientation.UP_ALT)), //
- new ModelClock(model, new ModelClockParams(7000, Orientation.RIGHT)), //
- new ModelTextComponent(model, "A bus"), //
- new ModelTextComponent(model, "MPM addr"), //
- new ModelTextComponent(model, "D bus"), //
- new ModelAm2900MainMemory(model, null), //
- new ModelAm2900MPROM(model, null), //
- new ModelAm2900MicroInstructionMemory(model, null), //
- new ModelBitDisplay(model, 12), //
- new ModelBitDisplay(model, 16)//
- ).map(c ->
- {
- String id = c.getIDForSerializing(new IdentifyParams());
- JsonElement params = c.getParamsForSerializingJSON(new IdentifyParams());
- ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping = ModelComponentToVerilogConverter
- .generateCanonicalDeclarationMapping(c, id, params, ModelComponentToVerilogConverter
- .sanitizeVerilogID("mgs_" + id + (params.isJsonNull() ? "" : "_" + params)));
- return generateCanonicalDeclarationMapping;
- }).collect(Collectors.toSet());
+ LogicModelModifiable model = new LogicModelModifiable();
- ModelComponent root = IndirectModelComponentCreator.createComponent(model, rootComponentID);
- Set<VerilogComponentImplementation> convertResult = ModelComponentToVerilogConverter.convert(atomicComponentMappings,
- Set.of(root), "mgs_conv_");
- for (VerilogComponentImplementation convertedComponent : convertResult)
- Files.writeString(target.resolve(convertedComponent.getDeclaration().getID() + ".v"),
- convertedComponent.toVerilogCode());
- }
- }
+ Set<ModelComponentToVerilogComponentDeclarationMapping> atomicComponentMappings = Stream.of(//
+ new ModelNandGate(model, 1), //
+ new ModelFixedOutput(model, BitVector.SINGLE_0, null), //
+ new ModelFixedOutput(model, BitVector.SINGLE_1, null), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.RIGHT)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.RIGHT_ALT)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(1, Orientation.DOWN)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(4, Orientation.RIGHT)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(12, Orientation.RIGHT_ALT)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(12, Orientation.DOWN)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(16, Orientation.LEFT)), //
+ new ModelTriStateBuffer(model, new ModelTriStateBufferParams(16, Orientation.RIGHT_ALT)), //
+ new ModelWireCrossPoint(model, 1), //
+ new ModelWireCrossPoint(model, 2), //
+ new ModelWireCrossPoint(model, 4), //
+ new ModelWireCrossPoint(model, 9), //
+ new ModelWireCrossPoint(model, 12), //
+ new ModelWireCrossPoint(model, 16), //
+ new ModelClock(model, new ModelClockParams(7000, Orientation.RIGHT)), //
+ new ModelTextComponent(model, "A bus"), //
+ new ModelTextComponent(model, "MPM addr"), //
+ new ModelTextComponent(model, "D bus"), //
+ new ModelAm2900MainMemory(model, null), //
+ new ModelAm2900MPROM(model, null), //
+ new ModelAm2900MicroInstructionMemory(model, null), //
+ new ModelBitDisplay(model, 12), //
+ new ModelBitDisplay(model, 16)//
+ ).map(c ->
+ {
+ String id = c.getIDForSerializing(new IdentifyParams());
+ JsonElement params = c.getParamsForSerializingJSON(new IdentifyParams());
+ ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping = ModelComponentToVerilogConverter
+ .generateCanonicalDeclarationMapping(c, new UnionFind<>(), id, params,
+ ModelComponentToVerilogConverter.sanitizeVerilogID("mgs_" + id + (params.isJsonNull() ? "" : "_" + params)));
+ return generateCanonicalDeclarationMapping;
+ }).collect(Collectors.toSet());
+
+ ModelComponent root = IndirectModelComponentCreator.createComponent(model, rootComponentID);
+ Set<VerilogComponentImplementation> convertResult = ModelComponentToVerilogConverter.convert(atomicComponentMappings, Set.of(root),
+ "mgs_conv_");
+ for (VerilogComponentImplementation convertedComponent : convertResult)
+ Files.writeString(target.resolve(convertedComponent.getDeclaration().getID() + ".v"), convertedComponent.toVerilogCode());
}
}