FullDecoder: UserProc = {
zero: Object ← Get[design, "zero"];
one: Object ← Get[design, "one"];
left: Object ← Get[design, "left"];
right: Object ← Get[design, "right"];
inverter: Object ← Get[design, "inverter"];
invLeft: Object ← Get[design, "invLeft"];
invRight: Object ← Get[design, "invRight"];
DecGen:
PROC [n:
INT]
RETURNS [decoder: Object] = {
subDecoder: Object;
IF n=0 THEN RETURN[NIL];
subDecoder ← DecGen[n-1];
decoder ← AbutY[design,
AbutX[design, ArrayY[design, zero, TwoToThe[n-1]], subDecoder],
AbutX[design, ArrayY[design, one, TwoToThe[n-1]], subDecoder]];
};
RenamePadsProc: PWPins.RenameProc = {
newRope ←
SELECT
TRUE
FROM
Rope.Match["*.dataIn", oldRope] => Rope.Substr[oldRope, 0, Rope.Size[oldRope]-7],
Rope.Match["*.dataOut", oldRope] => Rope.Substr[oldRope, 0, Rope.Size[oldRope]-8],
Rope.Match["*.enableWrite", oldRope] => "enableWrite",
ENDCASE => oldRope;
};
MakeRight:
PROC [nb:
INT]
RETURNS [Object] = {
list: LIST OF Object ← NIL;
FOR i:
INT
IN [0 .. nb)
DO
Rename: PWPins.RenameProc = {
newRope ←
SELECT
TRUE
FROM
Rope.Equal["Output", oldRope] => PWPins.Index["Out", i],
ENDCASE => oldRope;
};
list ← CONS[PWPins.RenamePins[design, right, Rename], list];
ENDLOOP;
RETURN [AbutListY[design, list]];
};
MakeTop:
PROC [nb:
INT]
RETURNS [top: Object] = {
listOb: PW.ListOb ← NIL;
FOR n:
INT
IN [0..nb)
DO
Rename: PWPins.RenameProc = {
newRope ←
SELECT
TRUE
FROM
Rope.Equal["Input", oldRope] => PWPins.Index["In", n],
ENDCASE => oldRope;
};
listOb ← CONS[PWPins.RenamePins[design, inverter, Rename], listOb];
ENDLOOP;
top ← AbutX[design, invLeft, AbutListX[design, listOb], invRight];
};
PadFrameProc:
PROC [n:
INT]
RETURNS [padFrame: Object] = {
padNames: LIST OF ROPE ← LIST["In", "Out", "Decode", "Precharge", "enableWrite"];
padDescr: PWDescr.Descriptor ← PWDescr.RopesToDescr[padNames];
p: INT = TwoToThe[n];
PWDescr.SetTypePad[padDescr, "Decode" , PGA144.Single[20], $In];
PWDescr.SetTypePad[padDescr, "enableWrite" , PGA144.Single[21], $In];
PWDescr.SetTypePad[padDescr, "Precharge" , PGA144.Single[22], $In];
PWDescr.SetTypePad[padDescr, "In", PGA144.Segment[74, n], $In];
PWDescr.SetTypePad[padDescr, "Out", PGA144.Segment[128, p], $IOTst];
RETURN [PGA144.MakePadFrame[design, padDescr, , TRUE]];
};
StopPins: PWPins.RenameProc = {newRope ← NIL};
inner, outer, result, array: CD.Object;
layersParams: Onion.LayersParameters ← Onion.defaultLayersParameters;
n: INT ← 0;
WHILE n<1 DO n ← TerminalIO.RequestInt["How many bits in the decoder? "]; ENDLOOP;
layersParams.wireExtendProc ← Onion.WireExtendPolToMetForPads;
array ← AbutX[design, ArrayY[design, left, TwoToThe[n]], DecGen[n]];
array ← PWPins.RenamePins[design, array, StopPins];
inner ← AbutX[design, array, MakeRight[TwoToThe[n]]];
inner ← AbutY[design, inner, MakeTop[n]];
inner ← Onion.MakeInner[design, inner];
outer ← PGA144.MakeOuter[design, PadFrameProc[n], RenamePadsProc];
result ← Onion.LRSRoute[design, inner, outer, Onion.Center[inner, outer], layersParams].cell;
RETURN [result];
};