Fixes to make the verify tests match FPGA v32b
This commit is contained in:
parent
1b0c107390
commit
3b728bd09e
12
README.md
12
README.md
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
87
pasmsim2.c
87
pasmsim2.c
|
@ -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
|
||||
|
|
3386
verify/testhdw.txt
3386
verify/testhdw.txt
File diff suppressed because it is too large
Load Diff
2048
verify/testhdwq.txt
2048
verify/testhdwq.txt
File diff suppressed because it is too large
Load Diff
|
@ -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 };
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue