mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
79df271a6f
@ -1 +1 @@
|
||||
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
|
||||
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
|
@ -1,4 +1,5 @@
|
||||
# Makefile added 1/20/22 David_Harris@hmc.edu
|
||||
# Expanded and developed by dtorres@hmc.edu
|
||||
# Compile Embench for Wally
|
||||
|
||||
all: build sim
|
||||
@ -6,9 +7,9 @@ all: build sim
|
||||
allClean: clean all
|
||||
|
||||
build:
|
||||
../../addins/embench-iot/build_all.py --builddir=bd_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-nostartfiles"
|
||||
../../addins/embench-iot/build_all.py -v --builddir=bd_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-nostartfiles"
|
||||
find ../../addins/embench-iot/bd_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done
|
||||
../../addins/embench-iot/build_all.py --builddir=bd_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles" --cflags="-msave-restore" --dummy-libs="libgcc libm libc crt0"
|
||||
../../addins/embench-iot/build_all.py -v --builddir=bd_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/dummy.S" --cflags="-msave-restore" --dummy-libs="libgcc libm libc crt0"
|
||||
|
||||
sim: modelSimBuild size speed
|
||||
|
||||
@ -20,10 +21,10 @@ size:
|
||||
../../addins/embench-iot/benchmark_size.py --builddir=bd_size
|
||||
|
||||
speed:
|
||||
../../addins/embench-iot/benchmark_speed.py --builddir=bd_speed --target-module run_wally --cpu-mhz=50
|
||||
../../addins/embench-iot/benchmark_speed.py --builddir=bd_speed --target-module run_wally --cpu-mhz=1
|
||||
|
||||
objdump:
|
||||
find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S "$$f" > "$$f.objdump"; done
|
||||
find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done
|
||||
|
||||
clean:
|
||||
rm -rf ../../addins/embench-iot/bd_speed/
|
||||
@ -37,3 +38,5 @@ clean:
|
||||
# ../../addins/embench-iot/build_all.py --arch riscv32 --chip generic --board rv32wallyverilog --cc riscv64-unknown-elf-gcc --cflags="-c -Os -ffunction-sections -nostdlib -march=rv32imac -mabi=ilp32" --ldflags="-Wl,-gc-sections -nostdlib -march=rv32imac -mabi=ilp32 -T../../../config/riscv32/boards/rv32wallyverilog/link.ld" --dummy-libs="libgcc libm libc"
|
||||
# --user-libs="-lm"
|
||||
# riscv64-unknown-elf-gcc -O2 -g -nostartfiles -I/home/harris/riscv-wally/addins/embench-iot/support -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/boards/ri5cyverilator -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/chips/generic -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32 -DCPU_MHZ=1 -DWARMUP_HEAT=1 -o main.o /home/harris/riscv-wally/addins/embench-iot/support/main.c
|
||||
|
||||
# find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf.objdump.lab" | while read f; do grep -n "begin_signature" $f | cut -f1 -d:
|
||||
|
@ -7,4 +7,4 @@
|
||||
# sqrt - test square root
|
||||
# all - test everything
|
||||
|
||||
vsim -c -do "do fp.do rv64fp fma"
|
||||
vsim -c -do "do fp.do rv64fp cvtfp"
|
@ -76,8 +76,6 @@ add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/PMPCFG_ARRAY_RE
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SATP_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SCOUNTEREN_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SEPC_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SIE_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SIP_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SSTATUS_REGW
|
||||
add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/STVEC_REGW
|
||||
add wave -noupdate -group Bpred -color Orange /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHR
|
||||
@ -420,8 +418,6 @@ add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/HRESPCLINT
|
||||
add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/HREADYCLINT
|
||||
add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/MTIME
|
||||
add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/MTIMECMP
|
||||
add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/TimerIntM
|
||||
add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/SwIntM
|
||||
add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HCLK
|
||||
add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HRESETn
|
||||
add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HSELUART
|
||||
|
@ -42,7 +42,7 @@ module fcvt (
|
||||
logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size
|
||||
logic [`LGLEN-1:0] LzcIn; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [`NE:0] CalcExp; // the calculated expoent
|
||||
logic [$clog2(`LGLEN)-1:0] ShiftAmt; // how much to shift by
|
||||
logic [$clog2(`LGLEN+1)-1:0] ShiftAmt; // how much to shift by
|
||||
logic [`LGLEN+`NF:0] ShiftIn; // number to be shifted
|
||||
logic ResDenormUf;// does the result underflow or is denormalized
|
||||
logic ResUf; // does the result underflow
|
||||
@ -72,7 +72,7 @@ module fcvt (
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic ToInt; // is the opperation an fp->int conversion?
|
||||
logic [$clog2(`LGLEN)-1:0] ZeroCnt; // output from the LZC
|
||||
logic [$clog2(`LGLEN+1)-1:0] ZeroCnt; // output from the LZC
|
||||
|
||||
|
||||
// seperate OpCtrl for code readability
|
||||
@ -143,9 +143,9 @@ module fcvt (
|
||||
// - only shift fp -> fp if the intital value is denormalized
|
||||
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
||||
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
|
||||
assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN)-1:0]&{$clog2(`LGLEN){~CalcExp[`NE]}} :
|
||||
ResDenormUf&~IntToFp ? ($clog2(`LGLEN))'(`NF-1)+CalcExp[$clog2(`LGLEN)-1:0] :
|
||||
(ZeroCnt+1)&{$clog2(`LGLEN){XDenormE|IntToFp}};
|
||||
assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN+1)-1:0]&{$clog2(`LGLEN+1){~CalcExp[`NE]}} :
|
||||
ResDenormUf&~IntToFp ? ($clog2(`LGLEN+1))'(`NF-1)+CalcExp[$clog2(`LGLEN+1)-1:0] :
|
||||
(ZeroCnt+1)&{$clog2(`LGLEN+1){XDenormE|IntToFp}};
|
||||
|
||||
// shift
|
||||
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
||||
@ -255,13 +255,13 @@ module fcvt (
|
||||
// | keep |
|
||||
//
|
||||
// - if the input is denormalized then we dont shift... so the "- (ZeroCnt+1)" is just leftovers from other options
|
||||
// int -> fp : largest bias XLEN - Largest bias + new bias - 1 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt
|
||||
// int -> fp : largest bias + XLEN - Largest bias + new bias - 1 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt
|
||||
// Process:
|
||||
// - shifted right by XLEN (XLEN)
|
||||
// - shift left to normilize (-1-ZeroCnt)
|
||||
// - newBias to make the biased exponent
|
||||
//
|
||||
assign CalcExp = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-$clog2(`LGLEN)+1{1'b0}}, (ZeroCnt&{$clog2(`LGLEN){XDenormE|IntToFp}})};
|
||||
assign CalcExp = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-$clog2(`LGLEN+1)+1{1'b0}}, (ZeroCnt&{$clog2(`LGLEN+1){XDenormE|IntToFp}})};
|
||||
// find if the result is dnormal or underflows
|
||||
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
|
||||
// - can't underflow an integer to Fp conversion
|
||||
|
@ -21,538 +21,20 @@ module unpack (
|
||||
logic XExpZero, YExpZero, ZExpZero; // is the exponent zero
|
||||
logic YExpMaxE, ZExpMaxE; // is the exponent all 1s
|
||||
|
||||
if (`FPSIZES == 1) begin // if there is only one floating point format supported
|
||||
unpackinput unpackinputX (.In(X), .FmtE, .Sgn(XSgnE), .Exp(XExpE), .Man(XManE),
|
||||
.NaN(XNaNE), .SNaN(XSNaNE), .Denorm(XDenormE),
|
||||
.Zero(XZeroE), .Inf(XInfE), .ExpMax(XExpMaxE), .ExpZero(XExpZero));
|
||||
|
||||
// sign bit
|
||||
assign XSgnE = X[`FLEN-1];
|
||||
assign YSgnE = Y[`FLEN-1];
|
||||
assign ZSgnE = Z[`FLEN-1];
|
||||
unpackinput unpackinputY (.In(Y), .FmtE, .Sgn(YSgnE), .Exp(YExpE), .Man(YManE),
|
||||
.NaN(YNaNE), .SNaN(YSNaNE), .Denorm(YDenormE),
|
||||
.Zero(YZeroE), .Inf(YInfE), .ExpMax(YExpMaxE), .ExpZero(YExpZero));
|
||||
|
||||
// exponent
|
||||
assign XExpE = {X[`FLEN-2:`NF+1], X[`NF]|XDenormE};
|
||||
assign YExpE = {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE};
|
||||
assign ZExpE = {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE};
|
||||
|
||||
// fraction (no assumed 1)
|
||||
assign XFracE = X[`NF-1:0];
|
||||
assign YFracE = Y[`NF-1:0];
|
||||
assign ZFracE = Z[`NF-1:0];
|
||||
|
||||
// is the exponent non-zero
|
||||
assign XExpNonzero = |XExpE;
|
||||
assign YExpNonzero = |YExpE;
|
||||
assign ZExpNonzero = |ZExpE;
|
||||
|
||||
// is the exponent all 1's
|
||||
assign XExpMaxE = &XExpE;
|
||||
assign YExpMaxE = &YExpE;
|
||||
assign ZExpMaxE = &ZExpE;
|
||||
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign XDenormE = ~|X[`FLEN-2:`NF] & ~XFracZero;
|
||||
assign YDenormE = ~|Y[`FLEN-2:`NF] & ~YFracZero;
|
||||
assign ZDenormE = ~|Z[`FLEN-2:`NF] & ~ZFracZero;
|
||||
|
||||
|
||||
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
|
||||
//***need better names for these constants
|
||||
// largest format | smaller format
|
||||
//----------------------------------
|
||||
// `FLEN | `LEN1 length of floating point number
|
||||
// `NE | `NE1 length of exponent
|
||||
// `NF | `NF1 length of fraction
|
||||
// `BIAS | `BIAS1 exponent's bias value
|
||||
// `FMT | `FMT1 precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
// Possible combinantions specified by spec:
|
||||
// double and single
|
||||
// single and half
|
||||
|
||||
// Not needed but can also handle:
|
||||
// quad and double
|
||||
// quad and single
|
||||
// quad and half
|
||||
// double and half
|
||||
|
||||
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
||||
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
|
||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||
assign XSgnE = FmtE ? X[`FLEN-1] : XLen1[`LEN1-1];
|
||||
assign YSgnE = FmtE ? Y[`FLEN-1] : YLen1[`LEN1-1];
|
||||
assign ZSgnE = FmtE ? Z[`FLEN-1] : ZLen1[`LEN1-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// extract the exponent, converting the smaller exponent into the larger precision if nessisary
|
||||
// - if the original precision had a denormal number convert the exponent value 1
|
||||
assign XExpE = FmtE ? {X[`FLEN-2:`NF+1], X[`NF]|XDenormE} : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]}}, XLen1[`LEN1-3:`NF1+1], XLen1[`NF1]|XDenormE};
|
||||
assign YExpE = FmtE ? {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE} : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]}}, YLen1[`LEN1-3:`NF1+1], YLen1[`NF1]|YDenormE};
|
||||
assign ZExpE = FmtE ? {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE} : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]}}, ZLen1[`LEN1-3:`NF1+1], ZLen1[`NF1]|ZDenormE};
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign XDenormE = (FmtE ? ~|X[`FLEN-2:`NF] : ~|XLen1[`LEN1-2:`NF1]) & ~XFracZero;
|
||||
assign YDenormE = (FmtE ? ~|Y[`FLEN-2:`NF] : ~|YLen1[`LEN1-2:`NF1]) & ~YFracZero;
|
||||
assign ZDenormE = (FmtE ? ~|Z[`FLEN-2:`NF] : ~|ZLen1[`LEN1-2:`NF1]) & ~ZFracZero;
|
||||
|
||||
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
||||
assign XFracE = FmtE ? X[`NF-1:0] : {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
assign YFracE = FmtE ? Y[`NF-1:0] : {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
assign ZFracE = FmtE ? Z[`NF-1:0] : {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
|
||||
// is the exponent non-zero
|
||||
assign XExpNonzero = FmtE ? |X[`FLEN-2:`NF] : |XLen1[`LEN1-2:`NF1];
|
||||
assign YExpNonzero = FmtE ? |Y[`FLEN-2:`NF] : |YLen1[`LEN1-2:`NF1];
|
||||
assign ZExpNonzero = FmtE ? |Z[`FLEN-2:`NF] : |ZLen1[`LEN1-2:`NF1];
|
||||
|
||||
// is the exponent all 1's
|
||||
assign XExpMaxE = FmtE ? &X[`FLEN-2:`NF] : &XLen1[`LEN1-2:`NF1];
|
||||
assign YExpMaxE = FmtE ? &Y[`FLEN-2:`NF] : &YLen1[`LEN1-2:`NF1];
|
||||
assign ZExpMaxE = FmtE ? &Z[`FLEN-2:`NF] : &ZLen1[`LEN1-2:`NF1];
|
||||
|
||||
|
||||
end else if (`FPSIZES == 3) begin // three floating point precsions supported
|
||||
|
||||
//***need better names for these constants
|
||||
// largest format | larger format | smallest format
|
||||
//---------------------------------------------------
|
||||
// `FLEN | `LEN1 | `LEN2 length of floating point number
|
||||
// `NE | `NE1 | `NE2 length of exponent
|
||||
// `NF | `NF1 | `NF2 length of fraction
|
||||
// `BIAS | `BIAS1 | `BIAS2 exponent's bias value
|
||||
// `FMT | `FMT1 | `FMT2 precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
// Possible combinantions specified by spec:
|
||||
// quad and double and single
|
||||
// double and single and half
|
||||
|
||||
// Not needed but can also handle:
|
||||
// quad and double and half
|
||||
// quad and single and half
|
||||
|
||||
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision
|
||||
logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for smallest precision
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for larger precision
|
||||
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for smaller precision
|
||||
assign XLen2 = &X[`FLEN-1:`LEN2] ? X[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||
assign YLen2 = &Y[`FLEN-1:`LEN2] ? Y[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||
assign ZLen2 = &Z[`FLEN-1:`LEN2] ? Z[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||
|
||||
// There are 2 case statements
|
||||
// - one for other singals and one for sgn/exp/frac
|
||||
// - need two for the dependencies in the expoenent calculation
|
||||
//*** pull out the ~FracZero and and it at the end
|
||||
always_comb begin
|
||||
case (FmtE)
|
||||
`FMT: begin // if input is largest precision (`FLEN - ie quad or double)
|
||||
|
||||
// This is the original format so set OrigDenorm to 0
|
||||
XDenormE = ~|X[`FLEN-2:`NF] & ~XFracZero;
|
||||
YDenormE = ~|Y[`FLEN-2:`NF] & ~YFracZero;
|
||||
ZDenormE = ~|Z[`FLEN-2:`NF] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |X[`FLEN-2:`NF];
|
||||
YExpNonzero = |Y[`FLEN-2:`NF];
|
||||
ZExpNonzero = |Z[`FLEN-2:`NF];
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &X[`FLEN-2:`NF];
|
||||
YExpMaxE = &Y[`FLEN-2:`NF];
|
||||
ZExpMaxE = &Z[`FLEN-2:`NF];
|
||||
end
|
||||
`FMT1: begin // if input is larger precsion (`LEN1 - double or single)
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|XLen1[`LEN1-2:`NF1] & ~XFracZero;
|
||||
YDenormE = ~|YLen1[`LEN1-2:`NF1] & ~YFracZero;
|
||||
ZDenormE = ~|ZLen1[`LEN1-2:`NF1] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |XLen1[`LEN1-2:`NF1];
|
||||
YExpNonzero = |YLen1[`LEN1-2:`NF1];
|
||||
ZExpNonzero = |ZLen1[`LEN1-2:`NF1];
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &XLen1[`LEN1-2:`NF1];
|
||||
YExpMaxE = &YLen1[`LEN1-2:`NF1];
|
||||
ZExpMaxE = &ZLen1[`LEN1-2:`NF1];
|
||||
end
|
||||
`FMT2: begin // if input is smallest precsion (`LEN2 - single or half)
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|XLen2[`LEN2-2:`NF2] & ~XFracZero;
|
||||
YDenormE = ~|YLen2[`LEN2-2:`NF2] & ~YFracZero;
|
||||
ZDenormE = ~|ZLen2[`LEN2-2:`NF2] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |XLen2[`LEN2-2:`NF2];
|
||||
YExpNonzero = |YLen2[`LEN2-2:`NF2];
|
||||
ZExpNonzero = |ZLen2[`LEN2-2:`NF2];
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &XLen2[`LEN2-2:`NF2];
|
||||
YExpMaxE = &YLen2[`LEN2-2:`NF2];
|
||||
ZExpMaxE = &ZLen2[`LEN2-2:`NF2];
|
||||
end
|
||||
default: begin
|
||||
XDenormE = 0;
|
||||
YDenormE = 0;
|
||||
ZDenormE = 0;
|
||||
XExpNonzero = 0;
|
||||
YExpNonzero = 0;
|
||||
ZExpNonzero = 0;
|
||||
XExpMaxE = 0;
|
||||
YExpMaxE = 0;
|
||||
ZExpMaxE = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
always_comb begin
|
||||
case (FmtE)
|
||||
`FMT: begin // if input is largest precision (`FLEN - ie quad or double)
|
||||
// extract the sign bit
|
||||
XSgnE = X[`FLEN-1];
|
||||
YSgnE = Y[`FLEN-1];
|
||||
ZSgnE = Z[`FLEN-1];
|
||||
|
||||
// extract the exponent
|
||||
XExpE = {X[`FLEN-2:`NF+1], X[`NF]|XDenormE};
|
||||
YExpE = {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE};
|
||||
ZExpE = {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE};
|
||||
|
||||
// extract the fraction
|
||||
XFracE = X[`NF-1:0];
|
||||
YFracE = Y[`NF-1:0];
|
||||
ZFracE = Z[`NF-1:0];
|
||||
end
|
||||
`FMT1: begin // if input is larger precsion (`LEN1 - double or single)
|
||||
|
||||
// extract the sign bit
|
||||
XSgnE = XLen1[`LEN1-1];
|
||||
YSgnE = YLen1[`LEN1-1];
|
||||
ZSgnE = ZLen1[`LEN1-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the larger precision's exponent to use the largest precision's bias
|
||||
XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]}}, XLen1[`LEN1-3:`NF1+1], XLen1[`NF1]|XDenormE};
|
||||
YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]}}, YLen1[`LEN1-3:`NF1+1], YLen1[`NF1]|YDenormE};
|
||||
ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]}}, ZLen1[`LEN1-3:`NF1+1], ZLen1[`NF1]|ZDenormE};
|
||||
|
||||
// extract the fraction and add the nessesary trailing zeros
|
||||
XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
end
|
||||
`FMT2: begin // if input is smallest precsion (`LEN2 - single or half)
|
||||
|
||||
// exctract the sign bit
|
||||
XSgnE = XLen2[`LEN2-1];
|
||||
YSgnE = YLen2[`LEN2-1];
|
||||
ZSgnE = ZLen2[`LEN2-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the smallest precision's exponent to use the largest precision's bias
|
||||
XExpE = XDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]}}, XLen2[`LEN2-3:`NF2]};
|
||||
YExpE = YDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]}}, YLen2[`LEN2-3:`NF2]};
|
||||
ZExpE = ZDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]}}, ZLen2[`LEN2-3:`NF2]};
|
||||
|
||||
// extract the fraction and add the nessesary trailing zeros
|
||||
XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||
YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||
ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||
end
|
||||
default: begin
|
||||
XSgnE = 0;
|
||||
YSgnE = 0;
|
||||
ZSgnE = 0;
|
||||
XExpE = 0;
|
||||
YExpE = 0;
|
||||
ZExpE = 0;
|
||||
XFracE = 0;
|
||||
YFracE = 0;
|
||||
ZFracE = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
end else if (`FPSIZES == 4) begin // if all precsisons are supported - quad, double, single, and half
|
||||
|
||||
// quad | double | single | half
|
||||
//-------------------------------------------------------------------
|
||||
// `Q_LEN | `D_LEN | `S_LEN | `H_LEN length of floating point number
|
||||
// `Q_NE | `D_NE | `S_NE | `H_NE length of exponent
|
||||
// `Q_NF | `D_NF | `S_NF | `H_NF length of fraction
|
||||
// `Q_BIAS | `D_BIAS | `S_BIAS | `H_BIAS exponent's bias value
|
||||
// `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
|
||||
logic [`D_LEN-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision
|
||||
logic [`S_LEN-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision
|
||||
logic [`H_LEN-1:0] XLen3, YLen3, ZLen3; // Remove NaN boxing or NaN, if not properly NaN boxed for half percision
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for double precision
|
||||
assign XLen1 = &X[`Q_LEN-1:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||
assign YLen1 = &Y[`Q_LEN-1:`D_LEN] ? Y[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||
assign ZLen1 = &Z[`Q_LEN-1:`D_LEN] ? Z[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for single precision
|
||||
assign XLen2 = &X[`Q_LEN-1:`S_LEN] ? X[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||
assign YLen2 = &Y[`Q_LEN-1:`S_LEN] ? Y[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||
assign ZLen2 = &Z[`Q_LEN-1:`S_LEN] ? Z[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for half precision
|
||||
assign XLen3 = &X[`Q_LEN-1:`H_LEN] ? X[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||
assign YLen3 = &Y[`Q_LEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||
assign ZLen3 = &Z[`Q_LEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||
|
||||
|
||||
// There are 2 case statements
|
||||
// - one for other singals and one for sgn/exp/frac
|
||||
// - need two for the dependencies in the expoenent calculation
|
||||
always_comb begin
|
||||
case (FmtE)
|
||||
2'b11: begin // if input is quad percision
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|X[`Q_LEN-2:`Q_NF] & ~XFracZero;
|
||||
YDenormE = ~|Y[`Q_LEN-2:`Q_NF] & ~YFracZero;
|
||||
ZDenormE = ~|Z[`Q_LEN-2:`Q_NF] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |X[`Q_LEN-2:`Q_NF];
|
||||
YExpNonzero = |Y[`Q_LEN-2:`Q_NF];
|
||||
ZExpNonzero = |Z[`Q_LEN-2:`Q_NF];
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &X[`Q_LEN-2:`Q_NF];
|
||||
YExpMaxE = &Y[`Q_LEN-2:`Q_NF];
|
||||
ZExpMaxE = &Z[`Q_LEN-2:`Q_NF];
|
||||
end
|
||||
2'b01: begin // if input is double percision
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &XLen1[`D_LEN-2:`D_NF];
|
||||
YExpMaxE = &YLen1[`D_LEN-2:`D_NF];
|
||||
ZExpMaxE = &ZLen1[`D_LEN-2:`D_NF];
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|XLen1[`D_LEN-2:`D_NF] & ~XFracZero;
|
||||
YDenormE = ~|YLen1[`D_LEN-2:`D_NF] & ~YFracZero;
|
||||
ZDenormE = ~|ZLen1[`D_LEN-2:`D_NF] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |XLen1[`D_LEN-2:`D_NF];
|
||||
YExpNonzero = |YLen1[`D_LEN-2:`D_NF];
|
||||
ZExpNonzero = |ZLen1[`D_LEN-2:`D_NF];
|
||||
end
|
||||
2'b00: begin // if input is single percision
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &XLen2[`S_LEN-2:`S_NF];
|
||||
YExpMaxE = &YLen2[`S_LEN-2:`S_NF];
|
||||
ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF];
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|XLen2[`S_LEN-2:`S_NF] & ~XFracZero;
|
||||
YDenormE = ~|YLen2[`S_LEN-2:`S_NF] & ~YFracZero;
|
||||
ZDenormE = ~|ZLen2[`S_LEN-2:`S_NF] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |XLen2[`S_LEN-2:`S_NF];
|
||||
YExpNonzero = |YLen2[`S_LEN-2:`S_NF];
|
||||
ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF];
|
||||
end
|
||||
2'b10: begin // if input is half percision
|
||||
|
||||
// is the exponent all 1's
|
||||
XExpMaxE = &XLen3[`H_LEN-2:`H_NF];
|
||||
YExpMaxE = &YLen3[`H_LEN-2:`H_NF];
|
||||
ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF];
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
XDenormE = ~|XLen3[`H_LEN-2:`H_NF] & ~XFracZero;
|
||||
YDenormE = ~|YLen3[`H_LEN-2:`H_NF] & ~YFracZero;
|
||||
ZDenormE = ~|ZLen3[`H_LEN-2:`H_NF] & ~ZFracZero;
|
||||
|
||||
// is the exponent non-zero
|
||||
XExpNonzero = |XLen3[`H_LEN-2:`H_NF];
|
||||
YExpNonzero = |YLen3[`H_LEN-2:`H_NF];
|
||||
ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (FmtE)
|
||||
2'b11: begin // if input is quad percision
|
||||
// extract sign bit
|
||||
XSgnE = X[`Q_LEN-1];
|
||||
YSgnE = Y[`Q_LEN-1];
|
||||
ZSgnE = Z[`Q_LEN-1];
|
||||
|
||||
// extract the exponent
|
||||
XExpE = {X[`Q_LEN-2:`Q_NF+1], X[`Q_NF]|XDenormE};
|
||||
YExpE = {Y[`Q_LEN-2:`Q_NF+1], Y[`Q_NF]|YDenormE};
|
||||
ZExpE = {Z[`Q_LEN-2:`Q_NF+1], Z[`Q_NF]|ZDenormE};
|
||||
|
||||
// extract the fraction
|
||||
XFracE = X[`Q_NF-1:0];
|
||||
YFracE = Y[`Q_NF-1:0];
|
||||
ZFracE = Z[`Q_NF-1:0];
|
||||
end
|
||||
2'b01: begin // if input is double percision
|
||||
// extract sign bit
|
||||
XSgnE = XLen1[`D_LEN-1];
|
||||
YSgnE = YLen1[`D_LEN-1];
|
||||
ZSgnE = ZLen1[`D_LEN-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the double precsion exponent into quad precsion
|
||||
|
||||
XExpE = {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]}}, XLen1[`D_LEN-3:`D_NF+1], XLen1[`D_NF]|XDenormE};
|
||||
YExpE = {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]}}, YLen1[`D_LEN-3:`D_NF+1], YLen1[`D_NF]|YDenormE};
|
||||
ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]}}, ZLen1[`D_LEN-3:`D_NF+1], ZLen1[`D_NF]|ZDenormE};
|
||||
|
||||
// extract the fraction and add the nessesary trailing zeros
|
||||
XFracE = {XLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)};
|
||||
YFracE = {YLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)};
|
||||
ZFracE = {ZLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)};
|
||||
end
|
||||
2'b00: begin // if input is single percision
|
||||
// extract sign bit
|
||||
XSgnE = XLen2[`S_LEN-1];
|
||||
YSgnE = YLen2[`S_LEN-1];
|
||||
ZSgnE = ZLen2[`S_LEN-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the single precsion exponent into quad precsion
|
||||
XExpE = {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]}}, XLen2[`S_LEN-3:`S_NF+1], XLen2[`S_NF]|XDenormE};
|
||||
YExpE = {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]}}, YLen2[`S_LEN-3:`S_NF+1], YLen2[`S_NF]|YDenormE};
|
||||
ZExpE = {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]}}, ZLen2[`S_LEN-3:`S_NF+1], ZLen2[`S_NF]|ZDenormE};
|
||||
|
||||
// extract the fraction and add the nessesary trailing zeros
|
||||
XFracE = {XLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||
YFracE = {YLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||
ZFracE = {ZLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||
end
|
||||
2'b10: begin // if input is half percision
|
||||
// extract sign bit
|
||||
XSgnE = XLen3[`H_LEN-1];
|
||||
YSgnE = YLen3[`H_LEN-1];
|
||||
ZSgnE = ZLen3[`H_LEN-1];
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the half precsion exponent into quad precsion
|
||||
XExpE = {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]}}, XLen3[`H_LEN-3:`H_NF+1], XLen3[`H_NF]|XDenormE};
|
||||
YExpE = {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]}}, YLen3[`H_LEN-3:`H_NF+1], YLen3[`H_NF]|YDenormE};
|
||||
ZExpE = {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]}}, ZLen3[`H_LEN-3:`H_NF+1], ZLen3[`H_NF]|ZDenormE};
|
||||
|
||||
// extract the fraction and add the nessesary trailing zeros
|
||||
XFracE = {XLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||
YFracE = {YLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||
ZFracE = {ZLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// is the exponent all 0's
|
||||
assign XExpZero = ~XExpNonzero;
|
||||
assign YExpZero = ~YExpNonzero;
|
||||
assign ZExpZero = ~ZExpNonzero;
|
||||
|
||||
// is the fraction zero
|
||||
assign XFracZero = ~|XFracE;
|
||||
assign YFracZero = ~|YFracE;
|
||||
assign ZFracZero = ~|ZFracE;
|
||||
|
||||
// add the assumed one (or zero if denormal or zero) to create the mantissa
|
||||
assign XManE = {XExpNonzero, XFracE};
|
||||
assign YManE = {YExpNonzero, YFracE};
|
||||
assign ZManE = {ZExpNonzero, ZFracE};
|
||||
unpackinput unpackinputZ (.In(Z), .FmtE, .Sgn(ZSgnE), .Exp(ZExpE), .Man(ZManE),
|
||||
.NaN(ZNaNE), .SNaN(ZSNaNE), .Denorm(ZDenormE),
|
||||
.Zero(ZZeroE), .Inf(ZInfE), .ExpMax(ZExpMaxE), .ExpZero(ZExpZero));
|
||||
|
||||
|
||||
// is X normalized
|
||||
assign XNormE = ~(XExpMaxE|XExpZero);
|
||||
|
||||
// is the input a NaN
|
||||
// - force to be a NaN if it isn't properly Nan Boxed
|
||||
assign XNaNE = XExpMaxE & ~XFracZero;
|
||||
assign YNaNE = YExpMaxE & ~YFracZero;
|
||||
assign ZNaNE = ZExpMaxE & ~ZFracZero;
|
||||
|
||||
// is the input a singnaling NaN
|
||||
assign XSNaNE = XNaNE&~XFracE[`NF-1];
|
||||
assign YSNaNE = YNaNE&~YFracE[`NF-1];
|
||||
assign ZSNaNE = ZNaNE&~ZFracE[`NF-1];
|
||||
|
||||
// // is the input denormalized
|
||||
// assign XDenormE = XExpZero & ~XFracZero;
|
||||
// assign YDenormE = YExpZero & ~YFracZero;
|
||||
// assign ZDenormE = ZExpZero & ~ZFracZero;
|
||||
|
||||
// is the input infinity
|
||||
assign XInfE = XExpMaxE & XFracZero;
|
||||
assign YInfE = YExpMaxE & YFracZero;
|
||||
assign ZInfE = ZExpMaxE & ZFracZero;
|
||||
|
||||
// is the input zero
|
||||
assign XZeroE = XExpZero & XFracZero;
|
||||
assign YZeroE = YExpZero & YFracZero;
|
||||
assign ZZeroE = ZExpZero & ZFracZero;
|
||||
|
||||
endmodule
|
301
pipelined/src/fpu/unpackinput.sv
Normal file
301
pipelined/src/fpu/unpackinput.sv
Normal file
@ -0,0 +1,301 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module unpackinput (
|
||||
input logic [`FLEN-1:0] In, // inputs from register file
|
||||
input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 01 - double 11 - quad 10 - half
|
||||
output logic Sgn, // sign bits of XYZ
|
||||
output logic [`NE-1:0] Exp, // exponents of XYZ (converted to largest supported precision)
|
||||
output logic [`NF:0] Man, // mantissas of XYZ (converted to largest supported precision)
|
||||
output logic NaN, // is XYZ a NaN
|
||||
output logic SNaN, // is XYZ a signaling NaN
|
||||
output logic Denorm, // is XYZ denormalized
|
||||
output logic Zero, // is XYZ zero
|
||||
output logic Inf, // is XYZ infinity
|
||||
output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
|
||||
output logic ExpZero // is the exponent zero
|
||||
);
|
||||
|
||||
logic [`NF-1:0] Frac; //Fraction of XYZ
|
||||
logic ExpNonZero; // is the exponent of XYZ non-zero
|
||||
logic FracZero; // is the fraction zero
|
||||
|
||||
if (`FPSIZES == 1) begin // if there is only one floating point format supported
|
||||
|
||||
// sign bit
|
||||
assign Sgn = In[`FLEN-1];
|
||||
|
||||
// fraction (no assumed 1)
|
||||
assign Frac = In[`NF-1:0];
|
||||
|
||||
// is the fraction zero
|
||||
assign FracZero = ~|Frac;
|
||||
|
||||
// is the exponent non-zero
|
||||
assign ExpNonZero = |Exp;
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign Denorm = ~ExpNonZero & ~FracZero;
|
||||
|
||||
// exponent
|
||||
assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm};
|
||||
|
||||
|
||||
// is the exponent all 1's
|
||||
assign ExpMax = &Exp;
|
||||
|
||||
|
||||
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
|
||||
//***need better names for these constants
|
||||
// largest format | smaller format
|
||||
//----------------------------------
|
||||
// `FLEN | `LEN1 length of floating point number
|
||||
// `NE | `NE1 length of exponent
|
||||
// `NF | `NF1 length of fraction
|
||||
// `BIAS | `BIAS1 exponent's bias value
|
||||
// `FMT | `FMT1 precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
// Possible combinantions specified by spec:
|
||||
// double and single
|
||||
// single and half
|
||||
|
||||
// Not needed but can also handle:
|
||||
// quad and double
|
||||
// quad and single
|
||||
// quad and half
|
||||
// double and half
|
||||
|
||||
logic [`LEN1-1:0] Len1; // Remove NaN boxing or NaN, if not properly NaN boxed
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
||||
assign Len1 = &In[`FLEN-1:`LEN1] ? In[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
|
||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||
assign Sgn = FmtE ? In[`FLEN-1] : Len1[`LEN1-1];
|
||||
|
||||
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
||||
assign Frac = FmtE ? In[`NF-1:0] : {Len1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
|
||||
// is the fraction zero
|
||||
assign FracZero = ~|Frac;
|
||||
|
||||
// is the exponent non-zero
|
||||
assign ExpNonZero = FmtE ? |In[`FLEN-2:`NF] : |Len1[`LEN1-2:`NF1];
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign Denorm = ~ExpNonZero & ~FracZero;
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// extract the exponent, converting the smaller exponent into the larger precision if nessisary
|
||||
// - if the original precision had a denormal number convert the exponent value 1
|
||||
assign Exp = FmtE ? {In[`FLEN-2:`NF+1], In[`NF]|Denorm} : {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm};
|
||||
|
||||
|
||||
|
||||
// is the exponent all 1's
|
||||
assign ExpMax = FmtE ? &In[`FLEN-2:`NF] : &Len1[`LEN1-2:`NF1];
|
||||
|
||||
|
||||
end else if (`FPSIZES == 3) begin // three floating point precsions supported
|
||||
|
||||
//***need better names for these constants
|
||||
// largest format | larger format | smallest format
|
||||
//---------------------------------------------------
|
||||
// `FLEN | `LEN1 | `LEN2 length of floating point number
|
||||
// `NE | `NE1 | `NE2 length of exponent
|
||||
// `NF | `NF1 | `NF2 length of fraction
|
||||
// `BIAS | `BIAS1 | `BIAS2 exponent's bias value
|
||||
// `FMT | `FMT1 | `FMT2 precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
// Possible combinantions specified by spec:
|
||||
// quad and double and single
|
||||
// double and single and half
|
||||
|
||||
// Not needed but can also handle:
|
||||
// quad and double and half
|
||||
// quad and single and half
|
||||
|
||||
logic [`LEN1-1:0] Len1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision
|
||||
logic [`LEN2-1:0] Len2; // Remove NaN boxing or NaN, if not properly NaN boxed for smallest precision
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for larger precision
|
||||
assign Len1 = &In[`FLEN-1:`LEN1] ? In[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for smaller precision
|
||||
assign Len2 = &In[`FLEN-1:`LEN2] ? In[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||
|
||||
|
||||
// extract the sign bit
|
||||
always_comb
|
||||
case (FmtE)
|
||||
`FMT: Sgn = In[`FLEN-1];
|
||||
`FMT1: Sgn = Len1[`LEN1-1];
|
||||
`FMT2: Sgn = Len2[`LEN2-1];
|
||||
default: Sgn = 0;
|
||||
endcase
|
||||
|
||||
// extract the fraction
|
||||
always_comb
|
||||
case (FmtE)
|
||||
`FMT: Frac = In[`NF-1:0];
|
||||
`FMT1: Frac = {Len1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
`FMT2: Frac = {Len2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||
default: Frac = 0;
|
||||
endcase
|
||||
|
||||
// is the fraction zero
|
||||
assign FracZero = ~|Frac;
|
||||
|
||||
|
||||
// is the exponent non-zero
|
||||
always_comb
|
||||
case (FmtE)
|
||||
`FMT: ExpNonZero = |In[`FLEN-2:`NF]; // if input is largest precision (`FLEN - ie quad or double)
|
||||
`FMT1: ExpNonZero = |Len1[`LEN1-2:`NF1]; // if input is larger precsion (`LEN1 - double or single)
|
||||
`FMT2: ExpNonZero = |Len2[`LEN2-2:`NF2]; // if input is smallest precsion (`LEN2 - single or half)
|
||||
default: ExpNonZero = 0;
|
||||
endcase
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign Denorm = ~ExpNonZero & ~FracZero;
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the larger precision's exponent to use the largest precision's bias
|
||||
always_comb
|
||||
case (FmtE)
|
||||
`FMT: Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm};
|
||||
`FMT1: Exp = {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm};
|
||||
`FMT2: Exp = {Len2[`LEN2-2], {`NE-`NE2{~Len2[`LEN2-2]}}, Len2[`LEN2-3:`NF2+1], Len2[`NF2]|Denorm};
|
||||
default: Exp = 0;
|
||||
endcase
|
||||
|
||||
// is the exponent all 1's
|
||||
always_comb
|
||||
case (FmtE)
|
||||
`FMT: ExpMax = &In[`FLEN-2:`NF];
|
||||
`FMT1: ExpMax = &Len1[`LEN1-2:`NF1];
|
||||
`FMT2: ExpMax = &Len2[`LEN2-2:`NF2];
|
||||
default: ExpMax = 0;
|
||||
endcase
|
||||
|
||||
end else if (`FPSIZES == 4) begin // if all precsisons are supported - quad, double, single, and half
|
||||
|
||||
// quad | double | single | half
|
||||
//-------------------------------------------------------------------
|
||||
// `Q_LEN | `D_LEN | `S_LEN | `H_LEN length of floating point number
|
||||
// `Q_NE | `D_NE | `S_NE | `H_NE length of exponent
|
||||
// `Q_NF | `D_NF | `S_NF | `H_NF length of fraction
|
||||
// `Q_BIAS | `D_BIAS | `S_BIAS | `H_BIAS exponent's bias value
|
||||
// `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 S=00 H=10
|
||||
|
||||
|
||||
logic [`D_LEN-1:0] Len1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision
|
||||
logic [`S_LEN-1:0] Len2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision
|
||||
logic [`H_LEN-1:0] Len3; // Remove NaN boxing or NaN, if not properly NaN boxed for half percision
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for double precision
|
||||
assign Len1 = &In[`Q_LEN-1:`D_LEN] ? In[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for single precision
|
||||
assign Len2 = &In[`Q_LEN-1:`S_LEN] ? In[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||
|
||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for half precision
|
||||
assign Len3 = &In[`Q_LEN-1:`H_LEN] ? In[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||
|
||||
// extract sign bit
|
||||
always_comb
|
||||
case (FmtE)
|
||||
2'b11: Sgn = In[`Q_LEN-1];
|
||||
2'b01: Sgn = Len1[`D_LEN-1];
|
||||
2'b00: Sgn = Len2[`S_LEN-1];
|
||||
2'b10: Sgn = Len3[`H_LEN-1];
|
||||
endcase
|
||||
|
||||
|
||||
// extract the fraction
|
||||
always_comb
|
||||
case (FmtE)
|
||||
2'b11: Frac = In[`Q_NF-1:0];
|
||||
2'b01: Frac = {Len1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)};
|
||||
2'b00: Frac = {Len2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||
2'b10: Frac = {Len3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||
endcase
|
||||
|
||||
// is the fraction zero
|
||||
assign FracZero = ~|Frac;
|
||||
|
||||
// is the exponent non-zero
|
||||
always_comb
|
||||
case (FmtE)
|
||||
2'b11: ExpNonZero = |In[`Q_LEN-2:`Q_NF];
|
||||
2'b01: ExpNonZero = |Len1[`D_LEN-2:`D_NF];
|
||||
2'b00: ExpNonZero = |Len2[`S_LEN-2:`S_NF];
|
||||
2'b10: ExpNonZero = |Len3[`H_LEN-2:`H_NF];
|
||||
endcase
|
||||
|
||||
// is the input (in it's original format) denormalized
|
||||
assign Denorm = ~ExpNonZero & ~FracZero;
|
||||
|
||||
|
||||
// example double to single conversion:
|
||||
// 1023 = 0011 1111 1111
|
||||
// 127 = 0000 0111 1111 (subtract this)
|
||||
// 896 = 0011 1000 0000
|
||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/denorm/inf/NaN values
|
||||
|
||||
// convert the double precsion exponent into quad precsion
|
||||
always_comb
|
||||
case (FmtE)
|
||||
2'b11: Exp = {In[`Q_LEN-2:`Q_NF+1], In[`Q_NF]|Denorm};
|
||||
2'b01: Exp = {Len1[`D_LEN-2], {`Q_NE-`D_NE{~Len1[`D_LEN-2]}}, Len1[`D_LEN-3:`D_NF+1], Len1[`D_NF]|Denorm};
|
||||
2'b00: Exp = {Len2[`S_LEN-2], {`Q_NE-`S_NE{~Len2[`S_LEN-2]}}, Len2[`S_LEN-3:`S_NF+1], Len2[`S_NF]|Denorm};
|
||||
2'b10: Exp = {Len3[`H_LEN-2], {`Q_NE-`H_NE{~Len3[`H_LEN-2]}}, Len3[`H_LEN-3:`H_NF+1], Len3[`H_NF]|Denorm};
|
||||
endcase
|
||||
|
||||
|
||||
// is the exponent all 1's
|
||||
always_comb
|
||||
case (FmtE)
|
||||
2'b11: ExpMax = &In[`Q_LEN-2:`Q_NF];
|
||||
2'b01: ExpMax = &Len1[`D_LEN-2:`D_NF];
|
||||
2'b00: ExpMax = &Len2[`S_LEN-2:`S_NF];
|
||||
2'b10: ExpMax = &Len3[`H_LEN-2:`H_NF];
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
// is the exponent all 0's
|
||||
assign ExpZero = ~ExpNonZero;
|
||||
|
||||
// add the assumed one (or zero if denormal or zero) to create the mantissa
|
||||
assign Man = {ExpNonZero, Frac};
|
||||
|
||||
// is the input a NaN
|
||||
// - force to be a NaN if it isn't properly Nan Boxed
|
||||
assign NaN = ExpMax & ~FracZero;
|
||||
|
||||
// is the input a singnaling NaN
|
||||
assign SNaN = NaN&~Frac[`NF-1];
|
||||
|
||||
// is the input infinity
|
||||
assign Inf = ExpMax & FracZero;
|
||||
|
||||
// is the input zero
|
||||
assign Zero = ExpZero & FracZero;
|
||||
|
||||
endmodule
|
@ -1,14 +1,14 @@
|
||||
//leading zero counter i.e. priority encoder
|
||||
module lzc #(parameter WIDTH=1) (
|
||||
input logic [WIDTH-1:0] num,
|
||||
output logic [$clog2(WIDTH)-1:0] ZeroCnt
|
||||
output logic [$clog2(WIDTH+1)-1:0] ZeroCnt
|
||||
);
|
||||
/* verilator lint_off CMPCONST */
|
||||
|
||||
logic [$clog2(WIDTH)-1:0] i;
|
||||
logic [$clog2(WIDTH+1)-1:0] i;
|
||||
always_comb begin
|
||||
i = 0;
|
||||
while (~num[WIDTH-1-(32)'(i)] & $unsigned(i) <= $unsigned(($clog2(WIDTH))'(WIDTH-1))) i = i+1; // search for leading one
|
||||
while (~num[WIDTH-1-(32)'(i)] & $unsigned(i) <= $unsigned(($clog2(WIDTH+1))'(WIDTH-1))) i = i+1; // search for leading one
|
||||
ZeroCnt = i;
|
||||
end
|
||||
/* verilator lint_on CMPCONST */
|
||||
|
@ -119,6 +119,7 @@ logic [3:0] dummy;
|
||||
"wally32i": tests = wally32i; // *** redo
|
||||
"wally32e": tests = wally32e;
|
||||
"wally32priv": tests = wally32priv; // *** redo
|
||||
"embench": tests = embench;
|
||||
endcase
|
||||
end
|
||||
if (tests.size() == 0) begin
|
||||
@ -127,7 +128,7 @@ logic [3:0] dummy;
|
||||
end
|
||||
end
|
||||
|
||||
string signame, memfilename, pathname;
|
||||
string signame, memfilename, pathname, objdumpfilename, adrstr;
|
||||
|
||||
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||
logic UARTSin, UARTSout;
|
||||
|
@ -28,6 +28,7 @@
|
||||
`define WALLYTEST "2"
|
||||
`define MYIMPERASTEST "3"
|
||||
`define COREMARK "4"
|
||||
`define EMBENCH "5"
|
||||
// *** remove MYIMPERASTEST cases when ported
|
||||
|
||||
string tvpaths[] = '{
|
||||
@ -35,15 +36,44 @@ string tvpaths[] = '{
|
||||
"../../addins/riscv-arch-test/work/",
|
||||
"../../tests/wally-riscv-arch-test/work/",
|
||||
"../../tests/imperas-riscv-tests/work/",
|
||||
"../../benchmarks/riscv-coremark/work/"
|
||||
"../../benchmarks/riscv-coremark/work/",
|
||||
"../../addins/embench-iot/bd_speed/src/"
|
||||
};
|
||||
|
||||
|
||||
|
||||
// *** make sure these are somewhere
|
||||
string coremark[] = '{
|
||||
`COREMARK,
|
||||
"coremark.bare.riscv", "100000"
|
||||
};
|
||||
|
||||
string embench[] = '{
|
||||
`EMBENCH,
|
||||
"aha-mont64/aha-mont64", "1080",
|
||||
"crc32/crc32", "1080",
|
||||
"cubic/cubic", "9080",
|
||||
"edn/edn", "1080",
|
||||
"huffbench/huffbench", "5080",
|
||||
"matmult-int/matmult-int", "1080",
|
||||
"md5sum/md5sum", "4080",
|
||||
"minver/minver", "2080",
|
||||
"nbody/nbody", "2080",
|
||||
"nettle-aes/nettle-aes", "1080",
|
||||
"nettle-sha256/nettle-sha256", "2080",
|
||||
"nsichneu/nsichneu", "4080",
|
||||
"picojpeg/picojpeg", "3080",
|
||||
"primecount/primecount", "1080",
|
||||
"qrduino/qrduino", "6080",
|
||||
"sglib-combined/sglib-combined", "5080",
|
||||
"slre/slre", "1080",
|
||||
"st/st", "2080",
|
||||
"statemate/statemate", "2080",
|
||||
"tarfind/tarfind", "4080",
|
||||
"ud/ud", "1080",
|
||||
"wikisort/wikisort", "3080"
|
||||
};
|
||||
|
||||
string wally64a[] = '{
|
||||
`WALLYTEST,
|
||||
"rv64i_m/privilege/WALLY-amo", "2210",
|
||||
|
Loading…
Reference in New Issue
Block a user