EURawSim2.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet July 31, 1985 3:03:17 pm PDT
Last edited by Bertrand Serlet December 18, 1986 1:21:07 am PST
Barth, September 26, 1986 2:59:10 pm PDT
Louis Monier June 19, 1986 11:54:42 pm PDT
Last Edited by: Louis Monier October 20, 1986 10:25:48 am PDT
Last Edited by: Gasbarro October 1, 1986 6:05:58 pm PDT
DIRECTORY
Core, Dragon, EUArith, IO, Rope, Rosemary, RosemaryUser, Ports, TerminalIO;
EURawSim2:
CEDAR
PROGRAM
IMPORTS EUArith, IO, Rosemary, RosemaryUser, Ports, TerminalIO =
BEGIN OPEN Core;
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];
allOnes: LONG CARDINAL ← LOOPHOLE[LONG[-1]];
Initialize:
PROC [p: Ports.Port, public: Wire] = {
InitializePublic[public];
p[DPRejectB].b ← FALSE;
p[DShA].b ← p[DShB].b ← TRUE; -- hack to clean up the ShReg.
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 ← 0; -- 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];
};
Phase: TYPE = {A, B};
constAdr: NAT ← 132;
junkAdr: NAT ← 128;
IFUAdr: NAT ← 129;
fieldAdr: NAT ← 131;
nbPhases: INT ← 0;
DoPh:
PROC [p: Ports.Port,
Eval:
PROC, ph: Phase] = {
-- Invariants
IF PhA=0 AND PhB=0 THEN ERROR; -- port indexes not initialized
-- On PhA the chip always drives the PBus, so we check that the tester is not driving
IF ph=A AND p[DPData].d=force THEN ERROR;
-- appropriate clock up
p[PhA].b ← ph=A; p[PhB].b ← ph=B; Eval[];
-- both clocks down
p[PhA].b ← FALSE; p[PhB].b ← FALSE; Eval[ ! Ports.CheckError => RESUME];
};
Ignore: PROC [p: Ports.Port, port: NAT] ~ {p[port].d ← none};
Force: PROC [p: Ports.Port, port: NAT, val: LONG CARDINAL] ~ {p[port].d ← force; p[port].lc ← val};
Expect: PROC [p: Ports.Port, port: NAT, val: LONG CARDINAL] ~ {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: LONG CARDINAL] ~ {
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:
PROC, ad:
NAT, val:
LONG
CARDINAL] ~ {
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:
PROC, ad:
NAT, val:
LONG
CARDINAL, m:
LONG
CARDINAL ← 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]
Force[p, KBus, PackK[]];
Ignore[p, DPData];
DoPh[p, Eval, B]; -- 1B: st2B ← st2A
Ignore[p, KBus];
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.
};
FromPtoK:
PROC [p: Ports.Port,
Eval:
PROC, val:
LONG
CARDINAL] ~ {
p[EURdFromPBus3AB].b ← TRUE;
p[EUWriteToPBus3AB].b ← FALSE;
Force[p, KBus, PackK[c: IFUAdr]]; -- cBus->IFU on next PhA
Force[p, DPData, val];
DoPh[p, Eval, B]; -- Cycle 0: dataIn ← val
p[EURdFromPBus3AB].b ← TRUE; -- because of a bug, needed to let...
p[EUWriteToPBus3AB].b ← TRUE; -- ... the cBus driver drive the bus
Ignore[p, DPData];
Expect[p, KBus, val];
DoPh[p, Eval, A]; -- Cycle 1: KBus ← cBus ← val
p[EURdFromPBus3AB].b ← FALSE;
p[EUWriteToPBus3AB].b ← FALSE;
};
ALUOp:
PROC [p: Ports.Port,
Eval:
PROC, op: Dragon.ALUOps, opL, opR, res:
LONG
CARDINAL, cc: Dragon.CondSelects ← False, cond:
BOOL ←
FALSE] ~ {
lAd: NAT = 1;
rAd: NAT = 3;
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
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]]];
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:
PROC, leftW, rightW, mask, shift:
LONG
CARDINAL, insert:
BOOL ←
FALSE] ~ {
fd: NAT ← ((IF insert THEN 1 ELSE 0)*64+mask)*64+shift;
res: LONG CARDINAL ← 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
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𡤏ield; 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
};
-- Test procs
-- The minimum expected from a chip
SanityCheck: RosemaryUser.TestProc = {
FromPtoP2:
PROC [val:
LONG
CARDINAL] ~ {
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:
LONG
CARDINAL] ~ {
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.
};
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];
};
-- A quick test of the RAM
RamTest: RosemaryUser.TestProc = {
CheckRamBlock:
PROC [from, to:
NAT] ~ {
FOR i:
NAT
IN [from..to)
DO
WriteInRam[p, Eval, i, 55555555H];
ENDLOOP;
FOR i:
NAT
IN [from..to)
DO
ReadFromRam[p, Eval, i, 55555555H, i];
WriteInRam[p, Eval, i, 0AAAAAAAAH];
ENDLOOP;
FOR i:
NAT
IN [from..to)
DO
ReadFromRam[p, Eval, i, 0AAAAAAAAH, i];
ENDLOOP;
};
Initialize[p, cellType.public];
CheckRamBlock[0, 4];
-- Read constants in ROM
ReadFromRam[p, Eval, constAdr, 0];
ReadFromRam[p, Eval, constAdr+1, 1];
ReadFromRam[p, Eval, constAdr+2, 2];
ReadFromRam[p, Eval, constAdr+3, 3];
};
-- Test the entire RAM
RamTest: RosemaryUser.TestProc = {
CheckRamBlock: PROC [from, to: NAT] ~ {
FOR i: NAT IN [from..to) DO
WriteInRam[p, Eval, i, 55555555H];
ENDLOOP;
FOR i: NAT IN [from..to) DO
ReadFromRam[p, Eval, i, 55555555H, i];
WriteInRam[p, Eval, i, 0AAAAAAAAH];
ENDLOOP;
FOR i: NAT IN [from..to) DO
ReadFromRam[p, Eval, i, 0AAAAAAAAH, i];
ENDLOOP;
};
Initialize[p, cellType.public];
CheckRamBlock[0, 132];
-- Read constants in ROM
ReadFromRam[p, Eval, constAdr, 0];
ReadFromRam[p, Eval, constAdr+1, 1];
ReadFromRam[p, Eval, constAdr+2, 2];
ReadFromRam[p, Eval, constAdr+3, 3];
CheckRamBlock[136, 160];
};
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:
LONG
CARDINAL, 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];
-- may generates a carry
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];
-- may generates a carry
TestALU[op, 000000000H,0FFFFFFFFH,000000001H];
ResetCarry[];
};
Initialize[p, cellType.public];
TerminalIO.PutF["New Test\n"];
-- OvFl ← (Cout XOR opL[0] XOR opR[0]) XOR res[0], so we need a carry out;
ResetCarry[];
TestALU[UAdd, 07FFFFFFFH, 000000001H, 080000000H, OvFl, TRUE];
ResetCarry[];
TestALU[UAdd, 07FFFFFFFH, 000000000H, 07FFFFFFFH, OvFl, FALSE];
BC ← ~Cout (passed)
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];
-- LZ ← Cout XOR opL[0] XOR opR[0], so we need a carry out; GE ← ~ LZ
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];
-- LE ← EZ OR LZ
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];
IL ← all 3 high-order bits equal (passed)
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
EZ ← zero, found after a sub at the top of the CLA tree (passed)
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];
Check integrity of aluLeft-> r2B-> pDriver path (passed)
TestALU[BndChk, 000000000H,000000000H,000000000H];
TestALU[BndChk, 055555555H,000000000H,055555555H];
TestALU[BndChk, 0AAAAAAAAH,000000000H,0AAAAAAAAH];
TestALU[BndChk, 0FFFFFFFFH,000000000H,0FFFFFFFFH];
Logic operations (passed)
TestALU[Or, 000FF00FFH,00F0F0F0FH,00FFF0FFFH];
TestALU[And, 000FF00FFH,00F0F0F0FH,0000F000FH];
TestALU[Xor, 000FF00FFH,00F0F0F0FH,00FF00FF0H];
All additions (passed)
TestAdd[SAdd];
TestAdd[UAdd];
TestAdd[VAdd];
TestAdd[LAdd];
TestAdd[VAdd2];
All subtractions (passed)
TestSub[SSub];
TestSub[USub];
TestSub[VSub];
TestSub[LSub];
Constant Conditions (passed)
TestALU[LAdd, 000000000H, 000000000H, 000000000H, False, FALSE];
TestALU[LAdd, 000000000H, 000000000H, 000000000H, ModeFault, TRUE];
};
FUTest: RosemaryUser.TestProc = {
TestFU:
PROC [leftW, rightW, mask, shift:
LONG
CARDINAL, insert:
BOOL ←
FALSE] ~ {
FUOp[p, Eval, leftW, rightW, mask, shift, insert];
};
Initialize[p, cellType.public];
-- Testing the shifter (no masking) (passed)
FOR shift:
NAT
IN [0..32]
DO
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: 32, shift: shift];
ENDLOOP;
-- Testing the mask generator (no shifting) (passed)
FOR shift:
NAT
IN [0..32]
DO
TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: shift, shift: 0];
ENDLOOP;
-- General Shift and Mask test (passed)
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;
-- With insert (passed)
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];
};
LoopTest: RosemaryUser.TestProc = {
Initialize[p, cellType.public];
FromPtoK[p, Eval,000000000H];
FromPtoK[p, Eval,0FFFFFFFFH];
TerminalIO.PutF["Starting Sanity Check\n"];
SanityCheck[cellType, p, Eval];
TerminalIO.PutF["Starting Ram Check\n"];
RamTest[cellType, p, Eval];
TerminalIO.PutF["Starting ALU Check\n"];
ALUTest[cellType, p, Eval];
TerminalIO.PutF["Starting FU Check\n"];
FUTest[cellType, p, Eval];
};
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";
RosemaryUser.RegisterTestProc["LoopTest", LoopTest];
END.