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

Subversion Repositories fpu

[/] [fpu/] [trunk/] [test_bench/] [test_top.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rudi
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  FPU                                                        ////
4
////  Floating Point Unit (Single precision)                     ////
5
////                                                             ////
6
////  TEST BENCH                                                 ////
7
////                                                             ////
8
////  Author: Rudolf Usselmann                                   ////
9
////          rudi@asics.ws                                      ////
10
////                                                             ////
11
/////////////////////////////////////////////////////////////////////
12
////                                                             ////
13
//// Copyright (C) 2000 Rudolf Usselmann                         ////
14
////                    rudi@asics.ws                            ////
15
////                                                             ////
16
//// This source file may be used and distributed without        ////
17
//// restriction provided that this copyright statement is not   ////
18
//// removed from the file and that any derivative work contains ////
19
//// the original copyright notice and the associated disclaimer.////
20
////                                                             ////
21
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
22
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
23
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
24
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
25
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
26
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
27
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
28
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
29
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
30
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
31
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
32
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
33
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
34
////                                                             ////
35
/////////////////////////////////////////////////////////////////////
36
 
37
 
38
`timescale 1ns / 100ps
39
 
40
module test;
41
 
42
reg             clk;
43
reg     [31:0]   opa;
44
reg     [31:0]   opb;
45
wire    [31:0]   sum;
46
wire            inf, snan, qnan;
47
wire            div_by_zero;
48
 
49
reg     [31:0]   exp, exp1, exp2, exp3, exp4;
50
reg     [31:0]   opa1, opa2, opa3, opa4;
51
reg     [31:0]   opb1, opb2, opb3, opb4;
52
reg     [2:0]    fpu_op, fpu_op1, fpu_op2, fpu_op3, fpu_op4, fpu_op5;
53
reg     [3:0]    rmode, rmode1, rmode2, rmode3, rmode4, rmode5;
54
reg             start, s1, s2, s3, s4;
55
reg     [111:0]  tmem[0:500000];
56
reg     [111:0]  tmp;
57
reg     [3:0]    oper;
58
reg     [7:0]    exc, exc1, exc2, exc3, exc4;
59
integer         i;
60
wire            ine;
61
reg             match;
62
wire            overflow, underflow;
63
wire            zero;
64
reg             exc_err;
65
reg             m0, m1, m2;
66
reg     [1:0]    fpu_rmode;
67
reg     [3:0]    test_rmode;
68
reg     [4:0]    test_sel;
69
reg             fp_fasu;
70
reg             fp_mul;
71
reg             fp_div;
72
reg             fp_combo;
73
reg             test_exc;
74
reg             show_prog;
75
event           error_event;
76
 
77
integer         error, vcount;
78
 
79
always #50 clk = ~clk;
80
 
81
initial
82
   begin
83
        $display ("\n\nFloating Point Unit Version 1.5\n\n");
84
        clk = 0;
85
        start = 0;
86
        s1 = 0;
87
        s2 = 0;
88
        s3 = 0;
89
        s4 = 0;
90
        error = 0;
91
        vcount = 0;
92
 
93
        show_prog = 0;
94
        fp_combo = 1;
95
        fp_fasu  = 1;
96
        fp_mul   = 1;
97
        fp_div   = 1;
98
        test_exc = 1;
99
        test_sel   = 5'b00110;
100
        test_rmode = 4'b0101;
101
 
102
        //test_sel   = 5'b00110;
103
        //test_rmode = 4'b01110;
104
 
105
        test_sel   = 5'b11111;
106
        test_rmode = 4'b1111;
107
 
108
        @(posedge clk);
109
 
110
`include "test_bench/sel_test.vh"
111
 
112
        repeat (4)      @(posedge clk);
113
        $display("\n\n");
114
 
115
        $display("\n\nAll test Done !\n\n");
116
        $display("Run %0d vecors, found %0d errors.\n\n",vcount, error);
117
 
118
        $finish;
119
   end
120
 
121
 
122
task run_test;
123
begin
124
        @(posedge clk);
125
        #1;
126
        opa = 32'hx;
127
        opb = 32'hx;
128
        fpu_rmode = 2'hx;
129
        fpu_op = 2'hx;
130
 
131
        repeat(4) @(posedge clk);
132
        #1;
133
 
134
        oper = 1;
135
        i=0;
136
        while( |oper == 1'b1 )
137
           begin
138
 
139
                @(posedge clk);
140
                #1;
141
                start = 1;
142
                tmp   = tmem[i];
143
                rmode = tmp[111:108];
144
                exc   = tmp[107:100];
145
                oper  = tmp[99:96];
146
                opa   = tmp[95:64];
147
                opb   = tmp[63:32];
148
                exp   = tmp[31:00];
149
 
150
                // FPU rounding mode
151
                //  0:  float_round_nearest_even
152
                //  1:  float_round_down
153
                //  2:  float_round_up
154
                //  3:  float_round_to_zero
155
 
156
                case(rmode)
157
                  0: fpu_rmode = 0;
158
                  1: fpu_rmode = 3;
159
                  2: fpu_rmode = 2;
160
                  3: fpu_rmode = 1;
161
                  default: fpu_rmode=2'hx;
162
                endcase
163
 
164
                // oper fpu operation
165
                //   1   add
166
                //   2   sub
167
                //   4   mul
168
                //   8   div
169
 
170
                case(oper)
171
                   1:   fpu_op=3'b000;  // Add
172
                   2:   fpu_op=3'b001;  // Sub
173
                   4:   fpu_op=3'b010;  // Mul
174
                   8:   fpu_op=3'b011;  // Div
175
                   default: fpu_op=3'bx;
176
                endcase
177
 
178
                if(show_prog)   $write("Vector: %d\015",i);
179
 
180
                //if(oper==1)   $write("+");
181
                //else
182
                //if(oper==2)   $write("-");
183
                //else
184
                //if(oper==4)   $write("*");
185
                //else
186
                //if(oper==8)   $write("/");
187
                //else          $write("Unknown Operation (%d)",oper);
188
 
189
                i= i+1;
190
           end
191
        start = 0;
192
 
193
        @(posedge clk);
194
        #1;
195
        opa = 32'hx;
196
        opb = 32'hx;
197
        fpu_rmode = 2'hx;
198
        fpu_op = 2'hx;
199
 
200
        repeat(4) @(posedge clk);
201
        #1;
202
 
203
        for(i=0;i<500000;i=i+1)          // Clear Memory
204
           tmem[i] = 112'hxxxxxxxxxxxxxxxxx;
205
 
206
   end
207
endtask
208
 
209
always @(posedge clk)
210
   begin
211
        s1 <= #1 start;
212
        s2 <= #1 s1;
213
        s3 <= #1 s2;
214
        s4 <= #1 s3;
215
        exp1 <= #1 exp;
216
        exp2 <= #1 exp1;
217
        exp3 <= #1 exp2;
218
        exp4 <= #1 exp3;
219
        opa1 <= #1 opa;
220
        opa2 <= #1 opa1;
221
        opa3 <= #1 opa2;
222
        opa4 <= #1 opa3;
223
        opb1 <= #1 opb;
224
        opb2 <= #1 opb1;
225
        opb3 <= #1 opb2;
226
        opb4 <= #1 opb3;
227
        fpu_op1 <= #1 fpu_op;
228
        fpu_op2 <= #1 fpu_op1;
229
        fpu_op3 <= #1 fpu_op2;
230
        fpu_op4 <= #1 fpu_op3;
231
        fpu_op5 <= #1 fpu_op4;
232
        rmode1 <= #1 rmode;
233
        rmode2 <= #1 rmode1;
234
        rmode3 <= #1 rmode2;
235
        rmode4 <= #1 rmode3;
236
        rmode5 <= #1 rmode4;
237
        exc1 <= #1 exc;
238
        exc2 <= #1 exc1;
239
        exc3 <= #1 exc2;
240
        exc4 <= #1 exc3;
241
 
242
        #3;
243
 
244
        //      Floating Point Exceptions ( exc4 )
245
        //      -------------------------
246
        //      float_flag_invalid   =  1,
247
        //      float_flag_divbyzero =  4,
248
        //      float_flag_overflow  =  8,
249
        //      float_flag_underflow = 16,
250
        //      float_flag_inexact   = 32
251
 
252
        exc_err=0;
253
 
254
        if(test_exc)
255
           begin
256
 
257
                if(div_by_zero !== exc4[2])
258
                   begin
259
                        exc_err=1;
260
                        $display("\nERROR: DIV_BY_ZERO Exception: Expected: %h, Got %h\n",exc4[2],div_by_zero);
261
                   end
262
 
263
                if(ine !== exc4[5])
264
                   begin
265
                        exc_err=1;
266
                        $display("\nERROR: INE Exception: Expected: %h, Got %h\n",exc4[5],ine);
267
                   end
268
 
269
                if(overflow !== exc4[3])
270
                   begin
271
                        exc_err=1;
272
                        $display("\nERROR: Overflow Exception Expected: %h, Got %h\n",exc4[3],overflow);
273
                   end
274
 
275
 
276
                if(underflow !== exc4[4])
277
                   begin
278
                        exc_err=1;
279
                        $display("\nERROR: Underflow Exception Expected: %h, Got %h\n",exc4[4],underflow);
280
                   end
281
 
282
 
283
                if(zero !== !(|sum[30:0]))
284
                   begin
285
                        exc_err=1;
286
                        $display("\nERROR: Zero Detection Failed. ZERO: %h, Sum: %h\n", zero, sum);
287
                   end
288
 
289
                if(inf !== ( (sum[30:23] == 8'hff) & ((|sum[22:0]) == 1'b0) ) )
290
                   begin
291
                        exc_err=1;
292
                        $display("\nERROR: INF Detection Failed. INF: %h, Sum: %h\n", inf, sum);
293
                   end
294
 
295
 
296
                if(qnan !== ( &sum[30:23]  & |sum[22:0] ) )
297
                   begin
298
                        exc_err=1;
299
                        $display("\nERROR: QNAN Detection Failed. QNAN: %h, Sum: %h\n", qnan, sum);
300
                   end
301
 
302
                if(snan !== ( ( &opa4[30:23] & !opa4[22] & |opa4[21:0]) | ( &opb4[30:23] & !opb4[22] & |opb4[21:0]) ) )
303
                   begin
304
                        exc_err=1;
305
                        $display("\nERROR: SNAN Detection Failed. SNAN: %h, OpA: %h, OpB: %h\n", snan, opa4, opb4);
306
                   end
307
 
308
           end
309
 
310
 
311
        m0 = ( (|sum) !== 1'b1) & ( (|sum) !== 1'b0);           // result unknown (ERROR)
312
        m1 = (exp4 === sum);                                    // results are equal
313
 
314
        // NAN   *** Ignore Fraction Detail ***
315
        m2 =    (sum[31] == exp4[31]) &
316
                (sum[30:23] == 8'hff)  & (exp4[30:23] == 8'hff) &
317
                (sum[22] == exp4[22]) &
318
                ( (|sum[22:0]) == 1'b1) & ((|exp4[22:0]) == 1'b1);
319
 
320
        match = m1 | m2;
321
 
322
        if( (exc_err | !match | m0) & s4 )
323
           begin
324
                -> error_event;
325
                #0.6;
326
                $display("\n%t: ERROR: output mismatch. Expected %h, Got %h (%h)", $time, exp4, sum, {opa4, opb4, exp4} );
327
                $write("opa:\t");       disp_fp(opa4);
328
                case(fpu_op4)
329
                   0: $display("\t+");
330
                   1: $display("\t-");
331
                   2: $display("\t*");
332
                   3: $display("\t/");
333
                   default: $display("\t Unknown Operation ");
334
                endcase
335
                $write("opb:\t");       disp_fp(opb4);
336
                $write("EXP:\t");       disp_fp(exp4);
337
                $write("GOT:\t");       disp_fp(sum);
338
 
339
$display("\nThis rmode: %h fpop: %h; Previous: rmode: %h fpop: %h; Next: rmode: %h fpop: %h\n",
340
rmode4, fpu_op4, rmode5, fpu_op5, rmode3, fpu_op3);
341
 
342
                $display("\n");
343
                error = error + 1;
344
           end
345
 
346
        if(s4)  vcount = vcount + 1;
347
 
348
        if(error > 10)
349
           begin
350
                @(posedge clk);
351
                $display("\n\nFound to many errors, aborting ...\n\n");
352
                $display("Run %0d vecors, found %0d errors.\n\n",vcount, error);
353
                $finish;
354
           end
355
   end
356
 
357
 
358
fpu u0(clk, fpu_rmode, fpu_op, opa, opb, sum, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero);
359
 
360
 
361
task disp_fp;
362
input [31:0]     fp;
363
 
364
reg     [63:0]   x;
365
reg     [7:0]    exp;
366
 
367
   begin
368
 
369
        exp = fp[30:23];
370
        if(exp==8'h7f)  $write("(%h %h ( 00 ) %h) ",fp[31], exp, fp[22:0]);
371
        else
372
        if(exp>8'h7f)   $write("(%h %h (+%d ) %h) ",fp[31], exp, exp-8'h7f, fp[22:0]);
373
        else            $write("(%h %h (-%d ) %h) ",fp[31], exp, 8'h7f-exp, fp[22:0]);
374
 
375
 
376
        x[51:0] = {fp[22:0], 29'h0};
377
        x[63] = fp[31];
378
        x[62] = fp[30];
379
        x[61:59] = {fp[29], fp[29], fp[29]};
380
        x[58:52] = fp[29:23];
381
 
382
        $display("\t%f",$bitstoreal(x));
383
   end
384
 
385
endtask
386
 
387
endmodule
388
 
389
 
390
 
391
 
392
 
393
 
394
 
395
 
396
 
397
 
398
 
399
 
400
 
401
 
402
 
403
 
404
 
405
 
406
 
407
 
408
 
409
 
410
 
411
 
412
 
413
 

powered by: WebSVN 2.1.0

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