Fixes to make the verify tests match FPGA v32b

This commit is contained in:
davehein 2018-04-15 19:55:21 -05:00
parent 1b0c107390
commit 3b728bd09e
8 changed files with 2812 additions and 2749 deletions

View File

@ -1,11 +1,11 @@
Spinsim 0.98 Spinsim 0.98
This version of spinsim supports most of the opcodes in the P2 v32a instruction This version of spinsim supports most of the opcodes in the P2 v32b instruction
set. The opcodes that are not supported are as follows: set. The opcodes that are not supported are as follows:
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin xzero xinit xcont hubset setdacs setxfrq getxacc getbrk
setbrk setcy setci setcq setcfrq setcmod getrnd xoro32 cogbrk brk setcy setci setcq setcfrq setcmod getrnd
skip skipf execf xoro32 skip skipf execf
skip, skipf and execf have been partially implemented, but do not handle jumps skip, skipf and execf have been partially implemented, but do not handle jumps
or interrupts correctly. or interrupts correctly.
@ -23,8 +23,8 @@ make. The Windows executable, spinsim.exe is included with this distribution.
The sub-directory verify contains five programs that have been used to test The sub-directory verify contains five programs that have been used to test
spinsim against the FPGA implementation. Approximately 150 instructions have spinsim against the FPGA implementation. Approximately 150 instructions have
been verified to match the hardware. The verify directory contains the been verified to match the hardware. The verify directory contains the
original C source code and the binary each of the five programs. It also original C source code and the output from running the test programs on the
contains the output from running the test programs on the FPGA. FPGA.
A test program can be run by going into the verify directory and typing A test program can be run by going into the verify directory and typing

View File

@ -91,7 +91,7 @@ static char *group8[] = {
"setint1", "setint2", "setint3", "setint1", "setint2", "setint3",
"setq", "setq2", "push", "pop", "jmp", "call", "calla", "callb", "setq", "setq2", "push", "pop", "jmp", "call", "calla", "callb",
"jmprel", "skip", "skipf", "execf", "getptr", "getbrk", "brk", "setluts", "jmprel", "skip", "skipf", "execf", "getptr", "getbrk", "brk", "setluts",
"setcy", "setci", "setcq", "setcfrq", "setcmod", "setpix", "setpiv", "cogatn", "setcy", "setci", "setcq", "setcfrq", "setcmod", "setpiv", "setpix", "cogatn",
"dirl", "dirh", "dirc", "dirnc", "dirz", "dirnz", "dirrnd", "dirnot", "dirl", "dirh", "dirc", "dirnc", "dirz", "dirnz", "dirrnd", "dirnot",
"outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot", "outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot",
"fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot", "fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot",

View File

@ -1670,6 +1670,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 1: // addxx, subxx case 1: // addxx, subxx
switch (opcode & 7) switch (opcode & 7)
{ {
int64_t d_result;
case 0: // add case 0: // add
result = value1 + value2; result = value1 + value2;
cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1;
@ -1683,15 +1684,27 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break; break;
case 2: // adds case 2: // adds
#ifdef OLD_SIGNED_CFLAG
result = value1 + value2; result = value1 + value2;
cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1;
#else
d_result = (int64_t)value1 + (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
zflag = (result == 0); zflag = (result == 0);
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
case 3: // addsx case 3: // addsx
#ifdef OLD_SIGNED_CFLAG
result = value1 + value2 + cflag; result = value1 + value2 + cflag;
cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; cflag = ((value1 ^ value2) & 0x80000000) ? ((result >> 31) & 1) : ((value1 >> 31) & 1);
#else
d_result = (int64_t)value1 + (int64_t)value2 + (int64_t)cflag;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
zflag = (result == 0) & zflag; zflag = (result == 0) & zflag;
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
@ -1711,15 +1724,27 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break; break;
case 6: // subs case 6: // subs
#ifdef OLD_SIGNED_CFLAG
result = value1 - value2; result = value1 - value2;
cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = (int64_t)value1 - (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
zflag = (result == 0); zflag = (result == 0);
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
case 7: // subsx case 7: // subsx
#ifdef OLD_SIGNED_CFLAG
result = value1 - value2 - cflag; result = value1 - value2 - cflag;
cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = (int64_t)value1 - (int64_t)value2 - (int64_t)cflag;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
zflag = (result == 0) & zflag; zflag = (result == 0) & zflag;
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
@ -1791,6 +1816,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 3: // fge, fle, fges, fles, sumxx case 3: // fge, fle, fges, fles, sumxx
switch (opcode & 7) switch (opcode & 7)
{ {
int64_t d_result;
case 0: // fge case 0: // fge
cflag = (((uint32_t)value1) < ((uint32_t)value2)); cflag = (((uint32_t)value1) < ((uint32_t)value2));
result = cflag ? value2 : value1; result = cflag ? value2 : value1;
@ -1812,30 +1838,54 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break; break;
case 4: // sumc case 4: // sumc
#ifdef OLD_SIGNED_CFLAG
result = cflag ? value1 - value2 : value1 + value2; result = cflag ? value1 - value2 : value1 + value2;
cflag = (~cflag) << 31; cflag = (~cflag) << 31;
cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = cflag ? (int64_t)value1 - (int64_t)value2 : (int64_t)value1 + (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
case 5: // sumnc case 5: // sumnc
#ifdef OLD_SIGNED_CFLAG
result = cflag ? value1 + value2 : value1 - value2; result = cflag ? value1 + value2 : value1 - value2;
cflag = cflag << 31; cflag = cflag << 31;
cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = cflag ? (int64_t)value1 + (int64_t)value2 : (int64_t)value1 - (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
case 6: // sumz case 6: // sumz
#ifdef OLD_SIGNED_CFLAG
result = zflag ? value1 - value2 : value1 + value2; result = zflag ? value1 - value2 : value1 + value2;
cflag = (~zflag) << 31; cflag = (~zflag) << 31;
cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = zflag ? (int64_t)value1 - (int64_t)value2 : (int64_t)value1 + (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
case 7: // sumnz case 7: // sumnz
#ifdef OLD_SIGNED_CFLAG
result = zflag ? value1 + value2 : value1 - value2; result = zflag ? value1 + value2 : value1 - value2;
cflag = zflag << 31; cflag = zflag << 31;
cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1;
#else
d_result = zflag ? (int64_t)value1 + (int64_t)value2 : (int64_t)value1 - (int64_t)value2;
result = (int32_t)d_result;
cflag = (int32_t)(d_result >> 32) & 1;
#endif
if (kludge) cflag = 0; if (kludge) cflag = 0;
break; break;
@ -2086,10 +2136,11 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 3: // signx case 3: // signx
temp = 31 - (value2 & 31); temp = 31 - (value2 & 31);
result = (value1 << temp) >> temp; result = (value1 << temp) >> temp;
cflag = (result >> 31) & 1;
break; break;
case 4: // encod case 4: // encod
cflag = (value2 == 0); cflag = (value2 != 0);
for (result = 31; result > 0; result--) for (result = 31; result > 0; result--)
{ {
if (value2 & 0x80000000) break; if (value2 & 0x80000000) break;
@ -2098,10 +2149,14 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
if (kludge) cflag = result & 1; if (kludge) cflag = result & 1;
break; break;
case 5: // ones (was anyb) case 5: // ones
result = value1 | value2; result = 0;
cflag = parity(result); for (i = 0; i < 32; i++)
write_czr &= 6; {
result += (value2 & 1);
value2 >>= 1;
}
cflag = (result & 1);
break; break;
case 6: // test case 6: // test
@ -2510,8 +2565,8 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 1: // mulpix case 1: // mulpix
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
temp = (value1 & 255) * (value2 &255); temp = (value1 & 255) * (value2 & 255);
temp += (temp + 255) >> 8; temp = (temp + 255) >> 8;
result = ((uint32_t)result >> 8) | (temp << 24); result = ((uint32_t)result >> 8) | (temp << 24);
value1 >>= 8; value1 >>= 8;
value2 >>= 8; value2 >>= 8;
@ -2523,9 +2578,17 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
dmix = (smix ^ 255); dmix = (smix ^ 255);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
#if 1
temp = (value1 & 255) * dmix; temp = (value1 & 255) * dmix;
temp += (value2 & 255) * smix; temp += (value2 & 255) * smix;
temp = (temp + 255) >> 8; temp = (temp + 255) >> 8;
#else
dmix = 256 - smix;
temp = (value1 & 255) * dmix;
temp += (value2 & 255) * smix;
temp = (temp + 255) >> 8;
if (temp > 255) temp = 255;
#endif
result = ((uint32_t)result >> 8) | (temp << 24); result = ((uint32_t)result >> 8) | (temp << 24);
value1 >>= 8; value1 >>= 8;
value2 >>= 8; value2 >>= 8;
@ -3734,12 +3797,12 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
NotImplemented(instruct); NotImplemented(instruct);
break; break;
case 61: // setpix case 61: // setpiv
pasmvars->mixpix_mode = value1 & 63; pasmvars->blnpix_var = value1 & 255;
break; break;
case 62: // setpiv case 62: // setpix
pasmvars->blnpix_var = value1 & 255; pasmvars->mixpix_mode = value1 & 63;
break; break;
case 63: // cogatn case 63: // cogatn

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ char *opcodeName[] = {
"bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitnot", "bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitnot",
"andn", "and", "or", "xor", "muxc", "muxnc", "muxz", "muxnz", "andn", "and", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
"mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz", "mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz",
"incmod", "decmod", "encod", "testn", "test", "anyb", "setnib", "getnib", "incmod", "decmod", "encod", "testn", "test", "ones", "setnib", "getnib",
"rolnib", "setbyte", "getbyte", "rolbyte", "getword", "sets", "signx", "movbyts", "rolnib", "setbyte", "getbyte", "rolbyte", "getword", "sets", "signx", "movbyts",
"muls"}; "muls"};
@ -34,10 +34,10 @@ int instruct[] = {
0x02000000, 0x02200000, 0x02400000, 0x02600000, 0x02800000, 0x02a00000, 0x02c00000, 0x02e00000, 0x02000000, 0x02200000, 0x02400000, 0x02600000, 0x02800000, 0x02a00000, 0x02c00000, 0x02e00000,
0x03000000, 0x03200000, 0x03400000, 0x03600000, 0x03800000, 0x03a00000, 0x03c00000, 0x03e00000, 0x03000000, 0x03200000, 0x03400000, 0x03600000, 0x03800000, 0x03a00000, 0x03c00000, 0x03e00000,
0x04000000, 0x04200000, 0x04400000, 0x04600000, 0x04800000, 0x04a00000, 0x04e00000, 0x04000000, 0x04200000, 0x04400000, 0x04600000, 0x04800000, 0x04a00000, 0x04e00000,
0x05000000, 0x05200000, 0x05400000, 0x05600000, 0x05800000, 0x05a00000, 0x05c00000, 0x05e00000, 0x05200000, 0x05000000, 0x05400000, 0x05600000, 0x05800000, 0x05a00000, 0x05c00000, 0x05e00000,
0x06000000, 0x06200000, 0x06400000, 0x06600000, 0x06800000, 0x06a00000, 0x06c00000, 0x06e00000, 0x06000000, 0x06200000, 0x06400000, 0x06600000, 0x06800000, 0x06a00000, 0x06c00000, 0x06e00000,
0x07000000, 0x07200000, 0x07400000, 0x07800000, 0x07a00000, 0x07c00000, 0x08000000, 0x08400000, 0x07000000, 0x07200000, 0x07800000, 0x07e00000, 0x07c00000, 0x07a00000, 0x08000000, 0x08400000,
0x08800000, 0x08c00000, 0x08e00000, 0x09000000, 0x09300000, 0x09b80000, 0x09d80000, 0x09f80000, 0x08800000, 0x08c00000, 0x08e00000, 0x09000000, 0x09300000, 0x09b80000, 0x07600000, 0x09f80000,
0x0a100000}; 0x0a100000};
int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff }; int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff };

View File

@ -33,8 +33,8 @@ int instruct[] = {
0x08800000, 0x08880000, 0x08900000, 0x08980000, 0x08a00000, 0x08a80000, 0x08b00000, 0x08b80000, 0x08800000, 0x08880000, 0x08900000, 0x08980000, 0x08a00000, 0x08a80000, 0x08b00000, 0x08b80000,
0x08c00000, 0x08c80000, 0x08d00000, 0x08d80000, 0x08e00000, 0x08e80000, 0x08f00000, 0x08f80000, 0x08c00000, 0x08c80000, 0x08d00000, 0x08d80000, 0x08e00000, 0x08e80000, 0x08f00000, 0x08f80000,
0x09000000, 0x09080000, 0x09100000, 0x09180000, 0x09200000, 0x09280000, 0x09300000, 0x09380000, 0x09000000, 0x09080000, 0x09100000, 0x09180000, 0x09200000, 0x09280000, 0x09300000, 0x09380000,
0x09400000, 0x09480000, 0x09a80000, 0x09b00000, 0x09b80000, 0x09c00000, 0x09c80000, 0x09d00000, 0x09400000, 0x09480000, 0x09a80000, 0x09b00000, 0x09b80000, 0x09c00000, 0x09c80000, 0x07400000,
0x09d80000, 0x09e00000, 0x09e80000, 0x09f80000, 0x0a080000, 0x0a180000, 0x0a400000, 0x0a480000}; 0x07600000, 0x09e00000, 0x09e80000, 0x09f80000, 0x0a080000, 0x0a180000, 0x0a400000, 0x0a480000};
int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff }; int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff };

View File

@ -13,17 +13,17 @@
#define MAX_NEG1 0x80000001 #define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000 #define WZ_BIT 0x00080000
#define WC_BIT 0x00100000 #define WC_BIT 0x00100000
#define SETQ_INSTR 0xfd601016 #define SETQ_INSTR 0xfd601028
#define SETPIX_INS 0xfd60103d #define SETPIV_INS 0xfd60103d
#define SETPIV_INS 0xfd60103e #define SETPIX_INS 0xfd60103e
#define SCLU_INSTR 0xfa20100a #define SCA_INSTR 0xfa20100a
#define SCL_INSTR 0xfa30100a #define SCAS_INSTR 0xfa30100a
void testit(int *); void testit(int *);
char *opcodeName[] = { char *opcodeName[] = {
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector", "qlog", "qexp", "qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector", "qlog", "qexp",
"muxq", "blnpix", "mixpix", "sclu", "scl" "muxq", "blnpix", "mixpix", "sca", "scas"
}; };
int instruct[] = { int instruct[] = {
@ -38,7 +38,7 @@ int dnum[] = { NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_V
int qnum[] = { 1, NUM_VALUES, NUM_VALUES, NUM_VALUES, 1, NUM_VALUES, 1, 1, int qnum[] = { 1, NUM_VALUES, NUM_VALUES, NUM_VALUES, 1, NUM_VALUES, 1, 1,
NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES}; NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES};
int inst[] = { SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, int inst[] = { SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR,
SETQ_INSTR, SETPIV_INS, SETPIX_INS, SCLU_INSTR, SCL_INSTR}; SETQ_INSTR, SETPIV_INS, SETPIX_INS, SCA_INSTR, SCAS_INSTR};
int test_values[38] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, int test_values[38] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,