<> <> Imports IO, NumTypes; Library SSI, Transistors; CELLTYPE "DataBuffer" PORTS [Vdd, Gnd, Read, nRead, Write, nWrite < BOOL, Select < INT[8], Bit, nBit = BIT[8], Data = BOOL] Expand mux, nmux, ndata: BIT; invert: Inverter[Input: Data, Output: ndata]; dataBuffer: TristateBuffer[nDataIn: nmux, Drive: Read, nDrive: nRead, Output: Data]; bitBuffer: TristateBuffer[nDataIn: ndata, Drive: Write, nDrive: nWrite, Output: mux]; nbitBuffer: TristateBuffer[nDataIn: Data, Drive: Write, nDrive: nWrite, Output: nmux]; Cedar {selectSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; bitSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; nbitSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; FOR muxCount: CARDINAL DECREASING IN [0..8) DO selectSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Select%g", IO.int[muxCount]], type: SwitchTypes.bitType], selector: [whole [ ]]]]], selectSubNodes.elts]; bitSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Bit%g", IO.int[muxCount]], type: SwitchTypes.bitType], selector: [whole [ ]]]]], bitSubNodes.elts]; nbitSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["nBit%g", IO.int[muxCount]], type: SwitchTypes.bitType], selector: [whole [ ]]]]], nbitSubNodes.elts]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: IO.PutFR["MuxTran%g", IO.int[muxCount]], typeName: "nE", interfaceNodes: IO.PutFR["gate: Select%g, ch1: Bit%g, ch2: mux", IO.int[muxCount], IO.int[muxCount]]]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: IO.PutFR["nMuxTran%g", IO.int[muxCount]], typeName: "nE", interfaceNodes: IO.PutFR["gate: Select%g, ch1: nBit%g, ch2: nmux", IO.int[muxCount], IO.int[muxCount]]]; ENDLOOP; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Select"]], selector: [whole [ ]]]]], b: selectSubNodes]; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Bit"]], selector: [whole [ ]]]]], b: bitSubNodes]; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["nBit"]], selector: [whole [ ]]]]], b: nbitSubNodes] }; ENDCELLTYPE; DataBufferSequence: LAMBDA [count: |NAT|] RETURN CELLTYPE NameMaker name _ IO.PutFR["DataBuffer%g", IO.int[count]] PortsProc portNumber: CARDINAL _ 0; InitPort: PROC[name: ROPE, input: BOOL _ TRUE, output: BOOL _ FALSE, type: NodeType _ NumTypes.boolType ] = { compilerBugBypass: Field _ [0, 0, 0]; ports[portNumber] _ [ simple: compilerBugBypass, switch: compilerBugBypass, name: name, type: type, input: input, output: output]; portNumber _ portNumber + 1; }; IF count<1 THEN ERROR; ports _ NEW [PortsRep[8]]; InitPort["Vdd"]; InitPort["Gnd"]; InitPort["Read"]; InitPort["nRead"]; InitPort["Write"]; InitPort["nWrite"]; InitPort[name: "Select", type: NumTypes.NumType[8]]; InitPort[name: "Bit", output: TRUE, type: NumTypes.NumType[8*count]]; InitPort[name: "nBit", output: TRUE, type: NumTypes.NumType[8*count]]; InitPort[name: "Data", output: TRUE, type: NumTypes.NumType[count]]; Expand Cedar dataSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; bitSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; nbitSubNodes: RoseTypes.UnnamedConsNE _ NEW[RoseTypes.NodeExpressionRep.unnamedCons _ [unnamedCons [elts: NIL]]]; FOR bitCount: CARDINAL DECREASING IN [0..count) DO dataSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Data%g", IO.int[bitCount]], type: SwitchTypes.bitType], selector: [whole [ ]]]]], dataSubNodes.elts]; bitSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["BitBundle%g", IO.int[bitCount]], type: SwitchTypes.Bundle[8]], selector: [whole [ ]]]]], bitSubNodes.elts]; nbitSubNodes.elts _ CONS[NEW[ NodeExpressionRep.primary _ [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["nBitBundle%g", IO.int[bitCount]], type: SwitchTypes.Bundle[8]], selector: [whole [ ]]]]], nbitSubNodes.elts]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: IO.PutFR["DataBuffer%g", IO.int[bitCount]], typeName: "DataBuffer", interfaceNodes: IO.PutFR["Bit: BitBundle%g, nBit: nBitBundle%g, Data: Data%g", IO.int[bitCount], IO.int[bitCount], IO.int[bitCount]]]; ENDLOOP; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Data"]], selector: [whole [ ]]]]], b: dataSubNodes]; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Bit"]], selector: [whole [ ]]]]], b: bitSubNodes]; to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary _ [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["nBit"]], selector: [whole [ ]]]]], b: nbitSubNodes] ENDCELLTYPE