<> <> <> <> <<>> DIRECTORY Atom, CDCommandOps, CDSequencer, Core, CoreCDUser, CoreClasses, CoreFlat, CoreOps, CoreProperties, FS, RefTab, SymTab, TerminalIO, IO, Rope, XilinxIO; XilinxIOImpl: CEDAR PROGRAM IMPORTS Atom, CDCommandOps, CoreCDUser, CoreFlat, CoreOps, CoreProperties, FS, RefTab, SymTab, TerminalIO, IO, Rope EXPORTS XilinxIO = BEGIN OPEN XilinxIO; <> ROPE: TYPE = Rope.ROPE; LOR: TYPE = LIST OF ROPE; BindList: TYPE = LIST OF RECORD[wire: Core.Wire, name: ROPE]; <> primitives: SymTab.Ref _ SymTab.Create[]; -- cell type name to Primitive Primitive: TYPE = REF PrimitiveRec; PrimitiveRec: TYPE = RECORD [ translate: TranslateProc, data: REF ANY]; TranslateProc: TYPE = PROC [circuit: FlatCircuit, root, cell: Core.CellType, instance: CoreClasses.CellInstance, name: ROPE, flatCell: CoreFlat.FlatCellTypeRec, flatWireToSignal, bindings: RefTab.Ref, part2000: BOOL, data: REF ANY]; Pins: TYPE = LIST OF Pin; PinRecList: TYPE = LIST OF PinRec; Pin: TYPE = REF PinRec; PinRec: TYPE = RECORD [ coreName: ROPE, xilinxName: ROPE, direction: InOrOut, physicalPin: BOOL _ FALSE, tristate: BOOL _ FALSE, invert: BOOL _ FALSE]; InOrOut: TYPE = {In, Out}; directionNames: ARRAY InOrOut OF ROPE _ ["I", "O"]; <> FlatCircuit: TYPE = REF FlatCircuitRec; FlatCircuitRec: TYPE = RECORD [ symbols: Symbols _ NIL, signals: Signals _ NIL, partType: ROPE _ NIL]; Symbols: TYPE = LIST OF Symbol; Symbol: TYPE = REF SymbolRec; SymbolRec: TYPE = RECORD [ name: ROPE _ NIL, type: ROPE _ NIL, connections: SymbolSignalPins _ NIL, parameters: LOR _ NIL, configs: LOR _ NIL]; SymbolSignalPins: TYPE = LIST OF SymbolSignalPin; SymbolSignalPin: TYPE = REF SymbolSignalPinRec; SymbolSignalPinRec: TYPE = RECORD [ symbol: Symbol _ NIL, signal: Signal _ NIL, pin: Pin _ NIL, parameters: LOR _ NIL]; Signals: TYPE = LIST OF Signal; Signal: TYPE = REF SignalRec; SignalRec: TYPE = RECORD [ name: ROPE _ NIL, connections: SymbolSignalPins _ NIL, pin: REF INT _ NIL, -- NIL => not forced unbonded: BOOL _ FALSE, parameters: LOR _ NIL]; <> <> PinSignals: TYPE = LIST OF PinSignalRec; PinSignalRec: TYPE = RECORD [ pin: Pin _ NIL, signal: Signal _ NIL]; <> SaveCellType: PUBLIC PROC [cellType: Core.CellType, fileName: ROPE _ NIL] RETURNS [multiplyDriven: LOR _ NIL] = { circuit: FlatCircuit _ FlattenCircuit[cellType]; pruned: RefTab.Ref _ PruneFlattenedCircuit[circuit]; multiplyDriven _ CheckMultipleDrivers[circuit]; IF fileName=NIL THEN fileName _ Rope.Cat[CoreOps.GetCellTypeName[cellType], ".xnf"]; WriteFlattenedCircuit[circuit, pruned, fileName]; }; FlattenCircuit: PROC [cellType: Core.CellType] RETURNS [circuit: FlatCircuit] = { PushPins: CoreOps.EachWireProc = { pinList: ROPE _ NARROW[CoreProperties.GetWireProp[wire, $Pins]]; IF pinList#NIL THEN { ris: IO.STREAM _ IO.RIS[pinList]; FOR i: INT IN [0..wire.size) DO pin: INT _ IO.GetInt[ris]; currentValue: REF INT _ NARROW[CoreProperties.GetWireProp[wire[i], $Pin]]; IF i#(wire.size-1) THEN { kind: IO.TokenKind; token: IO.ROPE; [kind, token] _ IO.GetCedarTokenRope[ris]; IF kind#tokenSINGLE OR NOT Rope.Equal[token, ","] THEN ERROR; }; IF wire[i].size#0 THEN ERROR; IF currentValue=NIL THEN CoreProperties.PutWireProp[wire[i], $Pin, NEW[INT _ pin]] ELSE IF pin#currentValue^ THEN ERROR; ENDLOOP; }; }; GetParms: CoreOps.EachWireProc = { FindParms: PROC [prop: ATOM, val: REF ANY] = { propName: ROPE _ Atom.GetPName[prop]; IF Rope.Match["Par*", propName, FALSE] THEN { SetParm: PROC [wire: Core.Wire] = { signal: Signal; flatWire.wire _ wire; signal _ NARROW[RefTab.Fetch[flatWireToSignal, flatWire].val]; signal.parameters _ CONS[parm, signal.parameters]; }; parm: ROPE _ NARROW[val]; IF wire.size#0 THEN [] _ CoreOps.VisitRootAtomics[wire, SetParm] ELSE SetParm[wire]; }; }; CoreProperties.Enumerate[wire.properties, FindParms]; }; FlattenCellType: CoreFlat.BoundFlatCellProc = { name: ROPE _ CoreOps.GetCellTypeName[cell]; primitive: Primitive _ NARROW[SymTab.Fetch[primitives, name].val]; IF primitive=NIL THEN CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCellType] ELSE primitive.translate[circuit, cellType, cell, instance, name, flatCell, flatWireToSignal, bindings, part2000, primitive.data]; }; flatWireToSignal: RefTab.Ref _ RefTab.Create[hash: CoreFlat.FlatWireHash, equal: CoreFlat.FlatWireEqual]; flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec]; part2000: BOOL _ FALSE; circuit _ NEW[FlatCircuitRec]; circuit.partType _ NARROW[CoreProperties.InheritCellTypeProp[cellType, $XilinxPartType]]; IF circuit.partType=NIL THEN circuit.partType _ "2064PC68-33"; part2000 _ Rope.Fetch[circuit.partType]='2; [] _ CoreOps.VisitWire[cellType.public, PushPins]; FlattenCellType[cell: cellType, bindings: CoreFlat.InitialBindingTable[cellType]]; [] _ CoreOps.VisitWire[cellType.public, GetParms]; }; trace: BOOL _ FALSE; PruneFlattenedCircuit: PROC [circuit: FlatCircuit] RETURNS [pruned: RefTab.Ref] = { CheckSignal: RefTab.EachPairAction = { signal: Signal _ NARROW[key]; sensed, physical: BOOL _ FALSE; IF RefTab.Fetch[pruned, signal].found THEN RETURN; [sensed, physical] _ SensedPhysicalDrivenTristate[signal, pruned]; IF NOT sensed AND (signal.unbonded OR NOT physical) THEN { IF trace THEN TerminalIO.PutF["\npruning signal: %g", IO.rope[signal.name]]; IF NOT RefTab.Insert[pruned, signal, signal] THEN ERROR; FOR cl: SymbolSignalPins _ signal.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; IF ssp.pin.direction=Out THEN IF NOT RefTab.Insert[pruned, ssp, ssp] THEN ERROR; [] _ RefTab.Insert[symbolCheck, ssp.symbol, ssp.symbol]; ENDLOOP; }; }; CheckSymbol: RefTab.EachPairAction = { symbol: Symbol _ NARROW[key]; IF RefTab.Fetch[pruned, symbol].found THEN RETURN; FOR cl: SymbolSignalPins _ symbol.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; IF ssp.pin.direction=Out AND NOT RefTab.Fetch[pruned, ssp].found THEN RETURN; ENDLOOP; IF trace THEN TerminalIO.PutF["\npruning symbol: %g", IO.rope[symbol.name]]; IF NOT RefTab.Insert[pruned, symbol, symbol] THEN ERROR; FOR cl: SymbolSignalPins _ symbol.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; IF ssp.pin.direction=In THEN IF NOT RefTab.Insert[pruned, ssp, ssp] THEN ERROR; [] _ RefTab.Insert[signalCheck, ssp.signal, ssp.signal]; ENDLOOP; }; signalCheck: RefTab.Ref _ RefTab.Create[]; symbolCheck: RefTab.Ref _ RefTab.Create[]; pruned _ RefTab.Create[]; FOR sl: Signals _ circuit.signals, sl.rest UNTIL sl=NIL DO IF NOT RefTab.Insert[signalCheck, sl.first, sl.first] THEN ERROR; ENDLOOP; UNTIL RefTab.GetSize[symbolCheck]=0 AND RefTab.GetSize[signalCheck]=0 DO [] _ RefTab.Pairs[signalCheck, CheckSignal]; RefTab.Erase[signalCheck]; [] _ RefTab.Pairs[symbolCheck, CheckSymbol]; RefTab.Erase[symbolCheck]; ENDLOOP; }; CheckMultipleDrivers: PROC [circuit: FlatCircuit] RETURNS [names: LOR _ NIL]= { Driven: TYPE = {Never, Always, Tristate}; FOR sl: Signals _ circuit.signals, sl.rest UNTIL sl=NIL DO driven: Driven _ Never; FOR cl: SymbolSignalPins _ sl.first.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; IF ssp.pin.direction=Out THEN { IF driven=Always OR (driven=Tristate AND NOT ssp.pin.tristate) THEN { names _ CONS[sl.first.name, names]; EXIT; }; driven _ IF ssp.pin.tristate THEN Tristate ELSE Always; }; ENDLOOP; ENDLOOP; }; WriteFlattenedCircuit: PROC [circuit: FlatCircuit, pruned: RefTab.Ref, fileName: ROPE] = { WriteRecord: PROC [record: ROPE, parameters: LOR _ NIL] = { FOR rl: LOR _ parameters, rl.rest UNTIL rl=NIL DO record _ Rope.Cat[record, ",", rl.first]; ENDLOOP; IF Rope.Length[record]>=253 THEN ERROR; IO.PutF[stream, "%g\n", IO.rope[record]]; }; stream: IO.STREAM _ FS.StreamOpen[fileName, $create]; WriteRecord["LCANET,1"]; WriteRecord[IO.PutFR["PROG,Core2XNF,1,%g", IO.time[]]]; WriteRecord[Rope.Cat["PART,", circuit.partType]]; FOR sl: Symbols _ circuit.symbols, sl.rest UNTIL sl=NIL DO symbol: Symbol _ sl.first; IF NOT RefTab.Fetch[pruned, symbol].found THEN { WriteRecord[IO.PutFR["SYM,%g,%g", IO.rope[symbol.name], IO.rope[symbol.type]], symbol.parameters]; FOR cl: SymbolSignalPins _ symbol.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; pinRecord: ROPE _ IO.PutFR["PIN,%g,%g,%g", IO.rope[ssp.pin.xilinxName], IO.rope[directionNames[ssp.pin.direction]], IO.rope[ssp.signal.name]]; IF ssp.pin.invert OR ssp.parameters#NIL THEN pinRecord _ Rope.Cat[pinRecord, ","]; IF ssp.pin.invert THEN pinRecord _ Rope.Cat[pinRecord, ",INV"]; WriteRecord[pinRecord, ssp.parameters]; ENDLOOP; FOR rl: LOR _ symbol.configs, rl.rest UNTIL rl=NIL DO WriteRecord[Rope.Cat["CFG,", rl.first]]; ENDLOOP; WriteRecord["END"]; }; ENDLOOP; WriteRecord["PWR,1,public-$Vdd"]; WriteRecord["PWR,0,public-$Gnd"]; FOR sl: Signals _ circuit.signals, sl.rest UNTIL sl=NIL DO signal: Signal _ sl.first; sensed, physical, driven, tristate: BOOL _ FALSE; [sensed, physical, driven, tristate] _ SensedPhysicalDrivenTristate[signal, pruned]; IF physical OR signal.parameters#NIL THEN { signalRecord: ROPE _ IF physical THEN "EXT," ELSE "SIG,"; signalRecord _ Rope.Cat[signalRecord, signal.name]; IF physical THEN { signalRecord _ Rope.Cat[signalRecord, SELECT TRUE FROM signal.unbonded => ",U", driven AND sensed => ",B", driven AND tristate => ",T", driven => ",O", sensed => ",I", ENDCASE => ERROR]; IF signal.pin#NIL OR signal.parameters#NIL THEN signalRecord _ Rope.Cat[signalRecord, SELECT TRUE FROM signal.pin#NIL => IO.PutFR[",,LOC=P%g", IO.int[signal.pin^]], signal.parameters#NIL => ",", ENDCASE => ERROR]; }; WriteRecord[signalRecord, signal.parameters]; }; ENDLOOP; WriteRecord["EOF"]; IO.Close[stream]; }; <> SimpleData: TYPE = REF SimpleDataRec; SimpleDataRec: TYPE = RECORD [ xilinxType: ROPE, pins: Pins]; RegisterSimplePrimitive: PROC [coreName: ROPE, xilinxType: ROPE, pins: PinRecList, aliases: LOR _ NIL] = { simpleData: SimpleData _ NEW[SimpleDataRec _ [ xilinxType: xilinxType, pins: PinRecListToPinList[pins]]]; RegisterPrimitive[coreName, FlattenSimplePrimitive, simpleData]; FOR al: LOR _ aliases, al.rest UNTIL al=NIL DO RegisterPrimitive[al.first, FlattenSimplePrimitive, simpleData]; ENDLOOP; }; FlattenSimplePrimitive: TranslateProc = { simpleData: SimpleData _ NARROW[data]; symbol: Symbol _ MakeSymbol[CoreFlat.CellTypePathRope[root, flatCell], simpleData.xilinxType, MakeBindList[cell.public], simpleData.pins, circuit, root, flatCell, flatWireToSignal, bindings]; GetParameters[symbol, instance]; }; <> CLBData: TYPE = REF CLBDataRec; CLBDataRec: TYPE = RECORD [ config: ROPE, equate: ROPE]; clbPins: Pins _ PinRecListToPinList[LIST[ ["A", "A", In], ["B", "B", In], ["C", "C", In], ["D", "D", In], ["X", "X", Out]]]; RegisterCLBPrimitive: PROC [coreName: ROPE, config: ROPE, equate: ROPE] = { clbData: CLBData _ NEW[CLBDataRec _ [ config: config, equate: equate]]; RegisterPrimitive[coreName, FlattenCLBPrimitive, clbData]; }; FlattenCLBPrimitive: TranslateProc = { clbData: CLBData _ NARROW[data]; configs: LOR _ LIST[Rope.Cat["EQUATE F=", clbData.equate]]; symbol: Symbol; configs _ CONS[Rope.Cat["CONFIG X:F F:", clbData.config], configs]; configs _ CONS[Rope.Cat["BASE ", IF part2000 THEN "F" ELSE "FG"], configs]; symbol _ MakeSymbol[CoreFlat.CellTypePathRope[root, flatCell], "CLB", MakeBindList[cell.public], clbPins, circuit, root, flatCell, flatWireToSignal, bindings, NIL, configs]; GetParameters[symbol, instance]; }; <> flopPins: Pins _ PinRecListToPinList[LIST[ ["D", "D", In], ["CK", "C", In], ["Q", "Q", Out]]]; flopEnPins: Pins _ PinRecListToPinList[LIST[ ["en", "CE", In], ["D", "D", In], ["CK", "C", In], ["Q", "Q", Out]]]; invPins: Pins _ PinRecListToPinList[LIST[ ["I", "I", In], ["X", "O", Out]]]; FlattenFlopPrimitive: TranslateProc = { symbol: Symbol; flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; enableName: ROPE _ CoreOps.FixStupidRef[data]; d: Core.Wire _ CoreOps.FindWire[cell.public, "D"]; c: Core.Wire _ CoreOps.FindWire[cell.public, "CK"]; q: Core.Wire _ CoreOps.FindWire[cell.public, "Q"]; nq: Core.Wire _ CoreOps.FindWire[cell.public, "NQ"]; en: Core.Wire _ IF enableName=NIL THEN NIL ELSE CoreOps.FindWire[cell.public, enableName]; bindList: BindList _ LIST[[d, "D"], [c, "CK"], [q, "Q"]]; IF en#NIL THEN bindList _ CONS[[en, enableName], bindList]; symbol _ MakeSymbol[flatName, "DFF", bindList, IF en=NIL THEN flopPins ELSE flopEnPins, circuit, root, flatCell, flatWireToSignal, bindings]; [] _ MakeSymbol[Rope.Cat[flatName, "ManufacturedInverter"], "INV", LIST[[q, "I"], [nq, "X"]], invPins, circuit, root, flatCell, flatWireToSignal, bindings]; GetParameters[symbol, instance]; }; <> symPins: Pins _ PinRecListToPinList[LIST[ ["I", "I", In], ["X", "O", Out]]]; FlattenSymDriverPrimitive: TranslateProc = { flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; i: Core.Wire _ CoreOps.FindWire[cell.public, "I"]; x: Core.Wire _ CoreOps.FindWire[cell.public, "X"]; nx: Core.Wire _ CoreOps.FindWire[cell.public, "nX"]; [] _ MakeSymbol[Rope.Cat[flatName, "ManufacturedBuffer"], "BUF", LIST[[i, "I"], [x, "X"]], symPins, circuit, root, flatCell, flatWireToSignal, bindings]; [] _ MakeSymbol[Rope.Cat[flatName, "ManufacturedInverter"], "INV", LIST[[i, "I"], [nx, "X"]], symPins, circuit, root, flatCell, flatWireToSignal, bindings]; }; <> tPin: Pin _ NEW[PinRec _ ["?", "T", In]]; iPin: Pin _ NEW[PinRec _ ["I", "I", In]]; oPin: Pin _ NEW[PinRec _ ["X", "O", Out,,TRUE]]; FlattenTristateDriver: TranslateProc = { symbol: Symbol; flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; en: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "EN"], circuit, root, flatWireToSignal, bindings]; i: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "I"], circuit, root, flatWireToSignal, bindings]; x: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "X"], circuit, root, flatWireToSignal, bindings]; nenb: Signal _ CreateSignal[circuit]; [] _ AddSymbol[circuit, Rope.Cat[flatName, "ManufacturedEnableInverter"], "INV", LIST[[iPin, en], [oPin, nenb]]]; symbol _ AddSymbol[circuit, Rope.Cat[flatName, "ManufacturedTristate"], "TBUF", LIST[[tPin, nenb], [iPin, i], [oPin, x]]]; GetParameters[symbol, instance]; }; FlattenTristateDriverInv: TranslateProc = { symbol: Symbol; flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; en: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "EN"], circuit, root, flatWireToSignal, bindings]; i: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "I"], circuit, root, flatWireToSignal, bindings]; x: Signal _ CreateBoundSignal[CoreOps.FindWire[cell.public, "X"], circuit, root, flatWireToSignal, bindings]; nenb: Signal _ CreateSignal[circuit]; nd: Signal _ CreateSignal[circuit]; [] _ AddSymbol[circuit, Rope.Cat[flatName, "ManufacturedEnableInverter"], "INV", LIST[[iPin, en], [oPin, nenb]]]; [] _ AddSymbol[circuit, Rope.Cat[flatName, "ManufacturedDataInverter"], "INV", LIST[[iPin, i], [oPin, nd]]]; symbol _ AddSymbol[circuit, Rope.Cat[flatName, "ManufacturedTristate"], "TBUF", LIST[[tPin, nenb], [iPin, nd], [oPin, x]]]; GetParameters[symbol, instance]; }; <> WriteXNF: PROC [command: CDSequencer.Command] = { XNFOne: CoreCDUser.EachRootCellTypeProc ~ { md: LOR _ SaveCellType[root]; FOR lor: LOR _ md, lor.rest UNTIL lor=NIL DO TerminalIO.PutF["\nMultiply driven: %g", IO.rope[lor.first]]; ENDLOOP; TerminalIO.PutF["\nXNF written: %g", IO.rope[CoreOps.GetCellTypeName[root]]]; }; [] _ CoreCDUser.EnumerateSelectedCellTypes[command.design, XNFOne]; }; <> RegisterPrimitive: PROC [coreName: ROPE, proc: TranslateProc, data: REF ANY _ NIL] = { primitive: Primitive _ NEW[PrimitiveRec _ [ translate: proc, data: data]]; IF NOT SymTab.Insert[primitives, coreName, primitive] THEN ERROR; }; PinRecListToPinList: PROC [pins: PinRecList] RETURNS [refPins: Pins _ NIL] = { FOR pl: PinRecList _ pins, pl.rest UNTIL pl=NIL DO refPins _ CONS[NEW[PinRec _ pl.first], refPins]; ENDLOOP; }; MakeBindList: PROC [public: Core.Wire] RETURNS [bindlist: BindList _ NIL] = { MakeBind: PROC [wire: Core.Wire] = { coreName: ROPE _ CoreOps.GetFullWireName[public, wire]; IF NOT GlobalDelete[coreName] THEN bindlist _ CONS[[wire, coreName], bindlist]; }; CoreOps.VisitRootAtomics[public, MakeBind]; }; MakeSymbol: PROC [name, type: ROPE, bind: BindList, pins: Pins, circuit: FlatCircuit, root: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec, flatWireToSignal, bindings: RefTab.Ref, parameters, configs: LOR _ NIL] RETURNS [symbol: Symbol] = { symbol _ CreateSymbol[circuit, name, type, parameters, configs]; FOR bl: BindList _ bind, bl.rest UNTIL bl=NIL DO IF NOT GlobalDelete[bl.first.name] THEN FOR pl: Pins _ pins, pl.rest UNTIL pl=NIL DO IF Rope.Equal[pl.first.coreName, bl.first.name] THEN { signal: Signal _ CreateBoundSignal[bl.first.wire, circuit, root, flatWireToSignal, bindings]; CreateSSP[symbol, pl.first, signal]; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; }; AddSymbol: PROC [circuit: FlatCircuit, name, type: ROPE, bindings: PinSignals] RETURNS [symbol: Symbol] = { symbol _ CreateSymbol[circuit, name, type]; FOR ps: PinSignals _ bindings, ps.rest UNTIL ps=NIL DO CreateSSP[symbol, ps.first.pin, ps.first.signal]; ENDLOOP; }; CreateSymbol: PROC [circuit: FlatCircuit, name, type: ROPE, parameters, configs: LOR _ NIL] RETURNS [symbol: Symbol] = { symbol _ NEW[SymbolRec]; symbol.name _ name; symbol.type _ type; symbol.parameters _ parameters; symbol.configs _ configs; circuit.symbols _ CONS[symbol, circuit.symbols]; }; CreateBoundSignal: PROC [wire: Core.Wire _ NIL, circuit: FlatCircuit, root: Core.CellType, flatWireToSignal: RefTab.Ref, bindings: RefTab.Ref] RETURNS [signal: Signal] = { flatWire: CoreFlat.FlatWire _ NARROW[RefTab.Fetch[bindings, wire].val]; signal _ NARROW[RefTab.Fetch[flatWireToSignal, flatWire].val]; IF signal=NIL THEN { signal _ CreateSignal[circuit, SignalName[root, flatWire]]; IF NOT RefTab.Insert[flatWireToSignal, NEW[CoreFlat.FlatWireRec _ flatWire^], signal] THEN ERROR; signal.pin _ NARROW[CoreProperties.GetWireProp[flatWire.wire, $Pin]]; }; }; CreateSignal: PROC [circuit: FlatCircuit, name: ROPE _ NIL] RETURNS [signal: Signal] = { signal _ NEW[SignalRec]; IF name=NIL THEN name _ SignalName[NIL, NIL]; signal.name _ name; circuit.signals _ CONS[signal, circuit.signals]; }; CreateSSP: PROC [symbol: Symbol, pin: Pin, signal: Signal] = { ssp: SymbolSignalPin _ NEW[SymbolSignalPinRec]; ssp.symbol _ symbol; ssp.pin _ pin; ssp.signal _ signal; symbol.connections _ CONS[ssp, symbol.connections]; signal.connections _ CONS[ssp, signal.connections]; }; GlobalDelete: PROC [name: ROPE] RETURNS [yes: BOOL _ FALSE] = { yes _ Rope.Equal[name, "Vdd"] OR Rope.Equal[name, "Gnd"] OR Rope.Equal[name, "RosemaryLogicTime"]; }; nameCount: INT _ 0; SignalName: PROC [cellType: Core.CellType, flatWire: CoreFlat.FlatWire] RETURNS [name: ROPE _ NIL] = { <> < />> <> BuildNew: Rope.ActionType = { c _ SELECT c FROM '/ => '$, '(, '[ => '<, '), '] => '>, '. => '-, '* => '_, ENDCASE => c; IF c IN ['A..'Z] THEN name _ Rope.Concat[name, "$"]; name _ Rope.Concat[name, Rope.FromChar[c]]; }; ManufactureName: PROC = { name _ IO.PutFR["N%g", IO.int[nameCount]]; nameCount _ nameCount + 1; }; IF cellType=NIL OR flatWire=NIL THEN ManufactureName[] ELSE { old: ROPE _ CoreFlat.WirePathRope[cellType, flatWire^]; shortName: ROPE _ CoreOps.GetShortWireName[flatWire.wire]; SELECT TRUE FROM Rope.Equal[shortName, "Vdd"] => name _ "public-$Vdd"; Rope.Equal[shortName, "Gnd"] => name _ "public-$Gnd"; Rope.Fetch[old]#'/ => [] _ Rope.Map[base: old, action: BuildNew]; ENDCASE => ManufactureName[]; }; }; SensedPhysicalDrivenTristate: PROC [signal: Signal, pruned: RefTab.Ref] RETURNS [sensed, physical, driven, tristate: BOOL _ FALSE] = { FOR cl: SymbolSignalPins _ signal.connections, cl.rest UNTIL cl=NIL DO ssp: SymbolSignalPin _ cl.first; IF NOT RefTab.Fetch[pruned, ssp].found THEN { sensed _ sensed OR ssp.pin.direction=In; physical _ physical OR ssp.pin.physicalPin; driven _ driven OR ssp.pin.direction=Out; tristate _ tristate OR ssp.pin.tristate; }; ENDLOOP; }; GetParameters: PROC [symbol: Symbol, instance: CoreClasses.CellInstance] = { FindParms: PROC [prop: ATOM, val: REF ANY] = { propName: ROPE _ Atom.GetPName[prop]; IF Rope.Match["Par*", propName, FALSE] THEN { parm: ROPE _ NARROW[val]; symbol.parameters _ CONS[parm, symbol.parameters]; }; }; CoreProperties.Enumerate[instance.properties, FindParms]; }; <> <> <<>> <> RegisterSimplePrimitive["IBuf", "IBUF", LIST[ ["I", "I", In, TRUE], ["X", "O", Out]]]; RegisterSimplePrimitive["OBuf", "OBUF", LIST[ ["I", "I", In], ["X", "O", Out, TRUE]]]; RegisterSimplePrimitive["OBufZ", "OBUFZ", LIST[ ["I", "I", In], ["EN", "T", In,,,TRUE], ["X", "O", Out, TRUE, TRUE]]]; RegisterSimplePrimitive["OutFF", "OUTFF", LIST[ ["D", "D", In], ["CK", "C", In], ["Q", "Q", Out, TRUE]]]; RegisterSimplePrimitive["OutFFZ", "OUTFFZ", LIST[ ["D", "D", In], ["EN", "T", In,,,TRUE], ["CK", "C", In], ["X", "O", Out, TRUE, TRUE]]]; RegisterSimplePrimitive["InFF", "INFF", LIST[ ["D", "D", In, TRUE], ["CK", "C", In], ["Q", "Q", Out]]]; RegisterSimplePrimitive["InLatch", "INLATCH", LIST[ ["D", "D", In, TRUE], ["E", "E", In], ["X", "O", In], ["Q", "Q", Out]]]; <> RegisterSimplePrimitive["inv", "INV", LIST[ ["I", "I", In], ["X", "O", Out]], LIST["invP", "invB", "invPB", "invBuffer", "invDriver"]]; RegisterSimplePrimitive["driver", "BUF", LIST[ ["I", "I", In], ["X", "O", Out]]]; RegisterPrimitive["symDriver", FlattenSymDriverPrimitive, NIL]; RegisterPrimitive["3BufferI", FlattenTristateDriverInv, NIL]; RegisterPrimitive["3BufferNI", FlattenTristateDriver, NIL]; <> <<["I", "I", In],>> <<["EN", "T", In,,,TRUE],>> <<["X", "O", Out, FALSE, TRUE]]];>> RegisterSimplePrimitive["AClk", "ACLK", LIST[ ["I", "I", In], ["X", "O", Out]]]; RegisterSimplePrimitive["GClk", "GCLK", LIST[ ["I", "I", In], ["X", "O", Out]]]; <> RegisterSimplePrimitive["and2", "AND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; RegisterSimplePrimitive["and3", "AND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["X", "O", Out]]]; RegisterSimplePrimitive["and4", "AND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["I-D", "4", In], ["X", "O", Out]]]; RegisterSimplePrimitive["or2", "OR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; RegisterSimplePrimitive["or3", "OR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["X", "O", Out]]]; RegisterSimplePrimitive["or4", "OR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["I-D", "4", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nand2", "NAND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nand3", "NAND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nand4", "NAND", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["I-D", "4", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nor2", "NOR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nor3", "NOR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["X", "O", Out]]]; RegisterSimplePrimitive["nor4", "NOR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["I-C", "3", In], ["I-D", "4", In], ["X", "O", Out]]]; RegisterSimplePrimitive["xor2", "XOR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; RegisterSimplePrimitive["xnor2", "XNOR", LIST[ ["I-A", "1", In], ["I-B", "2", In], ["X", "O", Out]]]; <> RegisterCLBPrimitive["a22o2iP", "A:B:C:D", "~((A*B)+(C*D))"]; RegisterCLBPrimitive["a22o2i", "A:B:C:D", "~((A*B)+(C*D))"]; RegisterCLBPrimitive["o22a2iP", "A:B:C:D", "~((A+B)*(C+D))"]; RegisterCLBPrimitive["o22a2i", "A:B:C:D", "~((A+B)*(C+D))"]; RegisterCLBPrimitive["a21o2i", "A:B:C", "~((A*B)+C)"]; RegisterCLBPrimitive["o21a2i", "A:B:C", "~((A+B)*C)"]; <> RegisterSimplePrimitive["DFF", "DFF", LIST[ ["D", "D", In], ["ap", "SD", In], ["ar", "RD", In], ["CK", "C", In], ["Q", "Q", Out]]]; RegisterSimplePrimitive["ffAR", "DFF", LIST[ ["D", "D", In], ["r", "RD", In], ["CK", "C", In], ["Q", "Q", Out]]]; RegisterPrimitive["ff", FlattenFlopPrimitive, NIL]; RegisterPrimitive["ffEn", FlattenFlopPrimitive, "en"]; <<>> <> RegisterSimplePrimitive["pullUp", "PULLUP", LIST[ ["out", "O", Out, FALSE, FALSE]]]; RegisterSimplePrimitive["Osc", "OSC", LIST[ ["X", "O", Out]]]; CDCommandOps.RegisterWithMenu[$SpecialMenu, "WriteXNF", "Extract selected cells and write xnf files", $WriteXNF, WriteXNF]; END.