CreateCellTypeFromDag:
PUBLIC
PROC [tree: Dag, fanout:
INT ← 4]
RETURNS [Core.CellType] ~ {
Given a tree, this will construct a CellType which implements the equations described by the tree
ctcoll: Treeset ← MakeNewCTreeSet[];
AssembleCTree[ctcoll];
FOR ctiter: Dag ← ctcoll^.top, ctiter^.next
UNTIL ctiter =
NIL
DO
RemoveOrs[ctiter];
ENDLOOP;
TwoifyAllTrees[ctcoll];
SimplifyDag[tree];
EstablishLevels[tree];
TwoifyTree[tree];
ReduceFanout[tree, fanout];
RemoveOrs[tree];
WHILE RemoveAllIdenticalLinks[tree] OR RemoveDuplicateNodes[tree] DO ENDLOOP;
BufferNecessaryNodes[tree];
ReduceFanout[tree, fanout];
KillHangingNodes[tree, FALSE];
ProduceTotalCovering[tree, ctcoll];
RETURN[FromDagToCellType[tree]]
};
Parse:
PUBLIC
PROC [tree: Dag, be:
ROPE, inpos, len:
INT]
RETURNS [outv: Node, outpos:
INT] ~ {
Given a Boolean expression, be, this will make incorporate it in tree representation into tree. Len is the length of be and is passed to avoid recomputing it--
onode, anode, temp: Node ← NIL; --the current or and and node
andcount, orcount: INT ← 0; --the number of terms encountered so far in the current or and and.
notactivep: BOOL ← FALSE; --should we negate the current expression
WHILE inpos # len
DO
SELECT Rope.Fetch[be, inpos]
FROM
'( => {
--Parse a subexpression
[outv: temp, outpos: inpos] ← Parse[tree, be, inpos+1, len];
IF notactivep THEN temp ← Negate[tree, temp];
notactivep ← FALSE;
IF andcount > 0 THEN MakeLink[anode, temp];
andcount ← andcount + 1};
' =>
--Ignore spaces
NULL;
'~ =>
--We should negate the next expression
notactivep ← NOT notactivep;
'* =>
--The past item was a term in a multiply
IF andcount = 1
THEN {
[] ← MakeNewNodeA[tree, NIL, and];
anode ← tree^.csucs;
MakeLink[anode, temp]};
'+ => {
--The past item was a term in an add
IF orcount = 0
THEN {
[] ← MakeNewNodeA[tree, NIL, or];
onode ← tree^.csucs};
orcount ← orcount + 1;
IF andcount = 1
THEN MakeLink[onode, temp]
ELSE MakeLink[onode, anode];
andcount ← 0};
') => {
--we've just finished an expression
IF orcount # 0
THEN {
outv ← onode;
IF andcount = 1
THEN MakeLink[onode, temp]
ELSE MakeLink[onode, anode]}
ELSE
IF andcount = 1
THEN outv ← temp
ELSE outv ← anode;
outpos ← inpos;
RETURN}
ENDCASE => {
--there is an input variable to be processed
nomen: ROPE;
[name: nomen, outpos: inpos] ← GetName[be, inpos];
temp ← FindNodeByName[tree, nomen];
IF temp =
NIL
THEN {
[] ← MakeNewNodeA[tree, NIL ,prim];
temp ← tree^.csucs;
temp^.inname ← nomen};
IF notactivep THEN temp ← Negate[tree, temp];
notactivep ← FALSE;
IF andcount > 0 THEN MakeLink[anode, temp];
andcount ← andcount + 1};
inpos ← inpos + 1;
outpos ← inpos;
ENDLOOP;
};
GetName:
PROC [be:
ROPE, inpos:
INT]
RETURNS [name:
ROPE, outpos:
INT] ~ {
Finds the next name substring in the input ROPE, be--
endpos: INT ← Rope.SkipTo[be, inpos, "()+*"] - 1;
inpos ← Rope.SkipOver[be, inpos, " "];
outpos ← endpos;
WHILE Rope.Fetch[be,endpos] = '
DO
endpos ← endpos - 1
ENDLOOP;
name ← Rope.Substr[be, inpos, endpos - inpos + 1]
};
AssembleCTree:
PROC [ctcoll: Treeset] ~ {
This is where the trees to be used in the cover are created.
1 input
AddInputToCover["X ← ~I", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "inv"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
2 inputs
AddInputToCover["X ← ~(I-A * I-B)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nand2"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← I-A * I-B", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "and2"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← ~(I-A + I-B)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nor2"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← I-A + I-B", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "or2"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
3 inputs (some missing)
AddInputToCover["X ← ~(I-A * I-B * I-C)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nand3"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← (I-A * I-B * I-C)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "and3"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← ~(I-A + I-B + I-C)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nor3"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← (I-A + I-B + I-C)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "or3"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
4 inputs (many missing)
AddInputToCover["X ← ~(I-A * I-B * I-C * I-D)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nand4"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
AddInputToCover["X ← ~(I-A + I-B + I-C + I-D)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "nor4"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
xors
AddInputToCover["X ← (I-A * I-B + ~I-A * ~I-B)", ctcoll];
ctcoll^.top^.cell ← NARROW[SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], "xor2"].val];
ctcoll^.top^.val ← NARROW[CoreProperties.GetCellTypeProp[ctcoll^.top^.cell, $CellArea], REF INT]^;
};
Commander.Register[key: "Gen", proc: MakeGenerator, doc: "Standard cells from logic equations"];