OpenCores
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 !
 

powered by: WebSVN 2.1.0

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