CoreNameImpl:
CEDAR
PROGRAM
IMPORTS Convert, CoreClasses, CoreOps, HashTable, IO, REFBit, Rope
EXPORTS CoreName
~ BEGIN
ROPE: TYPE = Core.ROPE;
Wire: TYPE = Core.Wire;
CellType: TYPE = Core.CellType;
Context: TYPE = CoreName.Context;
Ph: TYPE = CoreName.Ph;
Polarity: TYPE = CoreName.Polarity;
SigRec: TYPE = CoreName.SigRec;
table: HashTable.Table ←
HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope];
NILRope: ROPE = "NIL";
nilRope: ROPE = "nil";
NILRopeRegistered: BOOL ← HashTable.Store[table, NILRope, nilRope];
nilRopeRegistered: BOOL ← HashTable.Store[table, nilRope, nilRope];
Signal: SIGNAL = CODE;
RopeNm:
PUBLIC
PROC[rope:
ROPE]
RETURNS[registered:
ROPE] = {
IF rope=NIL THEN RETURN[NIL];
registered ← NARROW[HashTable.Fetch[table, rope].value];
SELECT registered
FROM
nilRope => RETURN[NIL];
NIL => {[] ← HashTable.Store[table, rope, rope]; RETURN[rope]};
ENDCASE => RETURN[registered]};
WireNm:
PUBLIC
PROC[wire: Core.Wire, rope:
ROPE←
NIL]
RETURNS[w: Core.Wire, n: ROPE] = {
IF wire=NIL THEN RETURN[NIL, NIL];
IF rope=NIL THEN rope ← CoreOps.GetShortWireName[wire];
n ← RopeNm[rope];
w ← CoreOps.SetShortWireName[wire, n]};
CellNm:
PUBLIC
PROC[cell: Core.CellType, rope:
ROPE←
NIL]
RETURNS[c: Core.CellType, n: ROPE] = {
IF rope=NIL THEN rope ← CoreOps.GetCellTypeName[cell];
n ← RopeNm[rope];
c ← CoreOps.SetCellTypeName[cell, n]};
NextIDIndex: INT ← 0;
ID:
PUBLIC
PROC[rope:
ROPE]
RETURNS[unique:
ROPE] = {
unique ← RopeNm[IO.PutFR["%g%g", IO.rope[rope], IO.int[NextIDIndex]]];
NextIDIndex ← NextIDIndex+1};
NewContext:
PUBLIC
PROC
RETURNS[ctx: Context] =
{RETURN[HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]]};
CtxCopyWire:
PUBLIC
PROC[ctx: Context, wire: Core.Wire]
-- only name prop is copied
RETURNS[new: Core.Wire] = {
Copy:
PROC [wire: Core.Wire]
RETURNS [new: Core.Wire] = {
IF (new ←
NARROW[HashTable.Fetch[table: visitTab, key: wire].value])=
NIL
THEN {
name: ROPE ← WireNm[wire].n;
new ← CtxNameToWire[ctx, name];
IF new#
NIL
THEN
{[]←HashTable.Insert[table: visitTab, key: wire, value: new]; RETURN[new]};
new ← CoreOps.CreateWires[size: wire.size];
IF name#NIL THEN IF NOT CtxRegisterWire[ctx, new, name].ok THEN ERROR;
IF NOT HashTable.Insert[table: visitTab, key: wire, value: new] THEN ERROR;
[]←WireNm[new, name];
FOR i: NAT IN [0 .. wire.size) DO new[i] ← Copy[wire[i]] ENDLOOP } };
visitTab: HashTable.Table ← HashTable.Create[]; -- Wire to Wire
IF ctx=NIL THEN RETURN[NIL];
new ← IF wire=NIL THEN NIL ELSE Copy[wire] };
CtxWire:
PUBLIC
PROC[ctx: Context, name:
ROPE, size:
INT ← -1]
RETURNS[wire: Core.Wire] = {
IF ctx=NIL THEN RETURN[NIL];
IF name=NIL OR name.Length[]=0 THEN RETURN[NIL];
wire ← CtxNameToWire[ctx, name];
IF wire=
NIL
THEN {wire ← NEW[Core.WireRec[MAX[size, 0]]]; [ ] ← CtxRegisterWire[ctx, wire, name]}
ELSE {IF size#-1 AND wire.size#size THEN wire ← NIL}};
CtxRegisterWire:
PUBLIC
PROC[ctx: Context, wire: Core.Wire, name:
ROPE ←
NIL]
RETURNS[ok: BOOL] ={
oldWire: Core.Wire;
IF ctx=NIL THEN RETURN[FALSE];
IF name=NIL OR name.Length[]=0 THEN name ← CoreOps.GetShortWireName[wire];
IF name=NIL OR name.Length[]=0 THEN RETURN[FALSE];
oldWire ← NARROW[HashTable.Fetch[ctx, name].value];
IF oldWire#NIL AND oldWire#wire THEN RETURN[FALSE];
wire ← CoreOps.SetShortWireName[wire, RopeNm[name]];
IF oldWire=wire THEN RETURN[TRUE];
[ ] ← HashTable.Store[ctx, name, wire]};
CtxNameToWire:
PUBLIC
PROC[ctx: Context, name:
ROPE]
RETURNS[wire: Core.Wire] = {
IF ctx=NIL THEN RETURN[NIL];
IF name=NIL OR name.Length[]=0 THEN RETURN[NIL];
wire ← NARROW[HashTable.Fetch[ctx, name].value]};
CtxWireToName:
PUBLIC
PROC[ctx: Context, wire: Core.Wire]
RETURNS[name:
ROPE] = {
oldWire: Core.Wire;
IF ctx=NIL THEN RETURN[NIL];
IF wire=NIL THEN RETURN[NIL];
name ← CoreOps.GetShortWireName[wire];
oldWire ← NARROW[HashTable.Fetch[ctx, name].value];
RETURN[ IF wire=NIL OR oldWire=NIL OR wire#oldWire THEN NIL ELSE name]};
WiresFromCtx:
PUBLIC
PROC[ctx: Context]
RETURNS[wires: Core.Wires] = {
TwoWires: TYPE = RECORD[w0, w1: Wire];
action: HashTable.EachPairAction = {wires ← CONS[NARROW[value], wires]};
ordered: BOOL;
[ ] ← HashTable.Pairs[ctx, action];
ordered ← wires=NIL OR wires.rest=NIL;
WHILE
NOT ordered
DO
ordered ← TRUE;
FOR ws: Core.Wires ← wires, ws.rest
WHILE ws.rest #
NIL
DO
IF Rope.Compare[WireNm[ws.first].n, WireNm[ws.rest.first].n] = greater
THEN
{[ws.first, ws.rest.first] ← TwoWires[ws.rest.first, ws.first]; ordered ← FALSE};
ENDLOOP;
ENDLOOP};
WireFromCtx:
PUBLIC
PROC[ctx: Context]
RETURNS[wire: Core.Wire] =
{wire ← CoreOps.CreateWire[ WiresFromCtx[ctx] ]};
killing: BOOL ← TRUE;
KillContext:
PUBLIC PROC[ctx: Context]
RETURNS[Context] =
{
IF killing
THEN {HashTable.Erase[ctx]; RETURN[NIL]}
ELSE {RETURN[ctx]}};
BindModules:
PUBLIC PROC[public: Wire, modules:
LIST
OF CellType, name:
ROPE ←
NIL]
RETURNS [cell: CellType] = {
RegPubs: CoreOps.EachWireProc = {[]𡤌txRegisterWire[ctx, wire]};
ctx: Context ← NewContext[];
rec: CoreClasses.RecordCellType;
cnt: NAT ← 0;
[] ← CoreOps.VisitWire[public, RegPubs];
FOR m: LIST OF CellType ← modules, m.rest WHILE m#NIL DO cnt ← cnt + 1 ENDLOOP;
rec ← NEW [CoreClasses.RecordCellTypeRec[cnt]];
cnt ← 0;
FOR m:
LIST
OF CellType ← modules, m.rest
WHILE m#
NIL
DO
rec[cnt] ←
NEW[ CoreClasses.CellInstanceRec ←
[actual: CtxCopyWire[ctx, m.first.public], type: m.first]];
cnt ← cnt+1 ENDLOOP;
rec.internal ← WireFromCtx[ctx];
cell ←
NEW [Core.CellTypeRec ← [
class: CoreClasses.recordCellClass,
public: public,
data: rec ]];
[ ] ← CellNm[cell, name];
ctx ← KillContext[ctx]};
PrintWire:
PUBLIC PROC[wire: Core.Wire] = {
};
PhRope:
PUBLIC
ARRAY Ph
OF
ROPE ←
["A", "AB", "ABB", "ABBB", "Ac", "B", "BA", "BAA", "BAAA", "Bc", ""];
PolarityRope: PUBLIC ARRAY Polarity OF ROPE ← ["", "n", "?n"];
SigName:
PUBLIC
PROC [sigRec: SigRec]
RETURNS [name:
ROPE ← NIL ] ~ {
name ← sigRec.root;
IF name = NIL THEN RETURN[NIL];
IF sigRec.not THEN name ← Rope.Cat["Not", name];
IF sigRec.cy#-1 THEN name ← name.Cat[ Convert.RopeFromInt[sigRec.cy]];
IF sigRec.ph#unk THEN name ← name.Cat[ PhRope[sigRec.ph]];
IF sigRec.idx#-1 THEN name ← name.Cat[ ".", Convert.RopeFromInt[sigRec.idx]];
name ← RopeNm[name]};
NameSig:
PUBLIC
PROC [name:
ROPE]
RETURNS [sigRec: SigRec ← [ ] ] ~ {
phasesize: ARRAY Ph OF INT ← [1,2,3,4,2,1,2,3,4,2,0];
char: CHARACTER;
end: INT;
not4: BOOL ← Rope.Equal[name.Substr[0, 4], "Not.", FALSE];
not3: BOOL ← Rope.Equal[name.Substr[0, 3], "Not", FALSE];
IF name=NIL THEN RETURN[[]];
name ← name.Substr[start: (IF not4 THEN 4 ELSE IF not3 THEN 3 ELSE 0)];
sigRec.not ← not3 OR not4;
end ← name.Index[0, "."];
sigRec.root ← name.Substr[0, end];
sigRec.idx ←
IF (end+1)< name.Length
THEN Convert.IntFromRope[name.Substr[end+1]] ELSE -1;
sigRec.ph ←
SELECT name.Fetch[sigRec.root.Length[]-1]
FROM
'A =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-2]
FROM
'B => BA,
'A =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-3]
FROM
'B => BAA,
'A =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-4]
FROM
'B => BAAA,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => A,
'B =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-2]
FROM
'A => AB,
'B =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-3]
FROM
'A => ABB,
'B =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-4]
FROM
'A => ABBB,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => B,
'c =>
SELECT sigRec.root.Fetch[sigRec.root.Length[]-2]
FROM
'A => Ac,
'B => Bc,
ENDCASE => unk,
ENDCASE => unk;
sigRec.root ← sigRec.root.Substr[0, sigRec.root.Length[]-phasesize[sigRec.ph]];
char ← sigRec.root.Fetch[sigRec.root.Length[]-1];
IF char
IN ['0..'9]
THEN {
sigRec.cy ← char.ORD - '0.ORD;
sigRec.root ← sigRec.root.Substr[0, sigRec.root.Substr.Length[]-1]};
sigRec.root ← RopeNm[sigRec.root] };
SelectName:
PUBLIC
PROC[inv:
BOOL, posNm, negNm:
ROPE]
RETURNS [inverted: BOOL, name: ROPE] = {
sig, sigI: SigRec;
IF posNm=NIL THEN {inv ← ~inv; posNm ← negNm; negNm ← NIL};
sig ← NameSig[posNm];
sigI ← NameSig[negNm];
IF inv#sig.not AND negNm#NIL AND inv#sigI.not THEN {sig ← sigI; inv ← ~inv};
inverted ← inv#sig.not; sig.not ← FALSE; name ← SigName[sig]};
NormalFormatNames:
PUBLIC PROC [format: REFBit.FormatRec]
RETURNS[name, nameInv:
ROPE, dual, inverted:
BOOL, cy, idx:
INT] = {
name ← BitRopeToSigRope[format.name];
nameInv ← BitRopeToSigRope[format.nameInv];
IF name#
NIL
AND nameInv#
NIL
THEN {
sig: SigRec ← NameSig[name];
sigI: SigRec ← NameSig[nameInv];
IF sig.not#sigI.not THEN Signal[];
IF sig.cy#sigI.cy THEN Signal[];
IF sig.idx#sigI.idx THEN Signal[];
IF sig.not
THEN {name ← sigI.root; nameInv ← sig.root}
ELSE {name ← sig.root; nameInv ← sigI.root};
cy ← sig.cy;
idx ← sig.idx;
inverted ← FALSE;
dual ← TRUE }
ELSE {
sig: SigRec;
IF name#
NIL
THEN {sig ← NameSig[name]; inverted ← sig.not}
ELSE {sig ← NameSig[nameInv]; inverted ← NOT sig.not};
name ← sig.root;
nameInv ← NIL;
dual ← FALSE ;
cy ← sig.cy;
idx ← sig.idx }};
BitRopeToSigRope:
PUBLIC
PROC [name:
ROPE]
RETURNS [
ROPE] ~ {
Cap:
PROC[rope:
ROPE, idx:
INT]
RETURNS[
ROPE] = {
char: CHAR ← rope.Fetch[idx+1];
IF char IN ['a..'z] THEN char ← char + LOOPHOLE['A - 'a];
RETURN[IO.PutFR["%g", IO.char[char]]]};
IF name = NIL THEN RETURN[NIL];
name ← Rope.Cat[Cap[name, -1], name.Substr[1]];
DO
-- remove peiods and Capitalize next letters until end or next char is number
index: INT ← name.Index[0, "."];
IF index+1 >= name.Length[] OR name.Fetch[index+1] IN ['0..'9] THEN RETURN[name];
name ← Rope.Cat[name.Substr[0,index], Cap[name, index], name.Substr[index+2]];
ENDLOOP };
RootExt:
PUBLIC
PROC [name:
ROPE]
RETURNS [root, ext:
ROPE] ~ {
end: INT;
end ← name.Index[0, "."];
root ← name.Substr[0, end];
ext ← IF end+1< name.Length THEN name.Substr[end] ELSE NIL};
EDTypeWire:
PUBLIC PROC[root, ext, ref:
ROPE]
RETURNS[wire: Wire] = {
bitName, bitNameInv: ROPE;
refREF: REF ← REFBit.NEWFromName[ref];
format: REFBit.Format ← REFBit.Desc[refREF].bitForm;
wire ← CoreOps.CreateWires[MAX[2, format.size], root.Cat[ext]];
FOR i:
INT
IN[0..format.size)
DO
bitName ← BitRopeToSigRope[format[i].name];
bitNameInv ← BitRopeToSigRope[format[i].nameInv];
IF ((format.size#1) = (i+1=format.size)) = (bitName#NIL) THEN ERROR;
IF ((format.size#1) = (bitNameInv#NIL)) = (bitName#NIL) THEN ERROR;
IF bitName=NIL THEN bitName ← bitNameInv;
wire[i] ← CoreOps.CreateWires[0, root.Cat[bitName, ext]];
IF format.size=1
THEN
wire[1] ← CoreOps.CreateWires[0, root.Cat[bitNameInv, ext]];
ENDLOOP};
END.