This commit is contained in:
mmasserfrye 2022-05-17 18:30:23 +00:00
commit c4618d1e57
8 changed files with 821 additions and 384 deletions

View file

@ -3,5 +3,5 @@ all: sqrttestgen testgen
sqrttestgen: sqrttestgen.c
gcc sqrttestgen.c -lm -o sqrttestgen
testgen: exptestgen.c
gcc exptestgen.c -lm -o exptestgen
testgen: testgen.c
gcc testgen.c -lm -o testgen

View file

@ -1,2 +1 @@
verilator --lint-only --top-module srt srt.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv
verilator --lint-only --top-module testbench testbench.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv ../src/fpu/unpack.sv

View file

@ -17,7 +17,7 @@ if [file exists work] {
}
vlib work
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/fpu/unpack.sv
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv
vopt +acc work.testbench -o workopt
vsim workopt

View file

@ -37,8 +37,6 @@ module srt #(parameter Nf=52) (
input logic Flush, // *** multiple pipe stages
// Floating Point Inputs
// later add exponents, signs, special cases
input logic [10:0] SrcXExpE, SrcYExpE, // exponents, for double precision exponents are 11 bits
// end of floating point inputs
input logic [Nf-1:0] SrcXFrac, SrcYFrac,
input logic [`XLEN-1:0] SrcA, SrcB,
input logic [1:0] Fmt, // Floats: 00 = 16 bit, 01 = 32 bit, 10 = 64 bit, 11 = 128 bit
@ -47,7 +45,6 @@ module srt #(parameter Nf=52) (
input logic Int, // Choose integer inputss
input logic Sqrt, // perform square root, not divide
output logic [Nf-1:0] Quot, Rem, // *** later handle integers
output logic [10:0] Exp, // output exponent is hardcoded for 11 bits for double precision
output logic [3:0] Flags
);
@ -81,9 +78,6 @@ module srt #(parameter Nf=52) (
// Partial Product Generation
csa csa(WS, WC, Dsel, qp, WSA, WCA);
// Exponent division
exp exp(SrcXExpE, SrcYExpE, Exp);
srtpostproc postproc(rp, rm, Quot);
endmodule
@ -92,9 +86,8 @@ module srtpostproc #(parameter N=52) (
output [N-1:0] Quot
);
// replace with on-the-fly conversion
//assign Quot = rp - rm;
finaladd finaladd(rp, rm, Quot);
finaladd finaladd(rp, rm, Quot);
endmodule
module srtpreproc #(parameter Nf=52) (
@ -254,14 +247,6 @@ module csa #(parameter N=56) (
(in2[54:0] & in3[54:0]), cin};
endmodule
//////////////
// exponent //
//////////////
module exp(input [10:0] e1, e2,
output [10:0] e); // for double precision, exponent is 11 bits
assign e = (e1 - e2) + 11'd1023; // bias is hardcoded
endmodule
//////////////
// finaladd //
//////////////

View file

@ -11,9 +11,7 @@
// This Verilog file models a radix 2 SRT divider which
// produces one quotient digit per cycle. The divider
// keeps the partial remainder in carry-save form.
`include "wally-config.vh"
/////////
// srt //
/////////
@ -328,9 +326,7 @@ module testbench;
begin
req <= #5 1;
$display("result was %h, should be %h\n", r, correctr);
//if (abs(correctr - r) > 1) // check if accurate to 1 ulp
// giving error "srt_stanford.sv(395): (vopt-7063) Failed to find 'abs' in hierarchical name 'abs'."
if (correctr - r > 1) // check if accurate to 1 ulp
if ((correctr - r) > 1) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("failed\n");

View file

@ -1,7 +1,7 @@
/////////////
// divcounter //
// counter //
/////////////
module divcounter(input logic clk,
module counter(input logic clk,
input logic req,
output logic done);
@ -36,76 +36,40 @@ endmodule
//////////
// testbench //
//////////
/* verilator lint_off STMTDLY */
/* verilator lint_off INFINITELOOP */
module testbench;
logic clk;
logic req;
logic done;
logic [63:0] a;
logic [63:0] b;
logic [63:0] result;
logic [51:0] r;
logic [51:0] a;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
logic [10:0] e; // output exponent
// input logic for Unpacker
// input logic [63:0] X, Y, Z, - numbers
// input logic FmtE, ---- format, 1 is for double precision, 0 is single
// input logic [2:0] FOpCtrlE, ---- controling operations for FPU, 1 is sqrt, 0 is divide
// all variables are commented in fpu.sv
// output logic from Unpacker
logic XSgnE, YSgnE, ZSgnE;
logic [10:0] XExpE, YExpE, ZExpE; // exponent
logic [52:0] XManE, YManE, ZManE;
logic XNormE;
logic XNaNE, YNaNE, ZNaNE;
logic XSNaNE, YSNaNE, ZSNaNE;
logic XDenormE, YDenormE, ZDenormE; // denormals
logic XZeroE, YZeroE, ZZeroE;
logic [10:0] BiasE; // currrently hardcoded, will probs be removed
logic XInfE, YInfE, ZInfE;
logic XExpMaxE; // says exponent is all ones, can ignore
// Test parameters
parameter MEM_SIZE = 60000;
parameter MEM_WIDTH = 64+64+64;
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 52+52+52;
`define memr 63:0
`define memb 127:64
`define mema 191:128
`define memr 51:0
`define memb 103:52
`define mema 155:104
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [63:0] correctr, nextr, diffn, diffp;
logic [51:0] correctr, nextr, diffn, diffp;
integer testnum, errors;
// Unpacker
// Note: BiasE will probably get taken out eventually
unpack unpack(.X({1'b1,a[62:0]}), .Y({1'b1,b[62:0]}), .Z(64'b0), .FmtE(1'b1),
.XSgnE(XSgnE), .YSgnE(YSgnE), .ZSgnE(ZSgnE), .XExpE(XExpE), .YExpE(YExpE), .ZExpE(ZExpE),
.XManE(XManE), .YManE(YManE), .ZManE(ZManE), .XNormE(XNormE), .XNaNE(XNaNE), .YNaNE(YNaNE), .ZNaNE(ZNaNE),
.XSNaNE(XSNaNE), .YSNaNE(YSNaNE), .ZSNaNE(ZSNaNE), .XDenormE(XDenormE), .YDenormE(YDenormE), .ZDenormE(ZDenormE),
.XZeroE(XZeroE), .YZeroE(YZeroE), .ZZeroE(ZZeroE),
.XInfE(XInfE), .YInfE(YInfE), .ZInfE(ZInfE), .XExpMaxE(XExpMaxE));
// Divider
srt #(52) srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.SrcXExpE(XExpE), .SrcYExpE(YExpE),
.SrcXFrac(XManE[51:0]), .SrcYFrac(YManE[51:0]),
.SrcXFrac(a), .SrcYFrac(b),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot(r), .Rem(), .Exp(e), .Flags());
.Quot(r), .Rem(), .Flags());
assign result = {1'b0, e, r};
// Divcounter
divcounter divcounter(clk, req, done);
// Counter
counter counter(clk, req, done);
initial
@ -126,7 +90,7 @@ module testbench;
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
req = #5 1;
req <= #5 1;
end
// Apply directed test vectors read from file.
@ -135,19 +99,17 @@ module testbench;
begin
if (done)
begin
req = #5 1;
diffp = correctr - result;
diffn = result - correctr;
req <= #5 1;
diffp = correctr - r;
diffn = r - correctr;
if (($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("a = %h b = %h result = %h",a,b,correctr);
$display("result was %h, should be %h %h %h\n", result, correctr, diffn, diffp);
$display("at fail");
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (a === 64'hxxxxxxxxxxxxxxxx)
if (a === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
@ -155,20 +117,16 @@ module testbench;
end
if (req)
begin
req = #5 0;
req <= #5 0;
correctr = nextr;
$display("pre increment");
testnum = testnum+1;
a = Vec[`mema];
b = Vec[`memb];
Vec = Tests[testnum];
$display("a = %h b = %h result = %h",a,b,nextr);
$display("a = %h b = %h",a,b);
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
$display("after increment");
end
end
endmodule
/* verilator lint_on STMTDLY */
/* verilator lint_on INFINITELOOP */

View file

@ -28,7 +28,7 @@ double random_input(void);
void main(void)
{
FILE *fptr;
double x1, x2, a, b, r;
double a, b, r;
double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625,
1.75, 1.875, 1.99999,
1.1, 1.2, 1.01, 1.001, 1.0001,
@ -63,7 +63,6 @@ void main(void)
void output(FILE *fptr, double a, double b, double r)
{
printhex(fptr, a);
fprintf(fptr, "_");
printhex(fptr, b);

File diff suppressed because it is too large Load diff