Line 43... |
Line 43... |
#include "Vdiv.h"
|
#include "Vdiv.h"
|
|
|
#include "testb.h"
|
#include "testb.h"
|
// #include "twoc.h"
|
// #include "twoc.h"
|
|
|
|
#define DIVASSERT(A) do { if (!(A)) { closetrace(); } assert(A); } while(0)
|
|
|
class DIV_TB : public TESTB<Vdiv> {
|
class DIV_TB : public TESTB<Vdiv> {
|
public:
|
public:
|
DIV_TB(void) {
|
DIV_TB(void) {
|
}
|
}
|
|
|
Line 55... |
Line 57... |
void reset(void) {
|
void reset(void) {
|
// m_flash.debug(false);
|
// m_flash.debug(false);
|
TESTB<Vdiv>::reset();
|
TESTB<Vdiv>::reset();
|
}
|
}
|
|
|
bool on_tick(void) {
|
|
tick();
|
|
return true;
|
|
}
|
|
|
|
void bprint(char *str, int nbits, unsigned long v) {
|
void bprint(char *str, int nbits, unsigned long v) {
|
while(*str)
|
while(*str)
|
str++;
|
str++;
|
for(int i=0; i<nbits; i++) {
|
for(int i=0; i<nbits; i++) {
|
if ((1l<<(nbits-1-i))&v)
|
if ((1l<<(nbits-1-i))&v)
|
Line 116... |
Line 113... |
void divtest(uint32_t n, uint32_t d, uint32_t ans, bool issigned) {
|
void divtest(uint32_t n, uint32_t d, uint32_t ans, bool issigned) {
|
const bool dbg = false;
|
const bool dbg = false;
|
|
|
// The test bench is supposed to assert that we are idle when
|
// The test bench is supposed to assert that we are idle when
|
// we come in here.
|
// we come in here.
|
assert(m_core->o_busy == 0);
|
DIVASSERT(m_core->o_busy == 0);
|
|
|
// Request a divide
|
// Request a divide
|
m_core->i_rst = 0;
|
m_core->i_rst = 0;
|
m_core->i_wr = 1;
|
m_core->i_wr = 1;
|
m_core->i_signed = (issigned)?1:0;
|
m_core->i_signed = (issigned)?1:0;
|
Line 139... |
Line 136... |
// Make certain busy is immediately true upon the first clock
|
// Make certain busy is immediately true upon the first clock
|
// after we issue the divide, and that our result is not also
|
// after we issue the divide, and that our result is not also
|
// listed as a valid result.
|
// listed as a valid result.
|
if (!m_core->o_busy) {
|
if (!m_core->o_busy) {
|
closetrace();
|
closetrace();
|
assert(m_core->o_busy);
|
DIVASSERT(m_core->o_busy);
|
} if (m_core->o_valid != 0) {
|
} if (m_core->o_valid != 0) {
|
closetrace();
|
closetrace();
|
assert(m_core->o_valid == 0);
|
DIVASSERT(m_core->o_valid == 0);
|
}
|
}
|
|
|
// while((!m_core->o_valid)&&(!m_core->o_err))
|
// while((!m_core->o_valid)&&(!m_core->o_err))
|
while(!m_core->o_valid) {
|
while(!m_core->o_valid) {
|
// If we aren't yet valid, we'd better at least
|
// If we aren't yet valid, we'd better at least
|
Line 154... |
Line 151... |
if (!m_core->o_busy) {
|
if (!m_core->o_busy) {
|
// We aren't valid, and we aren't busy. This
|
// We aren't valid, and we aren't busy. This
|
// is a test failure.
|
// is a test failure.
|
dbgdump();
|
dbgdump();
|
closetrace();
|
closetrace();
|
assert(m_core->o_busy);
|
DIVASSERT(m_core->o_busy);
|
}
|
}
|
|
|
// Let the algorithm work for another clock tick.
|
// Let the algorithm work for another clock tick.
|
tick();
|
tick();
|
} if (dbg) dbgdump();
|
} if (dbg) dbgdump();
|
|
|
// Insist that the core not be busy any more, now that a valid
|
// Insist that the core not be busy any more, now that a valid
|
// result has been produced.
|
// result has been produced.
|
if (m_core->o_busy) {
|
if (m_core->o_busy) {
|
closetrace();
|
closetrace();
|
assert(!m_core->o_busy);
|
DIVASSERT(!m_core->o_busy);
|
}
|
}
|
|
|
if (dbg) {
|
if (dbg) {
|
printf("%s%s: %d / %d =? %d\n",
|
printf("%s%s: %d / %d =? %d\n",
|
(m_core->o_valid)?"V":" ",
|
(m_core->o_valid)?"V":" ",
|
Line 189... |
Line 186... |
if (!m_core->o_err) {
|
if (!m_core->o_err) {
|
// Don't forget to close the trace before the
|
// Don't forget to close the trace before the
|
// assert, lest the file not get the final
|
// assert, lest the file not get the final
|
// values into it.
|
// values into it.
|
closetrace();
|
closetrace();
|
assert(m_core->o_err);
|
DIVASSERT(m_core->o_err);
|
}
|
}
|
} else if (m_core->o_err) {
|
} else if (m_core->o_err) {
|
// Otherwise, there should not have been any divide
|
// Otherwise, there should not have been any divide
|
// errors. The only errors allowed should be the
|
// errors. The only errors allowed should be the
|
// divide by zero. So, this is an error. Let's
|
// divide by zero. So, this is an error. Let's
|
// stop and report it.
|
// stop and report it.
|
closetrace();
|
closetrace();
|
assert(!m_core->o_err);
|
DIVASSERT(!m_core->o_err);
|
} else if (ans != (uint32_t)m_core->o_quotient) {
|
} else if (ans != (uint32_t)m_core->o_quotient) {
|
// The other problem we might encounter would be if the
|
// The other problem we might encounter would be if the
|
// result doesn't match the one we are expecting.
|
// result doesn't match the one we are expecting.
|
//
|
//
|
// Stop on this bug as well.
|
// Stop on this bug as well.
|
//
|
//
|
closetrace();
|
closetrace();
|
assert(ans == (uint32_t)m_core->o_quotient);
|
DIVASSERT(ans == (uint32_t)m_core->o_quotient);
|
|
}
|
|
|
|
if(((m_core->o_quotient == 0)&&((m_core->o_flags&1)==0))
|
|
||((m_core->o_quotient!= 0)&&((m_core->o_flags&1)!=0))){
|
|
fprintf(stderr, "Z-FLAG DOES NOT MATCH: FLAGS = %d, QUOTIENT = %08x\n", m_core->o_flags, m_core->o_quotient);
|
|
DIVASSERT((m_core->o_quotient!= 0)^(m_core->o_flags&1));
|
}
|
}
|
}
|
}
|
|
|
// Test a signed divide
|
// Test a signed divide
|
void divs(int n, int d) {
|
void divs(int n, int d) {
|
Line 252... |
Line 255... |
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
// Setup
|
// Setup
|
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
DIV_TB *tb = new DIV_TB();
|
DIV_TB *tb = new DIV_TB();
|
|
|
// tb->opentrace("divtrace.vcd");
|
|
|
|
tb->reset();
|
tb->reset();
|
// tb->opentrace("div_tb.vcd");
|
// tb->opentrace("div_tb.vcd");
|
|
|
// Now we're ready. All we need to do to test the divide of two
|
// Now we're ready. All we need to do to test the divide of two
|
// numbers is to call the respective divide(), divs(), or divu()
|
// numbers is to call the respective divide(), divs(), or divu()
|