CRProcsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, March 27, 1986 9:56:04 am PST
DIRECTORY
AMBridge, AMTypes, Basics, BitHacks, Core, CoreClasses, CoreCreate, CoreOps, CRProcs, CD, PWCore, Sisyph, SSI, SymTab;
CRProcsImpl: CEDAR PROGRAM    
IMPORTS AMBridge, Basics, BitHacks, CoreCreate, CoreOps, PWCore, Sisyph, SSI, SymTab
EXPORTS CRProcs =
BEGIN OPEN CoreCreate;
InitContext: PUBLIC PROC [cx: Sisyph.Context] = {
selectBits: NAT = 8;
log2SelectBits: NAT = BitHacks.Log2[selectBits];
addressDecoderBits: NAT = CRProcs.addressBits-log2SelectBits;
andPlaneBits: NAT = addressDecoderBits-1;
Sisyph.Store[cx, "dataBits", NEW[NAT ← CRProcs.dataBits]];
Sisyph.Store[cx, "addressBits", NEW[NAT ← CRProcs.addressBits]];
Sisyph.Store[cx, "selectBits", NEW[NAT ← selectBits]];
Sisyph.Store[cx, "rowQuads", NEW[NAT ← CRProcs.rowQuads]];
Sisyph.Store[cx, "log2SelectBits", NEW[NAT ← log2SelectBits]];
Sisyph.Store[cx, "addressDecoderBits", NEW[NAT ← addressDecoderBits]];
Sisyph.Store[cx, "andPlaneBits", NEW[NAT ← andPlaneBits]];
};
DecoderLogicDriver: PUBLIC PROC [cx: Sisyph.Context] RETURNS [ct: CellType] = {
select: NAT ← GetNat[cx, "selectBits"];
log2Select: NAT ← GetNat[cx, "log2SelectBits"];
invert8: CellType ← SSI.Inverter[];
and: CellType ← SSI.And[i: log2Select];
instances: CoreClasses.CellInstances ← NIL;
FOR adrBit: INT IN [0 .. log2Select) DO
instances ← CONS [
Instance[
invert8,
["Input", Index["LowAddressB", adrBit]],
["nOutput", Index["nLowAddressB", adrBit]]
],
instances];
ENDLOOP;
FOR sel: INT IN [0 .. select) DO
bind: LIST OF WRNIL;
FOR adrBit: INT DECREASING IN [0 .. log2Select) DO
bind ← CONS [
Index[
IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN "LowAddressB" ELSE "nLowAddressB",
adrBit],
bind];
ENDLOOP;
instances ← CONS [
Instance[
and,
["Input", WireList[bind]],
["Output", Index["Select", sel]]
],
instances];
ENDLOOP;
ct ← Cell[
name: "DecoderLogicDriver",
public: Wires["Vdd", "Gnd", "AdrBit", "nAdrBit", Seq["LowAddressB", log2Select], Seq["Select", select]],
onlyInternal: Wires[Seq["nLowAddressB", log2Select]],
instances: instances
];
PWCore.SetGet[ct, GetDesign[cx, Sisyph.designRope]];
};
DecoderAndPlane: PUBLIC PROC [cx: Sisyph.Context] RETURNS [ct: CellType] = {
DecoderRow: PROC [row: NAT] RETURNS [ct: CellType] = {
AdrBit: Wire ← Seq["AdrBit", andPlaneBits];
nAdrBit: Wire ← Seq["nAdrBit", andPlaneBits];
nDecode: Wire ← CoreOps.CreateWire[name: "nDecode"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
SeriesInternal: Wire ← Seq["SeriesInternal", andPlaneBits-1];
instances: CoreClasses.CellInstances ← NIL;
FOR adrBit: NAT DECREASING IN [0..andPlaneBits) DO
instances ← CONS [
Instance[
IF BitHacks.XthBitOfN[andPlaneBits-adrBit-1, row] THEN dec1
ELSE dec0,
["AdrBit", AdrBit[adrBit]],
["nAdrBit", nAdrBit[adrBit]],
["SeriesTop", IF adrBit=andPlaneBits-1 THEN nDecode ELSE SeriesInternal[adrBit]],
["SeriesBottom", IF adrBit=0 THEN Gnd ELSE SeriesInternal[adrBit-1]]],
instances];
ENDLOOP;
ct ← Cell[
public: Wires["Vdd", Gnd, AdrBit, nAdrBit, nDecode],
onlyInternal: Wires[SeriesInternal],
instances: instances];
PWCore.SetAbutX[ct];
};
design: CD.Design ← GetDesign[cx, Sisyph.designRope];
rowQuads: NAT ← GetNat[cx, "rowQuads"];
andPlaneBits: NAT ← GetNat[cx, "andPlaneBits"];
dec0: Core.CellType ← Sisyph.ExtractSchematicByName[ "DecoderZero.sch", cx];
dec1: Core.CellType ← Sisyph.ExtractSchematicByName[ "DecoderOne.sch", cx];
instances: CoreClasses.CellInstances ← NIL;
nDecode: Wire ← Seq["nDecode", 2*rowQuads];
PWCore.SetGet[dec0, design];
PWCore.SetGet[dec1, design];
FOR rowQ: NAT IN [0..rowQuads) DO
instances ← CONS [
Instance[
DecoderRow[2*rowQ],
["nDecode", nDecode[2*rowQ]]],
instances];
instances ← CONS [
Instance[
PWCore.RotateCellType[DecoderRow[2*rowQ+1], $FlipY],
["nDecode", nDecode[2*rowQ+1]]],
instances];
ENDLOOP;
ct ← Cell[
name: "DecoderAndPlane",
public: Wires["Vdd", "Gnd", Seq["AdrBit", andPlaneBits], Seq["nAdrBit", andPlaneBits], nDecode],
instances: instances];
PWCore.SetAbutY[ct];
};
DataBufferMux: PUBLIC PROC [cx: Sisyph.Context] RETURNS [ct: CellType] = {
SelectRow: PROC [row: NAT] RETURNS [ct: CellType] = {
Bit: Wire ← Seq["Bit", selectBits];
nBit: Wire ← Seq["nBit", selectBits];
Select: Wire ← CoreOps.CreateWire[name: "Select"];
VSelect: Wire ← Seq["VSelect", row];
instances: CoreClasses.CellInstances ← NIL;
FOR col: NAT DECREASING IN [0..selectBits) DO
subCell: CellType ← SELECT TRUE FROM
row<col => BitSelNoPoly,
row=col => BitSelContact,
row>col => BitSelPoly,
ENDCASE => ERROR;
instances ← CONS [
Instance[
subCell,
["Bit", Bit[col]],
["nBit", nBit[col]],
["Select", Select],
IF subCell=BitSelPoly THEN ["VSelect", VSelect[col]] ELSE []],
instances];
ENDLOOP;
ct ← Cell[
public: Wires[Bit, nBit, Select, IF VSelect.size>0 THEN VSelect ELSE NIL],
instances: instances];
PWCore.SetAbutX[ct];
};
selectBits: NAT ← GetNat[cx, "selectBits"];
design: CD.Design ← GetDesign[cx, Sisyph.designRope];
BitSelNoPoly: CellType ← Cell[
name: "BitSelNoPoly",
public: Wires["Select", "nBit", "Bit"],
instances: NIL];
BitSelContact: CellType ← Cell[
name: "BitSelContact",
public: Wires["Select", "nBit", "Bit"],
instances: NIL];
BitSelPoly: CellType ← Cell[
name: "BitSelPoly",
public: Wires["VSelect", "Select", "nBit", "Bit"],
instances: NIL];
Select: Wire ← Seq["Select", selectBits];
Bit: Wire ← Seq["Bit", selectBits];
nBit: Wire ← Seq["nBit", selectBits];
instances: CoreClasses.CellInstances ← NIL;
PWCore.SetGet[BitSelNoPoly, design];
PWCore.SetGet[BitSelContact, design];
PWCore.SetGet[BitSelPoly, design];
FOR row: NAT DECREASING IN [0..selectBits) DO
rowCell: CellType ← SelectRow[row];
publicV: Wire ← FindWire[rowCell.public, "VSelect"];
pas: LIST OF PACONS[["Select", Select[row]], NIL];
FOR col: NAT IN [0..row) DO
pas ← CONS[[publicV[col], Select[col]], pas];
ENDLOOP;
instances ← CONS[InstanceList[rowCell, pas], instances];
ENDLOOP;
ct ← Cell[
name: "DataBufferMux",
public: Wires[Select, Bit, nBit],
instances: instances];
PWCore.SetAbutY[ct];
};
GetDesign: PROC [cx: Sisyph.Context, design: ROPE] RETURNS [CD.Design] = {
found: BOOL;
ref: SymTab.Val;
[found, ref] ← SymTab.Fetch[cx, design];
IF found
THEN RETURN [NARROW [RefFromTV[ref], REF CD.Design]^]
ELSE ERROR
};
GetNat: PROC [cx: Sisyph.Context, var: ROPE] RETURNS [NAT] = {
found: BOOL;
ref: SymTab.Val;
[found, ref] ← SymTab.Fetch[cx, var];
IF found
THEN RETURN [NARROW [RefFromTV[ref], REF NAT]^]
ELSE ERROR
};
RefFromTV: PROC [tv: REF] RETURNS [REF] = {
IF tv=NIL THEN RETURN [NIL];
IF ~ISTYPE [tv, AMTypes.TV] THEN ERROR;
TRUSTED {RETURN [AMBridge.SomeRefFromTV[tv]]};
};
END.