<> <> <> <<>> 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 WR _ NIL; 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 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 PA _ CONS[["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.