forked from Github_Repos/cvw
srt fixes
This commit is contained in:
commit
dee2822359
@ -17,7 +17,7 @@ if [file exists work] {
|
|||||||
}
|
}
|
||||||
vlib work
|
vlib work
|
||||||
|
|
||||||
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv
|
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/fpu/unpacking.sv
|
||||||
vopt +acc work.testbench -o workopt
|
vopt +acc work.testbench -o workopt
|
||||||
vsim workopt
|
vsim workopt
|
||||||
|
|
||||||
|
@ -11,7 +11,52 @@
|
|||||||
// This Verilog file models a radix 2 SRT divider which
|
// This Verilog file models a radix 2 SRT divider which
|
||||||
// produces one quotient digit per cycle. The divider
|
// produces one quotient digit per cycle. The divider
|
||||||
// keeps the partial remainder in carry-save form.
|
// keeps the partial remainder in carry-save form.
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
// will also be used for integer division so keep in mind when naming modules/signals
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// srt_divide //
|
||||||
|
////////////////
|
||||||
|
module srt_divide(input logic clk,
|
||||||
|
input logic req,
|
||||||
|
input logic sqrt, // 1 to compute sqrt(a), 0 to compute a/b
|
||||||
|
input logic [63:0] a, b, // input numbers
|
||||||
|
output logic [54:0] rp, rm,
|
||||||
|
output logic [10:0] expE);
|
||||||
|
|
||||||
|
// output logic from Unpackers
|
||||||
|
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
|
||||||
|
|
||||||
|
// have Unpackers
|
||||||
|
// have mantissa divider
|
||||||
|
// exponent divider
|
||||||
|
|
||||||
|
// hopefully having the .* here works for unpacker --- nope it doesn't
|
||||||
|
unpack unpacking(a, b, 0, 1'b1, 0, XSgnE, YSgnE, ZSgnE, XExpE, YExpE, ZExpE, XManE, YManE, ZManE, XNormE,XNaNE, YNaNE, ZNaNE,XSNaNE, YSNaNE, ZSNaNE,XDenormE, YDenormE, ZDenormE,XZeroE, YZeroE, ZZeroE,BiasE,XInfE, YInfE, ZInfE,XExpMaxE);
|
||||||
|
srt srt(clk, req, XManE[51:0], YManE[51:0], rp, rm);
|
||||||
|
exp exp(XexpE, YExpE, expE);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// exponent module
|
||||||
|
// first iteration
|
||||||
|
module exp(input [10:0] e1, e2,
|
||||||
|
output [10:0] e); // for a 64 bit number, exponent section is 11 bits
|
||||||
|
assign e = (e1 - e2) + 11'd1023; // bias is hardcoded
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
/////////
|
/////////
|
||||||
// srt //
|
// srt //
|
||||||
/////////
|
/////////
|
||||||
@ -39,12 +84,12 @@ module srt(input logic clk,
|
|||||||
// When start is asserted, the inputs are loaded into the divider.
|
// When start is asserted, the inputs are loaded into the divider.
|
||||||
// Otherwise, the divisor is retained and the partial remainder
|
// Otherwise, the divisor is retained and the partial remainder
|
||||||
// is fed back for the next iteration.
|
// is fed back for the next iteration.
|
||||||
mux2 psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn);
|
mux2_special psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn);
|
||||||
flop psflop(clk, psn, ps);
|
flop_special psflop(clk, psn, ps);
|
||||||
mux2 pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn);
|
mux2_special pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn);
|
||||||
flop pcflop(clk, pcn, pc);
|
flop_special pcflop(clk, pcn, pc);
|
||||||
mux2 dmux(d, {4'b0001, b}, req, dn);
|
mux2_special dmux(d, {4'b0001, b}, req, dn);
|
||||||
flop dflop(clk, dn, d);
|
flop_special dflop(clk, dn, d);
|
||||||
|
|
||||||
// Quotient Selection logic
|
// Quotient Selection logic
|
||||||
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
|
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
|
||||||
@ -54,7 +99,7 @@ module srt(input logic clk,
|
|||||||
|
|
||||||
// Divisor Selection logic
|
// Divisor Selection logic
|
||||||
inv dinv(d, d_b);
|
inv dinv(d, d_b);
|
||||||
mux3 divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel);
|
mux3_special divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel);
|
||||||
|
|
||||||
// Partial Product Generation
|
// Partial Product Generation
|
||||||
csa csa(ps, pc, dsel, qp, psa, pca);
|
csa csa(ps, pc, dsel, qp, psa, pca);
|
||||||
@ -63,7 +108,7 @@ endmodule
|
|||||||
//////////
|
//////////
|
||||||
// mux2 //
|
// mux2 //
|
||||||
//////////
|
//////////
|
||||||
module mux2(input logic [55:0] in0, in1,
|
module mux2_special(input logic [55:0] in0, in1,
|
||||||
input logic sel,
|
input logic sel,
|
||||||
output logic [55:0] out);
|
output logic [55:0] out);
|
||||||
|
|
||||||
@ -73,7 +118,7 @@ endmodule
|
|||||||
//////////
|
//////////
|
||||||
// flop //
|
// flop //
|
||||||
//////////
|
//////////
|
||||||
module flop(clk, in, out);
|
module flop_special(clk, in, out);
|
||||||
input clk;
|
input clk;
|
||||||
input [55:0] in;
|
input [55:0] in;
|
||||||
output [55:0] out;
|
output [55:0] out;
|
||||||
@ -159,9 +204,9 @@ module inv(input logic [55:0] in,
|
|||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// mux3 //
|
// mux3_special //
|
||||||
//////////
|
//////////
|
||||||
module mux3(in0, in1, in2, sel0, sel1, sel2, out);
|
module mux3_special(in0, in1, in2, sel0, sel1, sel2, out);
|
||||||
input [55:0] in0;
|
input [55:0] in0;
|
||||||
input [55:0] in1;
|
input [55:0] in1;
|
||||||
input [55:0] in2;
|
input [55:0] in2;
|
||||||
@ -271,6 +316,24 @@ module testbench;
|
|||||||
logic [51:0] b;
|
logic [51:0] b;
|
||||||
logic [51:0] r;
|
logic [51:0] r;
|
||||||
logic [54:0] rp, rm; // positive quotient digits
|
logic [54:0] rp, rm; // positive quotient digits
|
||||||
|
|
||||||
|
//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 Unpackers
|
||||||
|
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
|
// Test parameters
|
||||||
parameter MEM_SIZE = 40000;
|
parameter MEM_SIZE = 40000;
|
||||||
@ -287,8 +350,15 @@ module testbench;
|
|||||||
logic [51:0] correctr, nextr;
|
logic [51:0] correctr, nextr;
|
||||||
integer testnum, errors;
|
integer testnum, errors;
|
||||||
|
|
||||||
|
// Unpackers
|
||||||
|
unpacking unpack(.X({12'b100010000010,a}), .Y({12'b100010000001,b}), .Z(0), .FmtE(1'b1), .FOpCtrlE(0), .*);
|
||||||
|
|
||||||
// Divider
|
// Divider
|
||||||
srt srt(clk, req, a, b, rp, rm);
|
srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(XManE[51:0]), .b(YManE[51:0]), .rp(rp),.rm(rm));
|
||||||
|
|
||||||
|
//srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(a), .b(b), .rp(rp),.rm(rm));
|
||||||
|
|
||||||
|
// Divider + unpacker
|
||||||
|
|
||||||
// Final adder converts quotient digits to 2's complement & normalizes
|
// Final adder converts quotient digits to 2's complement & normalizes
|
||||||
finaladd finaladd(rp, rm, r);
|
finaladd finaladd(rp, rm, r);
|
||||||
@ -326,7 +396,9 @@ module testbench;
|
|||||||
begin
|
begin
|
||||||
req <= #5 1;
|
req <= #5 1;
|
||||||
$display("result was %h, should be %h\n", r, correctr);
|
$display("result was %h, should be %h\n", r, correctr);
|
||||||
if ((correctr - r) > 1) // check if accurate to 1 ulp
|
//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
|
||||||
begin
|
begin
|
||||||
errors = errors+1;
|
errors = errors+1;
|
||||||
$display("failed\n");
|
$display("failed\n");
|
||||||
|
@ -28,7 +28,7 @@ double random_input(void);
|
|||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
double a, b, r;
|
double x1, x2, a, b, r;
|
||||||
double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625,
|
double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625,
|
||||||
1.75, 1.875, 1.99999,
|
1.75, 1.875, 1.99999,
|
||||||
1.1, 1.2, 1.01, 1.001, 1.0001,
|
1.1, 1.2, 1.01, 1.001, 1.0001,
|
||||||
@ -63,6 +63,7 @@ void main(void)
|
|||||||
|
|
||||||
void output(FILE *fptr, double a, double b, double r)
|
void output(FILE *fptr, double a, double b, double r)
|
||||||
{
|
{
|
||||||
|
|
||||||
printhex(fptr, a);
|
printhex(fptr, a);
|
||||||
fprintf(fptr, "_");
|
fprintf(fptr, "_");
|
||||||
printhex(fptr, b);
|
printhex(fptr, b);
|
||||||
|
Loading…
Reference in New Issue
Block a user