예제 #1
0
 /**
  * Method to tell whether this NodeInst is an icon of its parent. Electric does not allow
  * recursive circuit hierarchies (instances of Cells inside of themselves). However, it does allow
  * one exception: a schematic may contain its own icon for documentation purposes. This method
  * determines whether this NodeInst is such an icon.
  *
  * @return true if this NodeInst is an icon of its parent.
  */
 private boolean isIconOfParent(ImmutableNodeInst n) {
   if (!(n.protoId instanceof CellId)) {
     return false;
   }
   CellBackup subCell = snapshot.getCell((CellId) n.protoId);
   CellId subCellId = subCell.cellRevision.d.cellId;
   return subCellId.isIcon()
       && cellId.isSchematic()
       && subCellId.libId == cellId.libId
       && subCell.cellRevision.d.groupName.equals(cellRevision.d.groupName);
 }
예제 #2
0
 private EquivalentSchematicExports getEquivExports(CellId cellId) {
   if (!(cellId.isIcon() || cellId.isSchematic())) {
     throw new IllegalArgumentException();
   }
   EquivalentSchematicExports eq = snapshot.equivSchemExports[cellId.cellIndex];
   if (eq == null) {
     ImmutableNetSchem netSchem = new ImmutableNetSchem(snapshot, cellId);
     eq = new EquivalentSchematicExports(netSchem);
     snapshot.equivSchemExports[cellId.cellIndex] = eq;
   }
   return eq;
 }
예제 #3
0
  private void localConnections(int netMap[]) {

    // Exports
    for (int k = 0; k < numExports; k++) {
      ImmutableExport e = exports.get(k);
      int portOffset = portOffsets[k];
      Name expNm = e.name;
      int busWidth = expNm.busWidth();
      int drawn = drawns[k];
      int drawnOffset = drawnOffsets[drawn];
      for (int i = 0; i < busWidth; i++) {
        ImmutableNetLayout.connectMap(
            netMap,
            portOffset + i,
            drawnOffset + (busWidth == drawnWidths[drawn] ? i : i % drawnWidths[drawn]));
        GenMath.MutableInteger nn = netNames.get(expNm.subname(i));
        ImmutableNetLayout.connectMap(netMap, portOffset + i, netNamesOffset + nn.intValue());
      }
    }

    // PortInsts
    for (int k = 0; k < numNodes; k++) {
      ImmutableNodeInst n = nodes.get(k);
      if (isIconOfParent(n)) {
        continue;
      }
      //            NodeProto np = ni.getProto();
      if (n.protoId instanceof PrimitiveNodeId) {
        // Connect global primitives
        Global g = globalInst(n);
        if (g != null) {
          int drawn = drawns[ni_pi[k]];
          ImmutableNetLayout.connectMap(netMap, globals.indexOf(g), drawnOffsets[drawn]);
        }
        if (n.protoId == schem.wireConNode.getId()) {
          connectWireCon(netMap, n);
        }
        continue;
      }
      IconInst iconInst = iconInsts[k];
      if (iconInst == null || iconInst.iconOfParent) {
        continue;
      }

      assert iconInst.nodeInst == n;
      CellId subCellId = (CellId) n.protoId;
      assert subCellId.isIcon() || subCellId.isSchematic();
      EquivalentSchematicExports iconEq = iconInst.eq;
      EquivalentSchematicExports schemEq = iconEq.implementation;
      assert schemEq != null;
      Name nodeName = n.name;
      int arraySize = nodeName.busWidth();
      int numPorts = getNumPorts(n.protoId);
      CellBackup subCell = snapshot.getCell(subCellId);
      for (int m = 0; m < numPorts; m++) {
        ImmutableExport e = subCell.cellRevision.exports.get(m);
        Name busExportName = e.name;
        int busWidth = busExportName.busWidth();
        int drawn = drawns[ni_pi[k] + m];
        if (drawn < 0) {
          continue;
        }
        int width = drawnWidths[drawn];
        if (width != busWidth && width != busWidth * arraySize) {
          continue;
        }
        for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) {
          int nodeOffset = iconInst.netMapOffset + arrayIndex * iconInst.numExtendedExports;
          int busOffset = drawnOffsets[drawn];
          if (width != busWidth) {
            busOffset += busWidth * arrayIndex;
          }
          for (int j = 0; j < busWidth; j++) {
            Name exportName = busExportName.subname(j);
            int portOffset = schemEq.getExportNameMapOffset(exportName);
            if (portOffset < 0) {
              continue;
            }
            ImmutableNetLayout.connectMap(netMap, busOffset + j, nodeOffset + portOffset);
          }
        }
      }
    }

    // Arcs
    for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) {
      ImmutableArcInst a = arcs.get(arcIndex);
      int drawn = drawns[arcsOffset + arcIndex];
      if (drawn < 0) {
        continue;
      }
      if (!a.isUsernamed()) {
        continue;
      }
      int busWidth = drawnWidths[drawn];
      Name arcNm = a.name;
      if (arcNm.busWidth() != busWidth) {
        continue;
      }
      int drawnOffset = drawnOffsets[drawn];
      for (int i = 0; i < busWidth; i++) {
        GenMath.MutableInteger nn = netNames.get(arcNm.subname(i));
        ImmutableNetLayout.connectMap(netMap, drawnOffset + i, netNamesOffset + nn.intValue());
      }
    }

    // Globals of proxies
    for (IconInst iconInst : iconInsts) {
      if (iconInst == null || iconInst.iconOfParent) {
        continue;
      }
      Set<Global> excludeGlobals = null;
      if (iconInstExcludeGlobals != null) {
        excludeGlobals = iconInstExcludeGlobals.get(iconInst);
      }
      for (int k = 0; k < iconInst.nodeInst.name.busWidth(); k++) {
        EquivalentSchematicExports eq = iconInst.eq.implementation;
        assert eq.implementation == eq;
        int numGlobals = eq.portOffsets[0];
        if (numGlobals == 0) {
          continue;
        }
        int nodableOffset = iconInst.netMapOffset + k * iconInst.numExtendedExports;
        for (int i = 0; i < numGlobals; i++) {
          Global g = eq.globals.get(i);
          if (excludeGlobals != null && excludeGlobals.contains(g)) {
            continue;
          }
          ImmutableNetLayout.connectMap(netMap, this.globals.indexOf(g), nodableOffset + i);
        }
      }
    }

    ImmutableNetLayout.closureMap(netMap);
  }
예제 #4
0
  private void initNodables() {
    Global.Buf globalBuf = new Global.Buf();
    Map<ImmutableNodeInst, Set<Global>> nodeInstExcludeGlobal = null;
    for (int i = 0; i < numNodes; i++) {
      ImmutableNodeInst n = nodes.get(i);
      //            NodeProto np = ni.getProto();
      //            NetCell netCell = null;
      //            if (ni.isCellInstance()) {
      //                netCell = networkManager.getNetCell((Cell) np);
      //            }
      if (n.protoId instanceof CellId
          && (((CellId) n.protoId).isIcon() || ((CellId) n.protoId).isSchematic())) {
        if (n.name.hasDuplicates()) {
          String msg = cellId + ": Node name <" + n.name + "> has duplicate subnames";
          System.out.println(msg);
          //                    networkManager.pushHighlight(ni);
          //                    networkManager.logError(msg, NetworkTool.errorSortNodes);
        }
      } else {
        if (n.name.isBus()) {
          String msg = cellId + ": Array name <" + n.name + "> can be assigned only to icon nodes";
          System.out.println(msg);
          //                    networkManager.pushHighlight(ni);
          //                    networkManager.logError(msg, NetworkTool.errorSortNodes);
        }
      }
      if (n.protoId instanceof CellId) {
        CellId subCellId = (CellId) n.protoId;
        if (!(subCellId.isIcon() || subCellId.isSchematic())) {
          continue;
        }
        if (isIconOfParent(n)) {
          continue;
        }
        EquivalentSchematicExports netEq = getEquivExports((CellId) n.protoId);
        EquivalentSchematicExports schemEq = netEq.implementation;
        assert schemEq != null && schemEq.getCellId() != cellId;
        Global.Set gs = schemEq.getGlobals();

        // Check for rebinding globals
        if (schemEq.implementation.globalPartitions != null) {
          int numPortInsts = getNumPorts(n.protoId);
          Set<Global> gb = null;
          for (int j = 0; j < numPortInsts; j++) {
            PortInst pi = new PortInst(n.nodeId, getPortIdByIndex(n.protoId, j));
            int piOffset = pi.getPortInstOffset();
            int drawn = drawns[piOffset];
            if (drawn < 0 || drawn >= numConnectedDrawns) {
              continue;
            }
            ImmutableExport e = netEq.exports.get(j);
            assert e.exportId == pi.portId;
            Name busName = e.name;
            for (int busIndex = 0; busIndex < busName.busWidth(); busIndex++) {
              Name exportName = busName.subname(busIndex);
              Global.Set globalsOnElement = schemEq.globalPartitions.get(exportName);
              if (globalsOnElement == null) {
                continue;
              }
              if (gb == null) {
                gb = new HashSet<Global>();
              }
              for (int l = 0; l < globalsOnElement.size(); l++) {
                Global g = globalsOnElement.get(l);
                gb.add(g);
              }
            }
          }
          if (gb != null) {
            // remember excluded globals for this NodeInst
            if (nodeInstExcludeGlobal == null) {
              nodeInstExcludeGlobal = new HashMap<ImmutableNodeInst, Set<Global>>();
            }
            nodeInstExcludeGlobal.put(n, gb);
            // fix Set of globals
            gs = gs.remove(gb.iterator());
          }
        }

        String errorMsg = globalBuf.addToBuf(gs);
        if (errorMsg != null) {
          String msg =
              "Network: " + cellId + " has globals with conflicting characteristic " + errorMsg;
          System.out.println(msg);
          //                        networkManager.logError(msg, NetworkTool.errorSortNetworks);
          // TODO: what to highlight?
          // log.addGeom(shared[i].nodeInst, true, 0, null);
        }
      } else {
        Global g = globalInst(n);
        if (g != null) {
          PortCharacteristic characteristic;
          if (g == Global.ground) {
            characteristic = PortCharacteristic.GND;
          } else if (g == Global.power) {
            characteristic = PortCharacteristic.PWR;
          } else {
            characteristic = PortCharacteristic.findCharacteristic(n.techBits);
            if (characteristic == null) {
              String msg =
                  "Network: "
                      + cellId
                      + " has global "
                      + g.getName()
                      + " with unknown characteristic bits";
              System.out.println(msg);
              //                            networkManager.pushHighlight(ni);
              //                            networkManager.logError(msg,
              // NetworkTool.errorSortNetworks);
              characteristic = PortCharacteristic.UNKNOWN;
            }
          }
          String errorMsg = globalBuf.addToBuf(g, characteristic);
          if (errorMsg != null) {
            String msg =
                "Network: " + cellId + " has global with conflicting characteristic " + errorMsg;
            System.out.println(msg);
            //                        networkManager.logError(msg, NetworkTool.errorSortNetworks);
            // log.addGeom(shared[i].nodeInst, true, 0, null);
          }
        }
      }
    }
    globals = globalBuf.getBuf();
    //        boolean changed = false;
    //        if (globals != newGlobals) {
    //            changed = true;
    //            globals = newGlobals;
    //            if (NetworkTool.debug) {
    //                System.out.println(cell + " has " + globals);
    //            }
    //        }
    int mapOffset = portOffsets[0] = globals.size();
    for (int i = 1; i <= numExports; i++) {
      ImmutableExport export = exports.get(i - 1);
      if (DEBUG) {
        System.out.println(export + " " + portOffsets[i - 1]);
      }
      mapOffset += export.name.busWidth();
      //            if (portOffsets[i] != mapOffset) {
      //                changed = true;
      portOffsets[i] = mapOffset;
      //            }
    }
    equivPortsN = new int[mapOffset];
    equivPortsP = new int[mapOffset];
    equivPortsA = new int[mapOffset];

    for (int i = 0; i < numDrawns; i++) {
      drawnOffsets[i] = mapOffset;
      mapOffset += drawnWidths[i];
      if (DEBUG) {
        System.out.println("Drawn " + i + " has offset " + drawnOffsets[i]);
      }
    }
    iconInsts = new IconInst[numNodes];
    iconInstExcludeGlobals = null;
    for (int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
      ImmutableNodeInst n = nodes.get(nodeIndex);
      if (!(n.protoId instanceof CellId)) {
        continue;
      }
      CellId subCellId = (CellId) n.protoId;
      if (!subCellId.isIcon() && !subCellId.isSchematic()) {
        continue;
      }
      IconInst iconInst = new IconInst(n, mapOffset);
      iconInsts[nodeIndex] = iconInst;
      if (isIconOfParent(n)) {
        continue;
      }
      EquivalentSchematicExports netEq = iconInst.eq;
      EquivalentSchematicExports schemEq = netEq.implementation;
      assert schemEq != null;
      Set<Global> gs =
          nodeInstExcludeGlobal != null
              ? nodeInstExcludeGlobal.get(n)
              : null; // exclude set of globals
      if (gs != null) {
        if (iconInstExcludeGlobals == null) {
          iconInstExcludeGlobals = new IdentityHashMap<IconInst, Set<Global>>();
        }
        iconInstExcludeGlobals.put(iconInst, gs);
      }

      assert iconInst.numExtendedExports == schemEq.equivPortsN.length;
      mapOffset += iconInst.numExtendedExports * n.name.busWidth();
    }
    netNamesOffset = mapOffset;
    if (DEBUG) {
      System.out.println("netNamesOffset=" + netNamesOffset);
    }
  }
예제 #5
0
  void calcDrawnWidths() {
    Arrays.fill(drawnNames, null);
    Arrays.fill(drawnWidths, -1);

    for (int i = 0; i < numExports; i++) {
      int drawn = drawns[i];
      Name name = exports.get(i).name;
      int newWidth = name.busWidth();
      int oldWidth = drawnWidths[drawn];
      if (oldWidth < 0) {
        drawnNames[drawn] = name;
        drawnWidths[drawn] = newWidth;
        continue;
      }
      if (oldWidth != newWidth) {
        reportDrawnWidthError(
            /*cell.getPort(i), null,*/ drawnNames[drawn].toString(), name.toString());
        if (oldWidth < newWidth) {
          drawnNames[drawn] = name;
          drawnWidths[drawn] = newWidth;
        }
      }
    }
    for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) {
      ImmutableArcInst a = arcs.get(arcIndex);
      int drawn = drawns[arcsOffset + arcIndex];
      if (drawn < 0) {
        continue;
      }
      Name name = a.name;
      if (name.isTempname()) {
        continue;
      }
      int newWidth = name.busWidth();
      int oldWidth = drawnWidths[drawn];
      if (oldWidth < 0) {
        drawnNames[drawn] = name;
        drawnWidths[drawn] = newWidth;
        continue;
      }
      if (oldWidth != newWidth) {
        reportDrawnWidthError(/*null, ai,*/ drawnNames[drawn].toString(), name.toString());
        if (oldWidth < newWidth) {
          drawnNames[drawn] = name;
          drawnWidths[drawn] = newWidth;
        }
      }
    }
    for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) {
      int drawn = drawns[arcsOffset + arcIndex];
      if (drawn < 0) {
        continue;
      }
      ImmutableArcInst a = arcs.get(arcIndex);
      Name name = a.name;
      if (!name.isTempname()) {
        continue;
      }
      int oldWidth = drawnWidths[drawn];
      if (oldWidth < 0) {
        drawnNames[drawn] = name;
        if (a.protoId != busArc.getId()) {
          drawnWidths[drawn] = 1;
        }
      }
    }
    for (int i = 0; i < numNodes; i++) {
      ImmutableNodeInst n = nodes.get(i);
      //            NodeProto np = ni.getProto();
      if (n.protoId instanceof PrimitiveNodeId) {
        PrimitiveNode pn = techPool.getPrimitiveNode((PrimitiveNodeId) n.protoId);
        if (pn.getFunction().isPin()) {
          continue;
        }
        if (pn == Schematics.tech().offpageNode) {
          continue;
        }
      }
      int numPortInsts = getNumPorts(n.protoId);
      for (int j = 0; j < numPortInsts; j++) {
        PortInst pi = new PortInst(n.nodeId, getPortIdByIndex(n.protoId, j));
        int drawn = drawns[pi.getPortInstOffset()];
        if (drawn < 0) {
          continue;
        }
        int oldWidth = drawnWidths[drawn];
        int newWidth = 1;
        if (n.protoId instanceof CellId) {
          CellBackup subCell = snapshot.getCell((CellId) n.protoId);
          CellId subCellId = subCell.cellRevision.d.cellId;
          if (subCellId.isIcon() || subCellId.isSchematic()) {
            int arraySize = subCellId.isIcon() ? n.name.busWidth() : 1;
            int portWidth = subCell.cellRevision.exports.get(j).name.busWidth();
            if (oldWidth == portWidth) {
              continue;
            }
            newWidth = arraySize * portWidth;
          }
        }
        if (oldWidth < 0) {
          drawnWidths[drawn] = newWidth;
          continue;
        }
        if (oldWidth != newWidth) {
          String msg =
              "Network: Schematic "
                  + cellId
                  + " has net <"
                  + drawnNames[drawn]
                  + "> with width conflict in connection "
                  + pi.n.name
                  + " "
                  + pi.portId;
          System.out.println(msg);
          //                    networkManager.pushHighlight(pi);
          //                    networkManager.logError(msg, NetworkTool.errorSortNetworks);
        }
      }
    }
    for (int i = 0; i < drawnWidths.length; i++) {
      if (drawnWidths[i] < 1) {
        drawnWidths[i] = 1;
      }
      if (DEBUG) {
        System.out.println(
            "Drawn "
                + i
                + " "
                + (drawnNames[i] != null ? drawnNames[i].toString() : "")
                + " has width "
                + drawnWidths[i]);
      }
    }
  }
예제 #6
0
  ImmutableNetSchem(Snapshot snapshot, CellId cellId) {
    assert cellId.isIcon() || cellId.isSchematic();
    this.snapshot = snapshot;
    this.cellId = cellId;
    //        System.out.println("begin ImmutableNetSchem " + cellId);
    techPool = snapshot.techPool;
    schem = techPool.getSchematics();
    busPinPortId = schem != null ? schem.busPinNode.getPort(0).getId() : null;
    busArc = schem != null ? schem.bus_arc : null;
    cellTree = snapshot.getCellTree(cellId);
    cellBackup = cellTree.top;
    m = cellBackup.getMemoization();
    cellRevision = cellBackup.cellRevision;
    exports = cellRevision.exports;
    nodes = cellRevision.nodes;
    arcs = cellRevision.arcs;
    numExports = cellRevision.exports.size();
    numNodes = cellRevision.nodes.size();
    numArcs = cellRevision.arcs.size();

    CellId implementationCellId = cellId;
    if (cellId.isIcon()) {
      CellId mainSchemId = snapshot.getMainSchematics(cellId);
      if (mainSchemId != null) {
        getEquivExports(mainSchemId);
        implementationCellId = mainSchemId;
      }
    }
    this.implementationCellId = implementationCellId;

    // init connections
    ni_pi = new int[numNodes];
    int offset = numExports;
    for (int i = 0; i < numNodes; i++) {
      ImmutableNodeInst n = nodes.get(i);
      ni_pi[i] = offset;
      offset += getNumPorts(n.protoId);
    }
    arcsOffset = offset;
    offset += numArcs;

    headConn = new int[offset];
    tailConn = new int[offset];
    drawns = new int[offset];
    for (int i = numExports; i < arcsOffset; i++) {
      headConn[i] = i;
      tailConn[i] = i;
    }
    for (int i = 0; i < numExports; i++) {
      int portOffset = i;
      ImmutableExport export = exports.get(i);
      int orig = getPortInstOffset(export.originalNodeId, export.originalPortId);
      headConn[portOffset] = headConn[orig];
      headConn[orig] = portOffset;
      tailConn[portOffset] = -1;
    }
    for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) {
      ImmutableArcInst a = arcs.get(arcIndex);
      int arcOffset = arcsOffset + arcIndex;
      int head = getPortInstOffset(a.headNodeId, a.headPortId);
      headConn[arcOffset] = headConn[head];
      headConn[head] = arcOffset;
      int tail = getPortInstOffset(a.tailNodeId, a.tailPortId);
      tailConn[arcOffset] = tailConn[tail];
      tailConn[tail] = arcOffset;
    }

    makeDrawns();

    initNetnames();

    portOffsets = new int[numExports + 1];
    drawnNames = new Name[numDrawns];
    drawnWidths = new int[numDrawns];
    drawnOffsets = new int[numDrawns];

    calcDrawnWidths();

    initNodables();

    int mapSize = netNamesOffset + netNames.size();
    int[] netMapN = ImmutableNetLayout.initMap(mapSize);
    localConnections(netMapN);

    int[] netMapP = netMapN.clone();
    int[] netMapA = netMapN.clone();
    internalConnections(netMapN, netMapP, netMapA);

    ImmutableNetLayout.closureMap(netMapN);
    ImmutableNetLayout.closureMap(netMapP);
    ImmutableNetLayout.closureMap(netMapA);

    //        updatePortImplementation();

    updateInterface(netMapN, netMapP, netMapA);
    //        System.out.println("end ImmutableNetSchem " + cellId);
  }
예제 #7
0
  private void internalConnections(int[] netMapF, int[] netMapP, int[] netMapA) {
    for (int k = 0; k < numNodes; k++) {
      ImmutableNodeInst n = nodes.get(k);
      int nodeOffset = ni_pi[k];
      if (n.protoId instanceof PrimitiveNodeId) {
        PrimitiveNode.Function fun = getFunction(n);
        if (fun == PrimitiveNode.Function.RESIST) {
          ImmutableNetLayout.connectMap(
              netMapP, drawnOffsets[drawns[nodeOffset]], drawnOffsets[drawns[nodeOffset + 1]]);
          ImmutableNetLayout.connectMap(
              netMapA, drawnOffsets[drawns[nodeOffset]], drawnOffsets[drawns[nodeOffset + 1]]);
        } else if (fun.isComplexResistor()) {
          ImmutableNetLayout.connectMap(
              netMapA, drawnOffsets[drawns[nodeOffset]], drawnOffsets[drawns[nodeOffset + 1]]);
        }
        continue;
      }
      IconInst iconInst = iconInsts[k];
      if (iconInst != null) {
        continue;
      }
      CellId subCellId = (CellId) n.protoId;
      assert !subCellId.isIcon() && !subCellId.isSchematic();
      EquivPorts eq = snapshot.getCellTree(subCellId).getEquivPorts();
      int[] eqN = eq.getEquivPortsN();
      int[] eqP = eq.getEquivPortsP();
      int[] eqA = eq.getEquivPortsA();
      int numPorts = eq.getNumExports();
      assert eqN.length == numPorts && eqP.length == numPorts && eqA.length == numPorts;
      for (int i = 0; i < numPorts; i++) {
        int di = drawns[nodeOffset + i];
        if (di < 0) {
          continue;
        }
        int jN = eqN[i];
        if (i != jN) {
          int dj = drawns[nodeOffset + jN];
          if (dj >= 0) {
            ImmutableNetLayout.connectMap(netMapF, drawnOffsets[di], drawnOffsets[dj]);
          }
        }
        int jP = eqP[i];
        if (i != jP) {
          int dj = drawns[nodeOffset + jP];
          if (dj >= 0) {
            ImmutableNetLayout.connectMap(netMapP, drawnOffsets[di], drawnOffsets[dj]);
          }
        }
        int jA = eqA[i];
        if (i != jA) {
          int dj = drawns[nodeOffset + jA];
          if (dj >= 0) {
            ImmutableNetLayout.connectMap(netMapA, drawnOffsets[di], drawnOffsets[dj]);
          }
        }
      }
    }
    for (IconInst iconInst : iconInsts) {
      if (iconInst == null || iconInst.iconOfParent) {
        continue;
      }
      for (int k = 0; k < iconInst.nodeInst.name.busWidth(); k++) {
        EquivalentSchematicExports eq = iconInst.eq.implementation;
        assert eq.implementation == eq;
        int[] eqN = eq.getEquivPortsN();
        int[] eqP = eq.getEquivPortsP();
        int[] eqA = eq.getEquivPortsA();
        int nodableOffset = iconInst.netMapOffset + k * iconInst.numExtendedExports;
        for (int i = 0; i < eqN.length; i++) {
          int io = nodableOffset + i;

          int jF = eqN[i];
          if (i != jF) {
            ImmutableNetLayout.connectMap(netMapF, io, nodableOffset + jF);
          }

          int jP = eqP[i];
          if (i != jP) {
            ImmutableNetLayout.connectMap(netMapP, io, nodableOffset + jP);
          }

          int jA = eqA[i];
          if (i != jA) {
            ImmutableNetLayout.connectMap(netMapA, io, nodableOffset + jA);
          }
        }
      }
    }
  }