ArbPEGen.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
E. McCreight, February 11, 1987 5:15:01 pm PST
Last edited by: Christian Jacobi, January 9, 1987 5:08:31 pm PST
DIRECTORY
CDTexts, CDOps, CDRects, CDCells, CDGenerate, CD, CDDirectory,
CDSatellites, IO, Rope, TerminalIO;
ArbPEGen: CEDAR PROGRAM
IMPORTS CDOps, CDTexts, CDRects, CDCells, CDGenerate, CD,
CDSatellites, IO, Rope, TerminalIO
=
BEGIN
tech: CD.Technology ← CD.FetchTechnology[$cmosB];
comment: CD.Layer ← CD.FetchLayer[t: tech, uniqueKey: $comment];
font: CDTexts.CDFont ← CDTexts.MakeFont[name: "Xerox/TiogaFonts/Helvetica8", scale: 2];
lambda: INT ← tech.lambda;
cellSizeY: INT ← 8*13*lambda;
PETerms: CDGenerate.GeneratorProc =
BEGIN
Trit: TYPE = {zero, one, x};
nBits: [1..4] = TerminalIO.RequestInt["How many bits wide? [1..4] "];
Pattern: TYPE = ARRAY [0..4) OF Trit;
yBase: INT ← 0;
outGates: ARRAY BOOL -- isSome -- OF Rope.ROPE ← ["and8cw", "or8aw"];
inGates: ARRAY BOOL -- isSome -- OF ARRAY [1..4] OF Rope.ROPE ← [
["*pass", "Logic.nand2.icon", "Logic.nand3.icon", "Logic.nand4.icon"], ["*pass", "Logic.nor2P.icon", "Logic.nor3P.icon", "Logic.nor4P.icon"]];
gateInpPos: ARRAY [1..4] OF RECORD [base, delta: INT] ←
[[6,0], [4, 4], [2,4], [2,3]];
XOR: PROC [ a, b: BOOL ] RETURNS [ c: BOOL] = {
c ← (a AND NOT b) OR (b AND NOT a);
};
AddToTermCell: PROC [pattern: Pattern] =
BEGIN
mainGate, inGate, ioWire, text: CD.Object;
tInst, wInst: CD.Instance;
isSome: BOOL;
sCnt: NAT ← 0;
gateName: Rope.ROPENIL;
FOR i: NAT IN [0..nBits) DO
IF pattern[i] # x THEN {
sCnt ← sCnt+1;
isSome ← pattern[i] = zero;
};
ENDLOOP;
ioWire ← CDRects.CreateRect[size: [x: 19*lambda, y: lambda/2], l: comment];
mainGate ← CDGenerate.FetchNCall[directory, design, outGates[isSome]];
.. if sCnt=1 then optimize out a level of inverting gate
[] ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: mainGate, trans: CDOps.FitObjectI[mainGate, [x: (19+16)*lambda, y: yBase+6*lambda]]];
wInst ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: ioWire, trans: [[x: (19+16+40)*lambda, y: yBase+90*lambda]]].newInst;
text ← CDTexts.Create[
text: IO.PutFR["%s%s",
IO.rope[IF isSome THEN "Some" ELSE "No"], IO.rope[PatternToRope[pattern]]],
font: font, layer: comment, flip: TRUE];
tInst ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: text, trans: CDOps.FitObjectI[text, [x: (19+16+40+3)*lambda, y: yBase+90*lambda]]].newInst;
CDSatellites.Associate[wInst, tInst];
gateName ← inGates[isSome][sCnt];
inGate ← CDGenerate.FetchNCall[IF gateName.Fetch[0]='* THEN directory ELSE imports, design, IF gateName.Fetch[0]='* THEN gateName.Substr[1] ELSE gateName];
FOR input: NAT IN [0..8) DO
gateInput: NAT ← 0;
yPos: INT ← yBase+input*13*lambda;
[] ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: inGate, trans: CDOps.FitObjectI[inGate, [x: 19*lambda, y: yPos]]];
FOR bit: NAT IN [0..nBits) DO
IF pattern[bit] # x THEN {
inWireY: INT ← yPos+(gateInpPos[sCnt].base+gateInput*gateInpPos[sCnt].delta)*lambda;
wInst ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: ioWire, trans: CDOps.FitObjectI[ioWire, [x: 0, y: inWireY]]].newInst;
text ← CDTexts.Create[
text: IO.PutFR["%sIn[%d][%d]",
IO.rope[IF XOR[sCnt=1, XOR[isSome, (pattern[bit] = one)]] THEN "" ELSE "n"], IO.int[input], IO.int[bit]],
font: font, layer: comment, flip: TRUE];
tInst ← CDCells.IncludeOb[mode: dontResize, cell: ob, ob: text, trans: CDOps.FitObjectI[text, [x: 0, y: inWireY]]].newInst;
CDSatellites.Associate[wInst, tInst];
gateInput ← gateInput+1;
};
ENDLOOP;
ENDLOOP;
yBase ← yBase+cellSizeY;
END;
PatternToRope: PROC [p: Pattern] RETURNS [r: Rope.ROPE] =
BEGIN
r ← NIL;
FOR i: NAT IN [0..nBits) DO
r ← r.Cat[(SELECT p[i] FROM
zero => "0",
one => "1",
x => "x",
ENDCASE => ERROR)];
ENDLOOP;
END;
p: Pattern;
twoToThe: ARRAY [0..5) OF INT ← [1, 2, 4, 8, 16];
The useful patterns are
Some{0|x}*0{x}*
No{0|x}*0{0|x}*1{x}*
IF design.technology#tech THEN ERROR;
ob ← CDCells.CreateEmptyCell[];
FOR ls: NAT IN [0..nBits) DO -- position of last significant digit (0 or 1)
delta: NAT = twoToThe[(nBits-1)-ls];
FOR i: NAT ← 0, i+delta WHILE i+delta < twoToThe[nBits] DO
FOR j: NAT IN [0..nBits) DO
p[j] ← (SELECT (i/twoToThe[nBits-1-j]) MOD 2 FROM
0 => IF j <= ls THEN zero ELSE x,
1 => IF j = ls THEN one ELSE x,
ENDCASE => ERROR);
ENDLOOP;
AddToTermCell[p];
ENDLOOP;
ENDLOOP;
[] ← CDCells.ResizeCell[design, ob];
END;
table: CDGenerate.Context ← CDGenerate.AssertContext["USER"];
directory: CDGenerate.Context ← CDGenerate.AssertContext["DIRECTORY"];
imports: CDGenerate.Context ← CDGenerate.AssertContext["IMPORT"];
[] ← table.Register["PETerms", PETerms];
END.