<<--File: IPChipRoseImpl.mesa>> <> <<>> DIRECTORY Atom, FS, IO, CD, CDIO, CDDirectory, IP, IPBasicOps, IPOrient, IPTypeDict, IPToolBox, IPChipRose, ReadConnection, Rope, SymTab, TerminalIO; IPChipRoseImpl: CEDAR PROGRAM IMPORTS IO, FS, SymTab, Atom, Rope, TerminalIO, CD, CDIO, CDDirectory, ReadConnection, IP, IPBasicOps, IPOrient, IPToolBox, IPTypeDict EXPORTS IPChipRose = BEGIN OPEN BO: IPBasicOps, TD: IPTypeDict, TB: IPToolBox, IPChipRose; NameConflict: PUBLIC ERROR [name: Rope.ROPE, in: Which] = CODE; UnDeclared: PUBLIC ERROR[name: Rope.ROPE, in: Which] = CODE; CreateFrom: PUBLIC PROC[roseFile, chipFile, typFile, initFile: Rope.ROPE _ NIL, chipBeforeTyp, debug: BOOL] RETURNS [Ref] ={ r: Ref _ NEW[Rep _ [nets: SymTab.Create[], ports: SymTab.Create[], instances: SymTab.Create[], types: SymTab.Create[]]]; cdDesign: CD.Design _ IF chipFile = NIL THEN NIL ELSE CDIO.ReadDesign[chipFile]; ipTypDict: TD.Ref _ IF typFile = NIL THEN NIL ELSE TD.Create[typFile]; <<-- NB: This can only be used once (see FromIPType)>> <<-- otherwise there may be confusions in the >> <<-- TD.TypeEntryRep.shape and TD.TypeEntryRep.pins >> <<--These are procedures to build up entries in symTabs of r-->> <<>> <<--(1) This is simply to get the name of the assembly, other headers are ignored>> headerProc: ReadConnection.EnumHeaderProc = { IF Rope.Equal[key, "CellTypeName"] THEN r.cellTypeName _ val1}; --headerProc-- <<--(2)>> portsProc: ReadConnection.EnumPortsProc = { WHILE portList # NIL DO IF ~ r.ports.Insert[portList.first.portName, NEW[PortRec _ [portList.first.ecName, NIL, portList.first.portDir]]] THEN ERROR IP.Error[doubleRegistration, portList.first.portName]; portList _ portList.rest ENDLOOP; };--portsProc-- <<--(3)>> netProc: ReadConnection.EnumNetsProc= { IF ~ r.nets.Insert[netName, NEW[NetRec _ [generation]]] THEN ERROR IP.Error[doubleRegistration, netName]; };--netProc-- <<--(4)>> portNetProc: ReadConnection.EnumPortNetsProc= { found: BOOL; val: REF; port: REF PortRec; [found, val] _ r.ports.Fetch[portName]; IF ~ found THEN ERROR IP.Error[missingRegistration, portName]; port _ NARROW[val]; port.net _ netName; };--portNet-- <<--(5)>> instanceProc: ReadConnection.EnumCompsProc = { pinNets: LIST OF PinNetRec _ NIL; instType: REF TypeRec; WHILE pinNetList # NIL DO pN: ReadConnection.pinNet _ pinNetList.first; pinNets _ CONS[PinNetRec[pN.pinName, pN.netName], pinNets]; pinNetList _ pinNetList.rest; ENDLOOP; IF ~ r.instances.Insert[instName, NEW[InstanceRec _ [type: typeName, pinNets: pinNets, origin: NIL, orient: original]]] THEN ERROR IP.Error[doubleRegistration, instName]; BEGIN found: BOOL _ FALSE; val: REF; cdObj: CD.Object; ipType: REF TD.TypeEntryRep; [found, val] _ r.types.Fetch[typeName]; IF found THEN { instType _ NARROW[val]; instType.instances _ CONS[instName, instType.instances]; RETURN --Done }; --endIF IF chipBeforeTyp THEN { IF cdDesign # NIL THEN [found, cdObj]_ CDDirectory.Fetch[cdDesign, typeName]; IF found THEN { -- CDPins.CleanUpPins[cdDesign, cdObj]; instType _ FromCDType[cdObj, instName]; GOTO insert; }; --endIF IF ipTypDict # NIL THEN [found, ipType] _ ipTypDict.LookUp[typeName]; IF found THEN { instType _ FromIPType[ipType, instName]; GOTO insert; }; --endIF } ELSE { IF ipTypDict # NIL THEN [found, ipType] _ ipTypDict.LookUp[typeName]; IF found THEN { instType _ FromIPType[ipType, instName]; GOTO insert; }; --endIF IF cdDesign #NIL THEN [found, cdObj] _ CDDirectory.Fetch[cdDesign, typeName]; IF found THEN { -- CDPins.CleanUpPins[cdDesign, cdObj]; instType _ FromCDType[cdObj, instName]; GOTO insert; }; --endIF }; --endIF TerminalIO.PutRope[Rope.Cat[typeName, " is undefined\n"]] EXITS insert => [] _ r.types.Insert[typeName, instType]; END; };--instanceProc-- <<--(A) Read in all type definitions into r.types if debug = TRUE>> <<-- NB: precedence specified by chipBeforeTyp>> IF debug THEN { eachTypAction: IPTypeDict.EachTypeEntryAction ={ [] _ r.types.Insert[type, FromIPType[entry]] }; --eachTypAction eachCDObjAction: CDDirectory.EachEntryAction ={ -- CDPins.CleanUpPins[cdDesign, ob]; [] _ r.types.Insert[name, FromCDType[ob]] }; --eachCDObjAction IF chipBeforeTyp THEN { IF cdDesign # NIL THEN [] _ CDDirectory.Enumerate[cdDesign, eachCDObjAction]; IF ipTypDict # NIL THEN [] _ IPTypeDict.TypeEntries[ipTypDict, eachTypAction]; } ELSE { IF ipTypDict # NIL THEN [] _ IPTypeDict.TypeEntries[ipTypDict, eachTypAction]; IF cdDesign # NIL THEN [] _ CDDirectory.Enumerate[cdDesign, eachCDObjAction]; }; --endIF }; --endIF <<--(B) Read Connections: (i) roseFile (ii) chipFile and/or typeFile>> ReadConnection.ReadConct[roseFile, headerProc, portsProc, netProc, portNetProc, instanceProc]; <<--(C) Read initFile, that is the initial placement of components>> IF initFile # NIL THEN { stream: IO.STREAM _ FS.StreamOpen[initFile]; DO ENABLE IO.EndOfStream => EXIT; token: ATOM _ TB.GetIdAtom[stream]; SELECT token FROM $initialPlacement => GetInitialPlacement[r.instances, stream] ENDCASE => { TerminalIO.PutRope[Rope.Cat["Unknown Token: ", Atom.GetPName[token]]]; TB.RemoveBlock[stream]; TerminalIO.PutRope["\n\t Associated block is ignored"]; }; ENDLOOP; }; --endIF RETURN [r] }; --CreateFrom-- Fetch: PUBLIC PROC[r: Ref, name: Rope.ROPE, what: Which] RETURNS [val: REF] ={ found: BOOL; whatTable: SymTab.Ref _ SELECT what FROM net => r.nets, port => r.ports, type => r.types, instance => r.instances, ENDCASE => ERROR; [found, val] _ whatTable.Fetch[name]; IF found THEN RETURN [val] ELSE ERROR IP.Error[missingRegistration, name]; }; --Fetch-- Nets: PUBLIC PROC[r: Ref, action: EachNetAction] ={ netProc: SymTab.EachPairAction = { RETURN [action[key, NARROW[val]]]}; --netProc-- [] _ r.nets.Pairs[netProc]; }; --Nets-- Ports: PUBLIC PROC[r: Ref, action: EachPortAction] ={ portProc: SymTab.EachPairAction = { RETURN [action[key, NARROW[val]]]}; --portProc-- [] _ r.ports.Pairs[portProc]; }; --Ports-- Types: PUBLIC PROC [r: Ref, action: EachTypeAction] ={ typeProc: SymTab.EachPairAction = { RETURN [action[key, NARROW[val]]]}; --typeProc-- [] _ r.types.Pairs[typeProc]; }; --Types-- Instances: PUBLIC PROC[r: Ref, action: EachInstanceAction] ={ instanceProc: SymTab.EachPairAction = { RETURN [action[key, NARROW[val]]]}; --instanceProc-- [] _ r.instances.Pairs[instanceProc]; }; --Instances-- FromCDType: PROC[cdObj: CD.Object, firstInst: Rope.ROPE _ NIL] RETURNS [REF TypeRec] ={ shape: REF ShapeRep; pins: LIST OF REF IP.PinRep _ TB.IPPinsFromCDPins[cdObj]; cdRect: CD.Rect _ CD.InterestRect[cdObj].r; origin: IP.IntVector _ [cdRect.x1, cdRect.y1]; width: NAT _ cdRect.x2 - cdRect.x1; height: NAT _ cdRect.y2 - cdRect.y1; instances: LIST OF Rope.ROPE _ IF firstInst = NIL THEN NIL ELSE LIST[firstInst]; <<>> <<--Now only determine width and height of cdObj. Dimension of corners may come later>> shape _ NEW[ShapeRep _ [BO.NuNatVector [width, height]]]; RETURN [NEW[TypeRec _ [origin, instances, pins, shape]]] }; --FromCDType-- FromIPType: PROC [ipType: REF TD.TypeEntryRep, firstInst: Rope.ROPE _ NIL] RETURNS [REF TypeRec] = { instances: LIST OF Rope.ROPE _ IF firstInst = NIL THEN NIL ELSE LIST[firstInst]; RETURN [NEW[TypeRec _[ipType.origin, instances, ipType.pins, ipType.shape, ipType.shapeFn, ipType.restriction]]] }; --FromIPType GetInitialPlacement: PROC[instances: SymTab.Ref, stream: IO.STREAM] ={ found: BOOL; val: REF; TB.EnterBlock[stream]; UNTIL TB.ExitBlock[stream] DO instName: Rope.ROPE _ TB.GetIdRope[stream]; [found, val] _ instances.Fetch[instName]; IF found THEN { TB.EnterBlock[stream]; UNTIL TB.ExitBlock[stream] DO token: ATOM _ TB.GetIdAtom[stream]; SELECT token FROM $origin => NARROW[val, REF InstanceRec].origin _ TB.GetIntVector[stream]; $orient => NARROW[val, REF InstanceRec].orient _ IPOrient.CDIntToOrien[stream.GetInt]; ENDCASE => { TerminalIO.PutRope[Rope.Cat["Unknown token: ", Atom.GetPName[token], ". associated value ignored"]]; [] _ stream.GetRefAny; }; ENDLOOP; } ELSE { TerminalIO.PutRope[Rope.Cat[instName, " _ Unknown instance. Block is ignored\n"]]; TB.RemoveBlock[stream] }; ENDLOOP; }; --GetInitialPlacement END.