<> <> <> <> DIRECTORY Basics, Commander, Core, CoreOps, IO, ICTest, Ports, Rope, TerminalIO, TestCable; TestCableImpl: CEDAR PROGRAM IMPORTS Basics, IO, CoreOps, Ports, Rope, TerminalIO EXPORTS TestCable = BEGIN groupList: ICTest.Groups; assignmentList: ICTest.Assignments; clockAName: Core.ROPE; clockBName: Core.ROPE; Init: PUBLIC PROC [groups: ICTest.Groups, assignments: ICTest.Assignments, clockA, clockB: ICTest.ROPE _ NIL] ~ { groupList _ groups; assignmentList _ assignments; clockAName _ clockA; clockBName _ clockB; }; TestCable: PUBLIC ICTest.TestProc = { InitDrive: PROC [wire: Core.Wire, port: Ports.Port] RETURNS [subElements: BOOL _ TRUE, quit: BOOL _ FALSE] --Ports.EachPortPairProc-- = { IF port#NIL THEN port.d _ force; }; EachPair: PROC [wire: Core.Wire, port: Ports.Port] RETURNS [subElements: BOOL _ TRUE, quit: BOOL _ FALSE] --Ports.EachPortPairProc-- = { Cycle: PROC = { Eval[]; }; IF CoreOps.IsFullWireName[cellType.public, wire, a.name] AND a.group#0 THEN { IF port=NIL THEN SELECT rootPort.levelType FROM ls => {}; bs => {}; c => {rootPort.c _ Basics.BITSHIFT[08000h, -rootPort.fieldStart-count]; Cycle[]; rootPort.c _ 0; Cycle[]}; lc => {rootPort.lc _ Basics.DoubleShift[[lc[080000000h]], -rootPort.fieldStart-count].lc; Cycle[]; rootPort.lc _ 0; Cycle[]}; ENDCASE => ERROR ELSE SELECT port.levelType FROM l => {port.l _ L; Cycle[]; port.l _ H; Cycle[]}; b => {port.b _ TRUE; Cycle[]; port.b _ FALSE; Cycle[]}; ENDCASE => ERROR } ELSE IF port#NIL THEN SELECT port.levelType FROM l => port.l _ L; ls => {}; b => port.b _ port=clockAPort OR port=clockBPort; bs => {}; c => port.c _ 0; lc => port.lc _ 0; ENDCASE; IF port#NIL AND port.levelType#composite THEN {count _ 0; rootPort _ port} ELSE count _ count+1; }; directionality: ICTest.Directionality _ force; probe: INT _ 1; count: NAT _ 0; lastPin: NAT _ 0; a: ICTest.Assignment; rootPort: Ports.Port; clockAPort: Ports.Port _ IF clockAName#NIL THEN p[Ports.PortIndex[cellType.public, clockAName]] ELSE NIL; clockBPort: Ports.Port _ IF clockBName#NIL THEN p[Ports.PortIndex[cellType.public, clockBName]] ELSE NIL; IF clockAPort#NIL THEN clockAPort.b _ TRUE; IF clockBPort#NIL THEN clockBPort.b _ TRUE; TerminalIO.PutRope["\n\nProbe Card Tester\n"]; [] _ Ports.VisitBinding[cellType.public, p, InitDrive]; FOR l: ICTest.Assignments _ assignmentList, l.rest WHILE l#NIL DO lastPin _ MAX[l.first.probeCardPin, lastPin]; ENDLOOP; WHILE probe <= lastPin DO FOR l: ICTest.Assignments _ assignmentList, l.rest WHILE l#NIL DO a _ l.first; IF a.probeCardPin = probe THEN { FOR l: ICTest.Groups _ groupList, l.rest WHILE l#NIL DO IF l.first.number=a.group THEN { directionality _ l.first.directionality; EXIT; } ENDLOOP; SELECT TRUE FROM a.group=0 => { TerminalIO.PutRope[IO.PutFR["Pin %g is unused, %g\n", IO.int[probe], IO.rope[a.name]]]; probe _ probe+1; }; directionality=acquire => { TerminalIO.PutRope[IO.PutFR["Pin %g is acquire only\n", IO.int[probe]]]; probe _ probe+1; directionality _ force; }; ENDCASE => { TerminalIO.PutRope[IO.PutFR["Ready to test pin %g, %g ...", IO.int[probe], IO.rope[a.name]]]; SELECT Rope.Fetch[TerminalIO.RequestRope[""]] FROM 'b, 'B => { probe _ probe-1; TerminalIO.PutRope["\n"]; }; 'j, 'J => { --jump probe _ TerminalIO.RequestInt["\nJump to pin: "]; IF probe < 1 THEN probe _ 1; IF probe >LAST[ICTest.ProbeCardPin] THEN probe _ LAST[ICTest.ProbeCardPin]; LOOP; }; 'q, 'Q => GOTO quit; 'r, 'R => probe _ probe; --redo ENDCASE => { probe _ probe+1; }; [] _ Ports.VisitBinding[cellType.public, p, EachPair]; TerminalIO.PutRope["done\n"]; }; EXIT; }; REPEAT FINISHED => { TerminalIO.PutRope[IO.PutFR["Pin %g not found\n", IO.int[probe]]]; probe _ probe+1; }; ENDLOOP; ENDLOOP; EXITS quit => {}; }; END.