BEGIN
CellType: TYPE = Core.CellType;
Properties: TYPE = Core.Properties;
Wire: TYPE = Core.Wire;
Wires: TYPE = Core.Wires;
ROPE: TYPE = Core.ROPE;
Table: TYPE = HashTable.Table;
Field: TYPE = REF FieldRec;
FieldRec: TYPE = RECORD[root: ROPE, wire: Wire, octalIdx: BOOL];
WR: TYPE = REF ← NIL;
Context: TYPE = REF ContextRec;
ContextRec:
TYPE =
RECORD[
name: ROPE,
cell: CellType,
public: Wire,
publics: Wires,
internals: Wires, -- publics with no actuals
regPubs: Table,
nameFields: Table,
weakTrans: INT ];
transistorGateCount:
PUBLIC
ATOM ← CoreIO.RegisterProperty[
CoreProperties.RegisterProperty[
$TransistorGateCount,
CoreProperties.Props[
[CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc ← PrintTGC ]] ] ],
WriteINT,
ReadINT ];
WriteINT: CoreIO.PropWriteProc = {CoreIO.WriteInt[h, NARROW[value, REF INT]^]};
ReadINT: CoreIO.PropReadProc = {RETURN[ NEW[INT ← CoreIO.ReadInt[h] ] ]};
PrintTGC: CoreProperties.PropPrintProc =
{to.PutF[" Transistor Gate Count: %g", IO.int[NARROW[val, REF INT]^]]};
NewContext:
PROC[name:
ROPE, cell: CellType, public: Wire]
RETURNS[ctx: Context] = {
register: CoreOps.EachWireProc = {
name: ROPE ← CoreName.WireNm[wire].n;
IF name.Length[]#0 THEN []←HashTable.Store[ctx.regPubs, name, wire]};
ctx ←
NEW[ContextRec ← [
name: name,
cell: cell,
public: public,
publics: NIL,
regPubs: HashTable.Create[],
nameFields: HashTable.Create[],
weakTrans: 0 ] ];
[]𡤌oreOps.VisitWire[public, register] };
BindingRec:
TYPE =
RECORD[
bot: ROPE,
top: ROPE,
size: INT ← 0,
index: INT ← -1,
octalIdx: BOOL ← FALSE];
ifuToCluster2Bindings:
LIST
OF BindingRec ←
LIST[
["Pad-IPData", "IPData", 32, -1, TRUE ],
["Pad-NewFetchBAA", "IPCmdFetchA", ],
["Pad-IPFaultingB", "IPFaultingB" ],
["Pad-IPRejectB", "IPRejectB" ],
["Pad-DPCmnd2BAA", "DPCmdA", 8 ],
["Pad-DPFaultB", "DPFaultB", 4 ],
["Pad-DPRejectB", "DPRejectB" ],
["Pad-UserMode2BAA", "UserMode2BA", ],
["Pad-EUAluOp2ABB", "EUAluOp2AB", 4 ],
["Pad-EUCondSel2ABB", "EUCondSel2AB", 4 ],
["Pad-EURdFromPBus3ABB", "EURdFromPBus3AB" ],
["Pad-EUWriteToPBus3ABB", "EUWriteToPBus3AB" ],
["Pad-EUCondition2B", "EUCondition2B" ],
["Pad-XBus", "KBus", 32, -1, TRUE ],
["Pad-ResetAB", "ResetAB" ],
["Pad-RescheduleAB", "RescheduleAB" ],
["PhA", "PhA" ],
["PhB", "PhB" ],
["NotPhA", "NotPhA" ],
["NotPhB", "NotPhB" ],
["DShA", "DShA" ],
["DShB", "DShB" ],
["DShRd", "DShRd" ],
["DShWt", "DShWt" ],
["Pad-DShIn", "DShIn" ],
["Pad-DShOut", "DShOut" ],
["VDD", "Vdd" ],
["GND", "Gnd" ],
["PadVDD", "PadVdd" ],
["PadGND", "PadGnd" ],
["VBB", "Vdd" ],
["IDPlaFireV", "Vdd" ],
["IDPlaNotPhA", "NotPhA" ] ];
MakeFlatBotPublicCtx:
PROC[binds:
LIST
OF BindingRec]
RETURNS[ctx: CoreName.Context] ={
publics: Wires ← NIL;
temp: Wires ← NIL;
ctx ← CoreName.NewContext[];
FOR binds ← binds, binds.rest
WHILE binds#
NIL
DO
b: BindingRec ← binds.first;
IF b.size=0
THEN []𡤌oreName.CtxWire[ctx, b.bot]
ELSE
FOR i:
INT
IN [0..b.size)
DO
[]𡤌oreName.CtxWire[ctx, (
IF
NOT b.octalIdx
OR b.size<8
THEN IO.PutFR["%g.%g", IO.rope[b.bot], IO.int[i]]
ELSE IO.PutFR["%g.%02b", IO.rope[b.bot], IO.int[i]]) ]
ENDLOOP;
ENDLOOP};
RegTopBinds:
PROC[
ctx: Context,
binds: LIST OF BindingRec] = {
FOR binds ← binds, binds.rest
WHILE binds#
NIL
DO
b: BindingRec ← binds.first;
f: Field;
wire: Wire;
b.top ← CoreName.RopeNm[b.top];
wire ← NARROW[HashTable.Fetch[ctx.regPubs, b.top].value];
IF wire=
NIL
THEN {
wire ← CoreCreate.Seq[name: b.top, size: b.size];
[] ← HashTable.Store[ctx.regPubs, b.top, wire];
ctx.publics ← CONS[wire, ctx.publics]};
IF wire.size#b.size THEN ERROR;
f ←
NEW[FieldRec ← [
root: CoreName.RopeNm[b.bot],
wire: (IF b.index#-1 THEN wire[b.index] ELSE wire),
octalIdx: b.octalIdx] ];
IF b.index#-1 THEN ctx.internals ← CONS[wire, ctx.internals]; -- partially connctd publics
[] ← HashTable.Store[ctx.nameFields, f.root, f];
ENDLOOP};
FormalCell:
PUBLIC
PROC[ctx: Context]
RETURNS[formalCell: CellType] = {
rec: CoreClasses.RecordCellType;
actual: Wire ← CoreOps.CreateWires[size: ctx.cell.public.size];
public: Wire ←
IF ctx.publics#
NIL
THEN CoreOps.CreateWire[ctx.publics]
ELSE ctx.public;
IF ctx.public#NIL AND ctx.public#public THEN Signal[];
TerminalIO.WriteF["Recasting %g\n", IO.time[]];
TerminalIO.WriteF["Marking Trans %g\n", IO.time[]];
ctx.weakTrans ← MarkGatedTransistorsWeak[ctx.cell, "VBB"];
TerminalIO.WriteF["Setting Up %g\n", IO.time[]];
SetUp[ctx.cell];
TerminalIO.WriteF["Generate Formal %g\n", IO.time[]];
FOR index:
INT
IN [0..actual.size)
DO
f: Field;
name: ROPE ← CoreName.WireNm[ctx.cell.public[index]].n;
sigRec: CoreName.SigRec ← NameSig[name];
idx: INT ← sigRec.idx;
IF ctx.cell.public[index].size#0 THEN ERROR;
sigRec.idx ← -1;
name ← CoreName.SigName[sigRec];
f ← NARROW[HashTable.Fetch[ctx.nameFields, name].value];
IF f=NIL THEN ERROR;
actual[index] ←
IF f.wire.size=0
THEN f.wire
ELSE
IF f.octalIdx
THEN f.wire[ Adj[ idx ] ]
ELSE f.wire[ idx ];
ENDLOOP;
rec ← NEW [CoreClasses.RecordCellTypeRec[1]];
formalCell ←
NEW [Core.CellTypeRec ← [
class: CoreClasses.recordCellClass,
public: public,
data: rec ]];
IF ctx.internals=
NIL
THEN rec.internal ← public -- this is ok
ELSE {
FOR i: INT IN [0..public.size) DO ctx.internals ← CONS[public[i], ctx.internals] ENDLOOP;
rec.internal ← CoreOps.CreateWire[ctx.internals]};
rec[0] ← NEW [CoreClasses.CellInstanceRec ← [actual: actual, type: ctx.cell]];
[ ] ← CoreOps.SetCellTypeName[formalCell, ctx.name]};
CorrespondingWires:
PROC[atomic1, wire1, wire2: Wire]
RETURNS[atomic2s: Wires ←
NIL] = {
visitProc: CoreOps.EachWirePairProc =
{
IF actualWire=atomic1
THEN
FOR ws: Wires ← atomic2s, ws.rest
WHILE ws #
NIL
DO
IF ws.first=publicWire THEN EXIT;
REPEAT FINISHED => atomic2s ← CONS[publicWire, atomic2s] ENDLOOP};
[ ] ← CoreOps.VisitBinding[wire1, wire2, visitProc]};
SubstituteRecasted:
PUBLIC
PROC [cell: CellType]
RETURNS[recasted: CellType] = {
recasted ← cell;
SELECT cell.class
FROM
CoreClasses.recordCellClass => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
FOR child:
NAT
IN [0..data.size)
DO
data.instances[child].type ← SubstituteRecasted[data.instances[child].type]
ENDLOOP};
ENDCASE =>
IF cell.class.recast#
NIL
THEN recasted ← SubstituteRecasted[CoreOps.Recast[cell]]};
MarkGatedTransistorsWeak:
PUBLIC
PROC [cell: CellType, wr:
WR]
RETURNS[count:
INT ← 0]
= {RETURN[MarkGatedTypedTransistorsWeak[cell, wr, both]]};
MarkGatedTypedTransistorsWeak:
PROC [cell: CellType, wr:
WR, ttype: {p, n, both}]
RETURNS[count: INT ← 0] = {
refInt: REF INT;
gate: Wire;
WITH wr
SELECT
FROM
wire: Wire => gate ← wire;
rope: ROPE => gate ← CoreOps.FindWire [cell.public, rope];
text: REF TEXT => gate ← CoreOps.FindWire [cell.public, Rope.FromRefText[text]];
ENDCASE;
IF gate=
NIL
THEN {TerminalIO.WriteRope["Skipping misslabeled gate wire\n"]; RETURN}
ELSE refInt ← NARROW[CoreProperties.GetWireProp[gate, transistorGateCount].value];
IF refInt#NIL THEN RETURN[refInt^];
SELECT cell.class
FROM
CoreClasses.transistorCellClass => ERROR;
CoreClasses.recordCellClass => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
FOR child:
NAT
IN [0..data.size)
DO
wires: Wires ← CorrespondingWires
[gate, data.instances[child].actual, data.instances[child].type.public];
FOR wires ← wires, wires.rest
WHILE wires#
NIL
DO
cnt: INT ← 0;
IF data.instances[child].type.class # CoreClasses.transistorCellClass
THEN cnt ← MarkGatedTransistorsWeak[ data.instances[child].type, wires.first ]
ELSE
IF data.instances[child].type.public[0] = wires.first
THEN {
td: CoreClasses.Transistor ← NARROW[data.instances[child].type.data];
doit:
BOOL ←
SELECT ttype
FROM
p=>(td.type=pE), n=>(td.type=nE), ENDCASE=>TRUE;
IF doit
THEN {
[ ] ← Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak];
cnt ← 1}};
count ← count + cnt ENDLOOP ENDLOOP };
ENDCASE => {
recast: CellType ← CoreOps.Recast[cell];
wires: Wires ← CorrespondingWires[gate, cell.public, recast.public];
IF wires.rest#NIL THEN ERROR;
count ← MarkGatedTransistorsWeak[ recast, wires.first ]};
CoreProperties.PutWireProp[gate, transistorGateCount, NEW[INT ← count]]};
NameSig:
PROC[name:
ROPE]
RETURNS[sigRec: CoreName.SigRec] = {
base: INT = 10;
val: INT ← -1;
DO
-- Removes bracketed indexes
begin: INT ← name.Find["[", 0 ];
end: INT ← name.Find["]", 0 ];
last: ROPE ← IF (end+1) < name.Length[] THEN name.Substr[end+1] ELSE NIL;
IF begin=-1 THEN EXIT;
val ← MAX[0, val];
val ← val*base + Convert.IntFromRope[name.Substr[begin+1, end-begin-1]];
name ← Rope.Cat[name.Substr[0, begin], last]; ENDLOOP;
sigRec ← CoreName.NameSig[name];
sigRec.idx ← MAX[sigRec.idx, val]};
Adjustment for octal rope incorrectly converted using base 10. eg. 37 => 31, 40 => 32
Adj:
PUBLIC
PROC[dec:
INT]
RETURNS[oct:
INT ← 0] = {
digits: LIST OF INT ← NIL;
WHILE dec#0 DO digits ← CONS[dec MOD 10, digits]; dec ← dec/10 ENDLOOP;
WHILE digits#NIL DO oct ← oct*8 + digits.first; digits ← digits.rest ENDLOOP};
cacheQuick: CellType ← NIL;
cacheRouted: CellType ← NIL;
RoutedIFU:
PROC
RETURNS[CellType] = {
IF cacheRouted=
NIL
THEN
IF FilePresent["IFURouted.core"]
THEN {
TerminalIO.WriteF["Read: %g %g . . . ", IO.rope["IFURouted"], IO.time[]];
cacheRouted ← CoreIO.RestoreCellType["IFURouted"];
cacheRouted ← SubstituteRecasted[cacheRouted];
TerminalIO.WriteF["done\n"]}
ELSE {
TerminalIO.WriteF["Read/Recast: %g %g", IO.rope["IFUComplete"], IO.time[]];
cacheRouted ← CoreIO.RestoreCellType["IFUComplete"]; TerminalIO.WriteF[". "];
cacheRouted ← SubstituteRecasted[cacheRouted]; TerminalIO.WriteF[". "];
[ ] ← CoreName.CellNm[cacheRouted, "IFURouted"];
RemoveExtraneousProps[cacheRouted, keepPropTable]; TerminalIO.WriteF[". "];
CoreIO.SaveCellType[cacheRouted]; TerminalIO.WriteF["done\n"]};
RETURN[cacheRouted]};
QuickIFU:
PROC
RETURNS[cell: CellType] = {
IF cacheQuick=
NIL
THEN
IF FilePresent["IFUQuick.core"]
THEN {
TerminalIO.WriteF["Read: %g %g . . . ", IO.rope["IFUQuick"], IO.time[]];
cacheQuick ← CoreIO.RestoreCellType["IFUQuick"];
cacheQuick ← SubstituteRecasted[cacheQuick];
TerminalIO.WriteF["done\n"]}
ELSE {
{
GetCell:
PROC[subCellNm:
ROPE]
RETURNS[subCell: CellType] = {
TerminalIO.WriteF["Read/Recast: %g %g . . ", IO.rope[subCellNm], IO.time[]];
subCell ← CoreIO.RestoreCellType[subCellNm]; TerminalIO.WriteF[". "];
subCell ← SubstituteRecasted[subCell]; TerminalIO.WriteF[". done\n"]};
wireTbl: CoreName.Context ← MakeFlatBotPublicCtx[ifuToCluster2Bindings];
public: Wire ← CoreName.WireFromCtx[wireTbl];
modules:
LIST
OF CellType =
LIST[
GetCell["IFUDataColumnCore"],
GetCell["IFUControlPipe"],
GetCell["IFUABForm"],
GetCell["IFULSForm"],
GetCell["IFUStackBuf"],
GetCell["IFUPCFormBot"],
GetCell["IFUPCFormTop"],
GetCell["IFUXaForm"],
GetCell["IFUFetchBuf"],
GetCell["IFUFetch"],
GetCell["IFULeftColumnCore"],
GetCell["IFURightColumnCore"],
GetCell["IFUPadTopCore"],
GetCell["IFUPadLtCore"],
GetCell["IFUPadRtCore"],
GetCell["IFUPadBotCore"] ];
cacheQuick ← CoreName.BindModules[public, modules, "IFUQuick"];
};
TerminalIO.WriteF["Remove Props: %g %g . . . ", IO.rope["IFUQuick"], IO.time[]];
RemoveExtraneousProps[cacheQuick, keepPropTable];
TerminalIO.WriteF[" done\n"];
CoreIO.SaveCellType[cacheQuick]};
RETURN[cacheQuick]};
FormalIFU:
PUBLIC
PROC[public: Wire ←
NIL, quick:
BOOL]
RETURNS[ifu: CellType] = {
ctx: Context;
ifu ← IF quick THEN QuickIFU[] ELSE RoutedIFU[];
ctx ← NewContext["FormalIFU", ifu, public];
RegTopBinds[ctx, ifuToCluster2Bindings];
ifu ← FormalCell[ctx]};
FilePresent:
PUBLIC
PROC[name:
ROPE]
RETURNS[present:
BOOL ←
TRUE] = {
ENABLE FS.Error => {present ← FALSE; CONTINUE};
file: FS.OpenFile ← FS.Open[name];
IF present THEN FS.Close[file] ELSE TerminalIO.WriteF["\n%g not present", IO.rope[name]]};
DrLatch Transistors
DrLatch-io nDrLatch-io GND
DrLatch-io nDrLatch-io VDD
nDrLatch-io DrLatch-io GND weakTransistor
nDrLatch-io DrLatch-io VDD weakTransistor
bit nbit GND
bit nbit VDD
nbit bit GND weakTransistor
nbit bit VDD weakTransistor
nDShDataOut DShDataOut GND
nDShDataOut DShDataOut VDD
DShDataOut nDShDataOut GND weakTransistor
DShDataOut nDShDataOut VDD weakTransistor
DShWt nbit DrLatch-io
DShRd bit nDrLatch-io
DShB nbit nDShDataOut
DShA bit DShDataIn
EnumPropLists:
PROC
[cell: Core.CellType, eachList: PROC[pList: Properties] RETURNS[Properties]] = {
eachWireProc: CoreOps.EachWireProc = {wire.properties ← eachList[wire.properties]};
cell.properties ← eachList[cell.properties];
[]𡤌oreOps.VisitWire[cell.public, eachWireProc];
IF cell.class=CoreClasses.recordCellClass
THEN {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
[]𡤌oreOps.VisitWire[data.internal, eachWireProc];
FOR child:
NAT
IN [0..data.size)
DO
data[child].properties ← eachList[data[child].properties];
[]𡤌oreOps.VisitWire[data[child].actual, eachWireProc];
EnumPropLists[data[child].type, eachList] ENDLOOP } };
FindAllProps:
PROC[cell: Core.CellType]
RETURNS[atoms:
LIST
OF
ATOM ←
NIL]= {
propTable: HashTable.Table ← HashTable.Create[];
eachAtom: HashTable.EachPairAction = {
atoms ← CONS[NARROW[key, ATOM], atoms]};
eachProp:
PROC [prop:
ATOM, val:
REF
ANY ←
NIL] =
{[]←HashTable.Store[propTable, prop, prop]};
eachList:
PROC[pList: Properties]
RETURNS[Properties] = {
CoreProperties.Enumerate[pList, eachProp];
RETURN[pList]};
EnumPropLists[cell, eachList];
[]←HashTable.Pairs[propTable, eachAtom]};
RemoveExtraneousProps:
PROC[cell: Core.CellType, keepers: HashTable.Table] = {
eachList:
PROC[pList: Properties]
RETURNS[Properties] = {
atoms: LIST OF ATOM ← NIL;
eachProp:
PROC [prop:
ATOM, val:
REF
ANY ←
NIL] =
{IF ~HashTable.Fetch[keepers, prop].found THEN atoms ← CONS[prop, atoms]};
CoreProperties.Enumerate[pList, eachProp];
FOR atoms ← atoms, atoms.rest
WHILE atoms#
NIL
DO
pList ← CoreProperties.PutProp[pList, atoms.first, NIL] ENDLOOP;
RETURN[pList]};
EnumPropLists[cell, eachList]};
SetUp:
PUBLIC
PROC[cell: Core.CellType] = {
name: ROPE ← CoreName.CellNm[cell].n;
IF CoreProperties.GetCellTypeProp[cell, $RoseBehave].value#NIL THEN RETURN;
SELECT
TRUE
FROM
name=dpPreChg => {
[]←Rosemary.BindCellType[cell, dpPreChg];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpPreChg];
InitPort[cell.public, "0", b, none];
InitPort[cell.public, "out0", b, drive]};
name=dpLatchPreChg => {
[]←Rosemary.BindCellType[cell, dpLatchPreChg];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpPreChg];
InitPort[cell.public, "in0", b, none];
InitPort[cell.public, "out0", b, drive]};
name=dpDebugRec => {
[]←Rosemary.BindCellType[cell, dpDebugRec];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpDebugRec];
InitPort[cell.public, "in0", b, none];
InitPort[cell.public, "in1", b, none];
InitPort[cell.public, "0", b, none];
InitPort[cell.public, "1", b, none];
InitPort[cell.public, "2", b, none];
InitPort[cell.public, "out0", b, drive]};
name=dpLatchG => {
[]←Rosemary.BindCellType[cell, dpLatchG];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpLatch];
InitPort[cell.public, "out0", b, drive];
[]←MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]};
name=dpLatchV => {
[]←Rosemary.BindCellType[cell, dpLatchV];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpLatch];
InitPort[cell.public, "out0", b, drive];
[]←MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]};
name=dpLatch => {
[]←Rosemary.BindCellType[cell, dpLatch];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpLatch];
InitPort[cell.public, "in0", b, none];
InitPort[cell.public, "0", b, none];
InitPort[cell.public, "out0", b, drive];
[]←MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]};
name=dpLatchCtl => {
[]←Rosemary.BindCellType[cell, dpLatchCtl];
[]𡤌oreFlat.CellTypeCutLabels[cell, dpLatch];
InitPort[cell.public, "in1", b, none];
InitPort[cell.public, "in0", b, none];
InitPort[cell.public, "out0", b, drive];
[]←MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]};
name=drLatch => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
[]←Rosemary.BindCellType[cell, drLatch];
[]𡤌oreFlat.CellTypeCutLabels[cell, drLatch];
[]←MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "nDrLatch-io"]];
[]←MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "nbit"]];
[]←MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "DShDataOut"]];
InitPort[cell.public, "DrLatch-io", b, none];
InitPort[cell.public, "DShDataIn", b, none];
InitPort[cell.public, "DShDataOut", b, drive];
InitPort[cell.public, "DShA", b, none];
InitPort[cell.public, "DShB", b, none];
InitPort[cell.public, "DShWt", b, none];
InitPort[cell.public, "DShRd", b, none]};
Rope.Equal[name.Substr[0,4], "Mux|"] => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
ctl: ROPE← MuxNameField[name, ctl];
in: ROPE← MuxNameField[name, in];
blankIns: INT ← 0;
IF data.size=0 THEN RETURN;
[]←Rosemary.BindCellType [cell, genericMux];
[]𡤌oreFlat.CellTypeCutLabels [cell, genericMux];
FOR child:
NAT
IN [0..data.size)
DO
[] ← Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak];
ENDLOOP;
FOR i:
INT
IN [0..ctl.Length[])
DO
wire: Wire;
wire ← CoreOps.FindWire[cell.public, ctl.Substr[i,1]];
IF wire=NIL THEN Signal[];
[]←Ports.InitPort[wire: wire, levelType: b, initDrive: none];
wire ← CoreOps.FindWire[cell.public, in.Substr[i,1]];
IF wire#
NIL
THEN []←Ports.InitPort[wire: wire, levelType: b, initDrive: none]
ELSE blankIns ← blankIns+1;
ENDLOOP;
IF (data.size+blankIns)#ctl.Length[] THEN Signal[];
InitPort[cell.public, MuxNameField[name, out].Substr[0,1], l, drive]};
name=ifuFetchBuf => IFUSim.FetchBufInitPort [cell];
name=ifuStackBuf => IFUSim.StackBufInitPort [cell];
ENDCASE =>
SELECT cell.class
FROM
PLASim.simplePLAClass => PLASim.SetUpRose[cell];
CoreClasses.transistorCellClass => ERROR;
CoreClasses.recordCellClass => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
FOR child:
NAT
IN [0..data.size)
DO
IF data.instances[child].type.class # CoreClasses.transistorCellClass
THEN SetUp[ data.instances[child].type]
ELSE {
trans: CoreClasses.Transistor ← NARROW[data.instances[child].type.data];
length: REAL ← trans.length;
width: REAL ← trans.width;
IF length/width > .5
THEN
[] ← Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]};
ENDLOOP };
ENDCASE => {recast: CellType ← CoreOps.Recast[cell]; SetUp[ recast ]} };
ENDCASE => {Signal[]} };
InitPort:
PROC
[wire: Wire, name:
ROPE, levelType: Ports.LevelType, initDrive: Ports.Drive] ={
wire ← CoreOps.FindWire[wire, name];
IF wire#
NIL
THEN
[]←Ports.InitPort[wire: wire, levelType: levelType, initDrive: initDrive]};
dpPreChg:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpPreChg"],
DpPreChgInit, DpPreChgEval];
dpLatchPreChg:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpLatchPreChg"],
DpLatchPreChgInit, DpPreChgEval];
dpDebugRec:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpDebugRec"],
DpDebugRecInit, DpDebugRecEval];
dpLatch:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpLatch"],
DpLatchInit, DpLatchEval];
dpLatchG:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpLatch-G-="],
DpLatchGVInit, DpLatchGEval];
dpLatchV:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpLatch-V-="],
DpLatchGVInit, DpLatchVEval];
dpLatchCtl:
ROPE ← Rosemary.Register[CoreName.RopeNm["DpLatchCtl"],
DpLatchCtlInit, DpLatchEval];
drLatch:
ROPE ← Rosemary.Register[CoreName.RopeNm["DrLatch"],
DrLatchInit, DrLatchEval];
genericMux:
ROPE ← Rosemary.Register[CoreName.RopeNm["GenericMux"],
MuxInit, MuxEval];
ifuFetchBuf: ROPE ← CoreName.RopeNm["IFUFetchBuf"];
ifuStackBuf: ROPE ← CoreName.RopeNm["IFUStackBuf"];
upOneLevel: ROPE ← CoreName.RopeNm["UpOneLevel"];
simpleMux: ROPE ← CoreName.RopeNm["SimpleMux"];
DrLatchState: TYPE = REF DrLatchStateRec;
DrLatchStateRec:
TYPE =
RECORD[
io, DShIn, DShOut, DShA, DShB, DShWt, DShRd: INT ← -1,
inside: BOOL ← FALSE];
DpPreChgState: TYPE = REF DpPreChgStateRec;
DpPreChgStateRec: TYPE = RECORD[in, out: INT ← -1];
DpDebugRecState: TYPE = REF DpDebugRecStateRec;
DpDebugRecStateRec:
TYPE =
RECORD
[in0, in1, ctl0, ctl1, ctl2, out: INT ← -1, bit: BOOL ← FALSE];
DpLatchState: TYPE = REF DpLatchStateRec;
DpLatchStateRec:
TYPE =
RECORD[
in, ctl, out: INT ← -1,
inside: BOOL ← FALSE];
MuxState: TYPE = REF MuxStateRec;
MuxStateRec:
TYPE =
RECORD[
ctl: MuxPinSeq,
in: MuxPinSeq,
out: INT];
MuxPinSeq: TYPE = REF MuxPinSeqRec;
MuxPinSeqRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF INTEGER];
DrLatchInit: Rosemary.InitProc = {
s: DrLatchState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DrLatchStateRec];
s^ ← [
io: CoreOps.GetWireIndex[cellType.public, "DrLatch-io"],
DShIn: CoreOps.GetWireIndex[cellType.public, "DShDataIn"],
DShOut: CoreOps.GetWireIndex[cellType.public, "DShDataOut"],
DShA: CoreOps.GetWireIndex[cellType.public, "DShA"],
DShB: CoreOps.GetWireIndex[cellType.public, "DShB"],
DShWt: CoreOps.GetWireIndex[cellType.public, "DShWt"],
DShRd: CoreOps.GetWireIndex[cellType.public, "DShRd"],
inside: FALSE ];
RETURN[s]};
DpPreChgInit: Rosemary.InitProc = {
s: DpPreChgState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpPreChgStateRec];
s^ ← [
in: CoreOps.GetWireIndex[cellType.public, "0"],
out: CoreOps.GetWireIndex[cellType.public, "out0"]];
RETURN[s]};
DpLatchPreChgInit: Rosemary.InitProc = {
s: DpPreChgState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpPreChgStateRec];
s^ ← [
in: CoreOps.GetWireIndex[cellType.public, "in0"],
out: CoreOps.GetWireIndex[cellType.public, "out0"]];
RETURN[s]};
DpDebugRecInit: Rosemary.InitProc = {
s: DpDebugRecState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpDebugRecStateRec];
s^ ← [
in0: CoreOps.GetWireIndex[cellType.public, "in0"],
in1: CoreOps.GetWireIndex[cellType.public, "in1"],
ctl0: CoreOps.GetWireIndex[cellType.public, "0"],
ctl1: CoreOps.GetWireIndex[cellType.public, "1"],
ctl2: CoreOps.GetWireIndex[cellType.public, "2"],
out: CoreOps.GetWireIndex[cellType.public, "out0"],
bit: FALSE ];
RETURN[s]};
DpLatchInit: Rosemary.InitProc = {
s: DpLatchState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpLatchStateRec];
s^ ← [
in: CoreOps.GetWireIndex[cellType.public, "in0"],
ctl: CoreOps.GetWireIndex[cellType.public, "0"],
out: CoreOps.GetWireIndex[cellType.public, "out0"],
inside: FALSE ];
RETURN[s]};
DpLatchGVInit: Rosemary.InitProc = {
s: DpLatchState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpLatchStateRec];
s^ ← [out: CoreOps.GetWireIndex[cellType.public, "out0"] ];
RETURN[s]};
DpLatchCtlInit: Rosemary.InitProc = {
s: DpLatchState ←
IF oldStateAny #
NIL
THEN NARROW[oldStateAny]
ELSE NEW[DpLatchStateRec];
s^ ← [
in: CoreOps.GetWireIndex[cellType.public, "in0"],
ctl: CoreOps.GetWireIndex[cellType.public, "in1"],
out: CoreOps.GetWireIndex[cellType.public, "out0"],
inside: FALSE ];
RETURN[s]};
MuxInit: Rosemary.InitProc = {
name: ROPE ← CoreName.CellNm[cellType].n;
s: MuxState;
ctl: ROPE ← MuxNameField[name, ctl];
in: ROPE ← MuxNameField[name, in];
s ← NEW[MuxStateRec];
s.ctl ← NEW[MuxPinSeqRec[ctl.Length[]]];
s.in ← NEW[MuxPinSeqRec[ctl.Length[]]];
FOR i:
CARDINAL
IN [0..s.ctl.size)
DO
s.ctl[i] ← CoreOps.GetWireIndex[cellType.public, ctl.Substr[i,1] ];
s.in[i] ← CoreOps.GetWireIndex[cellType.public, in.Substr[i,1] ];
ENDLOOP;
s.out ← CoreOps.GetWireIndex[cellType.public, MuxNameField[name, out].Substr[0,1]];
RETURN[s]};
DrLatchEval: Rosemary.EvalProc = {
s: DrLatchState ← NARROW[stateAny];
IF p[s.DShRd].b AND p[s.DShA].b THEN Signal[];
IF p[s.DShRd].b AND p[s.DShWt].b THEN Signal[];
IF p[s.DShA].b THEN s.inside ← p[s.DShIn].b;
IF p[s.DShRd].b THEN s.inside ← NOT p[s.io].b;
IF p[s.DShWt].b
THEN {p[s.io].b ← NOT s.inside; p[s.io].d ← drive}
ELSE p[s.io].d ← none;
IF p[s.DShB].b THEN p[s.DShOut].b ← s.inside };
DpPreChgEval: Rosemary.EvalProc = {
s: DpPreChgState ← NARROW[stateAny];
IF
NOT p[s.in].b
THEN {p[s.out].d ← drive; p[s.out].b ← TRUE}
ELSE {p[s.out].d ← none}};
DpDebugRecEval: Rosemary.EvalProc = {
s: DpDebugRecState ← NARROW[stateAny];
IF p[s.ctl0].b AND p[s.ctl1].b THEN Signal[];
IF p[s.ctl0].b THEN s.bit ← p[s.in0].b;
IF p[s.ctl1].b THEN s.bit ← p[s.in1].b;
IF p[s.ctl2].b THEN p[s.out].b ← s.bit };
DpLatchEval: Rosemary.EvalProc = {
s: DpLatchState ← NARROW[stateAny];
IF p[s.ctl].b THEN s.inside ← p[s.in].b;
p[s.out].b ← s.inside };
DpLatchGEval: Rosemary.EvalProc = {
s: DpLatchState ← NARROW[stateAny];
p[s.out].b ← FALSE };
DpLatchVEval: Rosemary.EvalProc = {
s: DpLatchState ← NARROW[stateAny];
p[s.out].b ← TRUE };
MuxEval: Rosemary.EvalProc = {
s: MuxState ← NARROW[stateAny];
count: CARDINAL ← 0;
last: CARDINAL ← 0;
FOR i:
CARDINAL
IN [0..s.ctl.size)
DO
IF p[s.ctl[i]].b AND s.in[i]#-1 THEN {count ← count+1; last ← i} ENDLOOP;
SELECT count
FROM
0 => { };
1 => IF s.in[last]#-1 THEN p[s.out].l ← IF p[s.in[last]].b THEN H ELSE L;
ENDCASE => p[s.out].l ← X};
MuxNameField:
PROC[name:
ROPE, type: {ctl, in, out}]
RETURNS[field: ROPE ← NIL] = {
Must Agree with IFUCoreDataMuxImpl.ExpandDataMuxFrameHard CreateNameLetterCode
index: CARDINAL ← SELECT type FROM ctl=>1, in=>2, ENDCASE=>3;
THROUGH [0..index] DO name ← name.Substr[name.Find["|"]+1] ENDLOOP;
field ← name.Substr[0, name.Find["|"]]};
Signal: SIGNAL = CODE;
keepPropTable: HashTable.Table ← HashTable.Create[];
[]←HashTable.Store[keepPropTable, $CoreName, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $Layout, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $WireCap, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $RootCap, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $CapaLabel, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $TransistorGateCount, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $TransistorCount, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $CoreIOGlobal, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $CoreBlockSides, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $GivenName, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $FusedByName, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $CoreNameToWireCache, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $CoreWireToNamesCache NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $ClusterInfo, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $PortData, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $RoseFixedWire, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $RoseCutSet, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $RoseTransistorSize, NEW[INT ← 0]];
[]←HashTable.Store[keepPropTable, $RoseBehave, NEW[INT ← 0]];
END.