DIRECTORY Atom, CDCommandOps, CDSequencer, Core, CoreCDUser, 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, 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]; 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, 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]; MakeSymbol[CoreFlat.CellTypePathRope[root, flatCell], simpleData.xilinxType, MakeBindList[cell.public], simpleData.pins, circuit, root, flatCell, flatWireToSignal, bindings]; }; 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]]; configs _ CONS[Rope.Cat["CONFIG X:F F:", clbData.config], configs]; configs _ CONS[Rope.Cat["BASE ", IF part2000 THEN "F" ELSE "FG"], configs]; MakeSymbol[CoreFlat.CellTypePathRope[root, flatCell], "CLB", MakeBindList[cell.public], clbPins, circuit, root, flatCell, flatWireToSignal, bindings, NIL, configs]; }; 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 = { 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]; 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]; }; 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]; }; 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] = { symbol: Symbol _ NEW[SymbolRec]; symbol.name _ name; symbol.type _ type; symbol.parameters _ parameters; symbol.configs _ configs; circuit.symbols _ CONS[symbol, circuit.symbols]; 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 { ssp: SymbolSignalPin _ NEW[SymbolSignalPinRec]; flatWire: CoreFlat.FlatWire _ NARROW[RefTab.Fetch[bindings, bl.first.wire].val]; signal: Signal _ NARROW[RefTab.Fetch[flatWireToSignal, flatWire].val]; IF flatWire=NIL THEN ERROR; IF signal=NIL THEN { signal _ NEW[SignalRec]; IF NOT RefTab.Insert[flatWireToSignal, NEW[CoreFlat.FlatWireRec _ flatWire^], signal] THEN ERROR; signal.name _ SignalName[root, flatWire]; signal.pin _ NARROW[CoreProperties.GetWireProp[flatWire.wire, $Pin]]; circuit.signals _ CONS[signal, circuit.signals]; }; ssp.symbol _ symbol; ssp.signal _ signal; ssp.pin _ pl.first; symbol.connections _ CONS[ssp, symbol.connections]; signal.connections _ CONS[ssp, signal.connections]; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; }; 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]]; }; 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 => { name _ IO.PutFR["N%g", IO.int[nameCount]]; nameCount _ nameCount + 1; }; }; 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; }; 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]; RegisterSimplePrimitive["3BufferNI", "TBUF", LIST[ ["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. @XilinxIOImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Barth, September 19, 1989 12:06:23 pm PDT Last Edited by: Gasbarro July 18, 1989 6:23:49 pm PDT Types and Globals Primitive Data Base Flattened Circuit some connections' pin.physicalPin = TRUE causes an EXT record to be emitted using unbonded, pin, and parameters all connections' pin.physicalPin = FALSE and parameters#NIL causes a SIG record to be emitted Functions Simple CLB Flop SymDriver Interactive Command Utilities CoreFlat uses Letter Digit / ( ) [ ] . * LCA allows Letter Digit $  - < > / but / is reserved for path names and names are case insensitive Registration Really should load the primitive definitions by scanning a cell in Xilinx.dale I/O Symbols Inverters, Buffers Gates: 2, 3, and 4 input Gates, compound Flops Misc. Ê1– "cedar" style˜codešœ™Kšœ Ïmœ1™Kšœžœ˜2K˜—Kšœžœžœ˜Kšžœ žœ-˜@Kšžœ˜K˜—K˜—Kšœ5˜5K˜—š¡œ ˜/Kšœžœ!˜+Kšœžœ%˜BKšžœ žœžœy˜ŽKšžœt˜xK˜—Kšœi˜iKšœžœ˜8Kšœ žœžœ˜Kšœ žœ˜Kšœžœ@˜YKšžœžœžœ"˜>Kšœ+˜+Kšœ2˜2KšœR˜RKšœ2˜2K˜K˜—šœžœžœ˜K˜—š¡œžœžœ˜Sš¡ œ˜&Kšœžœ˜Kšœžœž˜Kšžœ$žœžœ˜2KšœB˜Bš žœžœžœžœžœ žœ˜:Kšžœžœ)žœ˜LKšžœžœ'žœžœ˜8šžœ4žœžœž˜FKšœ ˜ Kš žœžœžœžœ!žœžœ˜PKšœ8˜8Kšžœ˜—K˜—K˜—š¡ œ˜&Kšœžœ˜Kšžœ$žœžœ˜2šžœ4žœžœž˜FKšœ ˜ Kš žœžœžœ!žœžœ˜MKšžœ˜—Kšžœžœ)žœ˜LKšžœžœ'žœžœ˜8šžœ4žœžœž˜FKšœ ˜ Kš žœžœžœžœ!žœžœ˜OKšœ8˜8Kšžœ˜—K˜—Kšœ*˜*K˜*K˜šžœ(žœžœž˜:Kšžœžœ0žœžœ˜AKšžœ˜—šžœžœž˜HKšœ,˜,Kšœ˜Kšœ,˜,Kšœ˜Kšžœ˜—K˜K˜—š ¡œžœžœ žœžœ˜OKšœžœ˜)šžœ(žœžœž˜:K˜šžœ6žœžœž˜HKšœ ˜ šžœžœ˜š žœžœžœžœžœ˜EKšœžœ˜#Kšžœ˜K˜—Kšœ žœžœ žœ˜7K˜—Kšžœ˜—Kšžœ˜—K˜K˜—š¡œžœ6žœ˜Zš ¡ œžœ žœžœžœ˜;š žœžœžœžœž˜1Kšœ)˜)Kšžœ˜—Kšžœžœžœ˜'Kšžœžœ˜)K˜—Kšœžœžœžœ˜5Kšœ˜Kšœ žœžœ ˜7Kšœ1˜1šžœ(žœžœž˜:K˜šžœžœ$žœ˜0Kšœ žœžœžœ(˜bšžœ4žœžœž˜FKšœ ˜ Kš œ žœžœžœžœ*žœ˜ŽKšžœžœžœžœ&˜RKšžœžœ)˜?Kšœ'˜'Kšžœ˜—š žœžœžœžœž˜5Kšœ(˜(Kšžœ˜—Kšœ˜K˜—Kšžœ˜—Kšœ!˜!Kšœ!˜!šžœ(žœžœž˜:Kšœ˜Kšœ$žœžœ˜1KšœT˜Tšžœ žœžœžœ˜+Kš œžœžœ žœžœ˜9Kšœ3˜3šžœ žœ˜šœ&žœžœž˜6Kšœ˜Kšœžœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšžœžœ˜—šžœ žœžœžœžœ'žœžœž˜fKšœ žœžœžœ˜=Kšœžœ˜Kšžœžœ˜—K˜—Kšœ-˜-K˜—Kšžœ˜—Kšœ˜Kšžœ˜K˜K˜——™Kšœ žœžœ˜%šœžœžœ˜Kšœ žœ˜Kšœ ˜ K˜—š ¡œžœ žœžœžœžœ˜jšœžœ˜.Kšœ˜Kšœ"˜"—Kšœ@˜@š žœžœžœžœž˜.Kšœ@˜@Kšžœ˜—K˜K˜—š¡œ˜)Kšœžœ˜&Kšœ®˜®K˜K˜——šž™Kšœ žœžœ ˜šœ žœžœ˜Kšœžœ˜ Kšœžœ˜K˜—šœ$žœ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—š ¡œžœ žœ žœ žœ˜Kšœžœ˜%Kšœ˜Kšœ˜—Kšœ:˜:K˜K˜—š¡œ˜&Kšœžœ˜ Kšœ žœžœ(˜;Kšœ žœ5˜CKš œ žœžœ žœžœ˜KKšœ–žœ ˜¤K˜K˜——šœ™šœ%žœ˜*Kšœ˜Kšœ˜K˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜Kšœ˜K˜K˜—šœ$žœ˜)Kšœ˜K˜K˜—š¡œ˜'Kšœ žœ-˜;Kšœ žœ˜.Kšœ2˜2Kšœ3˜3Kšœ2˜2Kšœ4˜4Kš œžœ žœžœžœžœ+˜ZKšœžœ ˜9Kšžœžœžœ žœ˜;Kš œ&žœžœžœ žœB˜„Kšœ>žœU˜—K˜K˜——šœ ™ šœ$žœ˜)Kšœ˜K˜K˜—š¡œ˜,Kšœ žœ-˜;Kšœ2˜2Kšœ2˜2Kšœ4˜4Kšœ<žœT˜”Kšœ>žœU˜—K˜K˜——™š¡œžœ#˜1š¡œ%˜+Kšœžœ˜š žœžœžœžœž˜,Kšœ)žœ˜=Kšžœ˜—Kšœ%žœ&˜MK˜—KšœC˜CK˜——™ š ¡œžœ žœžœžœžœ˜Všœžœ˜+Kšœ˜Kšœ ˜ —Kšžœžœ0žœžœ˜AK˜K˜—š¡œžœžœžœ˜Nšžœ žœžœž˜2Kšœ žœžœ˜0Kšžœ˜—K˜K˜—š¡ œžœžœžœ˜Mš¡œžœ˜$Kšœ žœ)˜7Kšžœžœžœ žœ˜OK˜—Kšœ+˜+K˜K˜—š ¡ œžœžœªžœžœ˜ÚKšœžœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœ˜0šžœžœžœž˜0š žœžœžœžœžœž˜Tšžœ.žœ˜6Kšœžœ˜/Kšœžœ,˜PKšœžœ/˜FKšžœ žœžœžœ˜šžœžœžœ˜Kšœ žœ ˜Kš žœžœ!žœ,žœžœ˜aKšœ)˜)Kšœ žœ2˜EKšœžœ˜0K˜—Kšœ˜Kšœ˜Kšœ˜Kšœžœ˜3Kšœžœ˜3Kšžœ˜Kšœ˜—Kšžœžœžœ˜Kšžœ˜—Kšžœ˜—K˜K˜—š ¡ œžœžœžœžœžœ˜?Kšœžœžœ'˜bK˜K˜—Kšœ žœ˜š ¡ œžœ8žœžœžœ˜fK™(šžœ ™#K™?—š¡œ˜šœžœž˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšžœ˜ —Kšžœžœ žœ˜4Kšœ+˜+K˜—Kšœžœ.˜7Kšœ žœ+˜:šžœžœž˜Kšœ5˜5Kšœ5˜5KšœA˜Ašžœ˜ Kšœžœžœ˜*K˜K˜——K˜K˜—š ¡œžœ&žœ&žœžœ˜†šžœ4žœžœž˜FKšœ ˜ šžœžœ!žœ˜-Kšœžœ˜(Kšœžœ˜+Kšœžœ˜)Kšœžœ˜(K˜—Kšžœ˜—K˜——šœ ™ ™NK™—šœÏb ™ šœ(žœ˜-Kšœžœ˜Kšœ˜—šœ(žœ˜-Kšœ˜Kšœžœ˜—šœ*žœ˜/Kšœ˜Kšœžœ˜Kšœžœžœ˜—šœ*žœ˜/Kšœ˜Kšœ˜Kšœžœ˜—šœ,žœ˜1Kšœ˜Kšœžœ˜Kšœ˜Kšœžœžœ˜—šœ(žœ˜-Kšœžœ˜Kšœ˜K˜—šœ.žœ˜3Kšœžœ˜Kšœ˜Kšœ˜K˜—K˜—š¢™šœ&žœ˜+Kšœ˜Kšœžœ5˜K—šœ)žœ˜.Kšœ˜Kšœ˜—Kšœ:žœ˜?šœ-žœ˜2Kšœ˜Kšœžœ˜Kšœžœžœ˜—šœ(žœ˜-Kšœ˜K˜—šœ(žœ˜-Kšœ˜K˜—K˜—š¢™šœ'žœ˜,Kšœ˜Kšœ˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜Kšœ˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—K˜šœ%žœ˜*Kšœ˜Kšœ˜K˜—šœ%žœ˜*Kšœ˜Kšœ˜Kšœ˜K˜—šœ%žœ˜*Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜šœ)žœ˜.Kšœ˜Kšœ˜K˜—šœ)žœ˜.Kšœ˜Kšœ˜Kšœ˜K˜—šœ)žœ˜.Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—K˜šœ'žœ˜,Kšœ˜Kšœ˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜Kšœ˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜K˜—šœ'žœ˜,Kšœ˜Kšœ˜K˜—šœ)žœ˜.Kšœ˜Kšœ˜K˜—K˜—š¢™Kšœ=˜=Kšœ<˜