IFUCoreCtlPreCharge:
CEDAR
PROGRAM
IMPORTS Basics, CD, CDCells, CDRects, CDSymbolicObjects, CoreBlock, CoreCreate, CoreFrame, CoreGeometry, CoreLibrary, CoreName, CoreOps, IFUCoreCells, IFUCoreDrive, IO, Lists, PLAOps, PLASim, Ports, PW, PWC, PWCTilingClass, 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.ListOb ← NIL;
log.PutRope["\n Assemble precharged/hot pla row cells"];
FOR rowIndex:
INT
IN [0..pp.rows.size)
DO
objects: PW.ListOb ← 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[];
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
newPin2: CD.Instance; -- additional copy for decorating cellType
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];
newPin ← PW.IncludeInCell[shell, CDRects.CreateRect[size2, layer], loc2];
newPin2 ← NEW[CD.InstanceRep ← newPin^];
wire ← FindPublicWire[desc, cellType.public, oldNm, loc];
CDSymbolicObjects.SetName[newPin, CoreName.WireNm[wire].n];
CoreGeometry.PutPins[
decoration: PWC.extractMode.decoration,
public: wire,
pins: CONS[ newPin2, CoreGeometry.GetPins[PWC.extractMode.decoration, wire] ] ]};
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.PutIR[PWC.extractMode.decoration, cellType, CD.InterestRect[obj]];
PW.SetInterestRect[shell, iSize];
PW.RepositionCell[shell]}; -- note: this shell is not currently 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, CDOrient.mirrorY];
[] ← 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.