Emit74LS163Vectors.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Gasbarro February 14, 1987 11:26:09 am PST
Barth, September 20, 1988 10:45:21 am PDT
DIRECTORY
BitOps, Convert, Core, CoreCreate, CoreOps, FS, IO, Ports, Rope;
Emit74LS163Vectors: CEDAR PROGRAM
IMPORTS BitOps, Convert, CoreCreate, CoreOps, FS, IO, Ports, Rope
= BEGIN
Nibble: TYPE = [0..16);
nClear: NAT = 0;
Clock: NAT = 1;
DataIn: NAT = 2; --4 bits
EnableP: NAT = 3;
Gnd: NAT = 4;
nLoad: NAT = 5;
EnableT: NAT = 6;
DataOut: NAT = 7; --4 bits
RippleCarryOut: NAT = 8;
Vcc: NAT = 9;
width: NAT = 4;
thisTest: Rope.ROPE = "74LS163 Tester";
Init: PROC = {
file: IO.STREAMFS.StreamOpen["Vectors74LS163.tioga", $create];
port: Ports.Port;
ct: Core.CellType ← CoreCreate.Cell[
name: "74LS163",
public: CoreCreate.WireList[LIST[
"nClear", "Clock", CoreCreate.Seq["DataIn", width], "EnableP", "Gnd", "nLoad", "EnableT", CoreCreate.Seq["DataOut", width], "RippleCarryOut", "Vcc"]],
onlyInternal: NIL,
instances: NIL
];
[] ← Ports.InitPort[ct.public[DataIn], c];
[] ← Ports.InitPort[ct.public[DataOut], c];
Ports.InitTesterDrive[ct.public[nClear], force];
Ports.InitTesterDrive[ct.public[Clock], force];
Ports.InitTesterDrive[ct.public[DataIn], force];
Ports.InitTesterDrive[ct.public[EnableP], force];
Ports.InitTesterDrive[ct.public[nLoad], force];
Ports.InitTesterDrive[ct.public[EnableT], force];
Ports.InitTesterDrive[ct.public[DataOut], none];
Ports.InitTesterDrive[ct.public[RippleCarryOut], none];
port ← Ports.CreatePort[ct, TRUE];
WritePortNamesVertically[file, ct.public, port];
DoTest[ct, port, file];
IO.Close[file];
};
DoTest: PROC [cellType: Core.CellType, p: Ports.Port, file: IO.STREAM] = {
count: Nibble ← 0;
temp: Nibble ← 0;
cycleCount: CARD ← 0;
targetCycle: CARD = 1;
Cycle: PROC = {
t: Nibble ← p[DataOut].c;
p[DataOut].c ← temp;
p[RippleCarryOut].b ← temp=15;
temp ← t;
WritePortData[file, p, cycleCount=targetCycle];
cycleCount ← cycleCount + 1;
};
InitState: PROC ~ {
p[nClear].b ← FALSE;
p[Clock].b ← TRUE; --fire clock pulse every cycle
p[DataIn].c ← 0;
p[EnableP].b ← TRUE;
p[nLoad].b ← TRUE;
p[EnableT].b ← TRUE;
p[DataOut].d ← none;
p[RippleCarryOut].d ← none;
p[DataOut].c ← 0;
count ← 0;
Cycle[];
p[DataOut].d ← expect;
p[RippleCarryOut].d ← expect;
};
Clear: PROC ~ {
p[nClear].b ← FALSE;
p[DataOut].c ← 0;
count ← 0;
p[RippleCarryOut].b ← FALSE;
Cycle[];
p[nClear].b ← TRUE;
};
Load: PROC [value: Nibble] ~ {
p[nLoad].b ← FALSE;
p[DataIn].c ← value;
p[DataOut].c ← value;
count ← value;
p[RippleCarryOut].b ← count=15;
Cycle[];
p[nLoad].b ← TRUE;
};
IncCount: PROC ~ {
count ← IF count=15 THEN 0 ELSE count+1;
};
Count: PROC ~ {
IncCount[];
p[DataOut].c ← count;
p[RippleCarryOut].b ← count=15;
Cycle[];
};
InitState[];
Clear[];
THROUGH [0..16) DO
Count[];
ENDLOOP;
Load[8];
Load[4];
Load[2];
Load[1];
Load[0];
};
WritePortNamesVertically: PROC [stream: IO.STREAM, public: Core.Wire, port: Ports.Port] = {
EachWirePortPair: Ports.EachWirePortPairProc = {
IF port.levelType#composite THEN {
size: INTSELECT port.levelType FROM
l, b => 1,
ls => port.ls.size,
bs => port.bs.size,
c => 16 - port.fieldStart,
lc => 32 - port.fieldStart,
q => ERROR, -- not yet implemented
ENDCASE => ERROR;
size ← (size+3)/4;
names ← CONS[[CoreOps.GetFullWireName[public, wire], size], names];
subElements ← FALSE;
};
};
NameWidth: TYPE = RECORD [name: Rope.ROPE, width: INT];
names: LIST OF NameWidth ← NIL;
reversedNames: LIST OF NameWidth ← NIL;
maxLength: INT ← 0;
[] ← Ports.VisitBinding[public, port, EachWirePortPair];
FOR nl: LIST OF NameWidth ← names, nl.rest UNTIL nl=NIL DO
maxLength ← MAX[maxLength, Rope.Length[nl.first.name]];
reversedNames ← CONS[nl.first, reversedNames];
ENDLOOP;
IO.PutF[stream, "\nColumnNames\n"];
FOR charIndex: INT IN [0..maxLength) DO
IO.PutF[stream, " "];
FOR nl: LIST OF NameWidth ← reversedNames, nl.rest UNTIL nl=NIL DO
name: Rope.ROPE ← nl.first.name;
offset: INT ← maxLength-Rope.Length[name];
IO.PutF[stream, "%g", IO.char[IF charIndex >= offset THEN Rope.Fetch[name, charIndex-offset] ELSE ' ]];
THROUGH [0..(6*nl.first.width)-1) DO IO.PutChar[stream, ' ]; ENDLOOP;
ENDLOOP;
IO.PutF[stream, "\n"];
ENDLOOP;
IO.PutF[stream, "Vectors"];
};
WritePortData: PROC [stream: IO.STREAM, p: Ports.Port, targetVector: BOOL] = {
RecurseWritePortData: PROC [p: Ports.Port] = {
IF p.levelType=composite THEN FOR i: NAT IN [0..p.size) DO
RecurseWritePortData[p[i]];
ENDLOOP
ELSE {
WritePaddedCardinal: PROC [c: LONG CARDINAL, size: INT] = {
cAsRope: Rope.ROPE ← Convert.RopeFromCard[c, 16, FALSE];
size ← (size+3)/4;
FOR i: INT IN [0..size-Rope.Length[cAsRope]) DO
IO.PutChar[stream, '0];
ENDLOOP;
IO.PutRope[stream, cAsRope];
};
WriteLevel: PROC [l: Ports.Level] = {
WriteBool[l=H];
};
WriteBool: PROC [b: BOOL] = {
IO.PutRope[stream, IF b THEN "1" ELSE "0"];
};
inhibit: BitOps.BitDWord ← BitOps.BitDWordZero;
mask: BitOps.BitDWord ← BitOps.BitDWordZero;
size: INT ← 0;
IO.PutRope[stream, " "];
SELECT p.levelType FROM
l => {WriteLevel[p.l]; size ← 1};
ls => {
size ← p.ls.size;
FOR i: NAT IN [0..p.ls.size) DO
WriteLevel[p.ls[i]];
ENDLOOP;
};
b => {WriteBool[p.b]; size ← 1};
bs => {
size ← p.bs.size;
FOR i: NAT IN [0..p.bs.size) DO
WriteBool[p.bs[i]];
ENDLOOP;
};
c => {size ← 16 - p.fieldStart; WritePaddedCardinal[p.c, size]};
lc => {size ← 32 - p.fieldStart; WritePaddedCardinal[p.lc, size]};
q => ERROR; -- not yet implemented
ENDCASE => ERROR;
IO.PutRope[stream, " "];
SELECT p.driveType FROM
aggregate => SELECT p.d FROM
none => {mask ← BitOps.doubleMasks[size]; inhibit ← BitOps.doubleMasks[size]};
force => {mask ← BitOps.doubleMasks[size]; inhibit ← BitOps.BitDWordZero};
expect => {mask ← BitOps.BitDWordZero; inhibit ← BitOps.doubleMasks[size]};
ENDCASE => ERROR;
separate => ERROR;
ENDCASE => ERROR;
WritePaddedCardinal[inhibit, size];
IO.PutRope[stream, " "];
WritePaddedCardinal[mask, size];
};
};
IO.PutF[stream, "\n"];
IO.PutRope[stream, IF targetVector THEN "*" ELSE " "];
RecurseWritePortData[p];
};
Init[];
END.