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
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:
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin
setbrk setcy setci setcq setcfrq setcmod getrnd xoro32
skip skipf execf
xzero xinit xcont hubset setdacs setxfrq getxacc getbrk
cogbrk brk setcy setci setcq setcfrq setcmod getrnd
xoro32 skip skipf execf
skip, skipf and execf have been partially implemented, but do not handle jumps
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
spinsim against the FPGA implementation. Approximately 150 instructions have
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
contains the output from running the test programs on the FPGA.
original C source code and the output from running the test programs on the
FPGA.
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",
"setq", "setq2", "push", "pop", "jmp", "call", "calla", "callb",
"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",
"outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot",
"fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot",

View File

@ -1670,6 +1670,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 1: // addxx, subxx
switch (opcode & 7)
{
int64_t d_result;
case 0: // add
result = value1 + value2;
cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1;
@ -1683,15 +1684,27 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break;
case 2: // adds
#ifdef OLD_SIGNED_CFLAG
result = value1 + value2;
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);
if (kludge) cflag = 0;
break;
case 3: // addsx
#ifdef OLD_SIGNED_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;
if (kludge) cflag = 0;
break;
@ -1711,15 +1724,27 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break;
case 6: // subs
#ifdef OLD_SIGNED_CFLAG
result = value1 - value2;
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);
if (kludge) cflag = 0;
break;
case 7: // subsx
#ifdef OLD_SIGNED_CFLAG
result = value1 - value2 - cflag;
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;
if (kludge) cflag = 0;
break;
@ -1791,6 +1816,7 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 3: // fge, fle, fges, fles, sumxx
switch (opcode & 7)
{
int64_t d_result;
case 0: // fge
cflag = (((uint32_t)value1) < ((uint32_t)value2));
result = cflag ? value2 : value1;
@ -1812,30 +1838,54 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
break;
case 4: // sumc
#ifdef OLD_SIGNED_CFLAG
result = cflag ? value1 - value2 : value1 + value2;
cflag = (~cflag) << 31;
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;
break;
case 5: // sumnc
#ifdef OLD_SIGNED_CFLAG
result = cflag ? value1 + value2 : value1 - value2;
cflag = cflag << 31;
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;
break;
case 6: // sumz
#ifdef OLD_SIGNED_CFLAG
result = zflag ? value1 - value2 : value1 + value2;
cflag = (~zflag) << 31;
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;
break;
case 7: // sumnz
#ifdef OLD_SIGNED_CFLAG
result = zflag ? value1 + value2 : value1 - value2;
cflag = zflag << 31;
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;
break;
@ -2086,10 +2136,11 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 3: // signx
temp = 31 - (value2 & 31);
result = (value1 << temp) >> temp;
cflag = (result >> 31) & 1;
break;
case 4: // encod
cflag = (value2 == 0);
cflag = (value2 != 0);
for (result = 31; result > 0; result--)
{
if (value2 & 0x80000000) break;
@ -2098,10 +2149,14 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
if (kludge) cflag = result & 1;
break;
case 5: // ones (was anyb)
result = value1 | value2;
cflag = parity(result);
write_czr &= 6;
case 5: // ones
result = 0;
for (i = 0; i < 32; i++)
{
result += (value2 & 1);
value2 >>= 1;
}
cflag = (result & 1);
break;
case 6: // test
@ -2510,8 +2565,8 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
case 1: // mulpix
for (i = 0; i < 4; i++)
{
temp = (value1 & 255) * (value2 &255);
temp += (temp + 255) >> 8;
temp = (value1 & 255) * (value2 & 255);
temp = (temp + 255) >> 8;
result = ((uint32_t)result >> 8) | (temp << 24);
value1 >>= 8;
value2 >>= 8;
@ -2523,9 +2578,17 @@ int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars)
dmix = (smix ^ 255);
for (i = 0; i < 4; i++)
{
#if 1
temp = (value1 & 255) * dmix;
temp += (value2 & 255) * smix;
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);
value1 >>= 8;
value2 >>= 8;
@ -3734,12 +3797,12 @@ if (streamflag) printf("\nSTREAM COLLISION\n");
NotImplemented(instruct);
break;
case 61: // setpix
pasmvars->mixpix_mode = value1 & 63;
case 61: // setpiv
pasmvars->blnpix_var = value1 & 255;
break;
case 62: // setpiv
pasmvars->blnpix_var = value1 & 255;
case 62: // setpix
pasmvars->mixpix_mode = value1 & 63;
break;
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",
"andn", "and", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
"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",
"muls"};
@ -34,10 +34,10 @@ int instruct[] = {
0x02000000, 0x02200000, 0x02400000, 0x02600000, 0x02800000, 0x02a00000, 0x02c00000, 0x02e00000,
0x03000000, 0x03200000, 0x03400000, 0x03600000, 0x03800000, 0x03a00000, 0x03c00000, 0x03e00000,
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,
0x07000000, 0x07200000, 0x07400000, 0x07800000, 0x07a00000, 0x07c00000, 0x08000000, 0x08400000,
0x08800000, 0x08c00000, 0x08e00000, 0x09000000, 0x09300000, 0x09b80000, 0x09d80000, 0x09f80000,
0x07000000, 0x07200000, 0x07800000, 0x07e00000, 0x07c00000, 0x07a00000, 0x08000000, 0x08400000,
0x08800000, 0x08c00000, 0x08e00000, 0x09000000, 0x09300000, 0x09b80000, 0x07600000, 0x09f80000,
0x0a100000};
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,
0x08c00000, 0x08c80000, 0x08d00000, 0x08d80000, 0x08e00000, 0x08e80000, 0x08f00000, 0x08f80000,
0x09000000, 0x09080000, 0x09100000, 0x09180000, 0x09200000, 0x09280000, 0x09300000, 0x09380000,
0x09400000, 0x09480000, 0x09a80000, 0x09b00000, 0x09b80000, 0x09c00000, 0x09c80000, 0x09d00000,
0x09d80000, 0x09e00000, 0x09e80000, 0x09f80000, 0x0a080000, 0x0a180000, 0x0a400000, 0x0a480000};
0x09400000, 0x09480000, 0x09a80000, 0x09b00000, 0x09b80000, 0x09c00000, 0x09c80000, 0x07400000,
0x07600000, 0x09e00000, 0x09e80000, 0x09f80000, 0x0a080000, 0x0a180000, 0x0a400000, 0x0a480000};
int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff };

View File

@ -13,17 +13,17 @@
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
#define SETQ_INSTR 0xfd601016
#define SETPIX_INS 0xfd60103d
#define SETPIV_INS 0xfd60103e
#define SCLU_INSTR 0xfa20100a
#define SCL_INSTR 0xfa30100a
#define SETQ_INSTR 0xfd601028
#define SETPIV_INS 0xfd60103d
#define SETPIX_INS 0xfd60103e
#define SCA_INSTR 0xfa20100a
#define SCAS_INSTR 0xfa30100a
void testit(int *);
char *opcodeName[] = {
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector", "qlog", "qexp",
"muxq", "blnpix", "mixpix", "sclu", "scl"
"muxq", "blnpix", "mixpix", "sca", "scas"
};
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,
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,
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,
4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,