DIRECTORY AMBridge, AMTypes, Ascii, Asserting, Cucumber, IO, OrderedSymbolTableRef, Rope, RoseClocks, RoseCreate, RoseIOHacks, RoseRun, RoseStateIO, RoseTypes; RoseTesting: CEDAR PROGRAM IMPORTS AMBridge, AMTypes, Ascii, Asserting, Cucumber, IO, OrderedSymbolTableRef, Rope, RoseClocks, RoseCreate, RoseRun, RoseStateIO, RoseTypes EXPORTS RoseCreate, RoseIOHacks, RoseRun, RoseTypes = BEGIN OPEN RoseTypes, RoseIOHacks, RoseRun, RoseCreate; InterfaceMismatch: PUBLIC ERROR [cell: Cell, index: CARDINAL, expected, got: NodeType] = CODE; TV: TYPE = AMTypes.TV; Type: TYPE = AMTypes.Type; MirrorPorts: PUBLIC PROC [fwd: Ports, alwaysOutput, alwaysInput: BOOL _ FALSE] RETURNS [bkwd: Ports] = BEGIN bkwd _ NEW [PortsRep[fwd.length]]; FOR i: CARDINAL IN [0 .. fwd.length) DO bkwd[i] _ fwd[i]; bkwd[i].input _ alwaysInput OR fwd[i].output; bkwd[i].output _ alwaysOutput OR fwd[i].input; ENDLOOP; END; MakeMoreIO: PUBLIC PROC [cell: Cell, bToo: BOOL] RETURNS [a, b: REF ANY] = TRUSTED BEGIN org, aTV, bTV: AMTypes.TypedVariable; IF cell.realCellStuff.newIO = NIL THEN RETURN [NIL, NIL]; org _ AMBridge.TVForReferent[cell.realCellStuff.newIO]; aTV _ AMTypes.Copy[org]; a _ AMBridge.RefFromTV[aTV]; IF bToo THEN { bTV _ AMTypes.Copy[org]; b _ AMBridge.RefFromTV[bTV]; }; END; WrapTop: PUBLIC PROC [rootName, typeName: ROPE, decider: ExpandDeciderClosure, clocks: ROPE _ NIL, sim: Simulation] RETURNS [root: Cell] = BEGIN rootType: CellType; rootType _ GetWrappingType[typeName, clocks]; root _ CreateTopCell[instanceName: rootName, typeName: rootType.name, decider: decider, sim: sim]; END; GetWrappingType: PROC [subName, clocks: ROPE] RETURNS [wrappingType: CellType] = BEGIN wrappingName: ROPE = subName.Cat["-wrap-", clocks]; subType: CellType; IF (wrappingType _ GetCellType[wrappingName]) # NIL THEN RETURN; IF (subType _ GetCellType[subName]) = NIL THEN ERROR Error[msg: "No such type", data: subName]; wrappingType _ RegisterCellType[ name: wrappingName, expandProc: ExpandWrapper, evals: [], ports: NEW [PortsRep[0]], typeData: NEW [WrapTypeRep _ [subType, clocks]]]; END; WrapType: TYPE = REF WrapTypeRep; WrapTypeRep: TYPE = RECORD [ subType: CellType, clocks: ROPE]; ExpandWrapper: PROC [thisCell: Cell, to: ExpansionReceiver] --ExpandProc-- = BEGIN wc: WrapType _ NARROW[thisCell.type.typeData]; EnsureEnvironment[in: thisCell, forType: wc.subType, to: to]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: LowerFirst[wc.subType.name], typeName: wc.subType.name, interfaceNodes: ""]; IF wc.clocks # NIL THEN [] _ to.class.CellInstance[erInstance: to.instance, instanceName: "clockGen", typeName: RoseClocks.ClockGen[[]].name, interfaceNodes: wc.clocks]; END; LowerFirst: PROC [u: ROPE] RETURNS [l: ROPE] = { IF u.Length[] = 0 THEN RETURN [u]; l _ Rope.FromChar[Ascii.Lower[u.Fetch[0]]].Concat[u.Substr[start: 1]]}; EnsureEnvironment: PUBLIC PROC [in: Cell, forType: CellType, to: ExpansionReceiver] = BEGIN FOR portIndex: CARDINAL IN [0 .. forType.ports.length) DO port: Port = forType.ports[portIndex]; node: Node _ NARROW[in.internalNodes.Lookup[port.name]]; id: REF ANY _ NIL; IF node # NIL THEN LOOP; IF port.name.Equal["gnd", FALSE] THEN id _ $ZeroPower ELSE IF port.name.Equal["vdd", FALSE] THEN id _ $PlusPower ELSE IF port.input AND NOT port.output THEN id _ $Input ELSE IF port.output AND NOT port.input THEN id _ $Output; [] _ to.class.NodeInstance[erInstance: to.instance, name: port.name, type: port.type, initData: id]; ENDLOOP; END; CreateTest: PUBLIC PROC [rootName, testerName, testeeName, typeName: ROPE, stateToo: BOOL _ TRUE, decider: ExpandDeciderClosure, sim: Simulation] RETURNS [root: Cell, cth: CellTestHandle] = BEGIN rootType, testerType: CellType; rootTypeName: ROPE; rd: RootData _ NEW [RootDataRep _ [ testeeType: GetCellType[typeName], testerTypeName: IO.PutFR["%g-Tester[%g]", IO.rope[typeName], IO.bool[stateToo]], testeeTypeName: typeName, testerName: testerName, testeeName: testeeName]]; td: TesterData _ NEW [TesterDataRep _ [ testeeType: GetCellType[typeName], stateToo: stateToo]]; IF rd.testeeType = NIL THEN ERROR Error[msg: "No such type", data: typeName]; rootTypeName _ IO.PutFR["%g-%g-%g-TesterRoot[%g]", IO.rope[testerName], IO.rope[testeeName], IO.rope[typeName], IO.bool[stateToo]]; IF (testerType _ GetCellType[rd.testerTypeName]) = NIL THEN testerType _ RegisterCellType[ name: rd.testerTypeName, ioCreator: CreateTesterIO, initializer: InitTester, evals: testerEvals, ports: RoseCreate.MirrorPorts[fwd: rd.testeeType.ports, alwaysOutput: TRUE], drivePrototype: rd.testeeType.drivePrototype, typeData: td]; IF (rootType _ GetCellType[rootTypeName]) = NIL THEN rootType _ RegisterCellType[ name: rootTypeName, expandProc: ExpandTestRoot, evals: [], ports: NEW [PortsRep[0]], typeData: rd]; cth _ NEW [CellTestHandleRep _ [sim: sim, stateToo: stateToo]]; sim.other _ Asserting.AssertFn1[fn: cthKey, val: cth, inAdditionTo: sim.other]; root _ CreateTopCell[instanceName: rootName, typeName: rootType.name, decider: decider, sim: sim]; cth.testee _ LookupCell[path: LIST[testeeName], from: root]; cth.tester _ LookupCell[path: LIST[testerName], from: root]; END; cthKey: ATOM _ $cthKey; TesterData: TYPE = REF TesterDataRep; TesterDataRep: TYPE = RECORD [ testeeType: CellType, stateToo: BOOL]; RootData: TYPE = REF RootDataRep; RootDataRep: TYPE = RECORD [ testeeType: CellType, testerTypeName, testeeTypeName, testerName, testeeName: ROPE]; ExpandTestRoot: PROC [thisCell: Cell, to: ExpansionReceiver] --ExpandProc-- = BEGIN rd: RootData _ NARROW[thisCell.type.typeData]; FOR i: INT IN [0 .. rd.testeeType.ports.length) DO p: Port _ rd.testeeType.ports[i]; [] _ to.class.NodeInstance[erInstance: to.instance, name: p.name, type: p.type]; ENDLOOP; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: rd.testeeName, typeName: rd.testeeTypeName, interfaceNodes: ""]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: rd.testerName, typeName: rd.testerTypeName, interfaceNodes: ""]; END; testerEvals: EvalProcs _ [ PropQ: PropTesterQUD, PropUD: PropTesterQUD, ValsChanged: TesterValsChanged, EvalSimple: TesterSimple]; CellTestHandle: TYPE = REF CellTestHandleRep; CellTestHandleRep: PUBLIC TYPE = RECORD [ sim: Simulation, tester, testee: Cell _ NIL, parms: RoseRun.TestParms _ NIL, instructionsAsAny: REF ANY _ NIL, instructionsAsWP: LONG POINTER TO CARDINAL _ NIL, driveAsAny: REF ANY _ NIL, driveAsPtr: Drive _ NIL, first: BOOLEAN _ FALSE, stateToo: BOOLEAN _ TRUE ]; Waiting: TYPE = {Tester, Testee}; NarrowToCellTestHandle: PUBLIC PROC [any: REF ANY] RETURNS [cth: CellTestHandle] = {cth _ NARROW[any]}; GetSimulationFromCellTestHandle: PUBLIC PROC [cth: CellTestHandle] RETURNS [sim: Simulation] = {sim _ cth.sim}; TransferCellTestHandle: PROC [whole: REF ANY, part: Cucumber.Path, where: IO.STREAM, direction: Cucumber.Direction, data: REF ANY] --Cucumber.PartTransferProc-- = TRUSTED BEGIN cth: CellTestHandle _ NARROW[whole]; SELECT part.first FROM $sim, $tester, $testee, $testeeInitData, $instructionsAsAny, $driveAsPtr => NULL; $parms => Cucumber.Transfer[what: cth.parms, where: where, direction: direction]; $instructionsAsWP => RoseStateIO.TransferWords[cth.instructionsAsWP, cth.tester.type.ioWordCount, where, direction]; $driveAsAny => Cucumber.Transfer[what: cth.driveAsAny, where: where, direction: direction]; ENDCASE => ERROR; END; CreateTesterIO: PROC [cell: Cell] --IOCreator-- = BEGIN td: TesterData _ NARROW[cell.type.typeData]; td.testeeType.ioCreator[cell]; END; InitTester: PROC [cell: Cell, leafily: BOOLEAN] --Initializer-- = BEGIN IF leafily THEN BEGIN cth: CellTestHandle _ NARROW[Asserting.FnVal[fn: cthKey, from: cell.sim.other]]; cth.instructionsAsAny _ MakeMoreIO[cell: cell, bToo: FALSE].a; cth.instructionsAsWP _ LOOPHOLE[cth.instructionsAsAny]; IF cell.type.drivePrototype # NIL THEN { driveAsTV, driveProtoAsTV: TV; TRUSTED {driveProtoAsTV _ AMBridge.TVForReferent[cell.type.drivePrototype]}; driveAsTV _ AMTypes.Copy[driveProtoAsTV]; TRUSTED { cth.driveAsAny _ AMBridge.RefFromTV[driveAsTV]; cth.driveAsPtr _ LOOPHOLE[cth.driveAsAny]; }; } ELSE { cth.driveAsAny _ NIL; cth.driveAsPtr _ NIL}; cell.realCellStuff.state _ cth; END; END; PropTesterQUD: CellProc--PROC [cell: Cell]-- = BEGIN cth: CellTestHandle _ NARROW[cell.realCellStuff.state]; CopyIO[from: cth.instructionsAsWP, to: cell.realCellStuff.switchIOAsWP, by: cell.type.ports, what: [inputs: none, outputs: forward, bidirs: forward], specials: TRUE, generals: TRUE, simples: FALSE, drive: cth.driveAsPtr]; END; CopyIO: PUBLIC PROC [from, to: WordPtr, by: Ports, what: DirectionInstructions, specials, generals, simples: BOOLEAN, drive: Drive] = BEGIN FOR portIndex: CARDINAL IN [0 .. by.length) DO port: Port _ by[portIndex]; afterLast: CARDINAL; di: DirectionInstruction; IF NOT (IF port.type.simple THEN simples ELSE IF port.special THEN specials ELSE generals) THEN LOOP; di _ IF port.input THEN (IF port.output THEN what.bidirs ELSE what.inputs) ELSE (IF port.output THEN what.outputs ELSE ERROR); IF di = moveByDrive THEN {driven: BOOLEAN; TRUSTED {driven _ drive[portIndex].bool}; di _ IF driven THEN forward ELSE backward}; IF di = checkByDrive THEN {driven: BOOLEAN; TRUSTED {driven _ drive[portIndex].bool}; di _ IF driven THEN check ELSE backward}; afterLast _ port.firstWord + port.wordCount; SELECT di FROM forward => FOR c: CARDINAL IN [port.firstWord .. afterLast) DO TRUSTED {(to + c)^ _ (from + c)^}; ENDLOOP; backward => FOR c: CARDINAL IN [port.firstWord .. afterLast) DO TRUSTED {(from + c)^ _ (to + c)^}; ENDLOOP; check => FOR c: CARDINAL IN [port.firstWord .. afterLast) DO TRUSTED {IF (from + c)^ # (to + c)^ THEN SIGNAL Warning["drive contradicted"]}; ENDLOOP; none => NULL; ENDCASE => ERROR; ENDLOOP; END; TesterValsChanged: --PROC [cell: Cell]-- CellProc = BEGIN cth: CellTestHandle _ NARROW[cell.realCellStuff.state]; CopyIO[from: cell.realCellStuff.switchIOAsWP, to: cth.instructionsAsWP, by: cell.type.ports, what: [inputs: forward, outputs: none, bidirs: forward], specials: TRUE, generals: TRUE, simples: FALSE, drive: cth.driveAsPtr]; END; TesterSimple: --PROC [cell: Cell]-- CellProc = BEGIN cth: CellTestHandle _ NARROW[cell.realCellStuff.state]; bw: DirectionInstruction _ checkByDrive; IF cth.first THEN {bw _ moveByDrive; cth.first _ FALSE}; CopyIO[from: cth.instructionsAsWP, to: cell.realCellStuff.newIOAsWP, by: cell.type.ports, what: [inputs: backward, outputs: forward, bidirs: bw], specials: FALSE, generals: FALSE, simples: TRUE, drive: cth.driveAsPtr]; END; Eval: PUBLIC PROC [handle: CellTestHandle, returnAfter: ReturnAfter _ returnWhenSettled] RETURNS [happened: StepType] = BEGIN ScheduleCell[handle.tester]; PerturbDifferences[handle]; handle.first _ TRUE; IF handle.parms.stopBefore THEN SIGNAL Stop["About to eval", handle.testee]; DO happened _ StepSim[handle.sim]; IF (IF happened IN MaskableStepType THEN returnAfter[happened] ELSE TRUE) THEN EXIT; ENDLOOP; IF handle.parms.stopAfter THEN SIGNAL Stop["Just eval'd", handle.testee]; END; PerturbDifferences: PROC [cth: CellTestHandle] = BEGIN FOR portIndex: CARDINAL IN [0 .. cth.tester.type.ports.length) DO port: Port _ cth.tester.type.ports[portIndex]; different: BOOLEAN _ FALSE; IF NOT port.output THEN LOOP; IF port.type.simple THEN LOOP; FOR o: CARDINAL IN [0 .. port.wordCount) DO TRUSTED { IF (cth.instructionsAsWP + port.firstWord + o)^ # (cth.tester.realCellStuff.switchIOAsWP + port.firstWord + o)^ THEN {different _ TRUE; EXIT}}; ENDLOOP; IF different THEN PerturbPort[cell: cth.tester, index: portIndex, evenIfInput: TRUE]; ENDLOOP; END; Test: PUBLIC PROC [sim: Simulation, cth: CellTestHandle, parms: TestParms, testData: REF ANY _ NIL] = BEGIN test: CellTestProc _ IF cth.stateToo THEN cth.testee.type.stateToo ELSE cth.testee.type.blackBox; IF test = NIL THEN ERROR Error["Type has no such test proc", cth]; cth.parms _ parms; test[handle: cth, testeeType: cth.testee.type, testData: testData, io: cth.instructionsAsAny, driveAsAny: cth.driveAsAny, stateAsAny: IF cth.stateToo THEN cth.testee.realCellStuff.state ELSE NIL]; WHILE StepSim[sim] # noStep DO NULL ENDLOOP; END; cthHandler: Cucumber.Handler _ NEW [Cucumber.HandlerRep _ [TransferCellTestHandle]]; cthHandler.Register[CODE[CellTestHandleRep]]; END. [Indigo]2.6>Rosemary.DF=>RoseTesting.Mesa Last Edited by: Spreitzer, October 7, 1984 3:56:40 pm PDT Last Edited by: Barth, January 25, 1984 3:44 pm Last Edited by: Gasbarro, July 17, 1984 3:52:04 pm PDT type: AMTypes.Type; type _ AMTypes.TVType[org]; aTV _ AMTypes.New[type]; AMTypes.Assign[aTV, org]; bTV _ AMTypes.New[type]; AMTypes.Assign[bTV, org]; [cell.realCellStuff.newIO, cell.realCellStuff.oldIO] _ MakeMirrorIO[td.testee]; cth.driveAsPtr _ LOOPHOLE[AMBridge.PointerFromTV[driveAsTV]]; Κ ϋ– "cedar" style˜J™3J™:J™/J™6Icode˜KšΟk œ–˜ŸK˜šΠbx œœ˜Kšœ0œV˜Kšœ.˜5—K˜Kšœœ-˜7K˜šΠblœœœ ˜,Kšœœ˜Kšœœ˜ —K˜Kšœœ œ˜Kšœœ˜K˜š Οn œœœ)œœœ˜fKš˜Kšœœ˜"šœœœ˜'K˜Kšœœ˜-Kšœœ˜.Kšœ˜—Kšœ˜—K˜š  œœœœœœœ˜RKš˜˜%K™—Kš œœœœœœ˜9˜7K™K™K™—K˜K˜šœ˜ ˜K™K™—K˜K˜K˜—Kšœ˜—K˜š œœœœ)œœœ˜ŠKš˜K˜Kšœ-˜-Kšœb˜bKšœ˜—K˜š œœœœ˜PKš˜Kšœœ!˜3K˜Kšœ.œœœ˜@Kšœ$œœœ+˜_šœ ˜ Kšœ˜K˜K˜ Kšœœ˜Kšœ œ$˜1—Kšœ˜—K˜š œ œœœœ˜>K˜Kšœœ˜—K˜š  œœ)Οcœ˜LKš˜Kšœœ˜.Kšœ=˜=K˜ŽKšœ œœ’˜©Kšœ˜—K˜š   œœœœœ˜0Kšœœœ˜"K˜G—K˜š œœœ7˜UKš˜šœ œœ˜9K˜&Kšœ œ%˜8Kšœœœœ˜Kšœœœœ˜Kšœœœ˜:Kšœœœ˜:Kš œ œœ œ ˜7Kšœ œœ œ˜4K˜dKšœ˜—Kšœ˜—K˜š  œœœ.œ œœ2œ$˜½Kš˜K˜Kšœœ˜šœœ˜#Kšœ"˜"Kšœœœœ˜PKšœ˜Kšœ˜Kšœ˜—šœœ˜'Kšœ"˜"K˜—Kšœœœœ,˜MKš œœ"œœœœ˜ƒšœ1˜6šœ˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜KšœFœ˜LKšœ-˜-Kšœ˜——šœ*˜/šœ˜!Kšœ˜Kšœ˜Kšœ ˜ Kšœœ˜Kšœ˜——Kšœœ6˜?KšœO˜OKšœb˜bKšœœ˜—K˜š œœ)‘œ˜MKš˜Kšœœ˜.šœœœ#˜2K˜!KšœP˜PKšœ˜—Kšœ‚˜‚Kšœ‚˜‚Kšœ˜—K˜šœ˜Kšœ˜Kšœ˜K˜K˜—K˜Kšœœœ˜-šœœœœ˜)K˜Kšœœ˜Kšœœ˜Kšœœœœ˜!Kš œœœœœœ˜1Kšœ œœœ˜Kšœœ˜Kšœœœ˜Kšœ œ˜Kšœ˜—K˜Kšœ œ˜!K˜Kš œœœœœœ œ˜gK˜Kš œœœœ%˜oK˜š œœ œœœœ'œœ‘œ˜ͺKš˜Kšœœ˜$šœ ˜KšœLœ˜QKšœQ˜QKšœt˜tKšœ[˜[Kšœœ˜—Kšœ˜—K˜š œœ‘ œ˜1Kš˜Kšœœ˜,K™OKšœ˜Kšœ˜—K˜š  œœœ‘œ˜AKš˜šœ ˜Kš˜Kšœœ4˜PKšœ5œ˜>Kšœœ˜7šœœœ˜(Kšœœ˜KšœE˜LKšœ)˜)šœ˜ Kšœ/˜/Kšœœ˜*Kšœœ$™=Kšœ˜—K˜—šœ˜Kšœœ˜Kšœœ˜—Kšœ˜Kšœ˜—Kšœ˜—K˜š  œ ‘œ˜.Kš˜Kšœœ˜7Kšœ œ œ œ˜έKšœ˜—K˜š œœœZœ˜…Kš˜šœ œœ˜.Kšœ˜Kšœ œ˜Kšœ˜Kšœœœœ œœœ œ œœ˜ešœœ ˜Kšœœ œ œ ˜7Kš œœ œœœ˜3—šœ˜Kšœ œ˜Kšœ"˜)Kšœœœ œ ˜+—šœ˜Kšœ œ˜Kšœ"˜)Kšœœœœ ˜)—Kšœ,˜,šœ˜šœ œœœ˜>Kšœ˜"Kšœ˜—šœ œœœ˜?Kšœ˜"Kšœ˜—šœ œœœ˜œ˜UKšœ˜—Kšœ˜—K˜š  œœœDœœœ˜eKš˜Kšœœœœ˜aKšœœœœ*˜BK˜Kš œ†œœ œœ˜ΔKšœœœœ˜,Kšœ˜—K˜Kšœœ2˜TK˜Kšœœ˜-K˜Kšœ˜—…—/θ?γ