URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 76 to Rev 77
- ↔ Reverse comparison
Rev 76 → Rev 77
/zipcpu/trunk/bench/cpp/div_tb.cpp
0,0 → 1,229
/////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: div_tb.cpp |
// |
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
// |
// Purpose: Bench testing for the divide unit found within the Zip CPU. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <signal.h> |
#include <time.h> |
#include <unistd.h> |
#include <assert.h> |
|
#include <ctype.h> |
|
#include "verilated.h" |
#include "Vdiv.h" |
|
#include "testb.h" |
// #include "twoc.h" |
|
class DIV_TB : public TESTB<Vdiv> { |
public: |
DIV_TB(void) { |
} |
|
~DIV_TB(void) {} |
|
void reset(void) { |
// m_flash.debug(false); |
TESTB<Vdiv>::reset(); |
} |
|
bool on_tick(void) { |
tick(); |
return true; |
} |
|
void bprint(char *str, int nbits, unsigned long v) { |
while(*str) |
str++; |
for(int i=0; i<nbits; i++) { |
if ((1l<<(nbits-1-i))&v) |
*str++ = '1'; |
else |
*str++ = '0'; |
if (((nbits-1-i)&3)==0) |
*str++ = ' '; |
} *str = '\0'; |
} |
|
void tick(void) { |
char outstr[2048], *s; |
sprintf(outstr, "Tick %4ld %s%s%s%s%s%s %2d", m_tickcount, |
(m_core->o_busy)?"B":" ", |
(m_core->o_valid)?"V":" ", |
(m_core->i_wr)?"W":" ", |
(m_core->v__DOT__pre_sign)?"+":" ", |
(m_core->v__DOT__r_sign)?"-":" ", |
(m_core->v__DOT__r_z)?"Z":" ", |
m_core->v__DOT__r_bit); s = &outstr[strlen(outstr)]; |
sprintf(s, "%s\n%10s %40s",s, "Div",""); s = &s[strlen(s)]; |
bprint( s, 32, m_core->v__DOT__r_dividend); s=&s[strlen(s)]; |
sprintf(s, "%s\n%10s ",s, "Div"); s = &s[strlen(s)]; |
bprint( s, 64, m_core->v__DOT__r_divisor); s=&s[strlen(s)]; |
sprintf(s, "%s\n%10s %40s",s, "Q",""); s=&s[strlen(s)]; |
bprint( s, 32, m_core->o_quotient); s = &s[strlen(s)]; |
sprintf(s, "%s\n%10s %38s",s, "Diff",""); s=&s[strlen(s)]; |
bprint( s, 33, m_core->v__DOT__diff); s = &s[strlen(s)]; |
strcat(s, "\n"); |
puts(outstr); |
TESTB<Vdiv>::tick(); |
} |
|
void divs(int n, int d) { |
int ans; |
ans = (d==0)?0: (n / d); |
assert(m_core->o_busy == 0); |
|
m_core->i_rst = 0; |
m_core->i_wr = 1; |
m_core->i_signed = 1; |
m_core->i_numerator = n; |
m_core->i_denominator = d; |
|
tick(); |
|
m_core->i_wr = 0; |
m_core->i_signed = 0; |
m_core->i_numerator = 0; |
m_core->i_denominator = 0; |
|
assert(m_core->o_busy); |
assert(m_core->o_valid == 0); |
|
// while((!m_core->o_valid)&&(!m_core->o_err)) |
while(!m_core->o_valid) |
tick(); |
|
printf("%s%s: %d / %d =? %d\n", |
(m_core->o_valid)?"V":" ", |
(m_core->o_err)?"E":" ", |
n, d, m_core->o_quotient); |
if ((m_core->o_err)||(d==0)) { |
if (d==0) |
assert(m_core->o_err); |
else assert(!m_core->o_err); |
} else |
assert(ans == (int)m_core->o_quotient); |
} |
|
void divu(unsigned n, unsigned d) { |
unsigned ans; |
ans = (d==0)?0: (n / d); |
assert(m_core->o_busy == 0); |
|
m_core->i_rst = 0; |
m_core->i_wr = 1; |
m_core->i_signed = 0; |
m_core->i_numerator = n; |
m_core->i_denominator = d; |
|
tick(); |
|
m_core->i_wr = 0; |
m_core->i_signed = 0; |
m_core->i_numerator = 0; |
m_core->i_denominator = 0; |
|
assert(m_core->o_busy); |
assert(m_core->o_valid == 0); |
|
while(!m_core->o_valid) |
tick(); |
|
printf("%s%s: %u / %u =? %d (Expecting %u)\n", |
(m_core->o_valid)?"V":" ", |
(m_core->o_err)?"E":" ", |
n, d, m_core->o_quotient, ans); |
if ((m_core->o_err)||(d==0)) { |
if (d==0) |
assert(m_core->o_err); |
else assert(!m_core->o_err); |
} else |
assert(ans == (unsigned)m_core->o_quotient); |
} |
|
void divide(int n, int d) { |
divs(n,d); |
} |
}; |
|
void usage(void) { |
printf("USAGE: div_tb\n"); |
printf("\n"); |
printf("\t\n"); |
} |
|
int main(int argc, char **argv) { |
Verilated::commandArgs(argc, argv); |
DIV_TB *tb = new DIV_TB(); |
int rcode = 0; |
|
tb->reset(); |
tb->divide(125,7); |
tb->tick(); |
tb->divide(125,-7); |
tb->tick(); |
tb->divu((1u<<31),7); |
tb->divu((7u<<29),(1u<<31)); |
tb->tick(); |
tb->divs(32768,0); |
tb->tick(); |
tb->divu((1u<<31),0); |
tb->tick(); |
tb->divs((1u<<30),0); |
tb->tick(); |
for(int i=32767; i>=0; i--) { |
tb->divs((1u<<30),i); |
tb->tick(); |
} for(int i=32767; i>=0; i--) { |
// tb->divu(-1, i); |
tb->divu((1u<<31), i); |
tb->tick(); |
} for(int i=32767; i>=0; i--) { |
tb->divide(32768, i); |
tb->tick(); |
} |
/* |
* While random data is a nice test idea, the following just never |
* really tested the divide unit thoroughly enough. |
* |
tb->divide(rand(),rand()/2); |
tb->tick(); |
tb->divide(rand(),rand()/2); |
tb->tick(); |
tb->divide(rand(),rand()/2); |
tb->tick(); |
tb->divide(rand(),rand()/2); |
*/ |
|
exit(rcode); |
} |
|