Line 42... |
Line 42... |
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdint.h>
|
#include <stdint.h>
|
|
|
#include "Vqtrstage.h"
|
#include "Vqtrstage.h"
|
#include "verilated.h"
|
#include "verilated.h"
|
|
#include "twoc.h"
|
|
|
#define IWIDTH 16
|
#define IWIDTH 16
|
#define OWIDTH (IWIDTH+1)
|
#define OWIDTH (IWIDTH+1)
|
#define LGWIDTH 8
|
#define LGWIDTH 8
|
|
|
void tick(Vqtrstage *qstage) {
|
#define ASIZ 32
|
qstage->i_clk = 0;
|
#define AMSK (ASIZ-1)
|
qstage->eval();
|
|
qstage->i_clk = 1;
|
class QTRTEST_TB {
|
qstage->eval();
|
public:
|
|
Vqtrstage *m_qstage;
|
|
unsigned long m_data[ASIZ];
|
|
int m_addr, m_offset;
|
|
bool m_syncd;
|
|
|
|
QTRTEST_TB(void) {
|
|
m_qstage = new Vqtrstage;
|
|
m_addr = 0; m_offset = 6; m_syncd = false;
|
}
|
}
|
|
|
void reset(Vqtrstage *qstage) {
|
void tick(void) {
|
qstage->i_ce = 0;
|
m_qstage->i_clk = 0;
|
qstage->i_rst = 1;
|
m_qstage->eval();
|
tick(qstage);
|
m_qstage->i_clk = 1;
|
qstage->i_ce = 0;
|
m_qstage->eval();
|
qstage->i_rst = 0;
|
|
tick(qstage);
|
m_qstage->i_sync = 0;
|
}
|
}
|
|
|
int main(int argc, char **argv, char **envp) {
|
void reset(void) {
|
Verilated::commandArgs(argc, argv);
|
m_qstage->i_ce = 0;
|
Vqtrstage *qstage = new Vqtrstage;
|
m_qstage->i_rst = 1;
|
int16_t ir0, ii0, lstr, lsti;
|
tick();
|
int32_t sumr, sumi, difr, difi;
|
m_qstage->i_ce = 0;
|
int32_t smr, smi, dfr, dfi;
|
m_qstage->i_rst = 0;
|
int rnd = 0; // Can only be set to true if OWIDTH=IWIDTH
|
tick();
|
|
|
if ((OWIDTH<IWIDTH+1)&&(rnd!=0)) {
|
m_addr = 0; m_offset = 6; m_syncd = false;
|
fprintf(stderr, "ERR: Rounding can only be applied when\n");
|
|
fprintf(stderr, "\tthe output width is less than or equal\n");
|
|
fprintf(stderr, "\tto the input width. Turn rounding off\n");
|
|
fprintf(stderr, "\trebuild, and try again.\n");
|
|
assert(0 == rnd);
|
|
}
|
}
|
|
|
reset(qstage);
|
void check_results(void) {
|
|
int ir0, ii0, ir1, ii1, ir2, ii2;
|
|
int sumr, sumi, difr, difi, or0, oi0;
|
|
bool fail = false;
|
|
|
for(int k=0; k<1060; k++) {
|
if ((!m_syncd)&&(m_qstage->o_sync)) {
|
int32_t or0, oi0, or1, oi1;
|
m_syncd = true;
|
|
m_offset = m_addr;
|
|
}
|
|
|
qstage->i_ce = 1;
|
if (!m_syncd)
|
qstage->i_sync = ((k&0x0ff)==0);
|
return;
|
// Let's pick some random values, ...
|
|
ir0 = rand(); if (ir0&4) ir0 = -ir0;
|
ir0 = sbits(m_data[(m_addr-m_offset-1)&AMSK]>>IWIDTH, IWIDTH);
|
ii0 = rand(); if (ii0&2) ii0 = -ii0;
|
ii0 = sbits(m_data[(m_addr-m_offset-1)&AMSK], IWIDTH);
|
|
ir1 = sbits(m_data[(m_addr-m_offset )&AMSK]>>IWIDTH, IWIDTH);
|
|
ii1 = sbits(m_data[(m_addr-m_offset )&AMSK], IWIDTH);
|
|
ir2 = sbits(m_data[(m_addr-m_offset+1)&AMSK]>>IWIDTH, IWIDTH);
|
|
ii2 = sbits(m_data[(m_addr-m_offset+1)&AMSK], IWIDTH);
|
|
|
|
sumr = ir1 + ir2;
|
|
sumi = ii1 + ii2;
|
|
difr = ir0 - ir1;
|
|
difi = ii0 - ii1;
|
|
|
|
or0 = sbits(m_qstage->o_data >> OWIDTH, OWIDTH);
|
|
oi0 = sbits(m_qstage->o_data, OWIDTH);
|
|
|
qstage->i_data = ((ir0&0x0ffff) << 16) | (ii0 & 0x0ffff);
|
if (0==((m_addr-m_offset)&1)) {
|
tick(qstage);
|
if (or0 != sumr) {
|
|
printf("FAIL 1: or0 != sumr (%x(exp) != %x(sut))\n", sumr, or0); fail = true;}
|
|
if (oi0 != sumi) {
|
|
printf("FAIL 2: oi0 != sumi (%x(exp) != %x(sut))\n", sumi, oi0); fail = true;}
|
|
} else if (1==((m_addr-m_offset)&1)) {
|
|
if (or0 != difr) {
|
|
printf("FAIL 3: or0 != difr (%x(exp) != %x(sut))\n", difr, or0); fail = true;}
|
|
if (oi0 != difi) {
|
|
printf("FAIL 4: oi0 != difi (%x(exp) != %x(sut))\n", difi, oi0); fail = true;}
|
|
}
|
|
|
printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\n",
|
if (m_qstage->o_sync != ((((m_addr-m_offset)&127) == 0)?1:0)) {
|
k, qstage->i_sync, qstage->i_data,
|
printf("BAD O-SYNC, m_addr = %d, m_offset = %d\n", m_addr, m_offset); fail = true;
|
qstage->o_data, qstage->o_sync);
|
}
|
|
|
or0 = (qstage->o_data >> 17) & 0x01ffff;
|
if (fail)
|
oi0 = qstage->o_data & 0x01ffff;
|
exit(-1);
|
if (or0 & 0x010000) or0 |= (-1<<16);
|
}
|
if (oi0 & 0x010000) oi0 |= (-1<<16);
|
|
|
|
if (k>3) {
|
void sync(void) {
|
/*
|
m_qstage->i_sync = 1;
|
printf("\tOR0 = %6x, OI0 = %6x, SUM = %6x + %6x, DIF = %6x + %6x\n",
|
m_addr = 0;
|
or0, oi0, sumr, sumi, difr, difi);
|
|
*/
|
|
if (0==(k&1)) {
|
|
if (or0 != sumr) {fprintf(stderr, "FAIL 1\n"); exit(-1);}
|
|
if (oi0 != sumi) {fprintf(stderr, "FAIL 2\n"); exit(-1);}
|
|
} else if (1==(k&1)) {
|
|
if (or0 != difr) {fprintf(stderr, "FAIL 3\n"); exit(-1);}
|
|
if (oi0 != difi) {fprintf(stderr, "FAIL 4\n"); exit(-1);}
|
|
}
|
}
|
|
|
|
void test(unsigned int data) {
|
|
int isync = m_qstage->i_sync;
|
|
m_qstage->i_ce = 1;
|
|
m_qstage->i_data = data;
|
|
// m_qstage->i_sync = (((m_addr&127)==2)?1:0);
|
|
m_data[ (m_addr++)&AMSK] = data;
|
|
tick();
|
|
|
|
printf("k=%4d: ISYNC=%d, IN = %08x, OUT =%09lx, SYNC=%d\t%5x,%5x,%5x,%5x\t%x %4x %8x %d\n",
|
|
(m_addr-m_offset), isync, m_qstage->i_data,
|
|
m_qstage->o_data, m_qstage->o_sync,
|
|
m_qstage->v__DOT__sum_r,
|
|
m_qstage->v__DOT__sum_i,
|
|
m_qstage->v__DOT__diff_r,
|
|
m_qstage->v__DOT__diff_i,
|
|
m_qstage->v__DOT__pipeline,
|
|
m_qstage->v__DOT__iaddr,
|
|
m_qstage->v__DOT__imem,
|
|
m_qstage->v__DOT__wait_for_sync);
|
|
|
|
check_results();
|
}
|
}
|
|
|
if (((4==(k&0x07f))?1:0) != qstage->o_sync) { fprintf(stderr, "BAD O-SYNC\n"); exit(-1); }
|
void test(int ir0, int ii0) {
|
|
unsigned int data;
|
|
|
if (1 == (k&1)) {
|
data = (((ir0&((1<<IWIDTH)-1)) << IWIDTH) | (ii0 & ((1<<IWIDTH)-1)));
|
sumr = smr; sumi = smi; difr=dfr, difi= dfi;
|
// printf("%d,%d -> %8x\n", ir0, ii0, data);
|
|
test(data);
|
|
}
|
|
|
smr = lstr + ir0 + rnd;
|
void random_test(void) {
|
smi = lsti + ii0 + rnd;
|
int ir0, ii0;
|
|
|
dfr = lstr - ir0 + rnd;
|
// Let's pick some random values
|
dfi = lsti - ii0 + rnd;
|
ir0 = rand(); if (ir0&4) ir0 = -ir0;
|
|
ii0 = rand(); if (ii0&2) ii0 = -ii0;
|
|
test(ir0, ii0);
|
}
|
}
|
|
};
|
|
|
|
int main(int argc, char **argv, char **envp) {
|
|
Verilated::commandArgs(argc, argv);
|
|
QTRTEST_TB *tb = new QTRTEST_TB;
|
|
int16_t ir0, ii0, ir1, ii1, ir2, ii2;
|
|
int32_t sumr, sumi, difr, difi;
|
|
|
lstr = ir0;
|
tb->reset();
|
lsti = ii0;
|
|
|
tb->test( 16, 0);
|
|
tb->test( 16, 0);
|
|
tb->sync();
|
|
tb->test( 0, 16);
|
|
tb->test( 0, 16);
|
|
tb->test( 16, 0);
|
|
tb->test(-16, 0);
|
|
tb->test( 0, 16);
|
|
tb->test( 0,-16);
|
|
|
|
for(int k=0; k<1060; k++) {
|
|
tb->random_test();
|
}
|
}
|
|
|
delete qstage;
|
delete tb;
|
|
|
printf("SUCCESS!\n");
|
printf("SUCCESS!\n");
|
exit(0);
|
exit(0);
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
|
|
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|