<> <> <> <> <> <<>> DIRECTORY CoreCompose, CoreFlatten, CoreProperties, IO, PWCore, Rope, Rosemary, Sinix; CrossRAMRAM: CEDAR PROGRAM IMPORTS CoreCompose, CoreFlatten, CoreProperties, IO, PWCore, Rope, Rosemary, Sinix = BEGIN OPEN CoreCompose; <> RAMArray: ROPE = RegisterStructureProc[name: "RAMArray", proc: CreateRAMArray]; CreateRAMArray: StructureProc = { static, dynamic: InstanceRec; PushBool[context, $static, TRUE]; static _ [actual: "Vdd: Vdd[start: 0, len: rowQuads], Word: Word[start: 0, len: 2*rowQuads]", type: CreateStructure[name: SubArray, context: context]]; PushBool[context, $static, FALSE]; dynamic _ [actual: "Vdd: Vdd[start: rowQuads, len: rowQuads], Word: Word[start: 2*rowQuads, len: 2*rowQuads]", type: CreateStructure[name: SubArray, context: context]]; cellType _ CreateRecordCell[ name: RAMArray, context: context, public: CreateWires[context, "Vdd[seq: 2*rowQuads], Gnd, Word[seq: 4*rowQuads], Bit[seq: 8*columnOcts], nBit[seq: 8*columnOcts]"], instances: LIST [static, dynamic]]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutY[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> <> SubArray: ROPE = RegisterStructureProc[name: "SubArray", proc: CreateSubArray]; CreateSubArray: StructureProc = { static: BOOL _ GetBool[context, $static]; rowQuads: INT _ GetInt[context, $rowQuads]; cellType _ CreateSequenceCell[ name: IF static THEN "SSubArray" ELSE "DSubArray", baseCell: CreateStructure[name: RamRow, context: context], count: rowQuads, sequencePorts: Rope.Cat["Word", <> ", Vdd" ] ]; IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: SubArrayRoseClass]; CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayY[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; SubArrayRoseClass: ROPE = Rosemary.Register[roseClassName: SubArray, init: SubArrayInit, evalSimple: SubArraySimple]; SubArrayGnd: NAT = 0; SubArrayWord: NAT = 1; SubArrayBit: NAT = 2; SubArraynBit: NAT = 3; SubArrayVdd: NAT = 4; SubArrayState: TYPE = REF SubArrayStateRec; SubArrayStateRec: TYPE = RECORD [ static: BOOL, bits: SEQUENCE row: NAT OF SubArrayRow]; SubArrayRow: TYPE = REF SubArrayRowRec; SubArrayRowRec: TYPE = RECORD [ bits: SEQUENCE column: NAT OF SubArrayBitRec]; SubArrayBitRec: TYPE = RECORD [ bit: BOOL _ FALSE, nbit: BOOL _ TRUE]; SubArrayInit: Rosemary.InitProc = { state: SubArrayState; p[SubArrayGnd].type _ b; FOR port: NAT IN [0..p[SubArrayWord].size) DO p[SubArrayWord][port].type _ b; ENDLOOP; FOR port: NAT IN [0..p[SubArrayBit].size) DO p[SubArrayBit][port].type _ b; p[SubArraynBit][port].type _ b; ENDLOOP; state _ NEW[SubArrayStateRec[p[SubArrayWord].size]]; state.static _ p.size>4; IF state.static THEN FOR port: NAT IN [0..p[SubArrayVdd].size) DO p[SubArrayVdd][port].type _ b; ENDLOOP; FOR row: NAT IN [0..p[SubArrayBit].size) DO state[row] _ NEW[SubArrayRowRec[p[SubArrayBit].size]]; ENDLOOP; stateAny _ state; }; SubArraySimple: Rosemary.EvalProc = { state: SubArrayState _ NARROW[stateAny]; row: NAT; foundActive: BOOL _ FALSE; IF p[SubArrayGnd].b THEN SIGNAL Rosemary.Stop[]; IF state.static THEN FOR port: NAT IN [0..p[SubArrayVdd].size) DO IF NOT p[SubArrayVdd][port].b THEN SIGNAL Rosemary.Stop[]; ENDLOOP; FOR port: NAT IN [0..p[SubArrayWord].size) DO IF p[SubArrayWord][port].b THEN { IF foundActive THEN SIGNAL Rosemary.Stop[]; foundActive _ TRUE; row _ port; }; ENDLOOP; IF foundActive THEN { FOR column: NAT IN [0..p[SubArrayBit].size) DO state[row][column].bit _ IF state[row][column].nbit THEN FALSE ELSE p[SubArrayBit][column].b; state[row][column].nbit _ IF state[row][column].bit THEN FALSE ELSE p[SubArraynBit][column].b; state[row][column].bit _ IF state[row][column].nbit THEN FALSE ELSE p[SubArrayBit][column].b; p[SubArrayBit][column].d _ IF state[row][column].nbit THEN drive ELSE IF state.static THEN driveWeak ELSE none; p[SubArrayBit][column].b _ state[row][column].bit; p[SubArraynBit][column].d _ IF state[row][column].bit THEN drive ELSE IF state.static THEN driveWeak ELSE none; p[SubArraynBit][column].b _ state[row][column].nbit; ENDLOOP; } ELSE { FOR port: NAT IN [0..p[SubArrayBit].size) DO p[SubArrayBit][port].d _ none; p[SubArraynBit][port].d _ none; ENDLOOP; }; }; <<>> <> RamRow: ROPE = RegisterStructureProc[name: "RamRow", proc: CreateRAMRow]; CreateRAMRow: StructureProc = { static: BOOL _ GetBool[context, $static]; columnOcts: INT _ GetInt[context, $columnOcts]; cellType _ CreateSequenceCell[ name: IO.PutFR["%g*%g", IF static THEN IO.rope["SRamRow"] ELSE IO.rope["DRamRow"], IO.int[columnOcts]], baseCell: CreateStructure[name: RamOctStitch, context: context], count: columnOcts, sequencePorts: "Bit, nBit"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <<>> <> RamOctStitch: ROPE = RegisterStructureProc[name: "RamOctStitch", proc: CreateRAMOctStitch]; CreateRAMOctStitch: StructureProc = { static: BOOL _ GetBool[context, $static]; cellType _ CreateRecordCell[ name: IF static THEN "SRamOctStitch" ELSE "DRamOctStitch", context: context, public: CreateWires[context, Rope.Cat[ "Gnd, Word[seq: 2], Bit[seq: 8], nBit[seq: 8]", ", Vdd" <> ]], instances: LIST [ [type: CreateStructure[name: "RamOct", context: context], actual: "Gnd: [Gnd, Gnd]"], [type: CreateStructure[name: "RamStitch", context: context]]]]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <<>> <> RamOct: ROPE = RegisterStructureProc[name: "RamOct", proc: CreateRAMOct]; CreateRAMOct: StructureProc = { static: BOOL _ GetBool[context, $static]; cellType _ CreateSequenceCell[ name: IF static THEN "SRamOct" ELSE "DRamOct", baseCell: CreateStructure[name: "RamTwoBits", context: context], count: 8, sequencePorts: "Bit, nBit"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> RamTwoBits: ROPE = RegisterStructureProc[name: "RamTwoBits", proc: CreateRAMTwoBits]; CreateRAMTwoBits: StructureProc = { static: BOOL _ GetBool[context, $static]; cellType _ CreateSequenceCell[ name: IF static THEN "SRamTwoBits" ELSE "DRamTwoBits", baseCell: CreateStructure[name: "RAMBit", context: context], count: 2, sequencePorts: "Word, Gnd"]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; RAMBit: ROPE = RegisterStructureProc[name: "RAMBit", proc: CreateRAMBit]; CreateRAMBit: StructureProc = { static: BOOL _ GetBool[context, $static]; instances: InstanceList _ LIST [ [actual: "gate: Word, ch1: Bit, ch2: State", type: CreateTransistor[name: "Transistor", type: nE]], [actual: "gate: Word, ch1: nBit, ch2: nState", type: CreateTransistor[name: "Transistor", type: nE]], [actual: "gate: nState, ch1: State, ch2: Gnd", type: CreateTransistor[name: "Transistor", type: nE]], [actual: "gate: State, ch1: nState, ch2: Gnd", type: CreateTransistor[name: "Transistor", type: nE]]]; IF static THEN { instances _ CONS[ [actual: "gate: State, ch1: Vdd, ch2: nState", type: CreateTransistor[name: "Transistor", type: pE]], instances]; instances _ CONS[ [actual: "gate: nState, ch1: Vdd, ch2: State", type: CreateTransistor[name: "Transistor", type: pE]], instances];}; cellType _ CreateRecordCell[ name: IF static THEN "SRAMBit" ELSE "DRAMBit", context: context, public: CreateWires[context, Rope.Cat[ "Gnd, Word, Bit, nBit", <> ", Vdd" ]], onlyInternal: CreateWires[context, "State, nState"], instances: instances]; IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: RAMBitRoseClass]; }; RAMBitRoseClass: ROPE = Rosemary.Register[roseClassName: RAMBit, init: RAMBitInit, evalSimple: RAMBitSimple]; RAMBitGnd: NAT = 0; RAMBitWord: NAT = 1; RAMBitBit: NAT = 2; RAMBitnBit: NAT = 3; RAMBitVdd: NAT = 4; RAMBitState: TYPE = REF RAMBitStateRec; RAMBitStateRec: TYPE = RECORD [ bit: BOOL _ FALSE, nbit: BOOL _ TRUE, static: BOOL]; RAMBitInit: Rosemary.InitProc = { FOR port: NAT IN [0..p.size) DO p[port].type _ b; ENDLOOP; stateAny _ NEW[RAMBitStateRec _ [static: p.size>4]]; }; RAMBitSimple: Rosemary.EvalProc = { state: RAMBitState _ NARROW[stateAny]; IF p[RAMBitGnd].b OR (state.static AND NOT p[RAMBitVdd].b) THEN SIGNAL Rosemary.Stop[]; IF NOT p[RAMBitWord].b THEN { p[RAMBitBit].d _ none; p[RAMBitnBit].d _ none; } ELSE { state.bit _ IF state.nbit THEN FALSE ELSE p[RAMBitBit].b; state.nbit _ IF state.bit THEN FALSE ELSE p[RAMBitnBit].b; state.bit _ IF state.nbit THEN FALSE ELSE p[RAMBitBit].b; p[RAMBitBit].d _ IF state.nbit THEN drive ELSE IF state.static THEN driveWeak ELSE none; p[RAMBitBit].b _ state.bit; p[RAMBitnBit].d _ IF state.bit THEN drive ELSE IF state.static THEN driveWeak ELSE none; p[RAMBitnBit].b _ state.nbit; }; }; <> RamStitch: ROPE = RegisterStructureProc[name: "RamStitch", proc: CreateRAMStitch]; CreateRAMStitch: StructureProc = { static: BOOL _ GetBool[context, $static]; cellType _ CreateRecordCell[ name: IF static THEN "SRamStitch" ELSE "DRamStitch", context: context, public: CreateWires[context, Rope.Cat["Gnd, Word[seq: 2]", <> ", Vdd" ]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; RegisterBoolProperty[prop: $static]; END.