URL
https://opencores.org/ocsvn/fpu/fpu/trunk
Subversion Repositories fpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 7 to Rev 8
- ↔ Reverse comparison
Rev 7 → Rev 8
/branches/russelmann/FPU.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/russelmann/test_vectors/pg.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/russelmann/test_vectors/mkall_fcmp.bat
0,0 → 1,14
|
|
rem -------------------- fcmp |
|
pg -q -r 0 -fcmp -p 0 -o fcmp/fcmp_pat0.hex |
|
pg -q -r 0 -fcmp -p 1 -o fcmp/fcmp_pat1.hex |
|
pg -q -r 0 -fcmp -p 2 -o fcmp/fcmp_pat2.hex |
|
pg -q -r 0 -fcmp -n 199990 -ll -o fcmp/fcmp_lg.hex |
|
pg -q -r 0 -fcmp -n 199990 -o fcmp/fcmp_sm.hex |
|
branches/russelmann/test_vectors/mkall_fcmp.bat
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/russelmann/test_vectors/pg-src/fptpg.c
===================================================================
--- branches/russelmann/test_vectors/pg-src/fptpg.c (revision 7)
+++ branches/russelmann/test_vectors/pg-src/fptpg.c (revision 8)
@@ -34,6 +34,7 @@
int large=0;
int append=0;
int rall=0;
+int fcmp=0;
char *ofile=0;
// Prototypes ...
@@ -89,7 +90,8 @@
i=1;
while((argc-1)>=i) {
-
+ if(strcmp(argv[i],"-fcmp")==0) fcmp=1;
+ else
if(strcmp(argv[i],"-v")==0) verb=1;
else
if(strcmp(argv[i],"-q")==0) quiet=1;
@@ -147,7 +149,7 @@
srand( seed );
if(!quiet) {
- printf("\n Floating Point Test Vector Generation V1.6\n");
+ printf("\n Floating Point Test Vector Generation V1.7\n");
printf("\t by Rudolf Usselmann rudi@asics.ws\n\n");
switch(float_rounding_mode) {
@@ -183,6 +185,7 @@
}
if(ar) arop(count,ar);
+if(fcmp) do_fcmp(count);
return(0);
}
@@ -365,11 +368,91 @@
printf("Found %d errors\n",err_count);
printf("Wrote %d vectors from total %d specified.\n", (count-err_count), count);
- printf("\n ... f2i done.\n");
+ printf("\n ... fptpg done.\n");
}
return(0);
}
+
+
+do_fcmp(int count) {
+float32 f1, f2, f3, f4;
+int i;
+int fp;
+char *mode;
+int err;
+int err_count=0;
+int result;
+int eq, le, lt;
+
+if(!quiet) printf("\nGenerating %0d Arithmetic test vectors ...\n",count);
+
+if(append) mode = "a";
+else mode = "w";
+if(ofile==0) ofile = "ar.hex";
+
+fp = fopen(ofile,mode);
+if(fp == 0) {
+ printf("ERROR: Could not create file '%s'.\n",ofile);
+ return(-1);
+ }
+
+
+for(i=0;i0) {
+ f1 = get_pat(1);
+ f2 = get_pat(2);
+ } else {
+ f1 = get_fp();
+ f2 = get_fp();
+ }
+
+ eq = float32_eq( f1, f2 );
+ le = float32_le( f1, f2 );
+ lt = float32_lt( f1, f2 );
+
+ float_exception_flags = 0; // Reset Exceptions
+
+ eq = float32_eq( f1, f2 );
+ le = float32_le( f1, f2 );
+ lt = float32_lt( f1, f2 );
+
+ eq = *( (float *) &f1 ) == *( (float *) &f2 );
+ le = *( (float *) &f1 ) < *( (float *) &f2 );
+ lt = *( (float *) &f1 ) > *( (float *) &f2 );
+
+
+ if(eq) result = 1;
+ else
+ if(le) result = 2;
+ else
+ if(lt) result = 4;
+ else result = 0;
+
+
+ if(verb) printf("except: %02x, opa: %08x, opb: %08x res: %01x\n", float_exception_flags, f1, f2, result);
+ fprintf(fp,"%02x%08x%08x%01x\n", float_exception_flags, f1, f2, result);
+ }
+
+close(fp);
+
+if(!quiet) {
+ printf("Found %d errors\n",err_count);
+ printf("Wrote %d vectors from total %d specified.\n", (count-err_count), count);
+
+ printf("\n ... fptpg done.\n");
+
+ }
+
+return(0);
+
+}
+
+
+
float32 get_fp() {
float32 f1;
int i1, i2, e;
/branches/russelmann/test_vectors/README
10,6 → 10,9
The script 'mkall' builds all test vectors and places them |
in to the proper directories. |
|
The script 'mkall_cfmp' builds all test vectors for FP compare |
and places them in to the proper directories. |
|
There are currently two types of tests: |
|
1) Directed Test. This test, test a specific funstional unit |
21,7 → 24,8
mode are randomly selected and may change every cycle. This |
tests are located in the combo directory. |
|
There are currently 14,808,684 test vectors ! |
There are currently 14,808,684 FPU test vectors and 600,188 FP |
compare test vectors! |
|
WARNING: You need about 470Mb of disk space to build all test |
WARNING: You need about 480Mb of disk space to build all test |
vectors !!! |
/branches/russelmann/fcmp/verilog/fcmp.v
0,0 → 1,165
///////////////////////////////////////////////////////////////////// |
//// //// |
//// FCMP //// |
//// Single precision Floating Point Compare Unit //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 100ps |
|
|
module fcmp(opa, opb, unordered, altb, blta, aeqb, inf, zero); |
|
input [31:0] opa, opb; |
output unordered; |
output altb, blta, aeqb; |
output inf, zero; |
|
//////////////////////////////////////////////////////////////////////// |
// |
// Local Wire |
// |
|
reg altb, blta, aeqb; |
|
wire signa, signb; |
wire [7:0] expa, expb; |
wire [22:0] fracta, fractb; |
|
wire expa_ff, expb_ff, fracta_00, fractb_00; |
wire qnan_a, snan_a, qnan_b, snan_b, opa_inf, opb_inf, inf; |
wire qnan, snan, opa_zero, opb_zero; |
|
wire exp_eq, exp_gt, exp_lt; |
wire fract_eq, fract_gt, fract_lt; |
wire all_zero; |
|
//////////////////////////////////////////////////////////////////////// |
// |
// Aliases |
// |
|
assign signa = opa[31]; |
assign signb = opb[31]; |
assign expa = opa[30:23]; |
assign expb = opb[30:23]; |
assign fracta = opa[22:0]; |
assign fractb = opb[22:0]; |
|
//////////////////////////////////////////////////////////////////////// |
// |
// Exception Logic |
// |
|
assign expa_ff = &expa; |
assign expb_ff = &expb; |
|
assign fracta_00 = !(|fracta); |
assign fractb_00 = !(|fractb); |
|
assign qnan_a = fracta[22]; |
assign snan_a = !fracta[22] & |fracta[21:0]; |
assign qnan_b = fractb[22]; |
assign snan_b = !fractb[22] & |fractb[21:0]; |
|
assign opa_inf = (expa_ff & fracta_00); |
assign opb_inf = (expb_ff & fractb_00); |
assign inf = opa_inf | opb_inf; |
|
assign qnan = (expa_ff & qnan_a) | (expb_ff & qnan_b); |
assign snan = (expa_ff & snan_a) | (expb_ff & snan_b); |
assign unordered = qnan | snan; |
|
assign opa_zero = !(|expa) & fracta_00; |
assign opb_zero = !(|expb) & fractb_00; |
assign zero = opa_zero; |
|
|
//////////////////////////////////////////////////////////////////////// |
// |
// Comparison Logic |
// |
|
assign exp_eq = expa == expb; |
assign exp_gt = expa > expb; |
assign exp_lt = expa < expb; |
|
assign fract_eq = fracta == fractb; |
assign fract_gt = fracta > fractb; |
assign fract_lt = fracta < fractb; |
|
assign all_zero = opa_zero & opb_zero; |
|
always @( qnan or snan or opa_inf or opb_inf or signa or signb or exp_eq or exp_gt or |
exp_lt or fract_eq or fract_gt or fract_lt or all_zero) |
|
casex( {qnan, snan, opa_inf, opb_inf, signa, signb, exp_eq, exp_gt, exp_lt, fract_eq, fract_gt, fract_lt, all_zero}) |
//13'b??_??_??_???_???_?: {altb, blta, aeqb} = 3'b000; |
|
13'b1?_??_??_???_???_?: {altb, blta, aeqb} = 3'b000; // qnan |
13'b?1_??_??_???_???_?: {altb, blta, aeqb} = 3'b000; // snan |
|
13'b00_11_00_???_???_?: {altb, blta, aeqb} = 3'b001; // both op INF comparisson |
13'b00_11_01_???_???_?: {altb, blta, aeqb} = 3'b100; |
13'b00_11_10_???_???_?: {altb, blta, aeqb} = 3'b010; |
13'b00_11_11_???_???_?: {altb, blta, aeqb} = 3'b001; |
|
13'b00_10_00_???_???_?: {altb, blta, aeqb} = 3'b100; // opa INF comparisson |
13'b00_10_01_???_???_?: {altb, blta, aeqb} = 3'b100; |
13'b00_10_10_???_???_?: {altb, blta, aeqb} = 3'b010; |
13'b00_10_11_???_???_?: {altb, blta, aeqb} = 3'b010; |
|
13'b00_01_00_???_???_?: {altb, blta, aeqb} = 3'b010; // opb INF comparisson |
13'b00_01_01_???_???_?: {altb, blta, aeqb} = 3'b100; |
13'b00_01_10_???_???_?: {altb, blta, aeqb} = 3'b010; |
13'b00_01_11_???_???_?: {altb, blta, aeqb} = 3'b100; |
|
13'b00_00_10_???_???_0: {altb, blta, aeqb} = 3'b010; //compare base on sign |
13'b00_00_01_???_???_0: {altb, blta, aeqb} = 3'b100; //compare base on sign |
|
13'b00_00_??_???_???_1: {altb, blta, aeqb} = 3'b001; //compare base on sign both are zero |
|
13'b00_00_00_010_???_?: {altb, blta, aeqb} = 3'b100; // cmp exp, equal sign |
13'b00_00_00_001_???_?: {altb, blta, aeqb} = 3'b010; |
13'b00_00_11_010_???_?: {altb, blta, aeqb} = 3'b010; |
13'b00_00_11_001_???_?: {altb, blta, aeqb} = 3'b100; |
|
13'b00_00_00_100_010_?: {altb, blta, aeqb} = 3'b100; // compare fractions, equal sign, equal exp |
13'b00_00_00_100_001_?: {altb, blta, aeqb} = 3'b010; |
13'b00_00_11_100_010_?: {altb, blta, aeqb} = 3'b010; |
13'b00_00_11_100_001_?: {altb, blta, aeqb} = 3'b100; |
|
13'b00_00_00_100_100_?: {altb, blta, aeqb} = 3'b001; |
13'b00_00_11_100_100_?: {altb, blta, aeqb} = 3'b001; |
|
default: {altb, blta, aeqb} = 3'bxxx; |
endcase |
|
endmodule |
/branches/russelmann/fcmp/test_bench/test_top.v
0,0 → 1,335
///////////////////////////////////////////////////////////////////// |
//// //// |
//// FPU //// |
//// Floating Point Unit (Single precision) //// |
//// //// |
//// TEST BENCH //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
|
`timescale 1ns / 100ps |
|
module test; |
|
reg clk; |
reg [31:0] opa; |
reg [31:0] opb; |
wire [3:0] sum; |
wire inf, snan, qnan; |
wire div_by_zero; |
wire altb, blta, aeqb; |
wire unordered; |
|
reg [3:0] exp; |
reg [31:0] opa1; |
reg [31:0] opb1; |
reg [2:0] fpu_op; |
reg [3:0] rmode; |
reg start; |
reg [75:0] tmem[0:500000]; |
reg [75:0] tmp; |
reg [7:0] oper; |
reg [7:0] exc; |
integer i; |
wire ine; |
reg match; |
wire overflow, underflow; |
wire zero; |
reg exc_err; |
reg m0, m1, m2; |
reg [1:0] fpu_rmode; |
reg [3:0] test_rmode; |
reg [4:0] test_sel; |
reg fp_fasu; |
reg fp_mul; |
reg fp_div; |
reg fp_combo; |
reg fp_i2f; |
reg fp_0fcmp; |
reg test_exc; |
reg show_prog; |
event error_event; |
|
integer error, vcount; |
|
always #50 clk = ~clk; |
|
initial |
begin |
$display ("\n\nFloating Point Compare Version 1.0\n\n"); |
clk = 0; |
start = 0; |
|
error = 0; |
vcount = 0; |
|
show_prog = 0; |
|
test_exc = 1; |
test_sel = 5'b11111; |
|
@(posedge clk); |
|
$display("\n\nTesting FP CMP Unit\n"); |
|
if(test_sel[0]) |
begin |
$display("\nRunning Pat 0 Test ...\n"); |
$readmemh ("../test_vectors/fcmp/fcmp_pat0.hex", tmem); |
run_test; |
end |
|
if(test_sel[1]) |
begin |
$display("\nRunning Pat 1 Test ...\n"); |
$readmemh ("../test_vectors/fcmp/fcmp_pat1.hex", tmem); |
run_test; |
end |
|
if(test_sel[2]) |
begin |
$display("\nRunning Pat 2 Test ...\n"); |
$readmemh ("../test_vectors/fcmp/fcmp_pat2.hex", tmem); |
run_test; |
end |
|
if(test_sel[3]) |
begin |
$display("\nRunning Random Lg. Num Test ...\n"); |
$readmemh ("../test_vectors/fcmp/fcmp_lg.hex", tmem); |
run_test; |
end |
|
if(test_sel[4]) |
begin |
$display("\nRunning Random Sm. Num Test ...\n"); |
$readmemh ("../test_vectors/fcmp/fcmp_sm.hex", tmem); |
run_test; |
end |
|
repeat (4) @(posedge clk); |
$display("\n\n"); |
|
$display("\n\nAll test Done !\n\n"); |
$display("Run %0d vecors, found %0d errors.\n\n",vcount, error); |
|
$finish; |
end |
|
|
task run_test; |
begin |
@(posedge clk); |
#1; |
opa = 32'h0; |
opb = 32'hx; |
|
@(posedge clk); |
#1; |
|
i=0; |
while( |opa !== 1'bx ) |
begin |
|
@(posedge clk); |
#1; |
start = 1; |
tmp = tmem[i]; |
|
exc = tmp[75:68]; |
opa = tmp[67:36]; |
opb = tmp[35:04]; |
|
exp = exc==0 ? tmp[03:00] : 0; |
|
if(show_prog) $write("Vector: %d\015",i); |
|
i= i+1; |
end |
start = 0; |
|
@(posedge clk); |
#1; |
opa = 32'hx; |
opb = 32'hx; |
fpu_rmode = 2'hx; |
|
@(posedge clk); |
#1; |
|
for(i=0;i<500000;i=i+1) // Clear Memory |
tmem[i] = 76'hxxxxxxxxxxxxxxxxx; |
|
end |
endtask |
|
always @(posedge clk) |
begin |
|
#3; |
|
// Floating Point Exceptions ( exc4 ) |
// ------------------------- |
// float_flag_invalid = 1, |
// float_flag_divbyzero = 4, |
// float_flag_overflow = 8, |
// float_flag_underflow = 16, |
// float_flag_inexact = 32 |
|
exc_err=0; |
|
if(test_exc) |
begin |
|
if(exc[5]) |
begin |
exc_err=1; |
$display("\nERROR: INE Exception: Expected: 0, Got 1\n"); |
end |
|
if(exc[3]) |
begin |
exc_err=1; |
$display("\nERROR: Overflow Exception: Expected: 0, Got 1\n"); |
end |
|
if(exc[4]) |
begin |
exc_err=1; |
$display("\nERROR: Underflow Exception: Expected: 0, Got 1\n"); |
end |
|
if(zero !== !(|opa[30:0])) |
begin |
exc_err=1; |
$display("\nERROR: Zero Detection Failed. ZERO: %h, Sum: %h\n", zero, opa); |
end |
|
|
if(inf !== (((opa[30:23] == 8'hff) & ((|opa[22:0]) == 1'b0)) | ((opb[30:23] == 8'hff) & ((|opb[22:0]) == 1'b0))) ) |
begin |
exc_err=1; |
$display("\nERROR: INF Detection Failed. INF: %h, Sum: %h\n", inf, sum); |
end |
|
if(unordered !== ( ( &opa[30:23] & |opa[22:0]) | ( &opb[30:23] & |opb[22:0]) ) ) |
begin |
exc_err=1; |
$display("\nERROR: UNORDERED Detection Failed. SNAN: %h, OpA: %h, OpB: %h\n", snan, opa, opb); |
end |
|
end |
|
m0 = ( (|sum) !== 1'b1) & ( (|sum) !== 1'b0); // result unknown (ERROR) |
m1 = (exp === sum) ; // results are equal |
|
match = m1; |
|
if( (exc_err | !match | m0) & start ) |
begin |
$display("\n%t: ERROR: output mismatch. Expected %h, Got %h (%h)", $time, exp, sum, {opa, opb, exp} ); |
$write("opa:\t"); disp_fp(opa); |
$write("opb:\t"); disp_fp(opb); |
$display("EXP:\t%b",exp); |
$display("GOT:\t%b",sum); |
$display("\n"); |
|
error = error + 1; |
end |
|
if(start) vcount = vcount + 1; |
|
if(error > 10) |
begin |
@(posedge clk); |
$display("\n\nFound to many errors, aborting ...\n\n"); |
$display("Run %0d vecors, found %0d errors.\n\n",vcount, error); |
$finish; |
end |
end |
|
assign sum = {1'b0, altb, blta, aeqb}; |
|
fcmp u0(opa, opb, unordered, altb, blta, aeqb, inf, zero ); |
|
task disp_fp; |
input [31:0] fp; |
|
reg [63:0] x; |
reg [7:0] exp; |
|
begin |
|
exp = fp[30:23]; |
if(exp==8'h7f) $write("(%h %h ( 00 ) %h) ",fp[31], exp, fp[22:0]); |
else |
if(exp>8'h7f) $write("(%h %h (+%d ) %h) ",fp[31], exp, exp-8'h7f, fp[22:0]); |
else $write("(%h %h (-%d ) %h) ",fp[31], exp, 8'h7f-exp, fp[22:0]); |
|
|
x[51:0] = {fp[22:0], 29'h0}; |
x[63] = fp[31]; |
x[62] = fp[30]; |
x[61:59] = {fp[29], fp[29], fp[29]}; |
x[58:52] = fp[29:23]; |
|
$display("\t%f",$bitstoreal(x)); |
end |
|
endtask |
|
endmodule |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/branches/russelmann/README
9,7 → 9,8
|
|
|
|
FPU |
=== |
The FPU consists of the following files: |
|
verilog/fpu.v |
24,7 → 25,7
The testbench is in: test_bench/test_top.v |
|
To simulate the FPU using the included test bench |
us a comand like: |
use a comand like: |
|
verilog test_bench/test_top.v \ |
verilog/fpu.v \ |
35,6 → 36,24
verilog/pre_norm_fmul.v |
|
|
|
FCMP |
==== |
The FP compare consists of |
fcmp/verilog/fcmp.v |
|
The testbench for FP compare is in: fcmp/test_bench/test_top.v |
|
To simulate the FP compare using the included test bench |
use a comand like: |
|
verilog fcmp/test_bench/test_top.v \ |
fcmp/verilog/fcmp.v |
|
|
|
MISC |
==== |
Do not change the directory structure, the testbench |
depends on it ! |
|