IFUCoreCtlPreCharge:
CEDAR
PROGRAM
IMPORTS Basics, CD, CDCells, CDInstances, CDRects, CDSymbolicObjects, CoreBlock, CoreCreate, CoreFrame, CoreGeometry, CoreLibrary, CoreName, CoreOps, IFUCoreCells, IFUCoreDrive, IO, Lists, PLAOps, PLASim, Ports, PW, PWC, PWCTilingClass, PWObjects, PWPins, REFBit, Rope
EXPORTS IFUCoreCtl =
BEGIN
ROPE: TYPE = Core.ROPE;
CellType: TYPE = Core.CellType;
Wire: TYPE = Core.Wire;
Wires: TYPE = Core.Wires;
Frame: TYPE = CoreFrame.Frame;
Side: TYPE = CoreFrame.Side;
PLADescription: TYPE = IFUCoreCtl.PLADescription;
Connection: TYPE = IFUCoreCtl.Connection;
PLAType: TYPE = IFUCoreDrive.PLAType;
Drive: TYPE = IFUCoreDrive.Drive;
Drives: TYPE = IFUCoreDrive.Drives;
DriveRec: TYPE = IFUCoreDrive.DriveRec;
RowType: TYPE = IFUCoreDrive.RowType;
Dir: TYPE = IFUCoreDrive.Dir;
DrGate: TYPE = IFUCoreDrive.DrGate;
Ph: TYPE = IFUCoreDrive.Ph;
Polarity: TYPE = IFUCoreDrive.Polarity;
Signal: SIGNAL = CODE;
in: ROPE ← CoreName.RopeNm["in"];
nin: ROPE ← CoreName.RopeNm["nin"];
in0: ROPE ← CoreName.RopeNm["in0"];
in1: ROPE ← CoreName.RopeNm["in1"];
out: ROPE ← CoreName.RopeNm["out"];
GND: ROPE ← CoreName.RopeNm["GND"];
VDD: ROPE ← CoreName.RopeNm["VDD"];
fire: ROPE ← CoreName.RopeNm["Fire"];
fireV: ROPE ← CoreName.RopeNm["FireControlV"];
nPreChg: ROPE ← CoreName.RopeNm["NotPreChg"];
dChrg: ROPE ← CoreName.RopeNm["DisChg"];
MakeHotPLA,
MakePreChargedPLA:
PUBLIC
PROC[desc: PLADescription] = {
log.PutF["\n Make PreCharged/Hot PLA %g", IO.rope[desc.name]];
ZeroUnusedTTTOutputs [desc];
DefinePLARows [desc];
DressInDrs [desc];
MakeOutDrs [desc];
NewMakePla [desc]};
MakePla [desc]};
DressInDrs:
PROC [desc: PLADescription] = {
desc.inDrs ←
CONS[
NEW[DriveRec ←
[drRowType: xfooter, fire: desc.fire, fireV: desc.fireV, nPreChg: desc.nPreChg] ],
desc.inDrs];
FOR list: Drives ← desc.inDrs, list.rest
WHILE list.rest#
NIL DO
REPEAT FINISHED => list.rest ←
CONS [
NEW[DriveRec ←
[drRowType: xheader, fire: desc.fire, fireV: desc.fireV, nPreChg: desc.nPreChg]], NIL]
ENDLOOP};
ZeroUnusedTTTOutputs:
PROC [desc: PLADescription ] = {
maskTerm: PLAOps.Term ← PLAOps.CopyTerm[desc.ttt.termList.begin];
log.PutRope["\n Zero unused TTT outputs"];
FOR i:
CARDINAL
IN [0..maskTerm.out.wdSize)
DO maskTerm.out[i] ← PLAOps.initOutQrtWz ENDLOOP;
FOR index:
INT
IN [0..desc.smlToBigOut.size)
DO
pos: INT ← desc.smlToBigOut[index];
PLAOps.SetOutQrt[one, maskTerm, REFBit.Desc[desc.ttt.out].bitForm[pos].firstBit] ENDLOOP;
FOR term: PLAOps.Term ← desc.ttt.termList.begin, term.next
WHILE term#
NIL
DO
FOR i:
CARDINAL
IN [0..maskTerm.out.wdSize)
DO
term.out[i].d ← Basics.BITAND[term.out[i].d, maskTerm.out[i].d] ENDLOOP ENDLOOP };
PreChargedParams:
TYPE =
RECORD[
minConnSpace: INT ← 2, -- SPACING rows between driver rows;
insPerExtra: INT ← 10, -- SPACING cols between extra columns;
outsPerExtra: INT ← 10,
nextTerm: PLAOps.Term ← NIL, -- specific parameter
nextConn: INT ← 0, -- specific parameter
rows: REF RowsRec ← NIL ]; -- specific parameter
RowsRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF REF RowRec];
RowRec:
TYPE =
RECORD[
dr: REF DriveRec,
type: RowType,
and: ColSeqRef,
or: ColSeqRef ];
ColSeqRef: TYPE = REF ColSeqRec;
ColSeqRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF NormalCellType];
DefinePLARows:
PROC [desc: PLADescription] = {
pp:
REF PreChargedParams ←
NEW[PreChargedParams ← [
nextTerm: desc.ttt.termList.begin,
nextConn: desc.connSeq.size-1,
insPerExtra: IF desc.plaType = hot THEN 10000 ELSE 10]]; --extra AND column undefined
firstRow: BOOL ← TRUE;
index: INT ← 0;
termUp: BOOL ← TRUE;
nofOuts: INT ← MAX[Lists.ListLength[desc.plaOutNames], desc.nofOrCols];
nofIns: INT ← Lists.ListLength[desc.plaInNames];
cRowsLeft: INT ← Lists.ListLength[desc.plaOutNames];
dRowsLeft: INT ← desc.ttt.termList.length;
hRowsLeft: INT;
dRowsLeft ← MAX[dRowsLeft, cRowsLeft*(pp.minConnSpace)];
hRowsLeft ← MAX[1, (dRowsLeft+ desc.termsPerHeader/2)/desc.termsPerHeader];
log.PutRope["\n Assign precharged/hot pla row types"];
desc.data ← pp;
desc.nofAndCols ← nofIns/2 + (nofIns/2 -1) / pp.insPerExtra;
desc.nofOrCols ← nofOuts + (nofOuts -1) / pp.outsPerExtra;
pp.rows ← NEW[RowsRec[cRowsLeft+dRowsLeft+2*hRowsLeft]];
index ← pp.rows.size-1; -- start at the top
WHILE hRowsLeft#0
DO
-- actually one more header is appended afterwards
RperH: INT ← (cRowsLeft+dRowsLeft+hRowsLeft + hRowsLeft/2)/hRowsLeft;
IF firstRow
THEN firstRow←FALSE
ELSE {pp.rows[index] ← NextRow[desc, xfooter]; index←index-1};
pp.rows[index] ← NextRow[desc, header];
index←index-1; RperH←RperH-1; hRowsLeft←hRowsLeft-1;
WHILE RperH > 0
DO
CperD, DperC: INT;
CperD ← MAX[1, (cRowsLeft + dRowsLeft/2)/dRowsLeft];
DperC ← MAX[1, (dRowsLeft + cRowsLeft/2)/cRowsLeft];
IF DperC < pp.minConnSpace
OR
(CperD>1) AND (pp.minConnSpace>0) THEN ERROR;
RperH ← RperH - CperD - DperC;
WHILE CperD > 0
DO
pp.rows[index] ← NextRow[desc, conn];
index←index-1; cRowsLeft𡤌RowsLeft-1; CperD𡤌perD-1;
ENDLOOP;
termUp ← TRUE;
WHILE DperC > 0
DO
pp.rows[index] ← NextRow[desc, IF termUp THEN dataUp ELSE dataDn];
index←index-1; dRowsLeft𡤍RowsLeft-1; DperC𡤍perC-1;
termUp ← NOT termUp;
ENDLOOP;
ENDLOOP;
ENDLOOP;
IF index#0 THEN ERROR;
pp.rows[index] ← NextRow[desc, footer]};
NextRow:
PROC [desc: PLADescription, type: RowType]
RETURNS[row:
REF RowRec] = {
pp: REF PreChargedParams ← NARROW[desc.data];
andIndex, orIndex, index: INT ← 0;
data: PLAOps.Term;
conn: Connection;
row ← NEW[RowRec ← [type: type]];
row.and ← NEW[ColSeqRec[desc.nofAndCols]];
IF desc.nofOrCols#0 THEN row.or ← NEW[ColSeqRec[desc.nofOrCols]];
SELECT type
FROM
header => { };
conn => {conn ← NextConnection[desc]; row.dr ← conn.dr};
dataUp, dataDn => {
data ← NextDataTerm[desc];
row.dr ← NIL;
IF data=NIL THEN type ← row.type ← blank};
ENDCASE;
FOR index
IN[0..desc.nofAndCols)
DO
IF (index+1)
MOD (pp.insPerExtra+1) = 0
THEN row.and[index] ← extra
ELSE {
SELECT type
FROM
dataUp, dataDn =>
SELECT PLAOps.GetInQrt
[data, REFBit.Desc[desc.ttt.data].bitForm[andIndex].firstBit]
FROM
zero => row.and[index] ← left;
one => row.and[index] ← right;
ENDCASE => row.and[index] ← nc;
conn =>
IF conn.isOutput
OR conn.index#andIndex
THEN row.and[index] ← nc
ELSE
IF conn.isLeftSide
THEN row.and[index] ← left
ELSE row.and[index] ← right;
ENDCASE => row.and[index] ← nc;
andIndex𡤊ndIndex+1 } ENDLOOP;
IF desc.nofOrCols#0
THEN
FOR index
IN[0..desc.nofOrCols)
DO
IF (index+1)
MOD (pp.outsPerExtra+1) = 0
THEN row.or[index] ← extra
ELSE {
row.or[index] ← nc;
IF orIndex < desc.smlToBigOut.size
THEN {
IF (type=dataUp
OR type=dataDn)
AND PLAOps.GetOutQrt
[data, REFBit.Desc[desc.ttt.out].bitForm[desc.smlToBigOut[orIndex]].firstBit]=one
THEN row.or[index] ← left;
IF type=conn
AND conn.isOutput
AND conn.index=desc.smlToBigOut[orIndex]
THEN row.or[index] ← left };
orIndex←orIndex+1 } ENDLOOP};
NextDataTerm:
PROC [desc: PLADescription]
RETURNS[term: PLAOps.Term] = {
pp: REF PreChargedParams ← NARROW[desc.data];
term ← pp.nextTerm;
IF term#NIL THEN pp.nextTerm ← pp.nextTerm.next};
NextConnection:
PROC [desc: PLADescription]
RETURNS[conn: Connection] = {
pp: REF PreChargedParams ← NARROW[desc.data];
conn ← desc.connSeq[pp.nextConn];
pp.nextConn ← pp.nextConn-1};
MakeOutDrs:
PROC[desc: PLADescription] = {
pp: REF PreChargedParams ← NARROW[desc.data];
last: INT ← pp.rows.size+pp.minConnSpace;
FOR driverIndex:
INT DECREASING IN [0..pp.rows.size)
DO
type: RowType ← pp.rows[driverIndex].type;
template: DriveRec ← [plaType: desc.plaType, drRowType: type, fire: desc.fire, fireV: desc.fireV, nPreChg: desc.nPreChg];
SELECT type
FROM
header, xfooter, footer => {
IF (last-driverIndex) <= pp.minConnSpace THEN ERROR;
last ← driverIndex+pp.minConnSpace;
desc.outDrs ← CONS[NEW[DriveRec ← template], desc.outDrs]};
blank, dataUp, dataDn => {
IF (last-driverIndex) <= pp.minConnSpace THEN LOOP;
desc.outDrs ← CONS[NEW[DriveRec ← template], desc.outDrs]};
conn => {
IF (last-driverIndex) <= pp.minConnSpace THEN ERROR;
last ← driverIndex;
desc.outDrs ← CONS[pp.rows[driverIndex].dr, desc.outDrs]}
ENDCASE => ERROR;
ENDLOOP};
NewMakePla:
PROC[desc: PLADescription] = {
name: ROPE ← CoreName.RopeNm[desc.name.Cat["Body"]];
tiles: REF TileVarieties ← GetPLATiles[desc.plaType];
pp: REF PreChargedParams ← NARROW[desc.data];
obj: CD.Object;
cellType: CellType;
input: INT ← 0;
output: INT ← 0;
tileArray: PWCTilingClass.TileArray ← NIL;
fireWire: Wire ← CoreCreate.Seq[desc.fire, 0];
fireVWire: Wire ← CoreCreate.Seq[desc.fireV, 0];
nPreChgWire: Wire ← CoreCreate.Seq[desc.nPreChg, 0];
extras: Wires ←
IF desc.plaType#precharged
THEN NIL ELSE LIST [fireWire, fireVWire, nPreChgWire ];
public: Wire ← PLASim.CreateSimplePLAPublic[desc.name, extras ];
vddWire: Wire ← CoreOps.FindWire[public, VDD];
gndWire: Wire ← CoreOps.FindWire[public, GND];
log.PutRope["\n Assemble precharged/hot pla row tiles"];
tileArray ← NEW[PWCTilingClass.TileArrayRec[pp.rows.size]];
FOR rr:
INT
IN [0..pp.rows.size)
DO
TileIt:
PROC
[cell: CellType, type: {in, out, none} ← none, index: INT ← 0, header: BOOLLSE] = {
pas: LIST OF CoreCreate.PA ← NIL;
SELECT type
FROM
in => pas ←
LIST[
[in0, CoreOps.FindWire[public, in][index]],
[in1, CoreOps.FindWire[public, nin][index]] ];
out => pas ← LIST[[out, CoreOps.FindWire[public, out][index]]];
ENDCASE;
IF header
THEN{
pas ← CONS[[VDD, vddWire], CONS[[GND, gndWire], pas]];
IF extras#
NIL
THEN pas ←
CONS[[fire, fireWire],
CONS[[fireV, fireVWire],
CONS[[nPreChg, nPreChgWire], pas ] ] ]};
tileArray[rr][col] ← NEW[PWCTilingClass.TileRec ← [cell, pas]];
col ← col+1};
row: REF RowRec ← pp.rows[rr];
col: INT ← 1 + row.and.size + 1 + row.or.size + 1;
header: BOOL ← row.type=header OR row.type=footer;
tileArray[rr] ← NEW[PWCTilingClass.TileRowRec[col]];
col ← 0;
TileIt[ tiles.glue[row.type][leftSide], none, 0];
FOR i:
INT
IN [0..row.and.size)
DO
IF rr=0
AND row.and[i]#extra
THEN {TileIt[tiles.and[row.type][row.and[i]], in, input]; input ← input+1}
ELSE {TileIt[tiles.and[row.type][row.and[i]]]}; ENDLOOP;
TileIt[ tiles.glue[row.type][between]];
FOR i:
INT
IN [0..row.or.size)
DO
TileIt[ tiles.or[row.type][row.or[i]]] ENDLOOP;
IF row.type#conn
THEN {TileIt[tiles.glue[row.type][rightSide], none, 0, header]}
ELSE {TileIt[tiles.glue[row.type][rightSide], out, output ]; output ← output+1};
ENDLOOP;
AssignPublicNames[desc, public];
cellType ← PWCTilingClass.CreateTiling[
public: public,
tileArray: tileArray,
neighborX: PWCTilingClass.LayoutNeighborX,
neighborY: PWCTilingClass.LayoutNeighborY,
name: name,
props: NIL,
cacheNeighbor: TRUE ];
obj ← PWC.Layout[cellType]; -- cause recast
cellType ← PWC.Extract[obj]; -- get record CT
[]𡤌oreName.CellNm[cellType, name];
PLASim.SetUpRose[cellType];
CoreBlock.MarkSides[cellType, desc.capSides];
desc.outBodyCT ← CoreFrame.NewFrameCell[0, name, [first: left, cell: cellType] ]};
MakePla:
PROC[desc: PLADescription] = {
name: ROPE ← CoreName.RopeNm[desc.name.Cat["Body"]];
IF (desc.outBodyCT ← CoreFrame.ReadFrameCache[name])=NIL THEN {
{
body: CD.Object;
cellType: CellType;
tiles: REF TileVarieties ← GetPLATiles[desc.plaType];
pp: REF PreChargedParams ← NARROW[desc.data];
refPhase: Ph ← unk;
rowList: PW.Objects ← NIL;
log.PutRope["\n Assemble precharged/hot pla row cells"];
FOR rowIndex:
INT
IN [0..pp.rows.size)
DO
objects: PW.Objects ← NIL;
row: REF RowRec ← pp.rows[rowIndex];
IF pp.rows[rowIndex].dr#NIL THEN refPhase ← pp.rows[rowIndex].dr.ref.ph;
objects ← CONS[PWC.Layout[tiles.glue[row.type][leftSide]], objects];
FOR index:
INT
IN [0..row.and.size)
DO
objects ← CONS[PWC.Layout[tiles.and[row.type][row.and[index]]], objects] ENDLOOP;
IF desc.nofOrCols#0
THEN {
objects ← CONS[PWC.Layout[tiles.glue[row.type][between]], objects];
FOR index:
INT
IN [0..row.or.size)
DO
objects ← CONS[PWC.Layout[tiles.or[row.type][row.or[index]]], objects] ENDLOOP;
objects ← CONS[PWC.Layout[tiles.glue[row.type][rightSide]], objects] };
rowList ← CONS[PW.SharedAbutListX[PW.Reverse[objects]], rowList]
rowList ← CONS[PW.AbutListX[PW.Reverse[objects]], rowList]
ENDLOOP;
body ← PW.AbutListY[PW.Reverse[rowList]];
cellType ← MakeSimplePLACell[body, desc];
body ← ApplyNames[body, desc];
cellType ← CoreLibrary.ObjCell[body, name, NIL, 0];
CoreBlock.MarkSides[cellType, desc.capSides];
desc.outBodyCT ← CoreFrame.NewFrameCell[0, name, [first: left, cell: cellType] ];
} };
CoreFrame.WriteFrameCache[desc.outBodyCT]} };
MakeSimplePLACell:
PROC[obj:
CD.Object, desc: PLADescription]
RETURNS[cellType: CellType] = {
iSize: CD.Position ← CD.InterestSize[obj];
shell: CD.Object ← CDCells.CreateEmptyCell[];
shellPins: CD.InstanceList;
minW: INT = CMosB.lambda;
sides: CoreBlock.Sides;
loc, size: INT;
loc2, size2: CD.Position;
wire: Wire;
extras: Wires ←
IF desc.plaType#precharged
THEN
NIL
ELSE
LIST [
CoreCreate.Seq[fire, 0],
CoreCreate.Seq[fireV, 0],
CoreCreate.Seq[nPreChg, 0],
CoreCreate.Seq[dChrg, 0] ];
renameProc: PWPins.
ChangePinProc ~ { -- oldPin:
CD.Instance => newPin:
CD.Instance
layer: CD.Layer ← CDSymbolicObjects.GetLayer[oldPin];
oldNm: ROPE ← CoreName.RopeNm[CDSymbolicObjects.GetName[oldPin]];
[sides, loc, size] ← CoreBlock.GetInstSideLocSize[obj, oldPin];
loc2 ←
SELECT sides
FROM
left => [0, loc],
right => [iSize.x-minW, loc],
top => [loc, iSize.y-minW],
bottom => [loc, 0],
ENDCASE => ERROR;
size2 ←
SELECT sides
FROM
top, bottom => [size, minW]
ENDCASE => [minW, size];
shellPins ←
CONS
[CDInstances.NewInst[CDRects.CreateRect[size2, layer], [off: loc2]], shellPins];
wire ← FindPublicWire[desc, cellType.public, oldNm, loc];
CDSymbolicObjects.SetName[newPin, CoreName.WireNm[wire].n];
CoreGeometry.AddPins[
decoration: PWC.extractMode.decoration,
public: wire,
pins: LIST[CoreGeometry.Instance[shellPins.first.ob, shellPins.first.trans] ] ]};
cellType ← PLASim.CreateSimplePLA
[desc.name, PLASim.CreateSimplePLAPublic[desc.name, extras] ];
IF desc.plaType=precharged
THEN {
[]←Ports.InitPort[wire: CoreOps.FindWire[cellType.public, fire],
levelType:b, initDrive: none];
[]←Ports.InitPort[wire: CoreOps.FindWire[cellType.public, fireV],
levelType:b, initDrive: none];
[]←Ports.InitPort[wire: CoreOps.FindWire[cellType.public, nPreChg],
levelType:b, initDrive: none];
[]←Ports.InitPort[wire: CoreOps.FindWire[cellType.public, dChrg], -- present by accident
levelType:l, initDrive: none] };
AssignPublicNames[desc, cellType.public];
Make new object with renamed pins and also decorate cellType with additional copies of renamed pins
obj ← PWPins.ChangePins[obj, renameProc];
PWC.SetExtractCell[obj, cellType];
PWC.SetLayoutObj[cellType, obj];
CoreGeometry.PutObject[PWC.extractMode.decoration, cellType, obj];
shell ← PWObjects.CreateCell[shellPins, CD.InterestRect[obj]]}; -- note: shell not used
AssignPublicNames:
PROC[desc: PLADescription, public: Wire] = {
pp: REF PreChargedParams ← NARROW[desc.data];
name: ROPE;
oIndex: INT ← 0;
iIndex: INT ← 0;
IF desc.plaType=precharged
AND desc.fire#
NIL
THEN
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, fire], desc.fire];
IF desc.plaType=precharged
AND desc.fireV#
NIL
THEN
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, fireV], desc.fireV];
IF desc.plaType=precharged
AND desc.nPreChg#
NIL
THEN
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, nPreChg], desc.nPreChg];
FOR rIndex:
INT
IN [0..pp.rows.size)
DO
IF pp.rows[rIndex].type # conn THEN LOOP;
IF pp.rows[rIndex].dr = NIL THEN LOOP;
name ← IFUCoreDrive.DriveName[pp.rows[rIndex].dr, nin];
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, out][oIndex], name];
oIndex ← oIndex + 1 ENDLOOP;
FOR list:
LIST
OF
ROPE ← desc.plaInNames, list.rest.rest
WHILE list#
NIL
DO
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, in ][iIndex], list.first];
[ ] ← CoreName.WireNm[CoreOps.FindWire[public, nin ][iIndex], list.rest.first];
iIndex ← iIndex + 1 ENDLOOP};
FindPublicWire:
PROC[desc: PLADescription, public: Wire, oldNm:
ROPE, loc:
INT]
RETURNS[wire: Wire] = {
TileSize:
PROC[cell: CellType]
RETURNS[size:
CD.Position] =
{IF cell=NIL THEN RETURN[[0, 0]]; RETURN[PWC.InterestSize[cell]]};
pp: REF PreChargedParams ← NARROW[desc.data];
tiles: REF TileVarieties ← GetPLATiles[desc.plaType];
leftSize: INT ← TileSize[tiles.glue [blank] [leftSide]].x;
andWidth: INT ← TileSize[tiles.and [blank] [nc]].x;
extraWidth: INT ← TileSize[tiles.and [blank] [extra]].x;
headHt: INT ← TileSize[tiles.glue [header] [rightSide]].y;
xfootHt: INT ← TileSize[tiles.glue [xfooter] [rightSide]].y;
rowHt: INT ← TileSize[tiles.glue [blank] [rightSide]].y;
SELECT oldNm
FROM
out => {
oIndex: INT ← 0;
yPos: INT ← 0;
FOR rIndex:
INT
IN [0..pp.rows.size)
DO
SELECT pp.rows[rIndex].type
FROM
header, footer => {yPos ← yPos + headHt; LOOP};
xfooter => {yPos ← yPos + xfootHt; LOOP};
dataUp, dataDn => {yPos ← yPos + rowHt; LOOP};
blank => {yPos ← yPos + rowHt; LOOP};
#conn => Signal[];
ENDCASE;
SELECT loc
FROM
< yPos => Signal[];
< yPos + rowHt => RETURN[CoreOps.FindWire[public, out][oIndex]]
ENDCASE;
yPos ← yPos + rowHt;
oIndex ← oIndex + 1;
ENDLOOP;
Signal[]};
in0,
in1 => {
xpos: INT ← (loc - leftSize)/(pp.insPerExtra*andWidth+extraWidth);
xpos ← (loc - leftSize - extraWidth*xpos)/(andWidth/2);
IF ((xpos MOD 2)=0) # (oldNm=in0) THEN Signal[];
IF ((xpos
MOD 2)=0)
THEN RETURN[CoreOps.FindWire[public, in ][xpos/2]]
ELSE RETURN[CoreOps.FindWire[public, nin ][xpos/2]] };
ENDCASE => RETURN[CoreOps.FindWire[public, oldNm]]};
ApplyNames: PROC[oldObj: CD.Object, desc: PLADescription] RETURNS[newObj: CD.Object]= {
TileSize: PROC[obj: CD.Object] RETURNS[size: CD.Position] =
{IF obj=NIL THEN RETURN[[0, 0]]; RETURN[CD.InterestSize[obj]]};
pp: REF PreChargedParams ← NARROW[desc.data];
tiles: REF TileVarieties ← GetPLATiles[desc.plaType];
leftSize: INT ← TileSize[tiles.glue [blank] [leftSide]].x;
andWidth: INT ← TileSize[tiles.and [blank] [nc]].x;
extraWidth: INT ← TileSize[tiles.and [blank] [extra]].x;
headHt: INT ← TileSize[tiles.glue [header] [rightSide]].y;
xfootHt: INT ← TileSize[tiles.glue [xfooter] [rightSide]].y;
rowHt: INT ← TileSize[tiles.glue [blank] [rightSide]].y;
renameProc: PWPins.ChangePinProc ~ {
old: ROPE ← CoreName.RopeNm[CDSymbolicObjects.GetName[oldPin]];
side: CoreBlock.Sides;
loc: INT;
newPin ← oldPin;
[side, loc] ← CoreBlock.GetInstSideLoc[oldObj, newPin];
SELECT old FROM
GND => RETURN;
VDD => RETURN;
out => {
name: ROPE;
yPos: INT;
FOR oIndex: INT IN [0..pp.rows.size) DO
SELECT pp.rows[oIndex].type FROM
header, footer => {yPos ← yPos + headHt; LOOP};
xfooter => {yPos ← yPos + xfootHt; LOOP};
dataUp, dataDn => {yPos ← yPos + rowHt; LOOP};
blank => {yPos ← yPos + rowHt; LOOP};
conn => {IF loc < yPos THEN Signal[]};
ENDCASE => Signal[];
yPos ← yPos + rowHt;
IF loc > yPos THEN LOOP;
name ← IFUCoreDrive.DriveName[pp.rows[oIndex].dr, nin];
CDSymbolicObjects.SetName[newPin, name]; RETURN ENDLOOP;
Signal[]};
in0,
in1 => {
name: ROPE;
list: LIST OF ROPE ← desc.plaInNames;
xpos: INT;
xpos ← (loc - leftSize)/(pp.insPerExtra*andWidth+extraWidth);
xpos ← (loc - leftSize - extraWidth*xpos)/(andWidth/2);
WHILE xpos>1 DO
IF list=NIL THEN RETURN;
list ← list.rest.rest; xpos ← xpos-2 ENDLOOP;
name ← IF xpos=0 THEN list.first ELSE list.rest.first;
IF (xpos=0)#(old=in0) THEN Signal[];
CDSymbolicObjects.SetName[newPin, name];
RETURN};
fire => CDSymbolicObjects.SetName[newPin, "PhB"];
fireV => CDSymbolicObjects.SetName[newPin, "FireControlV"]; -- to conn pad
nPreChg => CDSymbolicObjects.SetName[newPin, "NotPreChg"]; -- to conn pad
ENDCASE => RETURN};
newObj ← PWPins.ChangePins[oldObj, renameProc]};
tileBuffer: REF TileVarieties;
hotTileBuffer: REF TileVarieties;
TileVarieties: TYPE = RECORD[glue: REF GlueTiles, and, or: REF NormalTiles];
GlueTiles: TYPE = ARRAY RowType OF ARRAY GlueCellType OF CellType;
GlueCellType: TYPE = {leftSide, between, rightSide};
NormalTiles: TYPE = ARRAY RowType OF ARRAY NormalCellType OF CellType;
NormalCellType: TYPE = {left, right, nc, extra};
GetPLATiles:
PROC[type: PLAType]
RETURNS[tiles:
REF TileVarieties] = {
tiles ←
SELECT type
FROM
hot => GetHotPLATiles[],
ENDCASE => GetPreChargedPLATiles[]};
FlipY:
PROC[orig: CellType]
RETURNS[flipped: CellType] = {
name: ROPE ← CoreName.CellNm[orig].n;
IF name.Length[]=0 THEN Signal[];
flipped ← CoreFrame.RotateCellType[orig, rotate180X];
[] ← CoreName.CellNm[flipped, name.Cat["-FlipY"]]};
FlipY: PROC[orig: CD.Object] RETURNS[flipped: CD.Object] = {
name: ROPE ← CDDirectory.Name[orig];
IF name.Length[]=0 THEN Signal[];
flipped ← PW.FlipY[orig];
PWC.SetObjName[flipped, name.Cat["-FlipY"]]};
GetPreChargedPLATiles:
PROC
RETURNS[tiles:
REF TileVarieties] = {
Get: PROC[name: ROPE] RETURNS[CellType] = {RETURN[CoreLibrary.Get[library, name ]]};
library: CoreLibrary.Library ← IFUCoreCells.library;
IF tileBuffer # NIL THEN RETURN[tileBuffer];
log.PutRope["\n Initialize precharged PLA tiles"];
tiles ← tileBuffer ← NEW[TileVarieties];
tiles.glue ← NEW[GlueTiles];
tiles.and ← NEW[NormalTiles];
tiles.or ← NEW[NormalTiles];
tiles.glue [xfooter][leftSide] ← Get[ "XLeftSide" ];
tiles.glue [xfooter][between] ← Get[ "XBetween" ];
tiles.glue [xfooter][rightSide] ← Get[ "XOrEx" ];
tiles.and [xfooter][nc] ← Get[ "XAnd" ];
tiles.and [xfooter][extra] ← Get[ "XAndEx" ];
tiles.or [xfooter][nc] ← Get[ "XOr" ];
tiles.or [xfooter][extra] ← Get[ "XOrEx" ];
tiles.glue [header][leftSide] ← Get[ "HLeftSide" ];
tiles.glue [header][between] ← Get[ "HBetween" ];
tiles.glue [header][rightSide] ← Get[ "HRightSide" ];
tiles.and [header][nc] ← Get[ "HAnd" ];
tiles.and [header][extra] ← Get[ "HAndEx" ];
tiles.or [header][nc] ← Get[ "HOr" ];
tiles.or [header][extra] ← Get[ "HOrEx" ];
tiles.glue [footer][leftSide] ← FlipY[ tiles.glue [header][leftSide] ];
tiles.glue [footer][between] ← FlipY[ tiles.glue [header][between] ];
tiles.glue [footer][rightSide] ← FlipY[ tiles.glue [header][rightSide] ];
tiles.and [footer][nc] ← FlipY[ tiles.and [header][nc] ];
tiles.and [footer][extra] ← FlipY[ tiles.and [header][extra] ];
tiles.or [footer][nc] ← Get[ "HOrFooter" ]; -- isolate outs from next stage
tiles.or [footer][extra] ← FlipY[ tiles.or [header][extra] ];
tiles.glue [blank][leftSide] ← Get[ "BLeftSide" ];
tiles.glue [blank][between] ← Get[ "BBetween" ];
tiles.glue [blank][rightSide] ← Get[ "BOrEx" ];
tiles.and [blank][nc] ← Get[ "BAnd" ];
tiles.and [blank][extra] ← Get[ "BAndEx" ];
tiles.or [blank][nc] ← Get[ "BOr" ];
tiles.or [blank][extra] ← Get[ "BOrEx" ];
tiles.glue [conn][leftSide] ← Get[ "BLeftSide" ];
tiles.glue [conn][between] ← Get[ "BBetween" ];
tiles.glue [conn][rightSide] ← Get[ "CRightSide" ];
tiles.and [conn][left] ← Get[ "CAndLt" ];
tiles.and [conn][right] ← Get[ "CAndRt" ];
tiles.and [conn][nc] ← Get[ "BAnd" ];
tiles.and [conn][extra] ← Get[ "BAndEx" ];
tiles.or [conn][left] ← Get[ "COr" ];
tiles.or [conn][nc] ← Get[ "COrNC" ];
tiles.or [conn][extra] ← Get[ "COrEx" ];
tiles.glue [dataUp][leftSide] ← Get[ "DLeftSide" ];
tiles.glue [dataUp][between] ← Get[ "DBetween" ];
tiles.glue [dataUp][rightSide] ← Get[ "DRightSide" ];
tiles.and [dataUp][left] ← Get[ "DAndLt" ];
tiles.and [dataUp][right] ← Get[ "DAndRt" ];
tiles.and [dataUp][nc] ← Get[ "DAnd" ];
tiles.and [dataUp][extra] ← Get[ "DAndEx" ];
tiles.or [dataUp][left] ← Get[ "DOr" ];
tiles.or [dataUp][nc] ← Get[ "DOrNC" ];
tiles.or [dataUp][extra] ← Get[ "DOrEx" ];
tiles.glue [dataDn][leftSide] ← tiles.glue [dataUp][leftSide];
tiles.glue [dataDn][between] ← FlipY[ tiles.glue [dataUp][between] ];
tiles.glue [dataDn][rightSide] ← FlipY[ tiles.glue [dataUp][rightSide] ];
tiles.and [dataDn][left] ← tiles.and [dataUp][left];
tiles.and [dataDn][right] ← tiles.and [dataUp][right];
tiles.and [dataDn][nc] ← tiles.and [dataUp][nc];
tiles.and [dataDn][extra] ← tiles.and [dataUp][extra];
tiles.or [dataDn][left] ← FlipY[ tiles.or [dataUp][left] ];
tiles.or [dataDn][nc] ← FlipY[ tiles.or [dataUp][nc] ];
tiles.or [dataDn][extra] ← FlipY[ tiles.or [dataUp][extra] ];
RETURN[tiles]};
GetHotPLATiles:
PROC
RETURNS[tiles:
REF TileVarieties] = {
Get: PROC[name: ROPE] RETURNS[CellType] = {RETURN[CoreLibrary.Get[library, name ]]};
library: CoreLibrary.Library ← IFUCoreCells.library;
IF hotTileBuffer # NIL THEN RETURN[hotTileBuffer];
log.PutRope["\n Initialize hot PLA tiles"];
tiles ← hotTileBuffer ← NEW[TileVarieties];
tiles.glue ← NEW[GlueTiles];
tiles.and ← NEW[NormalTiles];
tiles.or ← NEW[NormalTiles];
tiles.glue [header][leftSide] ← Get[ "HPlaHLeftSide" ];
tiles.glue [header][between] ← Get[ "HPlaHBetween" ];
tiles.glue [header][rightSide] ← Get[ "HPlaHRightSide" ];
tiles.and [header][nc] ← Get[ "HPlaHAnd" ];
tiles.or [header][nc] ← Get[ "HPlaHOr" ];
tiles.or [header][extra] ← Get[ "HPlaHOrEx" ];
tiles.glue [footer][leftSide] ← FlipY[ tiles.glue [header][leftSide] ];
tiles.glue [footer][between] ← FlipY[ tiles.glue [header][between] ];
tiles.glue [footer][rightSide] ← FlipY[ tiles.glue [header][rightSide] ];
tiles.and [footer][nc] ← FlipY[ tiles.and [header][nc] ];
tiles.or [footer][nc] ← FlipY[ tiles.or [header][nc] ];
tiles.or [footer][extra] ← FlipY[ tiles.or [header][extra] ];
tiles.glue [blank][leftSide] ← Get[ "HPlaBLeftSide" ];
tiles.glue [blank][between] ← Get[ "HPlaBBetween" ];
tiles.glue [blank][rightSide] ← Get[ "HPlaBRightSide" ];
tiles.and [blank][nc] ← Get[ "HPlaBAnd" ];
tiles.or [blank][nc] ← Get[ "BOr" ];
tiles.or [blank][extra] ← Get[ "HPlaBOrEx" ];
tiles.glue [conn][leftSide] ← Get[ "HPlaBLeftSide" ];
tiles.glue [conn][between] ← Get[ "HPlaBBetween" ];
tiles.glue [conn][rightSide] ← Get[ "HPlaCRightSide" ];
tiles.and [conn][left] ← Get[ "CAndLt" ]; -- input connections not used
tiles.and [conn][right] ← Get[ "CAndRt" ]; -- input connections not used
tiles.and [conn][nc] ← Get[ "HPlaBAnd" ]; -- input connections not used
tiles.or [conn][left] ← Get[ "COr" ];
tiles.or [conn][nc] ← Get[ "COrNC" ];
tiles.or [conn][extra] ← Get[ "HPlaCOrEx" ];
tiles.glue [dataUp][leftSide] ← Get[ "HPlaDLeftSide" ];
tiles.glue [dataUp][between] ← Get[ "HPlaDBetween" ];
tiles.glue [dataUp][rightSide] ← Get[ "HPlaDRightSide" ];
tiles.and [dataUp][left] ← Get[ "DAndLt" ];
tiles.and [dataUp][right] ← Get[ "DAndRt" ];
tiles.and [dataUp][nc] ← Get[ "DAnd" ];
tiles.or [dataUp][left] ← Get[ "DOr" ];
tiles.or [dataUp][nc] ← Get[ "DOrNC" ];
tiles.or [dataUp][extra] ← Get[ "HPlaDOrEx" ];
tiles.glue [dataDn][leftSide] ← tiles.glue [dataUp][leftSide];
tiles.glue [dataDn][between] ← FlipY[ tiles.glue [dataUp][between] ];
tiles.glue [dataDn][rightSide] ← FlipY[ tiles.glue [dataUp][rightSide] ];
tiles.and [dataDn][left] ← tiles.and [dataUp][left];
tiles.and [dataDn][right] ← tiles.and [dataUp][right];
tiles.and [dataDn][nc] ← tiles.and [dataUp][nc];
tiles.and [dataDn][extra] ← tiles.and [dataUp][extra];
tiles.or [dataDn][left] ← FlipY[ tiles.or [dataUp][left] ];
tiles.or [dataDn][nc] ← FlipY[ tiles.or [dataUp][nc] ];
tiles.or [dataDn][extra] ← FlipY[ tiles.or [dataUp][extra] ];
RETURN[tiles]};
log: IO.STREAM ← CoreFrame.GetLog[];
END.