OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [cpp/] [div_tb.cpp] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 77 dgisselq
///////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    div_tb.cpp
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     Bench testing for the divide unit found within the Zip CPU.
8
//
9
//
10
// Creator:     Dan Gisselquist, Ph.D.
11
//              Gisselquist Technology, LLC
12
//
13
///////////////////////////////////////////////////////////////////////////////
14
//
15
// Copyright (C) 2015, Gisselquist Technology, LLC
16
//
17
// This program is free software (firmware): you can redistribute it and/or
18
// modify it under the terms of  the GNU General Public License as published
19
// by the Free Software Foundation, either version 3 of the License, or (at
20
// your option) any later version.
21
//
22
// This program is distributed in the hope that it will be useful, but WITHOUT
23
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
24
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
// for more details.
26
//
27
// License:     GPL, v3, as defined and found on www.gnu.org,
28
//              http://www.gnu.org/licenses/gpl.html
29
//
30
//
31
///////////////////////////////////////////////////////////////////////////////
32
//
33
//
34
#include <signal.h>
35
#include <time.h>
36
#include <unistd.h>
37
#include <assert.h>
38
 
39
#include <ctype.h>
40
 
41
#include "verilated.h"
42
#include "Vdiv.h"
43
 
44
#include "testb.h"
45
// #include "twoc.h"
46
 
47
class   DIV_TB : public TESTB<Vdiv> {
48
public:
49
        DIV_TB(void) {
50
        }
51
 
52
        ~DIV_TB(void) {}
53
 
54
        void    reset(void) {
55
                // m_flash.debug(false);
56
                TESTB<Vdiv>::reset();
57
        }
58
 
59
        bool    on_tick(void) {
60
                tick();
61
                return true;
62
        }
63
 
64
        void    bprint(char *str, int nbits, unsigned long v) {
65
                while(*str)
66
                        str++;
67
                for(int i=0; i<nbits; i++) {
68
                        if ((1l<<(nbits-1-i))&v)
69
                                *str++ = '1';
70
                        else
71
                                *str++ = '0';
72
                        if (((nbits-1-i)&3)==0)
73
                                *str++ = ' ';
74
                } *str = '\0';
75
        }
76
 
77 154 dgisselq
        void    dbgdump(void) {
78
                char    outstr[2048], *s;
79
                sprintf(outstr, "Tick %4ld %s%s%s%s%s%s%s %2d(%s= 0)",
80
                        m_tickcount,
81
                        (m_core->o_busy)?"B":" ",
82
                        (m_core->v__DOT__r_busy)?"R":" ",
83
                        (m_core->o_valid)?"V":" ",
84
                        (m_core->i_wr)?"W":" ",
85
                        (m_core->v__DOT__pre_sign)?"+":" ",
86
                        (m_core->v__DOT__r_sign)?"-":" ",
87
                        (m_core->v__DOT__r_z)?"Z":" ",
88
                        m_core->v__DOT__r_bit,
89
                        (m_core->v__DOT__last_bit)?"=":"!");
90
                s = &outstr[strlen(outstr)];
91
                sprintf(s, "%s\n%10s %40s",s, "Div","");
92
                        s = &s[strlen(s)];
93
                bprint( s, 32, m_core->v__DOT__r_dividend);
94
                        s=&s[strlen(s)];
95
                sprintf(s, "%s\n%10s ",s, "Div"); s = &s[strlen(s)];
96
                bprint( s, 64, m_core->v__DOT__r_divisor);
97
                        s=&s[strlen(s)];
98
                sprintf(s, "%s\n%10s %40s",s, "Q",""); s=&s[strlen(s)];
99
                bprint( s, 32, m_core->o_quotient); s = &s[strlen(s)];
100
                sprintf(s, "%s\n%10s %38s",s, "Diff","");
101
                        s=&s[strlen(s)];
102
                bprint( s, 33, m_core->v__DOT__diff); s = &s[strlen(s)];
103
                strcat(s, "\n");
104
                puts(outstr);
105
        }
106
 
107 77 dgisselq
        void    tick(void) {
108 147 dgisselq
                bool    debug = false;
109
 
110 154 dgisselq
                if (debug)
111
                        dbgdump();
112 77 dgisselq
                TESTB<Vdiv>::tick();
113
        }
114
 
115
        void    divs(int n, int d) {
116 147 dgisselq
                bool    dbg = false;
117 77 dgisselq
                int     ans;
118
                ans = (d==0)?0:   (n / d);
119
                assert(m_core->o_busy == 0);
120
 
121
                m_core->i_rst = 0;
122
                m_core->i_wr = 1;
123
                m_core->i_signed = 1;
124
                m_core->i_numerator = n;
125
                m_core->i_denominator = d;
126
 
127
                tick();
128
 
129
                m_core->i_wr = 0;
130
                m_core->i_signed = 0;
131
                m_core->i_numerator = 0;
132
                m_core->i_denominator = 0;
133
 
134 154 dgisselq
                // Make certain busy is immediately true upon the first clock
135
                // after we issue the divide.
136 77 dgisselq
                assert(m_core->o_busy);
137
                assert(m_core->o_valid == 0);
138
 
139
                // while((!m_core->o_valid)&&(!m_core->o_err))
140 154 dgisselq
                while(!m_core->o_valid) {
141
                        if (!m_core->o_busy) {
142
                                // Make certain busy is asserted whenever
143
                                // valid is false and we're ... well, busy
144
                                dbgdump();
145
                                assert(m_core->o_busy);
146
                        }
147 77 dgisselq
                        tick();
148 154 dgisselq
                } if (dbg) dbgdump();
149
                assert(!m_core->o_busy);
150 77 dgisselq
 
151 147 dgisselq
                if (dbg) {
152
                        printf("%s%s: %d / %d =? %d\n",
153
                                (m_core->o_valid)?"V":" ",
154
                                (m_core->o_err)?"E":" ",
155
                                n, d, m_core->o_quotient);
156
                }
157 77 dgisselq
                if ((m_core->o_err)||(d==0)) {
158
                        if (d==0)
159
                                assert(m_core->o_err);
160
                        else    assert(!m_core->o_err);
161
                } else
162
                        assert(ans == (int)m_core->o_quotient);
163
        }
164
 
165
        void    divu(unsigned n, unsigned d) {
166 147 dgisselq
                bool    dbg = false;
167 77 dgisselq
                unsigned        ans;
168
                ans = (d==0)?0:   (n / d);
169
                assert(m_core->o_busy == 0);
170
 
171
                m_core->i_rst = 0;
172
                m_core->i_wr = 1;
173
                m_core->i_signed = 0;
174
                m_core->i_numerator = n;
175
                m_core->i_denominator = d;
176
 
177
                tick();
178
 
179
                m_core->i_wr = 0;
180
                m_core->i_signed = 0;
181
                m_core->i_numerator = 0;
182
                m_core->i_denominator = 0;
183
 
184
                assert(m_core->o_busy);
185
                assert(m_core->o_valid == 0);
186
 
187 154 dgisselq
                while(!m_core->o_valid) {
188
                        assert(m_core->o_busy);
189 77 dgisselq
                        tick();
190 154 dgisselq
                } assert(!m_core->o_busy);
191 77 dgisselq
 
192 147 dgisselq
                if (dbg) {
193
                        printf("%s%s: %u / %u =? %d (Expecting %u)\n",
194
                                (m_core->o_valid)?"V":" ",
195
                                (m_core->o_err)?"E":" ",
196
                                n, d, m_core->o_quotient, ans);
197
                }
198 77 dgisselq
                if ((m_core->o_err)||(d==0)) {
199
                        if (d==0)
200
                                assert(m_core->o_err);
201
                        else    assert(!m_core->o_err);
202
                } else
203
                        assert(ans == (unsigned)m_core->o_quotient);
204
        }
205
 
206
        void    divide(int n, int d) {
207
                divs(n,d);
208
        }
209
};
210
 
211
void    usage(void) {
212
        printf("USAGE: div_tb\n");
213
        printf("\n");
214
        printf("\t\n");
215
}
216
 
217
int     main(int argc, char **argv) {
218
        Verilated::commandArgs(argc, argv);
219
        DIV_TB  *tb = new DIV_TB();
220 147 dgisselq
        int     rcode = EXIT_SUCCESS;
221 77 dgisselq
 
222
        tb->reset();
223
        tb->divide(125,7);
224
        tb->tick();
225
        tb->divide(125,-7);
226
        tb->tick();
227
        tb->divu((1u<<31),7);
228
        tb->divu((7u<<29),(1u<<31));
229
        tb->tick();
230
        tb->divs(32768,0);
231
        tb->tick();
232
        tb->divu((1u<<31),0);
233
        tb->tick();
234
        tb->divs((1u<<30),0);
235
        tb->tick();
236
        for(int i=32767; i>=0; i--) {
237
                tb->divs((1u<<30),i);
238
                tb->tick();
239
        } for(int i=32767; i>=0; i--) {
240
                // tb->divu(-1, i);
241
                tb->divu((1u<<31), i);
242
                tb->tick();
243
        } for(int i=32767; i>=0; i--) {
244
                tb->divide(32768, i);
245
                tb->tick();
246
        }
247
        /*
248
         * While random data is a nice test idea, the following just never
249
         * really tested the divide unit thoroughly enough.
250
         *
251
        tb->divide(rand(),rand()/2);
252
        tb->tick();
253
        tb->divide(rand(),rand()/2);
254
        tb->tick();
255
        tb->divide(rand(),rand()/2);
256
        tb->tick();
257
        tb->divide(rand(),rand()/2);
258
        */
259
 
260 147 dgisselq
        printf("SUCCESS!\n");
261 77 dgisselq
        exit(rcode);
262
}
263
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.