DIRECTORY CD USING [commentLayer, Instance, InstanceList, InterestSize, Number, Object, Position, Rect], CDBasics USING [AddPoints, Extend, SubPoints, Surround], CDInstances USING [InstRectI, InstRectO], CDLayers USING [LayerWidth], CDOps USING [InstList, Redraw], CDRects USING [CreateRect, IsBareRect], CDSequencer USING [Command, ImplementCommand], Core USING [CellType, Wire, Wires], CoreCreate USING [Range, Seq], CoreGeometry USING [Decoration, HasPins], CoreOps USING [GetFullWireNames, SetShortWireName, VisitRootAtomics], IO USING [int, rope], Rope USING [ROPE], Sinix USING [Mode], SinixOps USING [SelectedCellType], Sisyph USING [Context, ES, mode], TerminalIO USING [PutF, PutRope]; IOBDesign: CEDAR PROGRAM IMPORTS CD, CDBasics, CDInstances, CDLayers, CDOps, CDRects, CDSequencer, CoreCreate, CoreGeometry, CoreOps, IO, SinixOps, Sisyph, TerminalIO ~ BEGIN CacheType: INT _ 001H; -- Constant defined in DynaBus protocol, Appendix B IOWRQ: INT _ 012H; -- Constant defined by the DynaBus protocol BIOWRQ: INT _ 014H; -- Constant defined by the DynaBus protocol ByteType: INT _ 02H; -- Constant defined by the IOBridge specs WordType: INT _ 03H; -- Constant defined by the IOBridge specs LongType: INT _ 04H; -- Constant defined by the IOBridge specs IOType: INT _ 02H; -- Constant defined by the IOBridge specs Fields: TYPE ~ LIST OF Field; Field: TYPE ~ REF FieldRep; FieldRep: TYPE ~ RECORD [name: Rope.ROPE, size: NAT]; -- size 0 means field is atomic wire Fld: PROC [name: Rope.ROPE, size: NAT _ 0] RETURNS [Field] ~ INLINE { RETURN [NEW[FieldRep _ [name, size]]] }; BusStructure: PROC [name: Rope.ROPE, size: NAT, fields: Fields] RETURNS [public: Core.Wires] ~ { bus: Core.Wire _ CoreCreate.Seq[name, size]; base: NAT _ 0; public _ LIST [bus]; WHILE fields#NIL DO f : Field = fields.first; IF f.size=0 THEN { -- Extraction of an atomic field public _ CONS [CoreOps.SetShortWireName[bus[base], f.name], public]; base _ base+1; } ELSE { -- Extraction of a regular field public _ CONS [CoreCreate.Range[bus, base, f.size, f.name], public]; base _ base+f.size; }; fields _ fields.rest; ENDLOOP; IF size#base THEN ERROR; -- the sum of field sizes is not equal to the bus size! }; Request: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "Request", size: 81, fields: LIST[ Fld["Cmd", 5], Fld["Mode"], Fld["IORange"], Fld["DeviceID", 10], Fld["Address", 32], Fld["Data", 32]]]; }; RequestH: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "RequestH", size: 49, fields: LIST[ Fld["Cmd", 5], Fld["Mode"], Fld["IORange"], Fld["DeviceID", 10], Fld["Address", 32]]]; }; Header: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "Header", size: 64, fields: LIST[ Fld["Cmd", 5], Fld["ModeError"], Fld["Shared"], Fld["DeviceID", 10], Fld["Address", 47]]]; }; IOAddress: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "IOA", size: 47, fields: LIST[ Fld["ZA", 15], Fld["Addr", 32]]]; }; IOLargeAddr: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "IOLarge", size: 32, fields: LIST[ Fld["DevT", 4], Fld["DevN", 4], Fld["DevSA", 24]]]; }; IOMediumAddr: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "IOMedium", size: 32, fields: LIST[ Fld["DevT", 8], Fld["DevN", 8], Fld["DevSA", 16]]]; }; IOSmallAddr: PROC [] RETURNS [public: Core.Wires] ~ { public _ BusStructure[name: "IOSmall", size: 32, fields: LIST[ Fld["DevT", 12], Fld["DevN", 10], Fld["DevSA", 10]]]; }; Interleave: PROC [b: NAT] RETURNS [public: Core.Wires] ~ { even: Core.Wire _ CoreCreate.Seq["Even", b]; odd: Core.Wire _ CoreCreate.Seq["Odd", b]; interleaved: Core.Wire _ CoreCreate.Seq["Interleaved", 2*b]; FOR i: NAT IN [0..b) DO interleaved[2*i] _ even[i]; interleaved[2*i+1] _ odd[i]; ENDLOOP; public _ LIST [even, odd, interleaved]; }; DBusSlave: PROC [cx: Sisyph.Context, dummy: BOOL] RETURNS [ct: Core.CellType] ~ { ct _ Sisyph.ES[IF dummy THEN "DummyDBusSlave.sch" ELSE "DBusSlave.sch", cx]; }; CheckSCBlock: PROC [comm: CDSequencer.Command] ~ { CheckPins: PROC [wire: Core.Wire] ~ { names: LIST OF Rope.ROPE; IF CoreGeometry.HasPins[decoration, wire] THEN RETURN; names _ CoreOps.GetFullWireNames[ct.public, wire]; IF names=NIL THEN names _ LIST ["-- Unnamed --"]; TerminalIO.PutF["Wire %g", IO.rope[names.first]]; WHILE names.rest#NIL DO names _ names.rest; TerminalIO.PutF[", %g", IO.rope[names.first]]; ENDLOOP; TerminalIO.PutF[" has no pin geometry\n"]; }; root, ct: Core.CellType; mode: Sinix.Mode = Sisyph.mode; decoration: CoreGeometry.Decoration = mode.decoration; [root: root, cell: ct] _ SinixOps.SelectedCellType[comm.design, mode]; IF root=NIL THEN RETURN; CoreOps.VisitRootAtomics[ct.public, CheckPins]; }; IsWire: PROC [inst: CD.Instance] RETURNS [BOOL] ~ { RETURN [inst.ob.layer=CD.commentLayer AND CDRects.IsBareRect[inst.ob]] }; FiddlePos: PROC [inst: CD.Instance, ir: CD.Rect] = { MoreZero: PROC [a, b: INT] RETURNS [INT_0] = { IF a>=0 AND b>=0 THEN RETURN [MIN[a, b]]; IF a<=0 AND b<=0 THEN RETURN [MAX[a, b]]; }; r: CD.Rect _ CDInstances.InstRectI[inst]; inst.trans.off.x _ inst.trans.off.x + MoreZero[ir.x1-r.x1, ir.x2-r.x2]; inst.trans.off.y _ inst.trans.off.y + MoreZero[ir.y1-r.y1, ir.y2-r.y2]; }; SwitchWireSizeCommand: PUBLIC PROC [comm: CDSequencer.Command] ~ { shrunk: INT _ 0; enlarged: INT _ 0; smallW: CD.Number = CDLayers.LayerWidth[comm.design, CD.commentLayer]; largeW: CD.Number = 3*smallW; TerminalIO.PutRope["switch size of selected wires\n"]; FOR list: CD.InstanceList _ CDOps.InstList[comm.design], list.rest WHILE list#NIL DO inst: CD.Instance _ list.first; -- instance may be modified ! IF inst.selected AND IsWire[inst] THEN { size: CD.Position = CD.InterestSize[inst.ob]; delta: CD.Number; SELECT MIN [size.x, size.y] FROM smallW => delta _ smallW; largeW => delta _ -smallW; ENDCASE => delta _ 0; IF delta#0 THEN { -- modify the instance goal: CD.Rect = CDBasics.Extend[CDInstances.InstRectI[inst], delta]; oldRect: CD.Rect = CDInstances.InstRectO[inst]; inst.ob _ CDRects.CreateRect[CDBasics.AddPoints[size, [2*delta, 2*delta]], inst.ob.layer]; inst.trans.off _ CDBasics.SubPoints[inst.trans.off, [delta, delta]]; FiddlePos[inst, goal]; -- move instance to fit goal: transf are the plague of CD CDOps.Redraw[comm.design, CDBasics.Surround[oldRect, CDInstances.InstRectO[inst]]]; IF delta>0 THEN enlarged _ enlarged + 1 ELSE shrunk _ shrunk + 1; }; }; ENDLOOP; TerminalIO.PutF["Enlarged %g wire(s), shrunk %g wire(s)\n", IO.int[enlarged], IO.int[shrunk]]; }; CDSequencer.ImplementCommand[$SwitchWireSize, SwitchWireSizeCommand]; CDSequencer.ImplementCommand[$CheckSCBlock, CheckSCBlock]; END. ήIOBDesign.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Jean-Marc Frailong, August 31, 1987 8:50:36 pm PDT Description of some wire icons in IOBDesign. Most of them could/should be replaced by schematics now that wire icons are correctly supported in Sisyph. Command to switch wire sizes between regular & bus-size Design Constants Structured buses Creates an interleaved wire icon: even, odd, interleaved. Each side is b bits, full bus is 2b bits. DBus slave block Return the real thing if dummy=FALSE, a version with hardwired constant registers if dummy=TRUE Sanity check of SC block(s) Notify of all public atomics that do not have geometry Pin definition name: TYPE ~ type declaration; DefinePins: PROC [Args] RETURNS [Results] ~ { Pins are described in LeftToRight, BottomToTop order as required by SC. Internal: PROC [internal: Rope.ROPE] ~ { Register wire on current side of SC block. TBD }; Pad: PROC [pad: Rope.ROPE] ~ { Register wire on current side of chip. TBD }; External: PROC [internal: Rope.ROPE, pad: Rope.ROPE] ~ { Wire is named internal on the SC block and pad on the chip boundary. The wire is an atomic input or output.. Pad[pad]; Internal[internal]; }; BusInternal: PROC [internal: Rope.ROPE, from: NAT, for: NAT] ~ { Wire is named internal on the SC block, but does not propagate to the side of the chip. The wire is a bus, of which bits [from..from+for) are used, as for extractors. Each of its atomic wires are input or output. The MSB has the lowest position. FOR i: NAT IN [from..from+for) DO suffix: ROPE = IO.PutFR["[%g]", IO.int[i]]; Internal[internal.Concat[suffix]]; ENDLOOP; }; BusExternal: PROC [internal: Rope.ROPE, pad: Rope.ROPE, from: NAT, for: NAT] ~ { Wire is named internal on the SC block and pad on the chip boundary. The wire is a bus, of which bits [from..from+for) are used, as for extractors. Each of its atomic wires are input or output. The MSB has the lowest position. FOR i: NAT IN [from..from+for) DO suffix: ROPE = IO.PutFR["[%g]", IO.int[i]]; External[internal.Concat[suffix], pad.Concat[suffix]]; ENDLOOP; }; IOInternal: PROC [input, output: Rope.ROPE] ~ { Wire has an input and an output wires on the SC block, but does not propagate to the side of the chip. The input has the lowest coordinate on the SC block. Internal[input]; Internal[output]; ENDLOOP; }; IOExternal: PROC [input, output: Rope.ROPE, pad: Rope.ROPE] ~ { Wire has an input and an output wires on the SC block and pad on the chip boundary. The input has the lowest coordinate on the SC block. Pad[pad]; Internal[input]; Internal[output]; ENDLOOP; }; IOBusInternal: PROC [input, output: Rope.ROPE, from: NAT, for: NAT] ~ { Wire is an IO bus that does not propagate to the chip boundary. Components are extracted according to from and for. Order is in[0], out[0], in[1], out[1], ... FOR i: NAT IN [from..from+for) DO suffix: ROPE = IO.PutFR["[%g]", IO.int[i]]; IOInternal[input.Concat[suffix], output.Concat[suffix]]; ENDLOOP; }; IOBusExternal: PROC [input, output: Rope.ROPE, pad: Rope.ROPE, from: NAT, for: NAT] ~ { Wire is an IO bus that propagates to the chip boundary. Components are extracted according to from and for. Order is in[0], out[0], in[1], out[1], ... FOR i: NAT IN [from..from+for) DO suffix: ROPE = IO.PutFR["[%g]", IO.int[i]]; IOExternal[input.Concat[suffix], output.Concat[suffix], pad.Concat[suffix]]; ENDLOOP; }; LeftSide: PROC ~ { Define pins on left side External["nHeaderIn", ""]; External["nGrant", ""]; External["ITIOBus", ""]; External["INT", ""]; External["MBReq", ""]; External["MBAck", ""]; External["PCLK", ""]; BusExternal["iDBus", "", 0, 7]; External["iDSelect", ""]; BusInternal["ExtraMapIn", 0, 6]; Internal["WExtra"]; BusInternal["LargeMapIn", 0, 14]; Internal["WLarge"]; BusInternal["SmallMapIn", 0, 22]; Internal["WSmall"]; BusInternal["MapOut", 0, 22]; BusInternal["MapAddr", 0, 4]; IOBusExternal["PBusIn", "PBusOut","" , 0, 32]; Internal["DrvPBus"]; BusInternal["FifoWAddr", 0, 4]; Internal["FifoWPulse"]; IOBusInternal["RqstIn", "RqstOut", 0, 81]; BusInternal["FifoRAddr", 0, 4]; External["iPReject", ""]; External["iPFault", ""]; BusExternal["iPCmd", "", 0, 7]; External["iPhA", ""]; External["iPhB", ""]; External["nRequest[0]", ""]; External["nSStopOut", ""]; External["nParityOut", ""]; }; RightSide: PROC ~ { Define pins on left side External["nParityIn", ""]; External["nSStopIn", ""]; External["nGLength", ""]; IOExternal["IOBAddrIn[31]", "nDEN", ""]; IOExternal["IOBAddrIn[30]", "DTnR", ""]; IOExternal["IOBAddrIn[29]", "MnINTA", ""]; BusExternal["IOBAddrIn", "", 24, 5]; IOBusExternal["IOBAddrIn", "IOBAddrOut", "", 0, 24]; IOExternal["nBHEIn", "nBHEOut", ""]; Internal["EnMOut"]; Internal["EnSOut"]; Internal["EnDOut"]; IOBusExternal["IOBDataIn", "IOBDataOut", "", 0, 16]; External["SnIOCS", ""]; External["SnMemCS", ""]; IOExternal["IOCheck", "nITFault", ""]; IOExternal["SnRD", "MnRD", ""]; IOExternal["SnWR", "MnWR", ""]; IOExternal["SnRDXnIOR", "MnIOR", ""]; IOExternal["SnWRXnIOW", "MnIOW", ""]; External["HReset", ""]; IOExternal["MnReady", "SnReady", ""]; External["nRequest[1]", ""]; External["nHeaderOut", ""]; External["CK", ""]; }; TopSide: PROC ~ { Define pins on top side IOBusExternal["nDataIn", "nDataOut", "", 0, 32]; }; BottomSide: PROC ~ { Define pins on bottom side IOBusExternal["nDataIn", "nDataOut", "", 32, 64]; }; }; Big wires versus small wires Return TRUE if the object of the instance is a schematics wire The command to enlarge/shrink all selected wires Initialization Κ ˜codešœ™Kšœ Οmœ1™šžœžœ  +˜?K˜—KšŸœžœ )˜>KšŸœžœ )˜>KšŸœžœ )˜>KšŸœžœ )˜K˜K˜ K˜K˜K˜K˜—K˜K˜—šŸœžœžœ˜2šœ:žœ˜?K˜K˜ K˜K˜K˜—K˜K˜—šŸœžœžœ˜0šœ8žœ˜=K˜K˜K˜K˜K˜—K˜K˜—šŸ œžœžœ˜3šœ5žœ˜:K˜K˜—K˜K˜—šŸ œžœžœ˜5šœ9žœ˜>K˜K˜K˜—K˜K˜—šŸ œžœžœ˜6šœ:žœ˜?K˜K˜K˜—K˜K˜—šŸ œžœžœ˜5šœ9žœ˜>K˜K˜K˜—K˜K˜—šŸ œžœžœžœ˜:K™cKšœ,˜,Kšœ*˜*Kšœ<˜<šžœžœžœž˜Kšœ˜Kšœ˜Kšžœ˜—Kšœ žœ˜'K˜K˜——™šŸ œžœ#žœ˜QK™_Kš œ žœžœžœžœ˜LK˜——™šŸ œžœ ˜2K™6šŸ œžœ˜%Kšœžœžœžœ˜Kšžœ(žœžœ˜6Kšœ2˜2Kšžœžœžœ žœ˜1Kšœžœ˜1šžœ žœž˜K˜Kšœžœ˜.Kšžœ˜—Kšœ*˜*K˜—K˜Kšœ˜Kšœ6˜6KšœF˜FKšžœžœžœžœ˜Kšœ/˜/K˜——™Kšœžœ™"šŸ œžœ žœ™1K™GšŸœžœžœ™(Kšœ*™*KšΟt™K™—šŸœžœ žœ™J™&Jš‘™K™—šŸœžœžœ žœ™8Kšœl™lKš‘œ‘™ Kšœ™K™—š Ÿ œžœžœžœžœ™@Kšœυ™υšžœžœžœž™!Kšœžœžœžœ ™+Kšœ"™"Kšžœ™—K™—š Ÿ œžœžœ žœžœžœ™PKšœžœΒ™βšžœžœžœž™!Kšœžœžœžœ ™+Kšœ6™6Kšžœ™—K™—šŸ œžœžœ™/Kšœ›™›Kšœ™Kšœ™Kšžœ™K™—šŸ œžœžœ žœ™?Kšœ-žœPžœ™ˆKšœ ™ Kšœ™Kšœ™Kšžœ™K™—š Ÿ œžœžœžœžœ™GKšœž™žšžœžœžœž™!Kšœžœžœžœ ™+Kšœ8™8Kšžœ™—K™—š Ÿ œžœžœ žœžœžœ™WKšœ–™–šžœžœžœž™!Kšœžœžœžœ ™+KšœL™LKšžœ™—K™—šŸœžœ™K™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ ™!Kšœ‘œ™Kšœ ™ Kšœ™Kšœ!™!Kšœ™Kšœ!™!Kšœ™Kšœ™Kšœ™Kšœ#‘œ ™0Kšœ™Kšœ™Kšœ™Jšœ*™*Kšœ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ ™!Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™K™—šŸ œžœ™K™Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™Kšœ%‘œ™*Kšœ%‘œ™*Kšœ'‘œ™,Kšœ‘œ ™&Kšœ*‘œ ™6Kšœ!‘œ™&Kšœ™Kšœ™Kšœ™Kšœ*‘œ ™6Kšœ‘œ™Kšœ‘œ™Kšœ#‘œ™(Kšœ‘œ™!Kšœ‘œ™!Kšœ"‘œ™'Kšœ"‘œ™'Kšœ‘œ™Kšœ"‘œ™'Kšœ‘œ™Kšœ‘œ™Kšœ‘œ™K™—šŸœžœ™K™Kšœ&‘œ ™2K™—šŸ œžœ™K™Kšœ&‘œ ™3K™—K™——™š Ÿœžœžœ žœžœ˜3Kšœžœ3™>Kšžœžœžœ˜FK˜K™—šŸ œžœžœžœ ˜4š Ÿœžœžœžœžœ˜.Kš žœžœžœžœžœ˜)Kš žœžœžœžœžœ˜)K˜—Kšœžœ$˜)KšœG˜GKšœG˜GK˜K˜—šŸœžœžœ ˜BK™0Kšœžœ˜Kšœ žœ˜Kšœžœ+žœ˜FKšœžœ˜Kšœ6˜6š žœžœ7žœžœž˜TKšœžœ ˜=šžœžœžœ˜(Kšœžœ žœ˜-Kšœžœ˜šžœžœž˜ Kšœ˜Kšœ˜Kšžœ˜—šžœ žœ ˜(Kšœžœ<˜DKšœ žœ$˜/KšœZ˜ZKšœD˜DKšœ 9˜PKšœS˜SKšžœ žœžœ˜AKšœ˜—Kšœ˜—Kšžœ˜—Kšœ<žœžœ˜^K˜——™šœE˜EK˜—šœ:˜:K˜——Kšžœ˜—…—<η