DIRECTORY Atom USING [MakeAtom], Basics USING [BITAND, BITSHIFT], CD, CDInstances, CDBusCells USING [CreateBusCell], CDCells, CDSimpleOps, CDDirectory USING [Include], CDIO, CDOps, CDProperties, CDRects USING [CreateRect], CDRepetitions, CDSequencer, CDTexts, CDViewer, Commander USING [CommandProc, Register], CommandTool, FS, IO, NMos, NMosContacts, NMosTransistors, Rope USING [ROPE, Cat, IsEmpty, FromChar], TerminalIO, ViewerClasses USING [Viewer]; ChipmonkNMosRead: CEDAR MONITOR IMPORTS Atom, Basics, CDInstances, CDBusCells, CDCells, CDSimpleOps, CDDirectory, CDIO, CDOps, CDProperties, CDRects, CDRepetitions, CDSequencer, CDTexts, CDViewer, Commander, CommandTool, FS, IO, NMos, NMosContacts, NMosTransistors, Rope, TerminalIO SHARES CDProperties = BEGIN lambdaInChipmonk: INTEGER = 2; lambdaFactor: INT = NMos.lambda/lambdaInChipmonk; instance: INTEGER = 1; transistor: INTEGER = 2; contact: INTEGER = 3; wire: INTEGER = 4; rectangle: INTEGER = 5; text: INTEGER = 6; bus: INTEGER = 7; repeat: INTEGER = 8; contTypALen: INTEGER = 12; maxCellNum: INTEGER = 1500; codeWordForDataFile : CARDINAL = 123751B; debugging: BOOLEAN = FALSE; debug: BOOLEAN = FALSE; atomTableSize: INTEGER = 256; contTypA: ARRAY [1..contTypALen] OF contType = [ mDif, mPol, butt, burr, mm2, mDif, mDif, mm2, mm2, mm2, mm2, difShort ]; contLevel: ARRAY [1..contTypALen] OF CD.Layer = [ NMos.dif, NMos.pol, NMos.dif, NMos.dif, NMos.met2, NMos.dif, --NMos.nwelCont-- CD.errorLayer, NMos.dif, NMos.pol, NMos.dif, NMos.dif, NMos.dif ]; -- for versions < 6 fileLevel: ARRAY [0..15] OF CD.Layer = [ NMos.cut, NMos.dif, NMos.pol, NMos.met, NMos.imp, NMos.ovg, NMos.bur, CD.errorLayer --snerd-- , NMos.cut2, CD.errorLayer--pdif--, CD.errorLayer--pwelcont--, NMos.met2, CD.errorLayer--pwel--, CD.errorLayer--NMos.nwel--, CD.errorLayer--NMos.nwelCont--, CD.errorLayer --NOcOL-- ]; contType: TYPE = {burr, mDif, difShort, butt, mPol, mm2}; design: CD.Design; cellNameA: REF ARRAY [0..maxCellNum] OF CD.Object _ NEW[ARRAY [0..maxCellNum] OF CD.Object]; atomTable: REF ARRAY [1..atomTableSize] OF ATOM _ NEW[ARRAY [1..atomTableSize] OF ATOM]; standardFont: CDTexts.CDFont = CDTexts.MakeFont[name: "Xerox/TiogaFonts/Tioga10"]; chipfile: IO.STREAM; fileName: Rope.ROPE; errs: INT _0; NotYetImpl: PROC [] = { errs _ errs+1; TerminalIO.PutRope["?"]; }; BadObject: PROC [size: CD.Position _ [4, 4]] RETURNS [CD.Object] = { RETURN [CDRects.CreateRect[size, CD.errorLayer]] }; InWord: PROC RETURNS [INTEGER] = { highbyte: CARDINAL = LOOPHOLE[IO.GetChar[chipfile], CARDINAL]; lowbyte: CARDINAL = LOOPHOLE[IO.GetChar[chipfile], CARDINAL]; RETURN [ LOOPHOLE[(256*highbyte) + lowbyte, INTEGER] ]; }; FileFormat: ERROR = CODE; Lambda: PROCEDURE [i: INT] RETURNS [CD.Number] = INLINE { RETURN [lambdaFactor*i] }; InOrientation: PROC [] RETURNS [CD.Orientation] = INLINE { i: INTEGER = InWord[]; IF i>=0 AND i<=15 THEN RETURN [VAL[i/4*2 + i MOD 2]] --different representation ELSE ERROR FileFormat; }; ToLayer: PROC [i: INTEGER] RETURNS [CD.Layer] = INLINE { IF i>= 0 AND i<= 15 THEN RETURN [fileLevel[i]] ELSE ERROR FileFormat; }; InLayer: PROC [] RETURNS [CD.Layer] = INLINE { RETURN [ToLayer[InWord[]]] }; NewCellName: PROC [index: INTEGER] RETURNS [cellName: Rope.ROPE] = { cellName _ IO.PutFR[ "cell#%d", IO.int[index]]; }; InObject: PROC[version: INTEGER] RETURNS [obj: CD.Object, instProp: REF_NIL, instVal: REF_NIL] = BEGIN j, k, w, l, we, le, dumsur : INTEGER; kk: CARDINAL; lev: CD.Layer; dumrope: Rope.ROPE; IF debugging OR debug THEN TerminalIO.PutRope[" (Include new object ... "]; j _ InWord[]; SELECT j FROM instance => { k _ InWord[]; -- cell ID num obj _ cellNameA[k]; }; transistor => BEGIN impl: NMosTransistors.Implant _ NMosTransistors.enhancement; aExt: CD.Number _ 0; w _ InWord[]; l _ InWord[]; kk _ LOOPHOLE[InWord[]]; IF version > 4 AND LOOPHOLE[Basics.BITAND[kk, 10000B], CARDINAL] # 0 THEN dumsur _ InWord[]; IF LOOPHOLE[Basics.BITAND[kk, 20000B], CARDINAL] # 0 THEN aExt _ Lambda[InWord[]]; -- if angle get angle ext. IF LOOPHOLE[Basics.BITAND[kk, 100000B], CARDINAL]#0 THEN { IF version>7 THEN impl _ InWord[] ELSE impl _ LAST[NMosTransistors.Implant] }; we _ Basics.BITAND[Basics.BITSHIFT[kk, -6], 77B]; le _ Basics.BITAND[kk, 77B]; obj _ SELECT TRUE FROM LOOPHOLE[Basics.BITAND[kk,40000B], CARDINAL] #0 => NMosTransistors.CreatePullUp[Lambda[w], Lambda[l], Lambda[we], Lambda[le]], LOOPHOLE[Basics.BITAND[kk, 20000B], CARDINAL] #0 => NMosTransistors.CreateAngleTransistor[ w: Lambda[w], l: Lambda[l], wExt: Lambda[we], lExt: Lambda[le], aExt: aExt, implant: impl ], ENDCASE => NMosTransistors.CreateTransistor[ w: Lambda[w], l: Lambda[l], wExt: Lambda[we], lExt: Lambda[le], implant: impl ]; END; contact => BEGIN j: CARDINAL _ LOOPHOLE[InWord[]]; -- get contact type kk: CARDINAL _ Basics.BITAND[j, 37B]; -- get contact type l: CARDINAL _ Basics.BITSHIFT[j, -8]; lev _ IF version > 5 THEN InLayer[] ELSE contLevel[kk]; IF version > 4 THEN dumsur _ LOOPHOLE[InWord[]]; SELECT contTypA[kk] FROM mPol => obj _ NMosContacts.CreatePolyCon[Lambda[l]]; mDif => obj _ NMosContacts.CreateDifCon[Lambda[l]]; butt => obj_ NMosContacts.CreateButCon[]; burr => BEGIN w _ LOOPHOLE[InWord[]]; kk _ LOOPHOLE[InWord[]]; j _ Basics.BITSHIFT[kk, -8]; obj _ NMosContacts.CreateBurCon[Lambda[w], Lambda[l], Lambda[j], Lambda[LOOPHOLE[Basics.BITAND[kk, 37B], CARDINAL]]]; END; mm2 => obj _ NMosContacts.CreateMmCon[Lambda[l], 0, 0]; ENDCASE => ERROR; END; wire => BEGIN i: INTEGER; w _ InWord[]; l _ InWord[]; i _ InWord[]; lev _ ToLayer[i]; SELECT i FROM 7 => {instVal _ $snerdRect; instProp _ $SignalName}; 15 => {instVal _ $NOcOLRect; instProp _ $SignalName}; ENDCASE => NULL; obj _ CDRects.CreateRect[[Lambda[w],Lambda[l]], lev]; END; rectangle => BEGIN i: INTEGER; w _ InWord[]; l _ InWord[]; instVal _ $Rect; instProp _ $CDxChipmonkThinks; i _ InWord[]; lev _ ToLayer[i]; SELECT i FROM 7 => {instVal _ $snerdRect; instProp _ $SignalName}; 15 => {instVal _ $NOcOLRect; instProp _ $SignalName}; ENDCASE => NULL; obj _ CDRects.CreateRect[[Lambda[w], Lambda[l]], lev]; END; text => { dumrope _ InString[]; obj _ CDTexts.Create[dumrope, standardFont] }; bus => BEGIN w: CD.Number = Lambda[InWord[]]; l: CD.Number = Lambda[InWord[]]; lev: CD.Layer = InLayer[]; count: NAT = InWord[]; spacing: CD.Number = Lambda[InWord[]]; topInc: CD.Number = Lambda[InWord[]]; botInc: CD.Number = Lambda[InWord[]]; obj _ CDBusCells.CreateBusCell[ design: design, sizeOfFirst: [w, l], lev: lev, count: count, offset: [spacing, topInc], lengIncrement: botInc-topInc ]; -- compare: obj _ Chipmonk.makeBus[l, w, lev, count, spacing, topInc, botInc]; END; repeat => BEGIN rob: CD.Object = InObject[version].obj; ignoredw: INT = InWord[]; -- ignored ignoredl: INT = InWord[]; -- ignored dx: CD.Number = Lambda[InWord[]]; dy: CD.Number = Lambda[InWord[]]; count: NAT _ InWord[]; orient: CD.Orientation _ InOrientation[]; obj _ CDRepetitions.CreateRepetition[design: design, ob: rob, count: count, offset: [dx, dy], orientation: orient]; END; ENDCASE => { obj _ BadObject[]; TerminalIO.PutRope["** Erronous object\n"]; }; IF debugging OR debug THEN TerminalIO.PutRope[" done) \n"]; END; -- of InObject InList: PROC[ver: INTEGER] RETURNS [list: CD.InstanceList _ NIL, length: INT] = BEGIN instProp: REF _ NIL; instVal: REF _ NIL; instCount: INTEGER; inst: CD.Instance; ob: CD.Object; location: CD.Position; orientation: CD.Orientation; IF debugging OR debug THEN TerminalIO.PutRope["start list\n"]; instCount _ InWord[]; FOR iNum: INTEGER IN [0..instCount) DO location.x _ Lambda[InWord[]]; location.y _ Lambda[InWord[]]; orientation _ InOrientation[]; [ob, instProp, instVal] _ InObject[ver]; IF ob=NIL THEN { ob _ BadObject[]; TerminalIO.PutRope["nil object\n"] }; inst _ CDInstances.NewInst[ob: ob]; inst.trans _ CDOps.FitObjectI[ob, location, orientation]; list _ CONS[inst, list]; IF instProp#NIL THEN CDProperties.PutInstanceProp[inst, instProp, instVal]; IF ver > 3 THEN BEGIN propCount: INTEGER = InWord[]; FOR propNum: INTEGER IN [0..propCount) DO InProp[inst]; ENDLOOP; END; ENDLOOP; RETURN[list, instCount]; END; sigName: ATOM = Atom.MakeAtom["SIGNAL NAME"]; InProp: PROC [inst: CD.Instance] = { kind: INTEGER _ InWord[]; name: REF _ NIL; value: REF; SELECT kind FROM 1 => { IF inst=NIL OR inst.ob=NIL OR ISTYPE[inst.ob.specific, CD.RectSpecific] THEN name _ $SignalName ELSE name _ $InstanceName; value _ InString[]; }; 2 => { name _ InAtom[]; value _ InAtom[]; IF name=sigName THEN name _ $SignalName; }; ENDCASE => { name _ NIL; TerminalIO.PutRope["** unknown property kind\n"]; }; IF name#NIL AND inst#NIL AND inst.ob#NIL THEN CDProperties.PutProp[onto: inst, prop: name, val: value] }; InAtom: PROC [] RETURNS[a: ATOM] = { i: INTEGER _ InWord[]; IF i<0 THEN { a _ atomTable[-i] } ELSE IF i>0 THEN { a _ Atom.MakeAtom[InString[]]; IF i <= atomTableSize THEN atomTable[i] _ a ELSE TerminalIO.PutRope["** atom table code wrong\n"]; } ELSE { TerminalIO.PutRope["** atom code wrong\n"]; a _ NIL } }; InString: PROC [] RETURNS[s: Rope.ROPE] = { j, len: CARDINAL; flg: BOOLEAN; j _ LOOPHOLE[InWord[]]; len _ Basics.BITSHIFT[j, -8]; IF len = 0 THEN BEGIN s _ ""; RETURN; END; flg _ TRUE; FOR i: CARDINAL IN [0..len) DO IF flg THEN s _ Rope.Cat[s, Rope.FromChar[LOOPHOLE[Basics.BITAND[j, 377B], CHAR]]] ELSE { j _ LOOPHOLE[InWord[]]; s _ Rope.Cat[s, Rope.FromChar[LOOPHOLE[Basics.BITSHIFT[j, -8], CHAR]]]; }; flg _ NOT flg; ENDLOOP; }; FileOpened: PROC [name: Rope.ROPE] RETURNS [fileWasOpened: BOOLEAN] = { IF Rope.IsEmpty[name] THEN name _ TerminalIO.RequestRope["Input file > "]; fileName _ CDIO.MakeName[name, "chip"]; chipfile _ FS.StreamOpen[fileName ! FS.Error => IF error.group#bug THEN { TerminalIO.PutRopes[fileName, " not opened: ", error.explanation]; TerminalIO.PutRope["\n"]; GOTO FileName }]; TerminalIO.PutRopes["File being read is ", fileName, "\n"]; fileWasOpened _ TRUE; EXITS FileName => {fileWasOpened _ FALSE}; }; signal: SIGNAL = CODE; ReadChip: PROC = BEGIN ENABLE { FileFormat => { TerminalIO.PutRope["\n**File-Format error [proceed does not clobber other designs]\n"]; SIGNAL signal; GOTO IOError; }; IO.EndOfStream => { TerminalIO.PutRope["\n**end of stream error [proceed does not clobber other designs]\n"]; SIGNAL signal; GOTO IOError; }; IO.Error => { TerminalIO.PutRope["\n**io error[proceed does not clobber other designs]\n"]; SIGNAL signal; GOTO IOError; }; }; i, j, k, ver, cCnt, dummy, depht: INTEGER; leng: INT; ss: Rope.ROPE; cob: CD.Object; cellSpecific: CD.CellSpecific; errs_0; i _ InWord[]; IF i # LOOPHOLE[codeWordForDataFile, INTEGER] AND NOT TerminalIO.Confirm["doesn't look like a .chip file -- should program continue?"] THEN RETURN; ver _ InWord[]; cCnt _ InWord[]; IF cCnt > maxCellNum THEN CDSequencer.Quit["Too many different kinds of cells in design...aborting read\n"]; IF ver < 3 THEN CDSequencer.Quit[" Version number too low...aborting read\n"]; IF ver>8 THEN CDSequencer.Quit[" new chipmonk version unknown to chipndale...aborting read\n"]; FOR j IN [0..cCnt] DO cellNameA[j] _ CDCells.CreateEmptyCell[]; ENDLOOP; TerminalIO.PutRope["Starting cell directory\n"]; FOR k IN [1..cCnt] DO j _ InWord[]; cob _ cellNameA[j]; ss _ InString[]; --cob.size.x--[] _ Lambda[InWord[]]; --cob.size.y--[] _ Lambda[InWord[]]; dummy _ InWord[]; cellSpecific _ NARROW[cob.specific, CD.CellSpecific]; [cellSpecific.contents, leng] _ InList[ver]; IF NOT Rope.IsEmpty[ss] THEN cellSpecific.name _ ss ELSE cellSpecific.name _ NewCellName[k]; [] _ CDDirectory.Include[design: design, object: cob, fiddleName: TRUE]; IF CDCells.IsEmpty[cob] THEN { TerminalIO.PutRopes["** empty cell ", cellSpecific.name, "\n"]; cellSpecific.contents _ LIST[CDInstances.NewInst[BadObject[]]]; }; [] _ CDCells.ResizeCell[NIL, cob]; CDCells.SetSimplificationTreshhold[cob]; ENDLOOP; TerminalIO.PutRope["finished cell directory\n"]; depht _ IF ver<7 THEN 0 ELSE InWord[]; IF depht>0 THEN { TerminalIO.PutRope["***design was pushed in; not read in correctly\n"]; RETURN; }; IF ver>=7 THEN { fileChangeCode: INTEGER = InWord[]; }; design.actual.first.specific.contents _ InList[ver].list; design.name _ fileName; TerminalIO.PutRope["Finished reading chip\n"]; IF errs>0 THEN { TerminalIO.PutF1[" %g unknown objects\n", [integer[errs]]]; errs _ 0; }; IO.Close[chipfile]; EXITS IOError => {TerminalIO.PutRope[" proceed; discard this design\n"];}; END; -- of ReadChip CommandReadChip: ENTRY Commander.CommandProc = BEGIN ENABLE { TerminalIO.UserAbort => GOTO UserAbrt; UNWIND => NULL; }; list: LIST OF Rope.ROPE; length: NAT; name: Rope.ROPE; [list, length] _ CommandTool.ParseToList[cmd]; IF length=0 THEN name_NIL ELSE IF length=1 THEN name_list.first ELSE { result_$Failure; msg_"unknown arguments"; RETURN }; design_ CDOps.CreateDesign[NMos.nmos]; IF FileOpened[name] THEN { ReadChip[]; CDSimpleOps.SelectAll[design]; CDSimpleOps.TransformSelected[design, rotate180X]; CDSimpleOps.DeselectAll[design]; [] _ CDViewer.CreateViewer[design]; }; EXITS UserAbrt => {TerminalIO.PutRope["read aborted\n"]}; END; Commander.Register[ key: "CDReadNMos", proc: CommandReadChip, doc: "Reads old nmos Chipmonk file" ]; Commander.Register[ key: "CDReadNMosA", proc: CommandReadChip, doc: "Reads old nmos Chipmonk file" ]; Commander.Register[ key: "CDReadCMNMos", proc: CommandReadChip, doc: "Reads old nmos Chipmonk file" ]; Commander.Register[ key: "CDReadCMNMosA", proc: CommandReadChip, doc: "Reads old nmos Chipmonk file" ]; END. žChipmonkNMosRead.mesa Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Last Edited by: Kimr, October 26, 1983 9:39 am Last Edited by: Jacobi, October 25, 1983 12:48 pm Last Edited by: Jacobi, March 25, 1986 5:06:39 pm PST Last edited by: Christian Jacobi, October 31, 1986 2:28:05 pm PST copy from cmos to nmos, not inverse! -- global constants --In Chipndale we must make no assumptions about the --value of lambda. It can (and does) change from time to time; --but we know that chipndales lambda is >= 2 -- global vars --lev _ IF Basics.BITAND[kk, 10000B] # LOOPHOLE[0] THEN NMos.pdif ELSE NMos.dif; --if you are debugging here: inspect "ec" ΚŽ˜code•StartOfExpansionl[r1: ROPE _ NIL, r2: ROPE _ NIL, r3: ROPE _ NIL, r4: ROPE _ NIL, r5: ROPE _ NIL, r6: ROPE _ NIL]šœ™Kšœ Οmœ7™BKšœ.™.Kšœ1™1Kšœ5™5K™AK™$—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˜šΟbœžœž˜KšžœΊžœ8˜ϋKšžœ˜—Kšž˜K˜šœ™K˜šœžœ˜ KšΟc5™5Kš ?™?Kš ,™,—Kšœžœ ˜1K˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜Kšœ žœ˜Kšœ žœ˜Kšœžœ ˜)Kšœ žœžœ˜Kšœžœžœ˜Kšœžœ˜šœ žœžœ ˜1Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ žœžœžœ ˜1Kšœ(˜(Kšœ œžœ˜@Kšœ&˜&Kšœ ˜—šœ žœ žœžœ ˜(Kšœ(˜(Kšœžœ   œ˜8Kšœ žœ˜"Kšžœ$˜&Kšžœžœ˜3Kšžœžœ   ˜7Kšœ˜—K˜—šœ™Kšœ žœ+˜9K˜Kšœžœ˜Kš œ ž œžœžœžœžœžœ ˜\Kš œ ž œžœžœžœžœžœ˜XK˜KšœR˜RK˜Kšœ žœžœ˜K˜K˜K˜ K˜šΟn œžœ˜Kšœ˜Kšœ˜Kšœ˜——K˜š ‘ œžœžœžœžœ ˜DKšžœžœ ˜0Kšœ˜—K˜š‘œžœžœžœ˜"Kš œ žœžœžœžœ˜>Kš œ žœžœžœžœ˜=Kšžœžœžœ˜7Kšœ˜K˜—Kšœ žœžœ˜K˜š ‘œž œžœžœžœ žœ˜9Kšžœ˜Kšœ˜K˜—š ‘ œžœžœžœžœ˜:Kšœžœ ˜Kš žœžœžœžœžœ žœ ˜OKšžœžœ ˜Kšœ˜K˜—š ‘œžœžœžœžœ žœ˜8Kšžœžœžœžœ˜.Kšžœžœ ˜Kšœ˜—K˜š ‘œžœžœžœ žœ˜.Kšžœ˜Kšœ˜—K˜š ‘ œžœ žœžœžœ˜DKšœ žœžœ ˜/Kšœ˜—K˜š‘œžœ žœžœžœžœžœ žœžœ˜aKšž˜Kšœžœ˜%Kšœžœ˜ Kšœžœ˜Kšœžœ˜K˜šžœ žœž˜Kšœ0˜0—Kšœ˜šžœž˜ šœ ˜ Kšœ ˜Kšœ˜Kšœ˜—šœ ˜ Kšž˜Kšœ<˜