DIRECTORY  
BitOps, Core, CoreFlat, Dragon, DragOpsCross, EUArith, ICTest, IO, Rope, Rosemary, RosemaryUser, Ports, TerminalIO;

EUSim: CEDAR PROGRAM
IMPORTS BitOps, CoreFlat, EUArith, ICTest, IO, Rosemary, RosemaryUser, Ports, TerminalIO = 
BEGIN
ROPE: TYPE = Rope.ROPE;
nbPhases: INT _ 0;

Vdd, Gnd, PadVdd, PadGnd, PhA, PhB,
DPRejectB, DPData, 	-- 32 bits
KBus, 			-- 32 bits
EURdFromPBus3AB, EUWriteToPBus3AB, 
EUAluOp2AB, 	-- 4 bits 
EUCondSel2AB, 	-- 4 bits 
EUCondition2B, 
DShA, DShB, DShRd, DShWt, DShIn, DShOut, DHold, DStAd: NAT _ LAST[NAT];

REProc: TYPE = PROC [memory: BOOL _ TRUE];
Initialize: PROC [p: Ports.Port, public: Core.Wire] = {
InitializePublic[public];
p[DPRejectB].b _ FALSE;
p[DShA].b _ p[DShB].b _ FALSE;
p[DShRd].b _ p[DShWt].b _ p[DShIn].b _ p[DHold].b _ FALSE;
p[DStAd].c _ 0;
p[EUCondSel2AB].c _ 0;				-- false
p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[Or]];		-- 0
p[EURdFromPBus3AB].b _ FALSE;	-- don't read data from PBus
p[EUWriteToPBus3AB].b _ FALSE;	-- and don't write onto PBus during PhB
p[DShOut].b _ FALSE;
p[DShOut].d _ none;
p[EUCondition2B].b _ FALSE;
p[EUCondition2B].d _ none;
p[KBus].d _ none;
p[DPData].d _ none;
};
InitializePublic: PROC [public: Core.Wire] = {
[Vdd, Gnd, PadVdd, PadGnd, PhA, PhB, DPRejectB, DPData] _ Ports.PortIndexes[public, "Vdd", "Gnd", "PadVdd", "PadGnd", "PhA", "PhB", "DPRejectB", "DPData"];
[KBus, EURdFromPBus3AB, EUWriteToPBus3AB, EUAluOp2AB, EUCondSel2AB, EUCondition2B] _ Ports.PortIndexes[public, "KBus", "EURdFromPBus3AB", "EUWriteToPBus3AB", "EUAluOp2AB", "EUCondSel2AB", "EUCondition2B"];
[DShA, DShB, DShRd, DShWt, DShIn, DShOut, DHold, DStAd] _ 
Ports.PortIndexes[public, "DShA", "DShB", "DShRd", "DShWt", "DShIn", "DShOut", "DHold", "DStAd"];
[] _ Rosemary.SetFixedWire[public[Vdd], H];
[] _ Rosemary.SetFixedWire[public[Gnd], L];
[] _ Rosemary.SetFixedWire[public[PadVdd], H];
[] _ Rosemary.SetFixedWire[public[PadGnd], L];
[] _ Ports.InitTesterDrive[public[PhA], force];
[] _ Ports.InitTesterDrive[public[PhB], force];
[] _ Ports.InitTesterDrive[public[DPRejectB], force];
[] _ Ports.InitPort[public[DPData], lc];
[] _ Ports.InitTesterDrive[public[DPData], expect];
[] _ Ports.InitPort[public[KBus], lc];
[] _ Ports.InitTesterDrive[public[KBus], force];
[] _ Ports.InitTesterDrive[public[EURdFromPBus3AB], force];
[] _ Ports.InitTesterDrive[public[EUWriteToPBus3AB], force];
[] _ Ports.InitPort[public[EUAluOp2AB], c];
[] _ Ports.InitTesterDrive[public[EUAluOp2AB], force];
[] _ Ports.InitPort[public[EUCondSel2AB], c];
[] _ Ports.InitTesterDrive[public[EUCondSel2AB], force];
[] _ Ports.InitTesterDrive[public[EUCondition2B], expect];
[] _ Ports.InitTesterDrive[public[DShA], force];
[] _ Ports.InitTesterDrive[public[DShB], force];
[] _ Ports.InitTesterDrive[public[DShRd], force];
[] _ Ports.InitTesterDrive[public[DShWt], force];
[] _ Ports.InitTesterDrive[public[DShIn], force];
[] _ Ports.InitTesterDrive[public[DHold], force];
[] _ Ports.InitPort[public[DStAd], c];
[] _ Ports.InitTesterDrive[public[DStAd], force];
[] _ Ports.InitTesterDrive[public[DShOut], none];
};

ExerciseRose: PUBLIC PROC [ct: Core.CellType, cutSets: LIST OF ROPE _ NIL] RETURNS [tester: RosemaryUser.Tester] = {
InitializePublic[ct.public];
tester _ RosemaryUser.TestProcedureViewer[
cellType: ct, 
testButtons: LIST["AllTests", "ZeroAndOne", "Sanity Check", "RamTest", "ALUTest", "FUTest", "WiresTest", "DBusTest"], 
name: "EUTest", 
displayWires: RosemaryUser.DisplayPortLeafWires[ct], 
cutSet: CoreFlat.CreateCutSet[labels: cutSets],
steady: FALSE];
};

stackAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euStack]];
junkAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euJunk]];
ifuAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euToKBus]];
marAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euMAR]];
fieldAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euField]];
constAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euConstant]];
bogusAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euBogus]];

Phase: TYPE = {A, B};

DoPh: PROC [p: Ports.Port, Eval: REProc, ph: Phase] = {
nbPhases _ nbPhases+1;
IF PhA=0 AND PhB=0 THEN ERROR;		-- port indexes not initialized
IF ph=A AND p[DPData].d=force THEN ERROR;
p[PhA].b _ ph=A;	p[PhB].b _ ph=B;	Eval[FALSE];
p[PhA].b _ FALSE;	p[PhB].b _ FALSE;	Eval[FALSE ! Ports.CheckError =>RESUME];
};
Ignore: PROC [p: Ports.Port, port: NAT] ~ {p[port].d _ none};
Force: PROC [p: Ports.Port, port: NAT, val: CARD] ~ {p[port].d _ force; p[port].lc _ val};
Expect: PROC [p: Ports.Port, port: NAT, val: CARD] ~ {p[port].d _ expect; p[port].lc _ val};
ReadPBus: PROC [p: Ports.Port] ~ {
p[EURdFromPBus3AB].b _ TRUE;	
p[EUWriteToPBus3AB].b _ FALSE;
};
WritePBus: PROC [p: Ports.Port] ~ {
p[EURdFromPBus3AB].b _ FALSE;	
p[EUWriteToPBus3AB].b _ TRUE;
};
IgnorePBus: PROC [p: Ports.Port] ~ {
p[EURdFromPBus3AB].b _ FALSE;	
p[EUWriteToPBus3AB].b _ FALSE;
};
PackK: PROC [a, b: NAT _ constAdr, c: NAT _ junkAdr, st3AisC: BOOL _ FALSE, 
aluL, aluR, st2A: NAT _ 0] RETURNS [k: CARD] ~ {
k _ (((((LONG[a]*256+LONG[b])*256+LONG[c])*2+(IF st3AisC THEN 1 ELSE 0))*4+aluL)*8+aluR)*4+st2A;
};
WriteInRam: PROC [p: Ports.Port, Eval: REProc, ad: NAT, val: CARD] ~ {
Force[p, KBus, PackK[c: ad]];	-- load c address in kReg
ReadPBus[p];
Force[p, DPData, val];
DoPh[p, Eval, B];									-- 0B: kReg _ ad; dataIn _ val
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: ram[ad] _ val
};
ReadFromRam: PROC [p: Ports.Port, Eval: REProc, ad: NAT, val: CARD, m: CARD _ 01234567H] ~ {
Force[p, KBus, PackK[b: ad, st2A: 0]];	-- load b address in kReg
ReadPBus[p];
Force[p, DPData, m];		-- to detect no drive on PBus
DoPh[p, Eval, B];									-- 0B: kReg _ ad
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: st2A _ ram[ad]
CheckSt2A[p, Eval, val];		-- 4 more phases
};
PutValInR2B: PROC [p: Ports.Port, Eval: REProc, val, k: CARD] ~ {
Force[p, KBus, PackK[a: constAdr, aluR: 3]];	-- load addresses in kReg
IgnorePBus[p];
Force[p, DPData, 0];			-- to detect no drive on PBus
DoPh[p, Eval, B];									-- 0B: kReg _ ad
Force[p, KBus, val];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: left _ ram[ad], right _ kBus
p[EUAluOp2AB].c _ 0;	-- ORD[Or]
Force[p, KBus, k];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 1B: r2B _ right
};
PutValInR3B: PROC [p: Ports.Port, Eval: REProc, val, k: CARD, reject: BOOL _ FALSE] ~ {
PutValInR2B[p, Eval, val, PackK[]];		-- 1B: r2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: r3A _ val
IF reject THEN p[DPRejectB].b _ TRUE;
Force[p, KBus, k];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 2B: r3B _ val
p[DPRejectB].b _ FALSE;
};
CheckSt2A: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
Force[p, KBus, PackK[]];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 0B: st2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: st3A _ val
Force[p, KBus, PackK[]];
WritePBus[p];
Expect[p, DPData, val];
DoPh[p, Eval, B];									-- 1B: PBus _ st3A = val ???
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: just for sync.
};
OpAndCheck: PROC [p: Ports.Port, Eval: REProc, val: CARD, op: NAT] ~ {
p[EUAluOp2AB].c _ op;	-- ORD[alu opcode]
Force[p, KBus, PackK[]];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 0B: r2B _ val
Ignore[p, KBus];
Expect[p, DPData, val];
DoPh[p, Eval, A];									-- 1A: PBus _ r2B = val ???.
};
FromPtoK: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
Force[p, KBus, PackK[c: ifuAdr]];	-- cBus->IFU on next PhA
ReadPBus[p];
Force[p, DPData, val];
DoPh[p, Eval, B];									-- Cycle 0: dataIn _ val
Expect[p, KBus, val];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- Cycle 1: KBus _ cBus _ val
IgnorePBus[p];
};
ALUOp: PROC [p: Ports.Port, Eval: REProc, op: Dragon.ALUOps, opL, opR, res: CARD, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE] ~ {
lAd: NAT = 1;
rAd: NAT = 3;
TerminalIO.PutF["ALU, phase %g: %g (%g) %g -> %g", IO.card[nbPhases], IO.card[opL], IO.rope[opName[op]], IO.card[opR], IO.card[res]];
TerminalIO.PutF[" cc: %g\n", IO.int[ORD[cc]]];
WriteInRam[p, Eval, lAd, opL];
WriteInRam[p, Eval, rAd, opR];
p[EURdFromPBus3AB].b _ FALSE;
Force[p, KBus, PackK[a: lAd, b: rAd]];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 0B: aAdr _ lAd, bAdr _ rAd
p[EUAluOp2AB].c _ ORD[op];
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: opL _ ram[lAd]; opR _ ram[rAd]
p[EUCondSel2AB].c _ ORD[cc];
p[EUCondition2B].b _ cond;
p[EUCondition2B].d _ expect;
p[DShOut].b _ FALSE;
p[DShOut].d _ expect;
Force[p, KBus, PackK[]];
Ignore[p, DPData];
DoPh[p, Eval, B];									-- 1B: r2B _ opL op opR
p[EUCondSel2AB].c _ 0;
p[EUCondition2B].b _ FALSE;
p[EUCondition2B].d _ none;
p[DShOut].d _ none;
Ignore[p, KBus];
Expect[p, DPData, res];
DoPh[p, Eval, A];									-- 2A: PBus _ r2B
p[EUAluOp2AB].c _ 0;
};
FUOp: PROC [p: Ports.Port, Eval: REProc, leftW, rightW, mask, shift: CARD, insert: BOOL _ FALSE] ~ {
fd: NAT _ ((IF insert THEN 1 ELSE 0)*64+mask)*64+shift;
res: CARD _ EUArith.FieldOp[leftW, rightW, fd];
TerminalIO.PutF["FU, phase %g, mask: %g, shift: %g, insert: %g\n", IO.card[nbPhases], IO.card[mask], IO.card[shift], IO.bool[insert]];
WriteInRam[p, Eval, fieldAdr, LONG[fd]];	-- field_fd
WriteInRam[p, Eval, 1, leftW];		-- ram[0]_leftW
WriteInRam[p, Eval, 2, rightW];		-- ram[1]_rightW

Force[p, KBus, PackK[a: 1, b: 2, aluR: 4]]; -- right_field; left_leftW; st2A_rightW
Ignore[p, DPData];
DoPh[p, Eval, B];							-- 0B: load operand addresses
p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[FOP]];
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];							-- 1A: read ram
Force[p, KBus, PackK[]];
Ignore[p, DPData];
DoPh[p, Eval, B];							-- 1B: field unit is active
Ignore[p, KBus];
Expect[p, DPData, res];
DoPh[p, Eval, A];							-- 2A: PBus _ r2B
};
AllTests: RosemaryUser.TestProc = {
TerminalIO.PutRope["Starting AllTests"];
ZeroAndOne[cellType, p, Eval];
SanityCheck[cellType, p, Eval];
WiresTest[cellType, p, Eval];
DBusTest[cellType, p, Eval];
ALUTest[cellType, p, Eval];
FUTest[cellType, p, Eval];
RamTest[cellType, p, Eval];
TerminalIO.PutRope["Finished with AllTests"];
};
ZeroAndOne: RosemaryUser.TestProc = {
TerminalIO.PutRope["Starting ZeroAndOne"];
Initialize[p, cellType.public];
FromPtoK[p, Eval,000000000H]; 
FromPtoK[p, Eval,0FFFFFFFFH]; 
FromPtoK[p, Eval,05555AAAAH]; 
TerminalIO.PutRope["Finished with ZeroAndOne"];
};
SanityCheck: RosemaryUser.TestProc = {
FromPtoP2: PROC [val: CARD] ~ {
Force[p, KBus, PackK[st3AisC: TRUE]];	-- st3A _ cBus on next PhA
ReadPBus[p];
Force[p, DPData, val];
DoPh[p, Eval, B];									-- 0B: dataIn _ val
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: st3A _ cBus _ dataIn (val)
Force[p, KBus, PackK[]];
WritePBus[p];
Expect[p, DPData, val];
DoPh[p, Eval, B];									-- 1B: PBus _ st3A = val ???
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: just for sync.
};
FromPtoP4: PROC [val: CARD] ~ {
Force[p, KBus, PackK[st2A: 2]];	-- st2A _ cBus on next PhA
ReadPBus[p];
Force[p, DPData, val];
DoPh[p, Eval, B];									-- 0B: dataIn _ val
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 1A: st2A _ cBus _ val
Force[p, KBus, PackK[]];
IgnorePBus[p];
Force[p, DPData, 01234567H];	-- to eliminate old (good) value on PBus
DoPh[p, Eval, B];									-- 1B: st2B _ st2A
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: st3A _ st2B
Force[p, KBus, PackK[]];
WritePBus[p];
Expect[p, DPData, val];
DoPh[p, Eval, B];									-- 2B: PBus _ st3A = val ???
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 3A: just for sync.
};
TerminalIO.PutRope["Starting SanityCheck"];
Initialize[p, cellType.public];
FromPtoP4[000000000H]; FromPtoP4[0AAAAAAAAH]; FromPtoP4[055555555H];
FromPtoP4[0FFFFFFFFH]; FromPtoP4[02BAD2BADH];
FromPtoP2[000000000H]; FromPtoP2[0AAAAAAAAH]; FromPtoP2[055555555H];
FromPtoP2[0FFFFFFFFH]; FromPtoP2[02BAD2BADH];
FromPtoK[p, Eval,000000000H]; FromPtoK[p, Eval,0AAAAAAAAH]; 
FromPtoK[p, Eval,055555555H]; FromPtoK[p, Eval,0FFFFFFFFH]; 
FromPtoK[p, Eval,02BAD2BADH];
TerminalIO.PutRope["Finished with SanityCheck"];
};
RamTest: RosemaryUser.TestProc = {
Val: PROC [i: NAT] RETURNS [val: CARD] ~ {
val _ 0137FA00H+i;
};
CheckRamBlock: PROC [from, to: NAT] ~ {
FOR i: NAT IN [from..to) DO
WriteInRam[p, Eval, i, 0137FA00H+i];
ENDLOOP;
FOR i: NAT IN [from..to) DO
ReadFromRam[p, Eval, i, 0137FA00H+i]; 
WriteInRam[p, Eval, i, 0FEC8500H+0FFH-i];
ENDLOOP;
FOR i: NAT IN [from..to) DO
ReadFromRam[p, Eval, i, 0FEC8500H+0FFH-i]; 
ENDLOOP;
};
TerminalIO.PutRope["Starting RamTest"];
Initialize[p, cellType.public];
CheckRamBlock[stackAdr, junkAdr];
CheckRamBlock[junkAdr+1, constAdr];	-- avoid euJunk, since it should not exist
CheckRamBlock[constAdr+4, bogusAdr];
ReadFromRam[p, Eval, constAdr,	0];
ReadFromRam[p, Eval, constAdr+1,	1];
ReadFromRam[p, Eval, constAdr+2,	2];
ReadFromRam[p, Eval, constAdr+3,	3];
TerminalIO.PutRope["Finished with RamTest"];
};

ALUTest: RosemaryUser.TestProc = {
ResetCarry: PROC ~ {TestALU[LAdd, 0, 0, 0]};
SetCarry: PROC ~ {TestALU[UAdd, 0FFFFFFFFH, 000000001H, 0]};
TestALU: PROC [op: Dragon.ALUOps, opL, opR, res: CARD, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE] ~ {
ALUOp[p, Eval, op, opL, opR, res, cc, cond];
};
TestAdd: PROC [op: Dragon.ALUOps] ~ {
IF op#SAdd AND op#UAdd AND op#VAdd AND op#LAdd AND op#VAdd2 THEN ERROR;
ResetCarry[];
TestALU[op, 000000000H,000000000H,000000000H];
TestALU[op, 000000001H,000000002H,000000003H];
TestALU[op, 00FFFFFFFH,000000001H,010000000H];
TestALU[op, 012345678H,087654321H,099999999H];
TestALU[op, 0FFFFFFFFH,000000000H,0FFFFFFFFH];
TestALU[op, 000000000H,0FFFFFFFFH,0FFFFFFFFH];
TestALU[op, 000000001H,0FFFFFFFFH,000000000H];
ResetCarry[];
};
TestSub: PROC [op: Dragon.ALUOps] ~ {
IF op#SSub AND op#USub AND op#VSub AND op#LSub THEN ERROR;
TestALU[op, 000000000H,000000000H,000000000H];
TestALU[op, 000000003H,000000002H,000000001H];
TestALU[op, 010000000H,000000001H,00FFFFFFFH];
TestALU[op, 099999999H,087654321H,012345678H];
TestALU[op, 0FFFFFFFFH,000000000H,0FFFFFFFFH];
TestALU[op, 0FFFFFFFFH,0FFFFFFFFH,000000000H];
TestALU[op, 000000000H,0FFFFFFFFH,000000001H];
ResetCarry[];
};
TerminalIO.PutRope["Starting ALUTest"];
Initialize[p, cellType.public];
TerminalIO.PutF["New Test\n"];
ResetCarry[];
TestALU[UAdd, 07FFFFFFFH, 000000001H, 080000000H, OvFl, TRUE];
ResetCarry[];
TestALU[UAdd, 07FFFFFFFH, 000000000H, 07FFFFFFFH, OvFl, FALSE];
ResetCarry[];
TestALU[BndChk, 000000000H, 000000001H, 000000000H, BC, FALSE];
ResetCarry[];
TestALU[BndChk, 000000002H, 000000001H, 000000002H, BC, TRUE];
ResetCarry[];
TestALU[BndChk, 000000000H, 000000001H, 000000000H, NotBC, TRUE];
ResetCarry[];
TestALU[BndChk, 000000002H, 000000001H, 000000002H, NotBC, FALSE];
ResetCarry[];
TestALU[USub, 000000000H, 000000001H, 0FFFFFFFFH, LZ, TRUE];
ResetCarry[];
TestALU[UAdd, 000000000H, 000000000H, 000000000H, LZ, FALSE];
ResetCarry[];
TestALU[UAdd, 000000000H, 000000000H, 000000000H, GE, TRUE];
ResetCarry[];
TestALU[USub, 000000000H, 000000001H, 0FFFFFFFFH, GE, FALSE];
ResetCarry[];
TestALU[USub, 000000000H, 000000000H, 000000000H, LE, TRUE];
TestALU[USub, 000000001H, 000000000H, 000000001H, LE, FALSE];

TestALU[USub, 000000001H, 000000000H, 000000001H, NE, TRUE];
TestALU[USub, 000000001H, 000000001H, 000000000H, NE, FALSE];

TestALU[USub, 000000001H, 000000000H, 000000001H, GZ, TRUE];
TestALU[USub, 000000000H, 000000000H, 000000000H, GZ, FALSE];
TestALU[LAdd, 07FFFFFFFH, 000000001H, 080000000H, IL, TRUE];	-- opL=011
TestALU[LAdd, 000000000H, 0FFFFFFFFH, 0FFFFFFFFH, IL, FALSE];	-- all 0 or 1
TestALU[LAdd, 010000000H, 010000000H, 020000000H, IL, TRUE];	-- res=001
TestALU[LAdd, 000000001H, 000000001H, 000000002H, IL, FALSE];	-- all 0
TestALU[LAdd, 07FFFFFFFH, 000000001H, 080000000H, NotIL, FALSE]; -- opL=011
TestALU[LAdd, 000000000H, 0FFFFFFFFH, 0FFFFFFFFH, NotIL, TRUE]; -- all 0 or 1
TestALU[LAdd, 010000000H, 010000000H, 020000000H, NotIL, FALSE]; -- res=001
TestALU[LAdd, 000000001H, 000000001H, 000000002H, NotIL, TRUE];	-- all 0
ResetCarry[];
TestALU[USub, 000000000H, 000000000H, 000000000H, EZ, TRUE];
TestALU[USub, 02BAD2BADH, 02BAD2BADH, 000000000H, EZ, TRUE];
TestALU[USub, 0FFFFFFFFH, 0FFFFFFFFH, 000000000H, EZ, TRUE];
TestALU[USub, 000000001H, 000000000H, 000000001H, EZ, FALSE];
TestALU[USub, 02BAD2BADH, 000000001H, 02BAD2BACH, EZ, FALSE];
TestALU[USub, 000000001H, 000000002H, 0FFFFFFFFH, EZ, FALSE];


TestALU[BndChk, 	000000000H,000000000H,000000000H];
TestALU[BndChk, 	055555555H,000000000H,055555555H];
TestALU[BndChk, 	0AAAAAAAAH,000000000H,0AAAAAAAAH];
TestALU[BndChk, 	0FFFFFFFFH,000000000H,0FFFFFFFFH];
TestALU[Or,	000FF00FFH,00F0F0F0FH,00FFF0FFFH];
TestALU[And, 	000FF00FFH,00F0F0F0FH,0000F000FH];
TestALU[Xor, 	000FF00FFH,00F0F0F0FH,00FF00FF0H];
TestAdd[SAdd];
TestAdd[UAdd];
TestAdd[VAdd];
TestAdd[LAdd];
TestAdd[VAdd2];
TestSub[SSub];
TestSub[USub];
TestSub[VSub];
TestSub[LSub];
TestALU[LAdd, 000000000H, 000000000H, 000000000H, False, FALSE];
TestALU[LAdd, 000000000H, 000000000H, 000000000H, ModeFault, TRUE];
TerminalIO.PutRope["Finished with ALUTest"];
};
FUTest: RosemaryUser.TestProc = {
TestFU: PROC [leftW, rightW, mask, shift: CARD, insert: BOOL _ FALSE] ~ {
FUOp[p, Eval, leftW, rightW, mask, shift, insert];
};
TerminalIO.PutRope["Starting FUTest"];
Initialize[p, cellType.public];
FOR shift: NAT IN [0..32] DO
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: 32, shift: shift];
ENDLOOP;
FOR shift: NAT IN [0..32] DO
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: shift, shift: 0];
ENDLOOP;
FOR i: NAT IN [0..32] DO
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: (4*i+19) MOD 33, shift: (3*i+5) MOD 33];
ENDLOOP;
TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 0, shift: 0, insert: TRUE];
TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 32, shift: 0, insert: TRUE];
TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 32, shift: 32, insert: TRUE];
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: 18, shift: 4, insert: TRUE];
TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 21, shift: 12, insert: TRUE];
TerminalIO.PutRope["Finished with FUTest"];
};

EUTest: RosemaryUser.TestProc = {
};	

c1: CARD = 00137FFFFH;
c2: CARD = 0FEC80000H;

R3BNormal: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR3B[p, Eval, val, PackK[st3AisC: TRUE]];-- 2B: r3B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 3A: st3A _ val
Force[p, KBus, PackK[]];
WritePBus[p];
Expect[p, DPData, val];
DoPh[p, Eval, B];									-- 3B: PBus _ st3A = val ???
Ignore[p, KBus];
IgnorePBus[p];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 4A: just for sync.
};
R3BReject: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR3B[p, Eval, val, PackK[], TRUE];-- 2B: r3B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 3A: ram[marAdr] _ cBus _ val (reject)
ReadFromRam[p, Eval, marAdr, val]; 		-- check marAdr
};

R2BtoLeft: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR2B[p, Eval, val, PackK[b: constAdr, aluL: 1]]; -- 1B: r2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: left _ r2B _ val; right _ 0
OpAndCheck[p, Eval, val, 0];
};
R2BtoRight: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR2B[p, Eval, val, PackK[a: constAdr, aluR: 1]]; -- 1B: r2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: right _ r2B _ val; left _ 0
OpAndCheck[p, Eval, val, 0];
};
R2BtoSt2A: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR2B[p, Eval, val, PackK[a: constAdr, st2A: 1]]; -- 1B: r2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: st2A _ r2B _ val
CheckSt2A[p, Eval, val];
};
CBustoLeft: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR3B[p, Eval, val, PackK[b: constAdr, aluL: 2]]; -- 1B: r3B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: left _ r2B _ val; right _ 0
OpAndCheck[p, Eval, val, 0];
};
CBustoRight: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR3B[p, Eval, val, PackK[a: constAdr, aluR: 2]]; -- 1B: r3B _ val
Ignore[p, KBus];
Ignore[p, DPData];
DoPh[p, Eval, A];									-- 2A: right _ r2B _ val; left _ 0
OpAndCheck[p, Eval, val, 0];
};


WiresTest: RosemaryUser.TestProc = {
TryAllPaths: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
FromPtoK[p, Eval, val];		-- 4 evals
R3BNormal[p, Eval, val];		-- 24 evals
R3BReject[p, Eval, val];		-- 24 evals
R2BtoLeft[p, Eval, val];		-- 12 evals
R2BtoRight[p, Eval, val];	-- 12 evals
R2BtoSt2A[p, Eval, val];		-- 16 evals
CBustoLeft[p, Eval, val];		-- 16 evals
CBustoRight[p, Eval, val];	-- 16 evals
};
TerminalIO.PutRope["Starting WiresTest"];
TryAllPaths[p, Eval, c1];
TryAllPaths[p, Eval, c2];
TerminalIO.PutRope["Finished with WiresTest"];
};

DBusTest: RosemaryUser.TestProc = {
TerminalIO.PutRope["Starting DBusTest"];
Initialize[p, cellType.public];
ReadR2BWithDBus[p, Eval, 0A123456FH];
TerminalIO.PutRope["Finished with DBusTest"];
};

ReadR2BWithDBus: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ {
PutValInR2B[p, Eval, val, PackK[a: constAdr, aluR: 2]]; -- 1B: r2B _ val
Ignore[p, KBus];
Ignore[p, DPData];
p[DStAd].c _ 7;			-- EUUtils.r2BRow
p[DShRd].b _ TRUE;
p[DShWt].b _ FALSE;
Eval[];						-- read the register: shiftReg _ reg[regAd]
p[DShRd].b _ FALSE;
p[DShWt].b _ FALSE;
FOR i: NAT IN [0..32) DO
bitOut: BOOL _ BitOps.EBFD[val, i];

p[DShOut].d _ expect;
p[DShOut].b _ bitOut;
p[DShB].b _ TRUE;
Eval[];						-- <b> _ <a>;  shOut _ new value

p[DShOut].d _ none;
p[DShB].b _ FALSE;
Eval[];						-- <b> latched; shOut tristate

p[DShIn].b _ FALSE;
p[DShA].b _ TRUE;
Eval[];						-- <a> _ <in>; shIn is sampled

p[DShA].b _ FALSE;
p[DShB].b _ FALSE;
Eval[];						-- <a> latched

ENDLOOP;

p[DShRd].b _ FALSE;
p[DShWt].b _ FALSE;
p[DHold].b _ FALSE;
p[DStAd].c _ 0;
Eval[];
DoPh[p, Eval, A];									-- A: for synch
};

Register: PROC [usingTester: BOOL] ~ {
IF usingTester THEN {	-- for IMS tester
ICTest.RegisterTestProc[euTest, "ZeroAndOne", ZeroAndOne];
ICTest.RegisterTestProc[euTest, "Sanity Check", SanityCheck];
ICTest.RegisterTestProc[euTest, "RamTest", RamTest];
ICTest.RegisterTestProc[euTest, "ALUTest", ALUTest];
ICTest.RegisterTestProc[euTest, "FUTest", FUTest];
}
ELSE {	-- for Rosemary simulation
RosemaryUser.RegisterTestProc["AllTests", 	AllTests];
RosemaryUser.RegisterTestProc["ZeroAndOne", 	ZeroAndOne];
RosemaryUser.RegisterTestProc["Sanity Check", 	SanityCheck];
RosemaryUser.RegisterTestProc["RamTest", 	RamTest];
RosemaryUser.RegisterTestProc["ALUTest", 	ALUTest];
RosemaryUser.RegisterTestProc["FUTest", 	FUTest];
RosemaryUser.RegisterTestProc["WiresTest", 	WiresTest];
RosemaryUser.RegisterTestProc["DBusTest", 	DBusTest];
};
};

euTest: ROPE = "EU4 Test";

opName: ARRAY Dragon.ALUOps OF Rope.ROPE;
opName[Or] _ "Or"; 		opName[And] _ "And";	
opName[VAdd2] _ "VAdd2"; 	opName[BndChk] _ "BndChk";
opName[SAdd] _ "SAdd";	opName[SSub] _ "SSub";
opName[LAdd] _ "LAdd";	opName[LSub] _ "LSub";
opName[Xor] _ "Xor";		opName[res9] _ "res9";
opName[FOP] _ "FOP";		opName[res11] _ "res11";
opName[VAdd] _ "VAdd";	opName[VSub] _ "VSub";	
opName[UAdd] _ "UAdd";	opName[USub] _ "USub";


END.




���L��EUSim.mesa
Copyright c 1985 by Xerox Corporation.  All rights reversed.
Created by Bertrand Serlet July 31, 1985 3:03:17 pm PDT
Last edited by Bertrand Serlet June 8, 1986 5:21:11 pm PDT
Barth, April 16, 1986 3:05:40 pm PST
Louis Monier June 19, 1986 11:54:42 pm PDT
Last Edited by: Louis Monier April 24, 1987 1:49:58 pm PDT

Test of EU
-- Invariants
-- On PhA the chip always drives the PBus, so we check that the tester is not driving
-- appropriate clock up
-- both clocks down
-- Utility, not a test in itself
-- Gets value through the KBus and computes OR[ct0, val]
-- Gets value through the KBus and computes OR[ct0, val], then moves it down by two latches
-- k is the value on the kBus in the last PhB
-- Checks whether st2A=val
-- Computes OP(left, right) and checks that the result is equal to val

-- From PBus to dataIn to cBus to KBus
-- This test uses the field register to hold the field descriptor


-- Test procs

-- The combination of all the test procs
[cellType: Core.CellType, p: Ports.Port, Eval: PROC [...]]

-- The absolute minimum expected from a chip

-- The minimum expected from a chip
-- Test the entire RAM
-- Read constants in ROM
-- may generates a carry
-- may generates a carry
-- OvFl _ (Cout XOR opL[0] XOR opR[0]) XOR res[0], so we need a carry out;
BC _ ~Cout
-- LZ _ Cout XOR opL[0] XOR opR[0], so we need a carry out; GE _ ~ LZ
-- LE _ EZ OR LZ
IL _ all 3 high-order bits equal
EZ _ zero, found after a sub at the top of the CLA tree
Check integrity of aluLeft-> r2B-> pDriver path
Logic operations
All additions
All subtractions
Constant Conditions
-- Testing the shifter (no masking)
-- Testing the mask generator (no shifting)
-- General Shift and Mask test
-- With insert
-- Try to put a zero and a 1 through every path in the EU
-- I use an asymetric pattern to detect flips in buses
-- I use the bus names defined in the schematics of the datapath
-- Test the tristate driver r3B on the cBus; normal case
-- Test the tristate driver r3B on the cBus; reject case
-- Bypass from r2B to left
-- Bypass from r2B to right
-- Bypass from r2B to st2A
-- Bypass from r3B to left
�Ê��–
"cedar" style˜�codešœ
™
Jšœ
Ïmœ1™<Jšœ4Ïk™7Jšœ7ž™:Kšœ!ž™$Kšœ'ž™*Kšœ:™:K™�—šž	œ˜Kšœ?žœ2˜s—J˜�•StartOfExpansion[]šÐbnœžœž˜Kšžœ$žœ.˜[Kšž˜—headšœž™
Kšžœžœžœ˜Kšœ
žœ˜K˜�Kšœ#˜#KšœÏc
˜Kšœ	 
˜Kšœ#˜#Kšœ
 
˜Kšœ 
˜Kšœ˜Kš	œ0Ïnœžœžœžœ˜GK˜�Kš	œžœžœ
žœžœ˜*š¡
œžœ'˜7Kšœ˜Kšœžœ˜Kšœžœ˜Kšœ4žœ˜:Kšœ˜Kšœ ˜"Kšœžœ ˜/Kšœžœ ˜:Kšœžœ '˜FKšœžœ˜Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜K˜—š¡œžœ˜.Kšœ›˜›KšœÍ˜Íšœ:˜:Kšœa˜a—Kšœ+˜+Kšœ+˜+Kšœ.˜.Kšœ.˜.Kšœ/˜/Kšœ/˜/Kšœ5˜5Kšœ(˜(Kšœ3˜3Kšœ&˜&Kšœ0˜0Kšœ;˜;Kšœ<˜<Kšœ+˜+Kšœ6˜6Kšœ-˜-Kšœ8˜8Kšœ:˜:Kšœ0˜0Kšœ0˜0Kšœ1˜1Kšœ1˜1Kšœ1˜1Kšœ1˜1Kšœ&˜&Kšœ1˜1Kšœ1˜1K˜—K˜�š¡œžœžœžœžœžœžœžœ"˜tKšœ˜šœ*˜*Kšœ˜Kšœ
žœe˜vKšœ˜Kšœ5˜5Kšœ/˜/Kšœžœ˜—K˜—K˜�Kšœ
žœžœ*˜=Kšœ	žœžœ)˜;Kšœžœžœ+˜<Kšœžœžœ(˜9Kšœ
žœžœ*˜=Kšœ
žœžœ-˜@Kšœ
žœžœ*˜=K˜�Kšœžœ
˜K˜�š¡œžœ¡œ˜7K˜Kš 
™
Kš	žœžœžœžœ ˜?Kš U™UKšžœžœžœžœ˜)Kš ™Kšœ'žœ˜.Jš ™Kš	œžœ
žœžœžœ˜LK˜—Kš¡œžœžœ˜=Kš¡œžœžœžœ*˜ZKš¡œžœžœžœ+˜\š¡œžœ˜"Kšœžœ˜Kšœžœ˜K˜—š¡	œžœ˜#Kšœžœ˜Kšœžœ˜K˜—š¡
œžœ˜$Kšœžœ˜Kšœžœ˜K˜—š¡œžœžœžœžœžœ˜LKšœžœžœžœ˜0Kš
œ	žœžœ	žœžœ	žœžœ˜`K˜—š
¡
œžœ¡œžœžœ˜FKšœ ˜7Kšœ˜šœ˜Jšœ Ðbc ˜8—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜.—K˜—š¡œžœ¡œžœžœžœ˜\Kšœ' ˜@Kšœ˜šœ ˜3Jšœ ¢ ˜*—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜/—Kšœ ¢
˜*K˜—Kš  ™ Kš 8™8š¡œžœ¡œžœ˜AKšœ- ˜FKšœ˜šœ ˜4Jšœ ¢ ˜*—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜=—Kšœ 
˜Kšœ˜šœ˜Jšœ ¢ 
˜,—K˜—Kš [™[Kš -™-š¡œžœ¡œžœ
žœžœ˜WKšœ% ¢ ˜5Kšœ˜šœ˜Jšœ ¢ ˜*—Kšžœžœžœ˜%Kšœ˜šœ˜Jšœ ¢ ˜*—Kšœžœ˜K˜—Kšœ™š¡	œžœ¡œžœ˜<Kšœ˜šœ˜Jšœ ¢ ˜+—Kšœ˜šœ˜Jšœ ¢ ˜+—Kšœ˜Kšœ
˜
šœ˜Jšœ ¢ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜/—K˜—KšœF™Fš
¡
œžœ¡œžœžœ˜FKšœ ˜(Kšœ˜šœ˜Jšœ ¢ ˜*—Kšœ˜šœ˜Jšœ ¢ ˜6—K˜—K™�Kš &™&š¡œžœ¡œžœ˜;Kšœ" ˜:Kšœ˜šœ˜Jšœ ¢ ˜2—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜7—Kšœ˜K˜—š¡œžœ¡œ,žœ(žœžœ˜‰Kšœžœ˜
Kšœžœ˜
Kšœ3žœžœžœžœžœ˜…Kšœžœžœ˜.Kšœ˜Kšœ˜Kšœžœ˜Kšœ&˜&šœ˜Jšœ ¢ ˜7—Kšœžœ˜Kšœ˜šœ˜Jšœ ¢  ˜?—Kšœžœ˜Kšœ˜Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜1—Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜+—Kšœ˜K˜—Kš A™Aš¡œžœ¡œ&žœ
žœžœ˜dKš	œžœžœžœžœ˜7Kšœžœ&˜/Kš	œCžœžœ
žœžœ˜†Kšœžœ ˜4Kšœ  ˜/Kšœ! ˜1K˜�Kšœ, '˜Sšœ˜Jšœ ¢ ˜5—Kšœžœžœ˜*Kšœ˜šœ˜Jšœ ¢ 
˜'—Kšœ˜šœ˜Jšœ ¢ ˜3—Kšœ˜šœ˜Jšœ ¢ ˜)—K˜—K™�K™�—šÑclx
™
K™�Kš (™(–> -- [cellType: Core.CellType, p: Ports.Port, Eval: PROC [...]]š¡œ˜#KšÐck:™:Kšœ(˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ-˜-Kšœ˜—K™�Kš ,™,š¡
œ˜%Kšœ*˜*Kšœ˜KšÏf˜Kš¥˜Kš¥˜Kšœ/˜/Kšœ˜—K™�Kš #™#š¡œ˜&š¡	œžœžœ˜Kšœžœ ˜@Kšœ˜šœ˜Jšœ ¢ ˜-—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜;—Kšœ˜Kšœ
˜
šœ˜Jšœ ¢ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜/—K˜—š¡	œžœžœ˜Kšœ  ˜:Kšœ˜šœ˜Jšœ ¢ ˜-—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜2—Kšœ˜Kšœ˜šœ (˜EJšœ ¢ 
˜,—Kšœ˜Kšœ˜šœ˜Jšœ ¢ 
˜,—Kšœ˜Kšœ
˜
šœ˜Jšœ ¢ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜/—K˜Kšœ+˜+Kšœ˜Kšœ	¥
œ
¥
œ
¥
˜DKšœ	¥
œ
¥
˜-Kšœ	¥
œ
¥
œ
¥
˜DKšœ	¥
œ
¥
˜-Kš¥<˜<Kš¥<˜<Kš¥˜Kšœ0˜0—Kšœ˜—Kš ™š¡œ˜"š
¡œžœžœžœžœ˜*Kšœ¥	œ˜K˜—š¡
œžœžœ˜'šžœžœžœž˜Kšœ¥	œ˜$Kšžœ˜—šžœžœžœž˜Kšœ¥	œ˜&Kšœ¥œ˜)Kšžœ˜—šžœžœžœž˜Kšœ¥œ˜+Kšžœ˜—K˜—Kšœ'˜'Kšœ˜Kšœ!˜!Kšœ$ *˜NKšœ$˜$Kš ™Kšœ"˜"Kšœ$˜$Kšœ$˜$Kšœ$˜$Kšœ,˜,Kšœ˜—K˜�š¡œ˜"Kš¡
œžœ¥œ¥
œ˜,Kš¡œžœ¥œ¥œ˜<š
¡œžœ$žœ(žœžœ˜nKšœ,˜,K˜—š¡œžœ˜%Kšžœ	žœ	žœ	žœ	žœ
žœžœ˜GKšœ
¥œ˜
Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš ™Kš¥œ¥$˜.Kšœ
¥œ˜
K˜—š¡œžœ˜%Kšžœ	žœ	žœ	žœ	žœžœ˜:Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš¥œ¥$˜.Kš ™Kš¥œ¥$˜.Kšœ
¥œ˜
K˜—Kšœ'˜'Kšœ˜Kšœ˜š J™JKšœ
¥œ˜
Kš¥œ¥&œ¥Ðfk¥˜>Kšœ
¥œ˜
Kš¥œ¥&œ¥¦¥˜?—šžœ™
Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜?Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜>Kšœ
¥œ˜
Kš¥œ¥&œ¥¦¥˜AKšœ
¥œ˜
Kš¥œ¥&œ¥¦¥˜B—š E™EKšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜<Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜=Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜<Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜=—š ™Kšœ
¥œ˜
Kš¥œ¥&ž¥¦¥˜<Kš¥œ¥&ž¥¦¥˜=K˜�Kš¥œ¥&ž¥¦¥˜<Kš¥œ¥&ž¥¦¥˜=K˜�Kš¥œ¥&ž¥¦¥˜<Kš¥œ¥&ž¥¦¥˜=—šžœ™ Kš¥2ž¥¦¥Ðcf
˜GKš¥2ž¥¦¥§
˜KKš¥2ž¥¦¥§
˜GKš¥2ž¥¦¥§˜FKš¥2œ¥¦¥§
˜KKš¥2œ¥¦¥§
˜MKš¥2œ¥¦¥§
˜KKš¥2œ¥¦¥§˜H—šžœ-žœ™7Kšœ
¥œ˜
Kš¥œ¥&¦¥¦¥˜<Kš¥œ¥&¦¥¦¥˜<Kš¥œ¥&¦¥¦¥˜<Kš¥œ¥&¦¥¦¥˜=Kš¥œ¥&¦¥¦¥˜=Kš¥œ¥&¦¥¦¥˜=K˜�—K˜�šœ/™/Kš¥3˜3Kš¥3˜3Kš¥3˜3Kš¥3˜3—šœ™Kš¥.˜.Kš¥0˜0Kš¥0˜0—šœ
™
Kšœ¥œ¥˜Kšœ¥œ¥˜Kšœ¥œ¥˜Kšœ¥œ¥˜Kšœ¥œ¥˜—šœ™Kšœ¥œ¥˜Kšœ¥œ¥˜Kšœ¥œ¥˜Kšœ¥œ¥˜—šœ™Kš¥2œ¥¦¥˜@Kš¥2œ	¥¦¥˜CKšœ,˜,—Kšœ˜—š¡œ˜!š
¡œžœžœ
žœžœ˜IKšœ2˜2K˜—Kšœ&˜&Kšœ˜š #™#šžœžœžœ	ž˜KšœF˜FKšžœ˜——š +™+šžœžœžœ	ž˜KšœE˜EKšžœ˜——š ™šžœžœžœ	ž˜Kšœ=žœžœ˜\Kšžœ˜——š ™Kšœ"¥
œžœ˜OKšœ"¥
œžœ˜PKšœ"¥
œžœ˜QKšœ"¥
œžœ˜PKšœ"¥
œžœ˜QKšœ+˜+—Kšœ˜K˜�—š¡œ˜!Kšœ˜K˜�—Kš 9™9Kš 6™6Kš @™@Kšœžœ¥
œ˜Kšœžœ¥
œ˜K˜�Kš 8™8š¡	œžœ¡œžœ˜<Kšœ)žœ ¢ ˜@Kšœ˜šœ˜Jšœ ¢ ˜+—Kšœ˜Kšœ
˜
šœ˜Jšœ ¢ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ¢ ˜/—K˜—Kš 8™8š¡	œžœ¡œžœ˜<Kšœ#žœ ¢ ˜9Kšœ˜šœ˜Jšœ ¢ #˜B—Kšœ% ˜4K˜—K˜�K™š¡	œžœ¡œžœ˜<Kšœ8 ¢ ˜HKšœ˜šœ˜Jšœ ¢ ˜<—Kšœ˜K˜—K™š¡
œžœ¡œžœ˜=Kšœ8 ¢ ˜HKšœ˜šœ˜Jšœ ¢ ˜<—Kšœ˜K˜—K™š¡	œžœ¡œžœ˜<Kšœ8 ¢ ˜HKšœ˜šœ˜Jšœ ¢ ˜1—Kšœ˜K˜—K™š¡
œžœ¡œžœ˜=Kšœ8 ¢ ˜HKšœ˜šœ˜Jšœ ¢ ˜<—Kšœ˜K˜—š¡œžœ¡œžœ˜>Kšœ8 ¢ ˜HKšœ˜šœ˜Jšœ ¢ ˜<—Kšœ˜K˜—K˜�K˜�š¡	œ˜$š¡œžœ¡œžœ˜>Kšœ 
˜#Kšœ ˜%Kšœ ˜%Kšœ ˜%Kšœ ˜%Kšœ ˜%Kšœ ˜&Kšœ ˜&K˜—Kšœ)˜)Kšœ˜Kšœ˜Kšœ.˜.Kšœ˜K˜�—š¡œ˜#Kšœ(˜(Kšœ˜Kšœ¥˜%Kšœ-˜-Kšœ˜—K˜�š¡œžœ¡œžœ˜BKšœ8 ¢ ˜HKšœ˜Kšœ˜Kšœ ˜#Kšœ
žœ˜Kšœ
žœ˜Jšœ
 +˜8Kšœ
žœ˜Kšœ
žœ˜šžœžœžœ	ž˜Kšœžœ
žœ	˜#K˜�Kšœ˜Kšœ˜Kšœžœ˜Jšœ
  ˜-K˜�Kšœ˜Kšœžœ˜Jšœ
 ˜+K˜�Kšœ
žœ˜Kšœžœ˜Jšœ
 ˜+K˜�Kšœžœ˜Kšœžœ˜Jšœ
 ˜K˜�Kšžœ˜—K˜�Kšœ
žœ˜Kšœ
žœ˜Kšœ
žœ˜Kšœ˜šœ˜Jšœ ¢ ˜)—K˜—K˜�š¡œžœžœ˜&šžœ
žœ ˜'Kšœ:˜:Kšœ=˜=Kšœ4˜4Kšœ4˜4Kšœ2˜2Kšœ˜—šžœ ˜!Kšœ5˜5Kšœ9˜9Kšœ<˜<Kšœ3˜3Kšœ3˜3Kšœ1˜1Kšœ7˜7Kšœ5˜5K˜—K˜—K˜�Kšœžœ˜K˜�Kšœžœžœžœ˜)Kšœ*˜*Kšœ4˜4Kšœ-˜-Kšœ-˜-Kšœ,˜,Kšœžœ$˜.Kšœ.˜.Kšœ-˜-K˜�—K˜�Kšžœ˜K˜�K˜�K˜�K˜�—�…—����Zž��~î��