ROPE = RegisterStructureProc[name: "DecoderLogicDriver", proc: CreateDecoderLogicDriver];
CreateDecoderLogicDriver: StructureProc = {
select: INT ← GetInt[context, $select];
log2Select: INT ← GetInt[context, $log2Select];
invert8: Core.CellType;
and: Core.CellType; -- inputCount: log2Select, width: 16
instances: InstanceList ← 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[[type: invert8, actual: IO.PutFR["Input: AddressB[%g], Output: nHighAddressB[%g]", IO.int[adrBit], IO.int[adrBit]]], instances];
ENDLOOP;
-- Drop eight nand gates
FOR sel:
INT
IN [0..select)
DO
bind: ROPE ← NIL;
FOR adrBit:
INT
IN [0..log2Select)
DO
bind ← Rope.Cat[bind, IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN IO.PutFR["AddressB[%g]", IO.int[adrBit]] ELSE IO.PutFR["nHighAddressB[%g]", IO.int[adrBit]]];
IF adrBit < log2Select-1 THEN bind ← Rope.Cat[bind, ", "];
ENDLOOP;
instances ← CONS[[type: and, actual: IO.PutFR["Input: [%g], Output: Select[%g]", IO.rope[bind], IO.int[sel]]], instances];
ENDLOOP;
cellType ← CreateRecordCell[
name: DecoderLogicDriver,
context: context,
public: CreateWires[context, "Vdd, Gnd, AdrBit, nAdrBit, AddressB[seq: log2Select], Select[seq: select]"],
onlyInternal: CreateWires[context, "nHighAddressB[seq: log2Select]"],
instances: instances];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};