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
font: CDTexts.CDFont ← CDTexts.MakeFont[name: "Xerox/TiogaFonts/Helvetica8", scale: 2];
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.ROPE ← NIL;
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;