DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, FS, RefTab, SymTab, IO, Rope, TerminalIO, XilinxIO; XilinxIOImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreFlat, CoreOps, CoreProperties, FS, RefTab, SymTab, IO, Rope, TerminalIO EXPORTS XilinxIO = BEGIN OPEN XilinxIO; ROPE: TYPE = Core.ROPE; Primitive: TYPE = REF PrimitiveRec; PrimitiveRec: TYPE = RECORD [ translate: TranslateProc, data: REF ANY]; TranslateProc: TYPE = PROC [stream: IO.STREAM, root, cell: Core.CellType, name: ROPE, flatCell: CoreFlat.FlatCellTypeRec, iomap: SymTab.Ref, part2000: BOOL, data: REF ANY]; Pins: TYPE = LIST OF Pin; Pin: TYPE = RECORD [ coreName: ROPE, xilinxName: ROPE, direction: InOrOut, physicalPin: BOOL _ FALSE]; InOrOut: TYPE = {In, Out}; directionNames: ARRAY InOrOut OF ROPE _ ["I", "O"]; primitives: SymTab.Ref _ SymTab.Create[]; SaveCellType: PUBLIC PROC [cellType: Core.CellType, fileName: ROPE _ NIL] = { WriteCellType: 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, WriteCellType] ELSE primitive.translate[stream, cellType, cell, name, flatCell, iomap, part2000, primitive.data]; }; WriteEXT: PROC [wire: Core.Wire] = { name: ROPE _ CoreOps.GetFullWireName[cellType.public, wire]; IF NOT GlobalDelete[name] THEN { signalName: ROPE _ SignalName[cellType, CoreFlat.rootCellType, wire]; pin: REF INT _ NARROW[CoreProperties.InheritPublicProp[cellType, wire, $Pin], REF INT]; direction: ROPE _ NARROW[SymTab.Fetch[iomap, signalName].val]; IF direction=NIL THEN ERROR; IO.PutF[stream, "EXT,%g,%g", IO.rope[signalName], IO.rope[direction]]; IF pin#NIL THEN IO.PutF[stream, ",,LOC=P%g", IO.int[pin^]]; IO.PutRope[stream, "\n"]; }; }; stream: IO.STREAM _ NIL; iomap: SymTab.Ref _ SymTab.Create[]; partTypeName: ROPE _ NARROW[CoreProperties.InheritCellTypeProp[cellType, $XilinxPartType]]; part2000: BOOL _ FALSE; IF fileName=NIL THEN fileName _ Rope.Cat[CoreOps.GetCellTypeName[cellType], ".xnf"]; stream _ FS.StreamOpen[fileName, $create]; IO.PutRope[stream, "LCANET,1\n"]; IO.PutF[stream, "PROG,Core2XNF,1,%g\n", IO.time[]]; IF partTypeName=NIL THEN partTypeName _ "2064PC68-33"; part2000 _ Rope.Fetch[partTypeName]='2; IO.PutF[stream, "PART,%g\n", IO.rope[partTypeName]]; WriteCellType[cell: cellType, bindings: CoreFlat.InitialBindingTable[cellType]]; IO.PutRope[stream, "PWR,1,public-$Vdd\n"]; IO.PutRope[stream, "PWR,0,public-$Gnd\n"]; CoreOps.VisitRootAtomics[cellType.public, WriteEXT]; IO.PutRope[stream, "EOF\n"]; IO.Close[stream]; }; PrintCoreRecursive: PUBLIC PROC [cellType: Core.CellType] = { WriteCellType: PROC [cell: Core.CellType, indent: NAT _ 0] = { name: ROPE _ CoreOps.GetCellTypeName[cell]; IF name#NIL THEN { FOR i: NAT IN [0..indent) DO IO.PutChar[stream, ' ] ENDLOOP; IO.PutF[stream, "%g\n", IO.rope[name]]; }; IF RefTab.Fetch[iomap, cell].found THEN RETURN; IF NOT RefTab.Insert[iomap, cell, $Printed] THEN ERROR; cell _ CoreOps.ToBasic[cell]; IF cell.class=CoreClasses.recordCellClass THEN { rct: CoreClasses.RecordCellType _ NARROW[cell.data]; subMap: RefTab.Ref _ RefTab.Create[]; FOR index: NAT IN [0..rct.size) DO subType: Core.CellType _ rct[index].type; IF NOT RefTab.Fetch[subMap, subType].found THEN { IF NOT RefTab.Insert[subMap, subType, $Printed] THEN ERROR; WriteCellType[subType, indent+2]; }; ENDLOOP; }; }; stream: IO.STREAM _ TerminalIO.TOS[]; iomap: RefTab.Ref _ RefTab.Create[]; WriteCellType[cellType]; }; SimpleData: TYPE = REF SimpleDataRec; SimpleDataRec: TYPE = RECORD [ xilinxType: ROPE, pins: Pins]; RegisterSimplePrimitive: PROC [coreName: ROPE, xilinxType: ROPE, pins: Pins] = { simpleData: SimpleData _ NEW[SimpleDataRec _ [ xilinxType: xilinxType, pins: pins]]; RegisterPrimitive[coreName, WriteSimplePrimitive, simpleData]; }; WriteSimplePrimitive: TranslateProc = { flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; simpleData: SimpleData _ NARROW[data]; IO.PutF[stream, "SYM,%g,%g\n", IO.rope[flatName], IO.rope[simpleData.xilinxType]]; WritePinsCleanly[root, flatCell, iomap, cell.public, stream, simpleData.pins]; IO.PutRope[stream, "END\n"]; IF (NOT part2000) AND Rope.Equal[simpleData.xilinxType, "DFF"] THEN ERROR; -- haven't sorted out 2000 vs. 3000 dependencies }; CLBData: TYPE = REF CLBDataRec; CLBDataRec: TYPE = RECORD [ config: ROPE, equate: ROPE]; clbPins: Pins _ 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, WriteCLBPrimitive, clbData]; }; WriteCLBPrimitive: TranslateProc = { flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; clbData: CLBData _ NARROW[data]; IO.PutF[stream, "SYM,%g,%g\n", IO.rope[flatName], IO.rope["CLB"]]; WritePinsCleanly[root, flatCell, iomap, cell.public, stream, clbPins]; IO.PutF[stream, "CFG,BASE %g\n", IO.rope[(IF part2000 THEN "F" ELSE "FG")]]; IO.PutF[stream, "CFG,CONFIG X:F F:%g\n", IO.rope[clbData.config]]; IO.PutF[stream, "CFG,EQUATE F=%g\n", IO.rope[clbData.equate]]; IO.PutRope[stream, "END\n"]; }; RegisterFlopPrimitive: PROC [coreName: ROPE, pins: Pins] = { simpleData: SimpleData _ NEW[SimpleDataRec _ [ xilinxType: NIL, pins: pins]]; RegisterPrimitive[coreName, WriteFlopPrimitive, simpleData]; }; WriteFlopPrimitive: TranslateProc = { unboundPins: LIST OF ROPE _ NIL; flatName: ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; simpleData: SimpleData _ NARROW[data]; IO.PutF[stream, "SYM,%g,%g\n", IO.rope[flatName], IO.rope["DFF"]]; unboundPins _ WritePins[root, flatCell, iomap, cell.public, stream, simpleData.pins]; IF unboundPins=NIL OR unboundPins.rest#NIL OR NOT Rope.Equal[unboundPins.first, "nQ", FALSE] THEN ERROR; IO.PutRope[stream, "END\n"]; { qSignalName: ROPE _ SignalName[root, flatCell, CoreOps.FindWire[cell.public, "Q"]]; nqSignalName: ROPE _ SignalName[root, flatCell, CoreOps.FindWire[cell.public, "NQ"]]; IO.PutF[stream, "SYM,%g,INV\n", IO.rope[Rope.Cat[flatName, "ManufacturedInverter"]]]; IO.PutF[stream, "PIN,I,%g,%g\n", IO.rope[directionNames[In]], IO.rope[qSignalName]]; IO.PutF[stream, "PIN,O,%g,%g\n", IO.rope[directionNames[Out]], IO.rope[nqSignalName]]; IO.PutRope[stream, "END\n"]; }; }; 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; }; GlobalDelete: PROC [name: ROPE] RETURNS [yes: BOOL _ FALSE] = { yes _ Rope.Equal[name, "Vdd"] OR Rope.Equal[name, "Gnd"] OR Rope.Equal[name, "RosemaryLogicTime"]; }; SignalName: PROC [cellType: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec, wire: Core.Wire] 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]]; }; canonicalWire: CoreFlat.FlatWireRec _ CoreFlat.CanonizeWire[cellType, [flatCell: flatCell, wire: wire]]; old: ROPE _ CoreFlat.WirePathRope[cellType, canonicalWire]; [] _ Rope.Map[base: old, action: BuildNew]; }; WritePinsCleanly: PROC [root: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec, iomap: SymTab.Ref, public: Core.Wire, stream: IO.STREAM, pins: Pins] = { IF WritePins[root, flatCell, iomap, public, stream, pins]#NIL THEN ERROR; }; WritePins: PROC [root: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec, iomap: SymTab.Ref, public: Core.Wire, stream: IO.STREAM, pins: Pins] RETURNS [unboundPins: LIST OF ROPE _ NIL] = { WritePin: PROC [wire: Core.Wire] = { coreName: ROPE _ CoreOps.GetFullWireName[public, wire]; signalName: ROPE _ SignalName[root, flatCell, wire]; FOR pl: Pins _ pins, pl.rest UNTIL pl=NIL DO IF Rope.Equal[pl.first.coreName, coreName] THEN { IF pl.first.physicalPin THEN { current: ROPE _ NARROW[SymTab.Fetch[iomap, signalName].val]; IF current=NIL THEN [] _ SymTab.Insert[iomap, signalName, directionNames[pl.first.direction]] ELSE IF NOT Rope.Equal[current, directionNames[pl.first.direction]] THEN ERROR; }; IO.PutF[stream, "PIN,%g,%g,%g\n", IO.rope[pl.first.xilinxName], IO.rope[directionNames[pl.first.direction]], IO.rope[signalName]]; RETURN; }; ENDLOOP; IF GlobalDelete[coreName] THEN RETURN; unboundPins _ CONS[coreName, unboundPins]; }; CoreOps.VisitRootAtomics[public, WritePin]; }; 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], ["X", "O", Out, 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], ["CK", "C", In], ["Q", "Q", Out, 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]]]; RegisterSimplePrimitive["invP", "INV", LIST[ ["I", "I", In], ["X", "O", Out]]]; RegisterSimplePrimitive["invBuffer", "INV", LIST[ ["I", "I", In], ["X", "O", Out]]]; RegisterSimplePrimitive["driver", "BUF", LIST[ ["I", "I", In], ["X", "O", Out]]]; RegisterSimplePrimitive["3BufferNI", "TBUF", LIST[ ["I", "I", In], ["EN", "T", In], ["X", "O", Out]]]; 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]]]; RegisterFlopPrimitive["ff", LIST[ ["D", "D", In], ["CK", "C", In], ["Q", "Q", Out]]]; RegisterSimplePrimitive["pullUp", "PULLUP", LIST[ ["out", "O", Out]]]; RegisterSimplePrimitive["Osc", "OSC", LIST[ ["X", "O", Out]]]; END. (XilinxIOImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Barth, July 18, 1989 6:00:22 pm PDT Last Edited by: Gasbarro July 18, 1989 6:23:49 pm PDT Types and Globals Functions Simple CLB Flop 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. Κχ– "cedar" style˜codešœ™Kšœ Οmœ1™Kšžœ žœžœžœ˜Kšžœžœžœ˜FKš žœžœžœžœžœ ˜;Kšžœ˜K˜—K˜—Kšœžœžœžœ˜K˜$Kšœžœžœ@˜[Kšœ žœžœ˜Kšžœ žœžœ@˜TKšœ žœ˜*Kšžœ˜!Kšžœ&žœ ˜3Kšžœžœžœ˜6Kšœ'˜'Kšžœžœ˜4KšœP˜PKšžœ(˜*Kšžœ(˜*K˜4Kšžœ˜Kšžœ˜K˜K™—š œžœžœ˜=š  œžœžœ ˜>Kšœžœ!˜+šžœžœžœ˜Kš žœžœžœ žœžœžœ˜˜>K˜K˜—š œ˜'Kšœ žœ-˜;Kšœžœ˜&Kšžœžœžœ˜RKšœN˜NKšžœ˜Kš žœžœ žœ*žœžœΟc0˜{K˜K˜——šž™Kšœ žœžœ ˜šœ žœžœ˜Kšœžœ˜ Kšœžœ˜K˜—šœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—š  œžœ žœ žœ žœ˜Kšœžœ˜%Kšœ˜Kšœ˜—Kšœ8˜8K˜K˜—š œ˜$Kšœ žœ-˜;Kšœžœ˜ Kšžœžœžœ˜BKšœF˜FKš žœžœžœ žœžœ ˜LKšžœ'žœ˜BKšžœ#žœ˜>Kšžœ˜K˜K˜——šž™š œžœ žœ˜<šœžœ˜.Kšœ žœ˜Kšœ ˜ —Kšœ<˜