DecoderDriver:
PROC [context: CoreCompose.Context, log2Select:
INT]
RETURNS [cellType: CellType] = {
IF DecoderDriverCellType#NIL THEN RETURN[DecoderDriverCellType];
DecoderDriverCellType ← cellType ← CoreBeau.SequenceCell[
name: "DecoderDriver",
baseCell: DecoderDriverHalf[context: context, log2Select: log2Select],
count: 2,
sequencePorts: CoreBeau.Wires["HighAddressB", "AdrBit", "nAdrBit"]];
};
DecoderDriverHalf:
PROC [context: CoreCompose.Context, log2Select:
INT]
RETURNS [cellType: CellType] = {
inverter4, inverter16: Core.CellType;
PushReal[context: context, prop: $SSIRatio, val: 2.5];
PushInt[context: context, prop: $SSIWidth, val: 4];
inverter4 ← CreateStructure[name: "Inverter", context: context];
PushInt[context: context, prop: $SSIWidth, val: 16];
inverter16 ← CreateStructure[name: "Inverter", context: context];
cellType ← CoreBeau.Cell[
name: "DecoderDriverHalf",
public: CoreBeau.Wires["Vdd", "Gnd", "VddTop", "VddHigh", "GndHigh", "HighAddressB", "AdrBit", "nAdrBit", CoreBeau.Seq["LowAddressB", log2Select]],
onlyInternal: CoreBeau.Wires["nAddress"],
instances:
LIST [
CoreBeau.Instance[inverter4, ["Vdd", "VddHigh"], ["Gnd", "GndHigh"], ["Input", "HighAddressB"], ["Output", "nAddress"]],
CoreBeau.Instance[inverter16, ["Input", "nAddress"], ["Output", "AdrBit"]],
CoreBeau.Instance[inverter16, ["Input", "HighAddressB"], ["Output", "nAdrBit"]]
]];
};
DecoderLogicDriver:
PROC [context: CoreCompose.Context, select, log2Select:
INT]
RETURNS [cellType: CellType] = {
invert8: Core.CellType;
and: Core.CellType; -- inputCount: log2Select, width: 16
instances: LIST OF CoreClasses.CellInstance ← NIL; -- fill in!
PushReal[context: context, prop: $SSIRatio, val: 2.5];
PushInt[context: context, prop: $SSIWidth, val: 8];
invert8 ← CreateStructure[name: "Inverter", context: context];
PushInt[context: context, prop: $SSIWidth, val: 16];
PushInt[context: context, prop: $SSIInputCount, val: log2Select];
and ← CreateStructure[name: "And", context: context];
-- Drop three inverters
FOR adrBit:
INT
IN [0 .. log2Select)
DO
instances ←
CONS [
CoreBeau.Instance[
invert8,
["Input", CoreBeau.Index["AddressB", adrBit]],
["Output", CoreBeau.Index["nHighAddressB", adrBit]]
],
instances];
ENDLOOP;
-- Drop eight nand gates
FOR sel:
INT
IN [0 .. select)
DO
bind: LIST OF CoreBeau.WR ← NIL;
FOR adrBit:
INT
DECREASING
IN [0 .. log2Select)
DO
bind ←
CONS [
CoreBeau.Index[
IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN "AddressB" ELSE "nHighAddressB",
adrBit],
bind];
ENDLOOP;
instances ←
CONS [
CoreBeau.Instance[
and,
["Input", CoreBeau.WireList[bind]],
["Output", CoreBeau.Index["Select", sel]]
],
instances];
ENDLOOP;
cellType ← CoreBeau.Cell[
name: "DecoderLogicDriver",
public: CoreBeau.Wires["Vdd", "Gnd", "AdrBit", "nAdrBit", CoreBeau.Seq["AddressB", log2Select], CoreBeau.Seq["Select", select]],
onlyInternal: CoreBeau.Wires[CoreBeau.Seq["nHighAddressB", log2Select]],
instances: instances
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};