From e3d01c875b3af6bfa64d9a5a404b0b5495a49406 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Sat, 19 Mar 2022 19:39:03 +0000 Subject: [PATCH 01/11] FMA parameterized and FMA testbench reworked --- addins/riscv-arch-test | 2 +- pipelined/config/rv64fp/BTBPredictor.txt | 1024 +++++++++++++++++ pipelined/config/rv64fp/twoBitPredictor.txt | 1024 +++++++++++++++++ pipelined/config/rv64fp/wally-config.vh | 134 +++ pipelined/config/shared/wally-shared.vh | 43 +- pipelined/fpu-testfloat/FMA/tbgen/tb.sv | 376 +++--- pipelined/fpu-testfloat/FMA/tbgen/test_gen.sh | 2 +- pipelined/src/fpu/fcmp.sv | 1 + pipelined/src/fpu/{cvtfp.sv => fcvtfp.sv} | 3 +- pipelined/src/fpu/{fcvt.sv => fcvtint.sv} | 5 +- pipelined/src/fpu/fma.sv | 805 ++++++++++--- pipelined/src/fpu/fpu.sv | 5 +- pipelined/src/fpu/unpack.sv | 361 ++++++ pipelined/src/fpu/unpacking.sv | 95 -- pipelined/testbench/fp/tests/fma-testbench.sv | 279 +++++ pipelined/testbench/fp/tests/fma.do | 50 + pipelined/testbench/fp/tests/sim-fma | 1 + pipelined/testbench/fp/tests/sim-fma-batch | 1 + tests/fp/create_vectors128fma.sh | 31 + tests/fp/create_vectors16fma.sh | 31 + tests/fp/create_vectors32fma.sh | 31 + tests/fp/create_vectors64fma.sh | 31 + tests/fp/run_all.sh | 4 + 23 files changed, 3927 insertions(+), 412 deletions(-) create mode 100644 pipelined/config/rv64fp/BTBPredictor.txt create mode 100644 pipelined/config/rv64fp/twoBitPredictor.txt create mode 100644 pipelined/config/rv64fp/wally-config.vh rename pipelined/src/fpu/{cvtfp.sv => fcvtfp.sv} (98%) rename pipelined/src/fpu/{fcvt.sv => fcvtint.sv} (98%) create mode 100644 pipelined/src/fpu/unpack.sv delete mode 100644 pipelined/src/fpu/unpacking.sv create mode 100644 pipelined/testbench/fp/tests/fma-testbench.sv create mode 100644 pipelined/testbench/fp/tests/fma.do create mode 100755 pipelined/testbench/fp/tests/sim-fma create mode 100755 pipelined/testbench/fp/tests/sim-fma-batch create mode 100755 tests/fp/create_vectors128fma.sh create mode 100755 tests/fp/create_vectors16fma.sh create mode 100755 tests/fp/create_vectors32fma.sh create mode 100755 tests/fp/create_vectors64fma.sh diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index 307c77b26..be67c99bd 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86 +Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 diff --git a/pipelined/config/rv64fp/BTBPredictor.txt b/pipelined/config/rv64fp/BTBPredictor.txt new file mode 100644 index 000000000..b761147c6 --- /dev/null +++ b/pipelined/config/rv64fp/BTBPredictor.txt @@ -0,0 +1,1024 @@ +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 diff --git a/pipelined/config/rv64fp/twoBitPredictor.txt b/pipelined/config/rv64fp/twoBitPredictor.txt new file mode 100644 index 000000000..ff57bd473 --- /dev/null +++ b/pipelined/config/rv64fp/twoBitPredictor.txt @@ -0,0 +1,1024 @@ +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/pipelined/config/rv64fp/wally-config.vh b/pipelined/config/rv64fp/wally-config.vh new file mode 100644 index 000000000..249af8485 --- /dev/null +++ b/pipelined/config/rv64fp/wally-config.vh @@ -0,0 +1,134 @@ +////////////////////////////////////////// +// wally-config.vh +// +// Written: David_Harris@hmc.edu 4 January 2021 +// Modified: +// +// Purpose: Specify which features are configured +// Macros to determine which modes are supported based on MISA +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +// include shared configuration +`include "wally-shared.vh" + +`define FPGA 0 +`define QEMU 0 +`define DESIGN_COMPILER 0 + +// RV32 or RV64: XLEN = 32 or 64 +`define XLEN 64 + +// IEEE 754 compliance +`define IEEE754 1 + +// MISA RISC-V configuration per specification +`define MISA (32'h00000104 | 1 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 ) +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 +`define COUNTERS 32 +`define ZICOUNTERS_SUPPORTED 1 + +/// Microarchitectural Features +`define UARCH_PIPELINED 1 +`define UARCH_SUPERSCALR 0 +`define UARCH_SINGLECYCLE 0 +`define DMEM `MEM_CACHE +`define IMEM `MEM_CACHE +`define VIRTMEM_SUPPORTED 1 +`define VECTORED_INTERRUPTS_SUPPORTED 1 + +// TLB configuration. Entries should be a power of 2 +`define ITLB_ENTRIES 32 +`define DTLB_ENTRIES 32 + +// Cache configuration. Sizes should be a power of two +// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines +`define DCACHE_NUMWAYS 4 +`define DCACHE_WAYSIZEINBYTES 4096 +`define DCACHE_LINELENINBITS 256 +`define ICACHE_NUMWAYS 4 +`define ICACHE_WAYSIZEINBYTES 4096 +`define ICACHE_LINELENINBITS 256 + +// Integer Divider Configuration +// DIV_BITSPERCYCLE must be 1, 2, or 4 +`define DIV_BITSPERCYCLE 4 + +// Legal number of PMP entries are 0, 16, or 64 +`define PMP_ENTRIES 64 + +// Address space +`define RESET_VECTOR 64'h0000000080000000 + +// Bus Interface width +`define AHBW 64 + +// Peripheral Physiccal Addresses +// Peripheral memory space extends from BASE to BASE+RANGE +// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits + +// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file? +`define BOOTROM_SUPPORTED 1'b1 +`define BOOTROM_BASE 56'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder +`define BOOTROM_RANGE 56'h00000FFF +`define RAM_SUPPORTED 1'b1 +`define RAM_BASE 56'h80000000 +`define RAM_RANGE 56'h7FFFFFFF +`define EXT_MEM_SUPPORTED 1'b0 +`define EXT_MEM_BASE 56'h80000000 +`define EXT_MEM_RANGE 56'h07FFFFFF +`define CLINT_SUPPORTED 1'b1 +`define CLINT_BASE 56'h02000000 +`define CLINT_RANGE 56'h0000FFFF +`define GPIO_SUPPORTED 1'b1 +`define GPIO_BASE 56'h10060000 +`define GPIO_RANGE 56'h000000FF +`define UART_SUPPORTED 1'b1 +`define UART_BASE 56'h10000000 +`define UART_RANGE 56'h00000007 +`define PLIC_SUPPORTED 1'b1 +`define PLIC_BASE 56'h0C000000 +`define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b0 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h0000001F + +// Test modes + +// Tie GPIO outputs back to inputs +`define GPIO_LOOPBACK_TEST 1 + +// Hardware configuration +`define UART_PRESCALE 1 + +// Interrupt configuration +`define PLIC_NUM_SRC 10 +// comment out the following if >=32 sources +`define PLIC_NUM_SRC_LT_32 +`define PLIC_GPIO_ID 3 +`define PLIC_UART_ID 10 + +`define TWO_BIT_PRELOAD "../config/rv64ic/twoBitPredictor.txt" +`define BTB_PRELOAD "../config/rv64ic/BTBPredictor.txt" +`define BPRED_ENABLED 1 +`define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define TESTSBP 0 + +`define REPLAY 0 +`define HPTW_WRITES_SUPPORTED 0 diff --git a/pipelined/config/shared/wally-shared.vh b/pipelined/config/shared/wally-shared.vh index 277814f80..198a4ab2e 100644 --- a/pipelined/config/shared/wally-shared.vh +++ b/pipelined/config/shared/wally-shared.vh @@ -50,10 +50,47 @@ // Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries) `define PMPCFG_ENTRIES (`PMP_ENTRIES/8) + +// Floating-point half-precision +`define ZFH_SUPPORTED 0 + +// Floating point constants for Quad, Double, Single, and Half precisions +`define Q_LEN 128 +`define Q_NE 15 +`define Q_NF 112 +`define Q_BIAS 16383 +`define D_LEN 64 +`define D_NE 11 +`define D_NF 52 +`define D_BIAS 1023 +`define S_LEN 32 +`define S_NE 8 +`define S_NF 23 +`define S_BIAS 127 +`define H_LEN 16 +`define H_NE 5 +`define H_NF 10 +`define H_BIAS 15 + // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits -`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32) -`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) -`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) +`define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN) +`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) +`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) +`define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2) +`define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS) + +// Floating point constants needed for FPU paramerterization +`define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED) +`define LEN1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN : `H_LEN) +`define NE1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE : `H_NE) +`define NF1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF) +`define FMT1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1 : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0 : 2) +`define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS) +`define LEN2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN : `H_LEN) +`define NE2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE : `H_NE) +`define NF2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF : `H_NF) +`define FMT2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0 : 2) +`define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS : `H_BIAS) // Disable spurious Verilator warnings diff --git a/pipelined/fpu-testfloat/FMA/tbgen/tb.sv b/pipelined/fpu-testfloat/FMA/tbgen/tb.sv index 57c4e2ff0..5532aa634 100644 --- a/pipelined/fpu-testfloat/FMA/tbgen/tb.sv +++ b/pipelined/fpu-testfloat/FMA/tbgen/tb.sv @@ -1,10 +1,33 @@ -//`include "../../../config/old/rv64icfd/wally-config.vh" +`include "../../../config/old/rv64icfd/wally-config.vh" -`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32) -`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) -`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) -`define XLEN 64 +// `define FLEN (`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : `F_SUPPORTED ? 32 : 16) +// `define NE (`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : `F_SUPPORTED ? 8 : 5) +// `define NF (`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : `F_SUPPORTED ? 23 : 10) +// `define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2) +// `define BIAS (`Q_SUPPORTED ? 16383 : `D_SUPPORTED ? 1023 : `F_SUPPORTED ? 127 : 15) +// `define XLEN 64 +// `define IEEE754 1 +`define Q_SUPPORTED 1 +// `define D_SUPPORTED 0 +// `define F_SUPPORTED 0 +`define H_SUPPORTED 0 +`define FPSIZES ((`Q_SUPPORTED&`D_SUPPORTED&`F_SUPPORTED&`H_SUPPORTED) ? 4 : (`Q_SUPPORTED&`D_SUPPORTED&`F_SUPPORTED) | (`Q_SUPPORTED&`D_SUPPORTED&`H_SUPPORTED) | (`Q_SUPPORTED&`F_SUPPORTED&`H_SUPPORTED) | (`D_SUPPORTED&`F_SUPPORTED&`H_SUPPORTED) ? 3 : (`Q_SUPPORTED&`D_SUPPORTED) | (`Q_SUPPORTED&`F_SUPPORTED) | (`Q_SUPPORTED&`H_SUPPORTED) | (`D_SUPPORTED&`F_SUPPORTED) | (`D_SUPPORTED&`H_SUPPORTED) | (`F_SUPPORTED&`H_SUPPORTED) ? 2 : 1) +`define LEN1 ((`D_SUPPORTED & (`FLEN !== 64)) ? 64 : (`F_SUPPORTED & (`FLEN !== 32)) ? 32 : 16) +`define NE1 ((`D_SUPPORTED & (`FLEN !== 64)) ? 11 : (`F_SUPPORTED & (`FLEN !== 32)) ? 8 : 5) +`define NF1 ((`D_SUPPORTED & (`FLEN !== 64)) ? 52 : (`F_SUPPORTED & (`FLEN !== 32)) ? 23 : 10) +`define FMT1 ((`D_SUPPORTED & (`FLEN !== 64)) ? 1 : (`F_SUPPORTED & (`FLEN !== 32)) ? 0 : 2) +`define BIAS1 ((`D_SUPPORTED & (`FLEN !== 64)) ? 1023 : (`F_SUPPORTED & (`FLEN !== 32)) ? 127 : 15) +`define LEN2 ((`F_SUPPORTED & (`LEN1 !== 32)) ? 32 : 16) +`define NE2 ((`F_SUPPORTED & (`LEN1 !== 32)) ? 8 : 5) +`define NF2 ((`F_SUPPORTED & (`LEN1 !== 32)) ? 23 : 10) +`define FMT2 ((`F_SUPPORTED & (`LEN1 !== 32)) ? 0 : 2) +`define BIAS2 ((`F_SUPPORTED & (`LEN1 !== 32)) ? 127 : 15) +`define LEN3 16 +`define NE3 5//make constants for the constants ie 11/8/5 ect +`define NF3 10 // always support less hten max - maybe halfs +`define FMT3 2 +`define BIAS3 15 module testbench3(); logic [31:0] errors=0; @@ -15,33 +38,17 @@ module testbench3(); logic [`FLEN-1:0] ans; logic [7:0] flags; logic [2:0] FrmE; - logic FmtE; + logic [`FPSIZES/3:0] FmtE; logic [`FLEN-1:0] FMAResM; logic [4:0] FMAFlgM; -integer fp; logic [2:0] FOpCtrlE; logic [2*`NF+1:0] ProdManE; logic [3*`NF+5:0] AlignedAddendE; logic [`NE+1:0] ProdExpE; logic AddendStickyE; logic KillProdE; -// logic XZeroE; -// logic YZeroE; -// logic ZZeroE; -// logic XDenormE; -// logic YDenormE; -// logic ZDenormE; -// logic XInfE; -// logic YInfE; -// logic ZInfE; -// logic XNaNE; -// logic YNaNE; -// logic ZNaNE; logic wnan; -// logic XNaNE; -// logic YNaNE; -// logic ZNaNE; logic ansnan, clk; @@ -52,88 +59,86 @@ assign FOpCtrlE = 3'b0; // down - 010 // up - 011 // nearest max mag - 100 -assign FrmE = 3'b000; -assign FmtE = 1'b1; +assign FrmE = 3'b010; +assign FmtE = (`FPSIZES/3+1)'(1); logic [`FLEN-1:0] X, Y, Z; // logic FmtE; // logic [2:0] FOpCtrlE; logic XSgnE, YSgnE, ZSgnE; logic [`NE-1:0] XExpE, YExpE, ZExpE; - logic [`NF-1:0] XFracE, YFracE, ZFracE; - logic XAssumed1E, YAssumed1E, ZAssumed1E; + logic [`NF:0] XManE, YManE, ZManE; logic XNormE; + logic XExpMaxE; logic XNaNE, YNaNE, ZNaNE; logic XSNaNE, YSNaNE, ZSNaNE; logic XDenormE, YDenormE, ZDenormE; logic XZeroE, YZeroE, ZZeroE; logic [`NE-1:0] BiasE; logic XInfE, YInfE, ZInfE; - logic XExpMaxE; - //***rename to make significand = 1.frac m = significand - logic XFracZero, YFracZero, ZFracZero; // input fraction zero - logic XExpZero, YExpZero, ZExpZero; // input exponent zero logic [`FLEN-1:0] Addend; // value to add (Z or zero) - logic YExpMaxE, ZExpMaxE; // input exponent all 1s + logic YExpMaxE, ZExpMaxE, Mult; // input exponent all 1s - assign Addend = FOpCtrlE[2] ? (`FLEN)'(0) : Z; // Z is only used in the FMA, and is set to Zero if a multiply opperation - assign XSgnE = FmtE ? X[`FLEN-1] : X[31]; - assign YSgnE = FmtE ? Y[`FLEN-1] : Y[31]; - assign ZSgnE = FmtE ? Addend[`FLEN-1] : Addend[31]; + assign Mult = 1'b0; + unpacking unpacking(.*); - assign XExpE = FmtE ? X[62:52] : {X[30], {3{~X[30]&~XExpZero|XExpMaxE}}, X[29:23]}; - assign YExpE = FmtE ? Y[62:52] : {Y[30], {3{~Y[30]&~YExpZero|YExpMaxE}}, Y[29:23]}; - assign ZExpE = FmtE ? Addend[62:52] : {Addend[30], {3{~Addend[30]&~ZExpZero|ZExpMaxE}}, Addend[29:23]}; +// assign wnan = XNaNE|YNaNE|ZNaNE; +// assign ansnan = FmtE ? &ans[`FLEN-2:`NF] && |ans[`NF-1:0] : &ans[30:23] && |ans[22:0]; + + if (`FPSIZES === 1) begin + assign ansnan = &ans[`FLEN-2:`NF]&(|ans[`NF-1:0]); + assign wnan = &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]); + end else if (`FPSIZES === 2) begin + assign ansnan = FmtE ? &ans[`FLEN-2:`NF]&(|ans[`NF-1:0]) : &ans[`LEN1-2:`NF1]&(|ans[`NF1-1:0]); + assign wnan = FmtE ? &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]) : &FMAResM[`LEN1-2:`NF1]&(|FMAResM[`NF1-1:0]); + end else if (`FPSIZES === 3) begin + always_comb begin + case (FmtE) + `FMT: begin + assign ansnan = &ans[`FLEN-2:`NF]&(|ans[`NF-1:0]); + assign wnan = &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]); - assign XFracE = FmtE ? X[`NF-1:0] : {X[22:0], 29'b0}; - assign YFracE = FmtE ? Y[`NF-1:0] : {Y[22:0], 29'b0}; - assign ZFracE = FmtE ? Addend[`NF-1:0] : {Addend[22:0], 29'b0}; + end + `FMT1: begin + assign ansnan = &ans[`LEN1-2:`NF1]&(|ans[`NF1-1:0]); + assign wnan = &FMAResM[`LEN1-2:`NF1]&(|FMAResM[`NF1-1:0]); - assign XAssumed1E = FmtE ? |X[62:52] : |X[30:23]; - assign YAssumed1E = FmtE ? |Y[62:52] : |Y[30:23]; - assign ZAssumed1E = FmtE ? |Z[62:52] : |Z[30:23]; + end + `FMT2: begin + assign ansnan = &ans[`LEN2-2:`NF2]&(|ans[`NF2-1:0]); + assign wnan = &FMAResM[`LEN2-2:`NF2]&(|FMAResM[`NF2-1:0]); + end + default: begin + assign ansnan = 0; + assign wnan = 0; + end + endcase + end - assign XExpZero = ~XAssumed1E; - assign YExpZero = ~YAssumed1E; - assign ZExpZero = ~ZAssumed1E; - - assign XFracZero = ~|XFracE; - assign YFracZero = ~|YFracE; - assign ZFracZero = ~|ZFracE; + end else begin + always_comb begin + case (FmtE) + `FMT: begin + assign ansnan = &ans[`FLEN-2:`NF]&(|ans[`NF-1:0]); + assign wnan = &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]); - assign XExpMaxE = FmtE ? &X[62:52] : &X[30:23]; - assign YExpMaxE = FmtE ? &Y[62:52] : &Y[30:23]; - assign ZExpMaxE = FmtE ? &Z[62:52] : &Z[30:23]; - - assign XNormE = ~(XExpMaxE|XExpZero); - - assign XNaNE = XExpMaxE & ~XFracZero; - assign YNaNE = YExpMaxE & ~YFracZero; - assign ZNaNE = ZExpMaxE & ~ZFracZero; + end + `FMT1: begin + assign ansnan = &ans[`LEN1-2:`NF1]&(|ans[`NF1-1:0]); + assign wnan = &FMAResM[`LEN1-2:`NF1]&(|FMAResM[`NF1-1:0]); - assign XSNaNE = XNaNE&~XFracE[`NF-1]; - assign YSNaNE = YNaNE&~YFracE[`NF-1]; - assign ZSNaNE = ZNaNE&~ZFracE[`NF-1]; - - assign XDenormE = XExpZero & ~XFracZero; - assign YDenormE = YExpZero & ~YFracZero; - assign ZDenormE = ZExpZero & ~ZFracZero; - - assign XInfE = XExpMaxE & XFracZero; - assign YInfE = YExpMaxE & YFracZero; - assign ZInfE = ZExpMaxE & ZFracZero; - - assign XZeroE = XExpZero & XFracZero; - assign YZeroE = YExpZero & YFracZero; - assign ZZeroE = ZExpZero & ZFracZero; - - assign BiasE = 13'h3ff; - -assign wnan = FmtE ? &FMAResM[`FLEN-2:`NF] & |FMAResM[`NF-1:0] : &FMAResM[30:23] & |FMAResM[22:0]; -// assign XNaNE = FmtE ? &X[62:52] & |X[51:0] : &X[62:55] & |X[54:32]; -// assign YNaNE = FmtE ? &Y[62:52] & |Y[51:0] : &Y[62:55] & |Y[54:32]; -// assign ZNaNE = FmtE ? &Z[62:52] & |Z[51:0] : &Z[62:55] & |Z[54:32]; -assign ansnan = FmtE ? &ans[`FLEN-2:`NF] & |ans[`NF-1:0] : &ans[30:23] & |ans[22:0]; + end + `FMT2: begin + assign ansnan = &ans[`LEN2-2:`NF2]&(|ans[`NF2-1:0]); + assign wnan = &FMAResM[`LEN2-2:`NF2]&(|FMAResM[`NF2-1:0]); + end + `FMT3: begin + assign ansnan = &ans[`LEN3-2:`NF3]&(|ans[`NF3-1:0]); + assign wnan = &FMAResM[`LEN3-2:`NF3]&(|FMAResM[`NF3-1:0]); + end + endcase + end + end // instantiate device under test logic [3*`NF+5:0] SumE, SumM; @@ -141,16 +146,16 @@ assign ansnan = FmtE ? &ans[`FLEN-2:`NF] & |ans[`NF-1:0] : &ans[30:23] & |ans[22 logic NegSumE, NegSumM; logic ZSgnEffE, ZSgnEffM; logic PSgnE, PSgnM; - logic [8:0] NormCntE, NormCntM; + logic [$clog2(3*`NF+7)-1:0] NormCntE, NormCntM; - fma1 fma1 (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE({XAssumed1E,XFracE}), .YManE({YAssumed1E,YFracE}), .ZManE({ZAssumed1E,ZFracE}), + fma1 fma1 (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE, .ProdExpE, .AddendStickyE, .KillProdE); -fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZExpE), .XManM({XAssumed1E,XFracE}), .YManM({YAssumed1E,YFracE}), .ZManM({ZAssumed1E,ZFracE}), .XNaNM(XNaNE), .YNaNM(YNaNE), .ZNaNM(ZNaNE), .XZeroM(XZeroE), .YZeroM(YZeroE), .ZZeroM(ZZeroE), .XInfM(XInfE), .YInfM(YInfE), .ZInfM(ZInfE), .XSNaNM(XSNaNE), .YSNaNM(YSNaNE), .ZSNaNM(ZSNaNE), +fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZExpE), .XManM(XManE), .YManM(YManE), .ZManM(ZManE), .XNaNM(XNaNE), .YNaNM(YNaNE), .ZNaNM(ZNaNE), .XZeroM(XZeroE), .YZeroM(YZeroE), .ZZeroM(ZZeroE), .XInfM(XInfE), .YInfM(YInfE), .ZInfM(ZInfE), .XSNaNM(XSNaNE), .YSNaNM(YSNaNE), .ZSNaNM(ZSNaNE), // .FSrcXE, .FSrcYE, .FSrcZE, .FSrcXM, .FSrcYM, .FSrcZM, .KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE), .SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .NormCntM(NormCntE), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), - .FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM); + .FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM, .Mult); // produce clock @@ -168,61 +173,156 @@ fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZEx always @(posedge clk) begin #1; - if (FmtE==1'b1) {X, Y, Z, ans, flags} = testvectors[vectornum]; - else begin X = {{32{1'b1}}, testvectors[vectornum][135:104]}; - Y = {{32{1'b1}}, testvectors[vectornum][103:72]}; - Z = {{32{1'b1}}, testvectors[vectornum][71:40]}; - ans = {{32{1'b1}}, testvectors[vectornum][39:8]}; - flags = testvectors[vectornum][7:0]; + if (`FPSIZES === 3 | `FPSIZES === 4) begin + if (FmtE==2'b11) {X, Y, Z, ans, flags} = testvectors[vectornum]; + else if (FmtE==2'b01) begin + X = {{`FLEN-64{1'b1}}, testvectors[vectornum][263:200]}; + Y = {{`FLEN-64{1'b1}}, testvectors[vectornum][199:136]}; + Z = {{`FLEN-64{1'b1}}, testvectors[vectornum][135:72]}; + ans = {{`FLEN-64{1'b1}}, testvectors[vectornum][71:8]}; + flags = testvectors[vectornum][7:0]; + end + else if (FmtE==2'b00) begin + X = {{`FLEN-32{1'b1}}, testvectors[vectornum][135:104]}; + Y = {{`FLEN-32{1'b1}}, testvectors[vectornum][103:72]}; + Z = {{`FLEN-32{1'b1}}, testvectors[vectornum][71:40]}; + ans = {{`FLEN-32{1'b1}}, testvectors[vectornum][39:8]}; + flags = testvectors[vectornum][7:0]; + end + else begin + X = {{`FLEN-16{1'b1}}, testvectors[vectornum][71:56]}; + Y = {{`FLEN-16{1'b1}}, testvectors[vectornum][55:40]}; + Z = {{`FLEN-16{1'b1}}, testvectors[vectornum][39:24]}; + ans = {{`FLEN-16{1'b1}}, testvectors[vectornum][23:8]}; + flags = testvectors[vectornum][7:0]; + end + end + else begin + if (FmtE==1'b1) {X, Y, Z, ans, flags} = testvectors[vectornum]; + else if (FmtE==1'b0) begin + X = {{`FLEN-`LEN1{1'b1}}, testvectors[vectornum][8+4*(`LEN1)-1:8+3*(`LEN1)]}; + Y = {{`FLEN-`LEN1{1'b1}}, testvectors[vectornum][8+3*(`LEN1)-1:8+2*(`LEN1)]}; + Z = {{`FLEN-`LEN1{1'b1}}, testvectors[vectornum][8+2*(`LEN1)-1:8+(`LEN1)]}; + ans = {{`FLEN-`LEN1{1'b1}}, testvectors[vectornum][8+(`LEN1-1):8]}; + flags = testvectors[vectornum][7:0]; + end end end // check results on falling edge of clk always @(negedge clk) begin - - if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~((XNaNE & (FMAResM[`FLEN-2:0] == {XExpE,1'b1,X[`NF-2:0]})) | (YNaNE & (FMAResM[`FLEN-2:0] == {YExpE,1'b1,Y[`NF-2:0]})) | (ZNaNE & (FMAResM[`FLEN-2:0] == {ZExpE,1'b1,Z[`NF-2:0]})) | (FMAResM[`FLEN-2:0] == ans[`FLEN-2:0]))))) begin - // fp = $fopen("/home/kparry/riscv-wally/pipelined/src/fpu/FMA/tbgen/results.dat","w"); - // if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (FMAResM != ans))) begin - $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); - if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero "); - if(XDenormE) $display( "xdenorm "); - if(YDenormE) $display( "ydenorm "); - if(ZDenormE) $display( "zdenorm "); - if(FMAFlgM[4] != 0) $display( "invld "); - if(FMAFlgM[2] != 0) $display( "ovrflw "); - if(FMAFlgM[1] != 0) $display( "unflw "); - if(FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=-inf "); - if(~FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=+inf "); - if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); - if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); - if(ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=-inf "); - if(~ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=+inf "); - if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ~ans[`NF-1]) $display( "ans=sigNaN "); - if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ans[`NF-1]) $display( "ans=qutNaN "); - errors = errors + 1; - //if (errors == 10) - $stop; - end - if((FmtE==1'b0)&(FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~(((XNaNE & (FMAResM[30:0] == {X[30:23],1'b1,X[21:0]})) | (YNaNE & (FMAResM[30:0] == {Y[30:23],1'b1,Y[21:0]})) | (ZNaNE & (FMAResM[30:0] == {Z[30:23],1'b1,Z[21:0]})) | (FMAResM[30:0] == ans[30:0]))) ))) begin - $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); - if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero "); - if(~(|X[30:23]) & |X[22:0]) $display( "xdenorm "); - if(~(|Y[30:23]) & |Y[22:0]) $display( "ydenorm "); - if(~(|Z[30:23]) & |Z[22:0]) $display( "zdenorm "); - if(FMAFlgM[4] != 0) $display( "invld "); - if(FMAFlgM[2] != 0) $display( "ovrflw "); - if(FMAFlgM[1] != 0) $display( "unflw "); - if(FMAResM == 64'hFF80000000000000) $display( "FMAResM=-inf "); - if(FMAResM == 64'h7F80000000000000) $display( "FMAResM=+inf "); - if(&FMAResM[30:23] & |FMAResM[22:0] & ~FMAResM[22]) $display( "FMAResM=sigNaN "); - if(&FMAResM[30:23] & |FMAResM[22:0] & FMAResM[22] ) $display( "FMAResM=qutNaN "); - if(ans == 64'hFF80000000000000) $display( "ans=-inf "); - if(ans == 64'h7F80000000000000) $display( "ans=+inf "); - if(&ans[30:23] & |ans[22:0] & ~ans[22] ) $display( "ans=sigNaN "); - if(&ans[30:23] & |ans[22:0] & ans[22]) $display( "ans=qutNaN "); - errors = errors + 1; - if (errors == 10) - $stop; - end + if (`FPSIZES === 1 | `FPSIZES === 2) begin + if((FmtE==1'b1) & (FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~((XNaNE && (FMAResM[`FLEN-2:0] === {X[`FLEN-2:`NF],1'b1,X[`NF-2:0]})) || (YNaNE && (FMAResM[`FLEN-2:0] === {Y[`FLEN-2:`NF],1'b1,Y[`NF-2:0]})) || (ZNaNE && (FMAResM[`FLEN-2:0] === {Z[`FLEN-2:`NF],1'b1,Z[`NF-2:0]})) || (FMAResM[`FLEN-2:0] === ans[`FLEN-2:0]))))) begin + // fp = $fopen("/home/kparry/riscv-wally/pipelined/src/fpu/FMA/tbgen/results.dat","w"); + // if((FmtE==1'b1) & (FMAFlgM !== flags[4:0] || (FMAResM !== ans))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(XDenormE) $display( "xdenorm "); + if(YDenormE) $display( "ydenorm "); + if(ZDenormE) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=-inf "); + if(~FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=+inf "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); + if(ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=-inf "); + if(~ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=+inf "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ~ans[`NF-1]) $display( "ans=sigNaN "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ans[`NF-1]) $display( "ans=qutNaN "); + errors = errors + 1; + //if (errors === 10) + $stop; + end + if((FmtE==1'b0)&(FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~(((XNaNE && (FMAResM[`LEN1-2:0] === {X[`LEN1-2:`NF1],1'b1,X[`NF1-2:0]})) || (YNaNE && (FMAResM[`LEN1-2:0] === {Y[`LEN1-2:`NF1],1'b1,Y[`NF1-2:0]})) || (ZNaNE && (FMAResM[`LEN1-2:0] === {Z[`LEN1-2:`NF1],1'b1,Z[`NF1-2:0]})) || (FMAResM[`LEN1-2:0] === ans[`LEN1-2:0]))) ))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + // if (errors === 9) + $stop; + end + end else begin + + if((FmtE==2'b11) & (FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~((XNaNE && (FMAResM[`FLEN-2:0] === {X[`FLEN-2:`NF],1'b1,X[`NF-2:0]})) || (YNaNE && (FMAResM[`FLEN-2:0] === {Y[`FLEN-2:`NF],1'b1,Y[`NF-2:0]})) || (ZNaNE && (FMAResM[`FLEN-2:0] === {Z[`FLEN-2:`NF],1'b1,Z[`NF-2:0]})) || (FMAResM[`FLEN-2:0] === ans[`FLEN-2:0]))))) begin + // fp = $fopen("/home/kparry/riscv-wally/pipelined/src/fpu/FMA/tbgen/results.dat","w"); + // if((FmtE==1'b1) & (FMAFlgM !== flags[4:0] || (FMAResM !== ans))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(XDenormE) $display( "xdenorm "); + if(YDenormE) $display( "ydenorm "); + if(ZDenormE) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=-inf "); + if(~FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=+inf "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); + if(ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=-inf "); + if(~ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=+inf "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ~ans[`NF-1]) $display( "ans=sigNaN "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ans[`NF-1]) $display( "ans=qutNaN "); + errors = errors + 1; + //if (errors === 10) + $stop; + end + if((FmtE==1'b01)&(FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~(((XNaNE && (FMAResM[64-2:0] === {X[64-2:52],1'b1,X[52-2:0]})) || (YNaNE && (FMAResM[64-2:0] === {Y[64-2:52],1'b1,Y[52-2:0]})) || (ZNaNE && (FMAResM[64-2:0] === {Z[64-2:52],1'b1,Z[52-2:0]})) || (FMAResM[62:0] === ans[62:0]))) ))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + // if (errors === 9) + $stop; + end + if((FmtE==2'b00)&(FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~(((XNaNE && (FMAResM[32-2:0] === {X[32-2:23],1'b1,X[23-2:0]})) || (YNaNE && (FMAResM[32-2:0] === {Y[32-2:23],1'b1,Y[23-2:0]})) || (ZNaNE && (FMAResM[32-2:0] === {Z[32-2:23],1'b1,Z[23-2:0]})) || (FMAResM[30:0] === ans[30:0]))) ))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + // if (errors === 9) + $stop; + end + if((FmtE==2'b10)&(FMAFlgM !== flags[4:0] || (!wnan && (FMAResM !== ans)) || (wnan && ansnan && ~(((XNaNE && (FMAResM[16-2:0] === {X[16-2:10],1'b1,X[10-2:0]})) || (YNaNE && (FMAResM[16-2:0] === {Y[16-2:10],1'b1,Y[10-2:0]})) || (ZNaNE && (FMAResM[16-2:0] === {Z[16-2:10],1'b1,Z[10-2:0]})) || (FMAResM[14:0] === ans[14:0]))) ))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + // if (errors === 9) + $stop; + end + end + vectornum = vectornum + 1; if (testvectors[vectornum] === 194'bx) begin $display("%d tests completed with %d errors", vectornum, errors); diff --git a/pipelined/fpu-testfloat/FMA/tbgen/test_gen.sh b/pipelined/fpu-testfloat/FMA/tbgen/test_gen.sh index 0741e9d6d..8620f3b03 100755 --- a/pipelined/fpu-testfloat/FMA/tbgen/test_gen.sh +++ b/pipelined/fpu-testfloat/FMA/tbgen/test_gen.sh @@ -1,3 +1,3 @@ -testfloat_gen f64_mulAdd -tininessafter -n 6133248 -rnear_even -seed 113355 -level 1 > testFloat +testfloat_gen f128_mulAdd -tininessafter -n 6133248 -rmin -seed 113355 -level 1 > testFloat tr -d ' ' < testFloat > testFloatNoSpace diff --git a/pipelined/src/fpu/fcmp.sv b/pipelined/src/fpu/fcmp.sv index 3b058772c..1fbcae5e2 100755 --- a/pipelined/src/fpu/fcmp.sv +++ b/pipelined/src/fpu/fcmp.sv @@ -42,6 +42,7 @@ module fcmp ( // - if negitive - no // - if positive - yes // note: LT does -0 < 0 + //*** compare Exp and Man together assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE> AlignCnt; AddendStickyE = |(ZManShifted[`NF-1:0]); @@ -356,7 +378,7 @@ endmodule module loa( //https://ieeexplore.ieee.org/abstract/document/930098 input logic [3*`NF+6:0] A, // addend input logic [2*`NF+1:0] P, // product - output logic [8:0] NormCntE // normalization shift count for the positive result + output logic [$clog2(3*`NF+7)-1:0] NormCntE // normalization shift count for the positive result ); logic [3*`NF+6:0] T; @@ -389,14 +411,14 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098 endmodule module lzc( - input logic [3*`NF+6:0] f, - output logic [8:0] NormCntE // normalization shift + input logic [3*`NF+6:0] f, + output logic [$clog2(3*`NF+7)-1:0] NormCntE // normalization shift ); - logic [8:0] i; + logic [$clog2(3*`NF+7)-1:0] i; always_comb begin i = 0; - while (~f[3*`NF+6-i] & $unsigned(i) <= $unsigned(9'd3*9'd`NF+9'd6)) i = i+1; // search for leading one + while (~f[3*`NF+6-i] & $unsigned(i) <= $unsigned($clog2(3*`NF+7)'(3)*($clog2(3*`NF+7))'(`NF)+($clog2(3*`NF+7))'(6))) i = i+1; // search for leading one NormCntE = i; end endmodule @@ -410,27 +432,27 @@ endmodule module fma2( - input logic XSgnM, YSgnM, // input signs - input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents - input logic [`NF:0] XManM, YManM, ZManM, // input mantissas - input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude - input logic FmtM, // precision 1 = double 0 = single - input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias - input logic AddendStickyM, // sticky bit that is calculated during alignment - input logic KillProdM, // set the product to zero before addition if the product is too small to matter - input logic XZeroM, YZeroM, ZZeroM, // inputs are zero - input logic XInfM, YInfM, ZInfM, // inputs are infinity - input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN - input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs - input logic [3*`NF+5:0] SumM, // the positive sum - input logic NegSumM, // was the sum negitive - input logic InvZM, // do you invert Z - input logic ZSgnEffM, // the modified Z sign - depends on instruction - input logic PSgnM, // the product's sign - input logic Mult, // multiply opperation - input logic [8:0] NormCntM, // the normalization shift count - output logic [`FLEN-1:0] FMAResM, // FMA final result - output logic [4:0] FMAFlgM); // FMA flags {invalid, divide by zero, overflow, underflow, inexact} + input logic XSgnM, YSgnM, // input signs + input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents + input logic [`NF:0] XManM, YManM, ZManM, // input mantissas + input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude + input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single + input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias + input logic AddendStickyM, // sticky bit that is calculated during alignment + input logic KillProdM, // set the product to zero before addition if the product is too small to matter + input logic XZeroM, YZeroM, ZZeroM, // inputs are zero + input logic XInfM, YInfM, ZInfM, // inputs are infinity + input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN + input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs + input logic [3*`NF+5:0] SumM, // the positive sum + input logic NegSumM, // was the sum negitive + input logic InvZM, // do you invert Z + input logic ZSgnEffM, // the modified Z sign - depends on instruction + input logic PSgnM, // the product's sign + input logic Mult, // multiply opperation + input logic [$clog2(3*`NF+7)-1:0] NormCntM, // the normalization shift count + output logic [`FLEN-1:0] FMAResM, // FMA final result + output logic [4:0] FMAFlgM); // FMA flags {invalid, divide by zero, overflow, underflow, inexact} @@ -548,28 +570,27 @@ endmodule module normalize( - input logic [3*`NF+5:0] SumM, // the positive sum - input logic [`NE-1:0] ZExpM, // exponent of Z - input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias - input logic [8:0] NormCntM, // normalization shift count - input logic FmtM, // precision 1 = double 0 = single - input logic KillProdM, // is the product set to zero - input logic AddendStickyM, // the sticky bit caclulated from the aligned addend - input logic NegSumM, // was the sum negitive - output logic [`NF+2:0] NormSum, // normalized sum - output logic SumZero, // is the sum zero - output logic NormSumSticky, UfSticky, // sticky bits - output logic [`NE+1:0] SumExp, // exponent of the normalized sum - output logic ResultDenorm // is the result denormalized + input logic [3*`NF+5:0] SumM, // the positive sum + input logic [`NE-1:0] ZExpM, // exponent of Z + input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias + input logic [$clog2(3*`NF+7)-1:0] NormCntM, // normalization shift count + input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single + input logic KillProdM, // is the product set to zero + input logic AddendStickyM, // the sticky bit caclulated from the aligned addend + input logic NegSumM, // was the sum negitive + output logic [`NF+2:0] NormSum, // normalized sum + output logic SumZero, // is the sum zero + output logic NormSumSticky, UfSticky, // sticky bits + output logic [`NE+1:0] SumExp, // exponent of the normalized sum + output logic ResultDenorm // is the result denormalized ); - logic [`NE+1:0] SumExpTmp; // exponent of the normalized sum not taking into account denormal or zero results - logic [8:0] DenormShift; // right shift if the result is denormalized //***change this later - logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction - logic [3*`NF+8:0] SumShifted; // the shifted sum before LZA correction - logic [`NE+1:0] SumExpTmpTmp; // the exponent of the normalized sum with the `FLEN bias - logic PreResultDenorm; // is the result denormalized - calculated before LZA corection - logic PreResultDenorm2; // is the result denormalized - calculated before LZA corection - logic LZAPlus1, LZAPlus2; // add one or two to the sum's exponent due to LZA correction + logic [`NE+1:0] SumExpTmp; // exponent of the normalized sum not taking into account denormal or zero results + logic [$clog2(3*`NF+7)-1:0] DenormShift; // right shift if the result is denormalized //***change this later + logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction + logic [3*`NF+8:0] SumShifted; // the shifted sum before LZA correction + logic [`NE+1:0] SumExpTmpTmp; // the exponent of the normalized sum with the `FLEN bias + logic PreResultDenorm; // is the result denormalized - calculated before LZA corection + logic LZAPlus1, LZAPlus2; // add one or two to the sum's exponent due to LZA correction /////////////////////////////////////////////////////////////////////////////// // Normalization @@ -580,14 +601,89 @@ module normalize( // calculate the sum's exponent assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); - assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; + + //convert the sum's exponent into the propper percision + if (`FPSIZES == 1) begin + assign SumExpTmp = SumExpTmpTmp; + + end else if (`FPSIZES == 2) begin + assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|SumExpTmpTmp}}; + + end else if (`FPSIZES == 3) begin + always_comb begin + case (FmtM) + `FMT: assign SumExpTmp = SumExpTmpTmp; + `FMT1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS1)&{`NE+2{|SumExpTmpTmp}}; + `FMT2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS2)&{`NE+2{|SumExpTmpTmp}}; + default: assign SumExpTmp = `NE+2'bx; + endcase + end + + end else begin + always_comb begin + case (FmtM) + 2'h3: assign SumExpTmp = SumExpTmpTmp; + 2'h1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`D_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h0: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`S_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`H_BIAS)&{`NE+2{|SumExpTmpTmp}}; + endcase + end + + end - logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL; - assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; - assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd2))); - assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127); - assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd25+13'd1023-13'd127)) | ~|SumExpTmpTmp; - assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; + // determine if the result is denormalized + + if (`FPSIZES == 1) begin + logic Sum0LEZ, Sum0GEFL; + assign Sum0LEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; + assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); + assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + + end else if (`FPSIZES == 2) begin + logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; + assign Sum0LEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; + assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); + assign Sum1LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); + assign Sum1GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|SumExpTmpTmp; + assign PreResultDenorm = (FmtM ? Sum0LEZ : Sum1LEZ) & (FmtM ? Sum0GEFL : Sum1GEFL) & ~SumZero; + + end else if (`FPSIZES == 3) begin + logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; + assign Sum0LEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; + assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); + assign Sum1LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); + assign Sum1GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|SumExpTmpTmp; + assign Sum2LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)); + assign Sum2GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|SumExpTmpTmp; + always_comb begin + case (FmtM) + `FMT: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + `FMT1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + `FMT2: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + default: assign PreResultDenorm = 1'bx; + endcase + end + + end else begin + logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL; + assign Sum0LEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; + assign Sum0GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF )-(`NE+2)'(2)); + assign Sum1LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)); + assign Sum1GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`D_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)) | ~|SumExpTmpTmp; + assign Sum2LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)); + assign Sum2GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`S_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)) | ~|SumExpTmpTmp; + assign Sum3LEZ = $signed(SumExpTmpTmp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)); + assign Sum3GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|SumExpTmpTmp; + always_comb begin + case (FmtM) + 2'h3: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + 2'h1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + 2'h0: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + 2'h2: assign PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; + endcase + end + + end // 010. when should be 001. // - shift left one @@ -599,45 +695,66 @@ module normalize( // Determine the shift needed for denormal results // - if not denorm add 1 to shift out the leading 1 - assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; + assign DenormShift = PreResultDenorm ? SumExpTmp[$clog2(3*`NF+7)-1:0] : 1; // Normalize the sum assign SumShifted = {3'b0, SumM} << NormCntM+DenormShift; // LZA correction assign LZAPlus1 = SumShifted[3*`NF+7]; assign LZAPlus2 = SumShifted[3*`NF+8]; // the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone - assign CorrSumShifted = LZAPlus1&~KillProdM ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0]; + assign CorrSumShifted = LZAPlus1 ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0]; assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3]; + // Calculate the sticky bit - assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM); + if (`FPSIZES == 1) begin + assign NormSumSticky = |CorrSumShifted[2*`NF+2:0]; + + end else if (`FPSIZES == 2) begin + // 3*NF+5 - NF1 - 3 + assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | + (|CorrSumShifted[3*`NF+2-`NF1:2*`NF+3]&~FmtM); + + end else if (`FPSIZES == 3) begin + assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | + (|CorrSumShifted[3*`NF+2-`NF1:2*`NF+3]&((FmtM==`FMT1)|(FmtM==`FMT2))) | + (|CorrSumShifted[3*`NF+2-`NF2:3*`NF+3-`NF1]&(FmtM==`FMT2)); + + end else begin + assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | + (|CorrSumShifted[3*`NF+2-`D_NF:2*`NF+3]&((FmtM==1)|(FmtM==0)|(FmtM==2))) | + (|CorrSumShifted[3*`NF+2-`S_NF:3*`NF+3-`D_NF]&((FmtM==0)|(FmtM==2))) | + (|CorrSumShifted[3*`NF+2-`H_NF:3*`NF+3-`S_NF]&(FmtM==2)); + + end + assign UfSticky = AddendStickyM | NormSumSticky; // Determine sum's exponent // if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2 - assign SumExp = (SumExpTmp+{12'b0, LZAPlus1&~KillProdM}+{11'b0, LZAPlus2&~KillProdM, 1'b0}+{12'b0, ~ResultDenorm&PreResultDenorm2&~KillProdM}+{12'b0, &SumExpTmp&SumShifted[3*`NF+6]&~KillProdM}) & {`NE+2{~(SumZero|ResultDenorm)}}; + assign SumExp = (SumExpTmp+{12'b0, LZAPlus1&~KillProdM}+{11'b0, LZAPlus2&~KillProdM, 1'b0}+{12'b0, ~ResultDenorm&PreResultDenorm&~KillProdM}+{12'b0, &SumExpTmp&SumShifted[3*`NF+6]&~KillProdM}) & {`NE+2{~(SumZero|ResultDenorm)}}; // recalculate if the result is denormalized - assign ResultDenorm = PreResultDenorm2&~SumShifted[3*`NF+6]&~SumShifted[3*`NF+7]; + assign ResultDenorm = PreResultDenorm&~SumShifted[3*`NF+6]&~SumShifted[3*`NF+7]; endmodule module fmaround( - input logic FmtM, // precision 1 = double 0 = single - input logic [2:0] FrmM, // rounding mode - input logic UfSticky, // sticky bit for underlow calculation - input logic [`NF+2:0] NormSum, // normalized sum - input logic AddendStickyM, // addend's sticky bit - input logic NormSumSticky, // normalized sum's sticky bit - input logic ZZeroM, // is Z zero - input logic InvZM, // invert Z - input logic [`NE+1:0] SumExp, // exponent of the normalized sum - input logic ResultSgnTmp, // the result's sign - output logic CalcPlus1, UfPlus1, // do you add or subtract on from the result - output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow - output logic [`NF-1:0] ResultFrac, // Result fraction - output logic [`NE-1:0] ResultExp, // Result exponent - output logic Sticky, // sticky bit - output logic [`FLEN:0] RoundAdd, // how much to add to the result - output logic Round, Guard, UfLSBNormSum // bits needed to calculate rounding + input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single + input logic [2:0] FrmM, // rounding mode + input logic UfSticky, // sticky bit for underlow calculation + input logic [`NF+2:0] NormSum, // normalized sum + input logic AddendStickyM, // addend's sticky bit + input logic NormSumSticky, // normalized sum's sticky bit + input logic ZZeroM, // is Z zero + input logic InvZM, // invert Z + input logic [`NE+1:0] SumExp, // exponent of the normalized sum + input logic ResultSgnTmp, // the result's sign + output logic CalcPlus1, UfPlus1, // do you add or subtract on from the result + output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow + output logic [`NF-1:0] ResultFrac, // Result fraction + output logic [`NE-1:0] ResultExp, // Result exponent + output logic Sticky, // sticky bit + output logic [`FLEN:0] RoundAdd, // how much to add to the result + output logic Round, Guard, UfLSBNormSum // bits needed to calculate rounding ); logic LSBNormSum; // bit used for rounding - least significant bit of the normalized sum logic SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number @@ -676,18 +793,146 @@ module fmaround( // 101 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number) // 110/111 - Plus1 - // determine guard, round, and least significant bit of the result - assign Guard = FmtM ? NormSum[2] : NormSum[31]; - assign Round = FmtM ? NormSum[1] : NormSum[30]; - assign LSBNormSum = FmtM ? NormSum[3] : NormSum[32]; + if (`FPSIZES == 1) begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[2]; + assign Round = NormSum[1]; + assign LSBNormSum = NormSum[3]; + + // used to determine underflow flag + assign UfGuard = NormSum[1]; + assign UfRound = NormSum[0]; + assign UfLSBNormSum = NormSum[2]; + + // determine sticky + assign Sticky = UfSticky | NormSum[0]; + + end else if (`FPSIZES == 2) begin + // \/-------------NF---------------, + // | NF1 | 3 | | + // '-------NF1------^ + + // determine guard, round, and least significant bit of the result + assign Guard = FmtM ? NormSum[2] : NormSum[`NF-`NF1+2]; + assign Round = FmtM ? NormSum[1] : NormSum[`NF-`NF1+1]; + assign LSBNormSum = FmtM ? NormSum[3] : NormSum[`NF-`NF1+3]; + + // used to determine underflow flag + assign UfGuard = FmtM ? NormSum[1] : NormSum[`NF-`NF1+1]; + assign UfRound = FmtM ? NormSum[0] : NormSum[`NF-`NF1]; + assign UfLSBNormSum = FmtM ? NormSum[2] : NormSum[`NF-`NF1+2]; + + // determine sticky + assign Sticky = UfSticky | (FmtM ? NormSum[0] : NormSum[`NF-`NF1]); + + end else if (`FPSIZES == 3) begin + always_comb begin + case (FmtM) + `FMT: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[2]; + assign Round = NormSum[1]; + assign LSBNormSum = NormSum[3]; + // used to determine underflow flag + assign UfGuard = NormSum[1]; + assign UfRound = NormSum[0]; + assign UfLSBNormSum = NormSum[2]; + // determine sticky + assign Sticky = UfSticky | NormSum[0]; + end + `FMT1: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[`NF-`NF1+2]; + assign Round = NormSum[`NF-`NF1+1]; + assign LSBNormSum = NormSum[`NF-`NF1+3]; + // used to determine underflow flag + assign UfGuard = NormSum[`NF-`NF1+1]; + assign UfRound = NormSum[`NF-`NF1]; + assign UfLSBNormSum = NormSum[`NF-`NF1+2]; + // determine sticky + assign Sticky = UfSticky | NormSum[`NF-`NF1]; + end + `FMT2: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[`NF-`NF2+2]; + assign Round = NormSum[`NF-`NF2+1]; + assign LSBNormSum = NormSum[`NF-`NF2+3]; + // used to determine underflow flag + assign UfGuard = NormSum[`NF-`NF2+1]; + assign UfRound = NormSum[`NF-`NF2]; + assign UfLSBNormSum = NormSum[`NF-`NF2+2]; + // determine sticky + assign Sticky = UfSticky | NormSum[`NF-`NF2]; + end + default: begin + assign Guard = 1'bx; + assign Round = 1'bx; + assign LSBNormSum = 1'bx; + assign UfGuard = 1'bx; + assign UfRound = 1'bx; + assign UfLSBNormSum = 1'bx; + assign Sticky = 1'bx; + end + endcase + end + + end else begin + always_comb begin + case (FmtM) + 2'h3: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[2]; + assign Round = NormSum[1]; + assign LSBNormSum = NormSum[3]; + // used to determine underflow flag + assign UfGuard = NormSum[1]; + assign UfRound = NormSum[0]; + assign UfLSBNormSum = NormSum[2]; + // determine sticky + assign Sticky = UfSticky | NormSum[0]; + end + 2'h1: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[`NF-`D_NF+2]; + assign Round = NormSum[`NF-`D_NF+1]; + assign LSBNormSum = NormSum[`NF-`D_NF+3]; + // used to determine underflow flag + assign UfGuard = NormSum[`NF-`D_NF+1]; + assign UfRound = NormSum[`NF-`D_NF]; + assign UfLSBNormSum = NormSum[`NF-`D_NF+2]; + // determine sticky + assign Sticky = UfSticky | NormSum[`NF-`D_NF]; + end + 2'h0: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[`NF-`S_NF+2]; + assign Round = NormSum[`NF-`S_NF+1]; + assign LSBNormSum = NormSum[`NF-`S_NF+3]; + // used to determine underflow flag + assign UfGuard = NormSum[`NF-`S_NF+1]; + assign UfRound = NormSum[`NF-`S_NF]; + assign UfLSBNormSum = NormSum[`NF-`S_NF+2]; + // determine sticky + assign Sticky = UfSticky | NormSum[`NF-`S_NF]; + end + 2'h2: begin + // determine guard, round, and least significant bit of the result + assign Guard = NormSum[`NF-`H_NF+2]; + assign Round = NormSum[`NF-`H_NF+1]; + assign LSBNormSum = NormSum[`NF-`H_NF+3]; + // used to determine underflow flag + assign UfGuard = NormSum[`NF-`H_NF+1]; + assign UfRound = NormSum[`NF-`H_NF]; + assign UfLSBNormSum = NormSum[`NF-`H_NF+2]; + // determine sticky + assign Sticky = UfSticky | NormSum[`NF-`H_NF]; + end + endcase + end + + end - // used to determine underflow flag - assign UfGuard = FmtM ? NormSum[1] : NormSum[30]; - assign UfRound = FmtM ? NormSum[0] : NormSum[29]; - assign UfLSBNormSum = FmtM ? NormSum[2] : NormSum[31]; - // determine sticky - assign Sticky = UfSticky | NormSum[0]; // Deterimine if a small number was supposed to be subtrated assign SubBySmallNum = AddendStickyM & InvZM & ~(NormSumSticky|UfRound) & ~ZZeroM; //***here assign UfSubBySmallNum = AddendStickyM & InvZM & ~(NormSumSticky) & ~ZZeroM; //***here @@ -729,10 +974,40 @@ module fmaround( assign Minus1 = CalcMinus1 & (Sticky | Guard | Round); // Compute rounded result - assign RoundAdd = FmtM ? Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1} : - Minus1 ? {{36{1'b1}}, 29'b0} : {35'b0, Plus1, 29'b0}; - assign NormSumTruncated = {NormSum[`NF+2:32], NormSum[31:3]&{29{FmtM}}}; + if (`FPSIZES == 1) begin + assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{`FLEN{1'b0}}, Plus1}; + end else if (`FPSIZES == 2) begin + // \/FLEN+1 + // | NE+2 | NF | + // '-NE+2-^----NF1----^ + // `FLEN+1-`NE-2-`NF1 = FLEN-1-NE-NF1 + assign RoundAdd = FmtM ? Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1} : + Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; + + end else if (`FPSIZES == 3) begin + always_comb begin + case (FmtM) + `FMT: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + `FMT1: assign RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; + `FMT2: assign RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), Plus1, (`FLEN-1-`NE-`NF2)'(0)}; + default: assign RoundAdd = (`FLEN+1)'(0); + endcase + end + + end else begin + always_comb begin + case (FmtM) + 2'h3: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + 2'h1: assign RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), Plus1, (`FLEN-1-`NE-`D_NF)'(0)}; + 2'h0: assign RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), Plus1, (`FLEN-1-`NE-`S_NF)'(0)}; + 2'h2: assign RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), Plus1, (`FLEN-1-`NE-`H_NF)'(0)}; + endcase + end + + end + + assign NormSumTruncated = NormSum[`NF+2:3]; assign {FullResultExp, ResultFrac} = {SumExp, NormSumTruncated} + RoundAdd; assign ResultExp = FullResultExp[`NE-1:0]; @@ -748,7 +1023,7 @@ module fmaflags( input logic [`NE+1:0] SumExp, // exponent of the normalized sum input logic ZSgnEffM, PSgnM, // the product and modified Z signs input logic Round, Guard, UfLSBNormSum, Sticky, UfPlus1, // bits used to determine rounding - input logic FmtM, // precision 1 = double 0 = single + input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single output logic Invalid, Overflow, Underflow, // flags used to select the result output logic [4:0] FMAFlgM // FMA flags ); @@ -771,8 +1046,34 @@ module fmaflags( assign Invalid = SigNaN | ((XInfM | YInfM) & ZInfM & (PSgnM ^ ZSgnEffM) & ~XNaNM & ~YNaNM) | (XZeroM & YInfM) | (YZeroM & XInfM); // Set Overflow flag if the number is too big to be represented - // - Don't set the overflow flag if an overflowed result isn't outputed - assign GtMaxExp = FmtM ? &FullResultExp[`NE-1:0] | FullResultExp[`NE] : &FullResultExp[7:0] | FullResultExp[8]; + // - Don't set the overflow flag if an overflowed result isn't outputed + if (`FPSIZES == 1) begin + assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + + end else if (`FPSIZES == 2) begin + assign GtMaxExp = FmtM ? &FullResultExp[`NE-1:0] | FullResultExp[`NE] : &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; + + end else if (`FPSIZES == 3) begin + always_comb begin + case (FmtM) + `FMT: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + `FMT1: assign GtMaxExp = &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; + `FMT2: assign GtMaxExp = &FullResultExp[`NE2-1:0] | FullResultExp[`NE2]; + default: assign GtMaxExp = 1'bx; + endcase + end + + end else begin + always_comb begin + case (FmtM) + 2'h3: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + 2'h1: assign GtMaxExp = &FullResultExp[`D_NE-1:0] | FullResultExp[`D_NE]; + 2'h0: assign GtMaxExp = &FullResultExp[`S_NE-1:0] | FullResultExp[`S_NE]; + 2'h2: assign GtMaxExp = &FullResultExp[`H_NE-1:0] | FullResultExp[`H_NE]; + endcase + end + + end assign Overflow = GtMaxExp & ~FullResultExp[`NE+1]&~(XNaNM|YNaNM|ZNaNM|XInfM|YInfM|ZInfM); // Set Underflow flag if the number is too small to be represented in normal numbers @@ -793,57 +1094,227 @@ endmodule module resultselect( - input logic XSgnM, YSgnM, // input signs - input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents - input logic [`NF:0] XManM, YManM, ZManM, // input mantissas - input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude - input logic FmtM, // precision 1 = double 0 = single - input logic AddendStickyM, // sticky bit that is calculated during alignment - input logic KillProdM, // set the product to zero before addition if the product is too small to matter - input logic XInfM, YInfM, ZInfM, // inputs are infinity - input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN - input logic ZSgnEffM, // the modified Z sign - depends on instruction - input logic PSgnM, // the product's sign - input logic ResultSgn, // the result's sign - input logic CalcPlus1, // rounding bits - input logic [`FLEN:0] RoundAdd, // how much to add to the result - input logic Invalid, Overflow, Underflow, // flags - input logic ResultDenorm, // is the result denormalized - input logic [`NE-1:0] ResultExp, // Result exponent - input logic [`NF-1:0] ResultFrac, // Result fraction - output logic [`FLEN-1:0] FMAResM // FMA final result + input logic XSgnM, YSgnM, // input signs + input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents + input logic [`NF:0] XManM, YManM, ZManM, // input mantissas + input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude + input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single + input logic AddendStickyM, // sticky bit that is calculated during alignment + input logic KillProdM, // set the product to zero before addition if the product is too small to matter + input logic XInfM, YInfM, ZInfM, // inputs are infinity + input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN + input logic ZSgnEffM, // the modified Z sign - depends on instruction + input logic PSgnM, // the product's sign + input logic ResultSgn, // the result's sign + input logic CalcPlus1, // rounding bits + input logic [`FLEN:0] RoundAdd, // how much to add to the result + input logic Invalid, Overflow, Underflow, // flags + input logic ResultDenorm, // is the result denormalized + input logic [`NE-1:0] ResultExp, // Result exponent + input logic [`NF-1:0] ResultFrac, // Result fraction + output logic [`FLEN-1:0] FMAResM // FMA final result ); - logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results + logic InfSgn; + logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InfResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult, NormResult; // possible results + assign InfSgn = ZInfM ? ZSgnEffM : PSgnM; + if (`FPSIZES == 1) begin + if(`IEEE754) begin + assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end else begin + assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; + assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + + end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions? + if(`IEEE754) begin + assign XNaNResult = FmtM ? {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; + assign YNaNResult = FmtM ? {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; + assign ZNaNResult = FmtM ? {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; + assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + end else begin + assign XNaNResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + end + + assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} : + ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : + {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = FmtM ? {InfSgn, {`NE{1'b1}}, (`NF)'(0)} : {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + assign NormResult = FmtM ? {ResultSgn, ResultExp, ResultFrac} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; + + end else if (`FPSIZES == 3) begin + always_comb begin + case (FmtM) + `FMT: begin + if(`IEEE754) begin + assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end else begin + assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end + + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; + assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + end + `FMT1: begin + if(`IEEE754) begin + assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; + assign YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; + assign ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; + assign InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + end else begin + assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + end + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : + {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + assign KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + assign UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + assign NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; + end + `FMT2: begin + if(`IEEE754) begin + assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; + assign YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; + assign ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; + assign InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + end else begin + assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + end + + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : + {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, (`NF2)'(0)}; + assign KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; + assign UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; + assign NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; + end + default: begin + if(`IEEE754) begin + assign XNaNResult = (`FLEN)'(0); + assign YNaNResult = (`FLEN)'(0); + assign ZNaNResult = (`FLEN)'(0); + assign InvalidResult = (`FLEN)'(0); + end else begin + assign XNaNResult = (`FLEN)'(0); + end + assign OverflowResult = (`FLEN)'(0); + assign KillProdResult = (`FLEN)'(0); + assign UnderflowResult = (`FLEN)'(0); + assign InfResult = (`FLEN)'(0); + assign NormResult = (`FLEN)'(0); + end + endcase + end + + end else begin + always_comb begin + case (FmtM) + 2'h3: begin + if(`IEEE754) begin + assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end else begin + assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + end + + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; + assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + end + 2'h1: begin + if(`IEEE754) begin + assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; + assign YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; + assign ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; + assign InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + end else begin + assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + end + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : + {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; + assign KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; + assign UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; + assign NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; + end + 2'h0: begin + if(`IEEE754) begin + assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; + assign YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; + assign ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; + assign InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + end else begin + assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + end + + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : + {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; + assign KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; + assign UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; + assign NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; + end + 2'h2: begin + if(`IEEE754) begin + assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, XSgnM, {`H_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`H_NF]}; + assign YNaNResult = {{`FLEN-`H_LEN{1'b1}}, YSgnM, {`H_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`H_NF]}; + assign ZNaNResult = {{`FLEN-`H_LEN{1'b1}}, ZSgnEffM, {`H_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`H_NF]}; + assign InvalidResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + end else begin + assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + end + + assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : + {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; + + assign KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; + assign UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + assign InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; + assign NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; + end + endcase + end - if(`IEEE754) begin - assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]}; - assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]}; - assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]}; - assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0}; - end else begin - assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0}; - assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0}; - assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0}; - assign InvalidResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, 1'b0, 8'hff, 1'b1, 22'b0}; end - - assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : - {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} : - ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} : - {{32{1'b1}}, ResultSgn, 8'hff, 23'b0}; - assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} + (RoundAdd[59:29]&{31{AddendStickyM}})}; - assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign FMAResM = XNaNM ? XNaNResult : - YNaNM ? YNaNResult : - ZNaNM ? ZNaNResult : - Invalid ? InvalidResult : - XInfM ? FmtM ? {PSgnM, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, XExpM[7:0], XManM[51:29]} : - YInfM ? FmtM ? {PSgnM, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, YExpM[7:0], YManM[51:29]} : - ZInfM ? FmtM ? {ZSgnEffM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], ZManM[51:29]} : - KillProdM ? KillProdResult : - Overflow ? OverflowResult : - Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult : - FmtM ? {ResultSgn, ResultExp, ResultFrac} : - {{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]}; + if(`IEEE754) begin + assign FMAResM = XNaNM ? XNaNResult : + YNaNM ? YNaNResult : + ZNaNM ? ZNaNResult : + Invalid ? InvalidResult : + XInfM|YInfM|ZInfM ? InfResult : + KillProdM ? KillProdResult : + Overflow ? OverflowResult : + Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult : + NormResult; + end else begin + assign FMAResM = XNaNM|YNaNM|ZNaNM|Invalid ? XNaNResult : + XInfM|YInfM|ZInfM ? InfResult : + KillProdM ? KillProdResult : + Overflow ? OverflowResult : + Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult : + NormResult; + end endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index 0dd6ea1b2..f9472c9b5 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -89,7 +89,6 @@ module fpu ( logic [10:0] XExpM, YExpM, ZExpM; // input's exponent - memory stage logic [52:0] XManE, YManE, ZManE; // input's fraction - execute stage logic [52:0] XManM, YManM, ZManM; // input's fraction - memory stage - logic [10:0] BiasE; // bias based on precision (single=7f double=3ff) logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage logic XNaNQ, YNaNQ; // is the input a NaN - divide @@ -179,7 +178,7 @@ module fpu ( unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FOpCtrlE, .FmtE, .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, - .XZeroE, .YZeroE, .ZZeroE, .BiasE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE); + .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE); // FMA // - two stage FMA @@ -231,7 +230,7 @@ module fpu ( .XSNaNE, .ClassResE); // Convert - fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .BiasE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE, + fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE, .CvtResE, .CvtFlgE); // data to be stored in memory - to IEU diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv new file mode 100644 index 000000000..0db63fe91 --- /dev/null +++ b/pipelined/src/fpu/unpack.sv @@ -0,0 +1,361 @@ +`include "wally-config.vh" + +module unpack ( + input logic [`FLEN-1:0] X, Y, Z, + input logic [`FPSIZES/3:0] FmtE, + input logic [2:0] FOpCtrlE, + output logic XSgnE, YSgnE, ZSgnE, + output logic [`NE-1:0] XExpE, YExpE, ZExpE, + output logic [`NF:0] XManE, YManE, ZManE, + output logic XNormE, + output logic XNaNE, YNaNE, ZNaNE, + output logic XSNaNE, YSNaNE, ZSNaNE, + output logic XDenormE, YDenormE, ZDenormE, + output logic XZeroE, YZeroE, ZZeroE, + output logic XInfE, YInfE, ZInfE, + output logic XExpMaxE +); + + logic [`NF-1:0] XFracE, YFracE, ZFracE; + logic XExpNonzero, YExpNonzero, ZExpNonzero; + logic XFracZero, YFracZero, ZFracZero; // input fraction zero + logic XExpZero, YExpZero, ZExpZero; // input exponent zero + logic YExpMaxE, ZExpMaxE; // input exponent all 1s + + if (`FPSIZES == 1) begin + assign XSgnE = X[`FLEN-1]; + assign YSgnE = Y[`FLEN-1]; + assign ZSgnE = Z[`FLEN-1]; + + assign XExpE = X[`FLEN-2:`NF]; + assign YExpE = Y[`FLEN-2:`NF]; + assign ZExpE = Z[`FLEN-2:`NF]; + + assign XFracE = X[`NF-1:0]; + assign YFracE = Y[`NF-1:0]; + assign ZFracE = Z[`NF-1:0]; + + assign XExpNonzero = |XExpE; + assign YExpNonzero = |YExpE; + assign ZExpNonzero = |ZExpE; + + assign XExpMaxE = &XExpE; + assign YExpMaxE = &YExpE; + assign ZExpMaxE = &ZExpE; + + + end else if (`FPSIZES == 2) begin + + logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half 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)}; + + 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 + assign XExpE = FmtE ? X[`FLEN-2:`NF] : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; + assign YExpE = FmtE ? Y[`FLEN-2:`NF] : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; + assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + + 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)}; + + 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]; + + 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 + logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed + logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half 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)}; + + 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)}; + + always_comb begin + case (FmtE) + `FMT: begin + assign XSgnE = X[`FLEN-1]; + assign YSgnE = Y[`FLEN-1]; + assign ZSgnE = Z[`FLEN-1]; + + assign XExpE = X[`FLEN-2:`NF]; + assign YExpE = Y[`FLEN-2:`NF]; + assign ZExpE = Z[`FLEN-2:`NF]; + + assign XFracE = X[`NF-1:0]; + assign YFracE = Y[`NF-1:0]; + assign ZFracE = Z[`NF-1:0]; + + assign XExpNonzero = |X[`FLEN-2:`NF]; + assign YExpNonzero = |Y[`FLEN-2:`NF]; + assign ZExpNonzero = |Z[`FLEN-2:`NF]; + + assign XExpMaxE = &X[`FLEN-2:`NF]; + assign YExpMaxE = &Y[`FLEN-2:`NF]; + assign ZExpMaxE = &Z[`FLEN-2:`NF]; + end + `FMT1: begin + assign XSgnE = XLen1[`LEN1-1]; + assign YSgnE = YLen1[`LEN1-1]; + assign 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 + assign XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; + assign YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; + assign ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + + assign XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)}; + assign YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)}; + assign ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)}; + + assign XExpNonzero = |XLen1[`LEN1-2:`NF1]; + assign YExpNonzero = |YLen1[`LEN1-2:`NF1]; + assign ZExpNonzero = |ZLen1[`LEN1-2:`NF1]; + + assign XExpMaxE = &XLen1[`LEN1-2:`NF1]; + assign YExpMaxE = &YLen1[`LEN1-2:`NF1]; + assign ZExpMaxE = &ZLen1[`LEN1-2:`NF1]; + end + `FMT2: begin + assign XSgnE = XLen2[`LEN2-1]; + assign YSgnE = YLen2[`LEN2-1]; + assign 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 + assign XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]}; + assign YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]}; + assign ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]}; + + assign XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)}; + assign YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)}; + assign ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)}; + + assign XExpNonzero = |XLen2[`LEN2-2:`NF2]; + assign YExpNonzero = |YLen2[`LEN2-2:`NF2]; + assign ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; + + assign XExpMaxE = &XLen2[`LEN2-2:`NF2]; + assign YExpMaxE = &YLen2[`LEN2-2:`NF2]; + assign ZExpMaxE = &ZLen2[`LEN2-2:`NF2]; + end + default: begin + assign XSgnE = 0; + assign YSgnE = 0; + assign ZSgnE = 0; + assign XExpE = 0; + assign YExpE = 0; + assign ZExpE = 0; + assign XFracE = 0; + assign YFracE = 0; + assign ZFracE = 0; + assign XExpNonzero = 0; + assign YExpNonzero = 0; + assign ZExpNonzero = 0; + assign XExpMaxE = 0; + assign YExpMaxE = 0; + assign ZExpMaxE = 0; + end + endcase + end + + end else begin + logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed + logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half or NaN, if not properly NaN boxed + logic [`LEN2-1:0] XLen3, YLen3, ZLen3; // Bottom half 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:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; + assign YLen1 = &Y[`FLEN-1:`D_LEN] ? Y[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; + assign ZLen1 = &Z[`FLEN-1:`D_LEN] ? Z[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; + + assign XLen2 = &X[`FLEN-1:`S_LEN] ? X[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)}; + assign YLen2 = &Y[`FLEN-1:`S_LEN] ? Y[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)}; + assign ZLen2 = &Z[`FLEN-1:`S_LEN] ? Z[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)}; + + assign XLen3 = &X[`FLEN-1:`H_LEN] ? X[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; + assign YLen3 = &Y[`FLEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; + assign ZLen3 = &Z[`FLEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; + + always_comb begin + case (FmtE) + 2'b11: begin + assign XSgnE = X[`FLEN-1]; + assign YSgnE = Y[`FLEN-1]; + assign ZSgnE = Z[`FLEN-1]; + + assign XExpE = X[`FLEN-2:`NF]; + assign YExpE = Y[`FLEN-2:`NF]; + assign ZExpE = Z[`FLEN-2:`NF]; + + assign XFracE = X[`NF-1:0]; + assign YFracE = Y[`NF-1:0]; + assign ZFracE = Z[`NF-1:0]; + + assign XExpNonzero = |X[`FLEN-2:`NF]; + assign YExpNonzero = |Y[`FLEN-2:`NF]; + assign ZExpNonzero = |Z[`FLEN-2:`NF]; + + assign XExpMaxE = &X[`FLEN-2:`NF]; + assign YExpMaxE = &Y[`FLEN-2:`NF]; + assign ZExpMaxE = &Z[`FLEN-2:`NF]; + end + 2'b01: begin + assign XSgnE = XLen1[`LEN1-1]; + assign YSgnE = YLen1[`LEN1-1]; + assign 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 + assign XExpE = {XLen1[`D_LEN-2], {`NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]}; + assign YExpE = {YLen1[`D_LEN-2], {`NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]}; + assign ZExpE = {ZLen1[`D_LEN-2], {`NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; + + assign XFracE = {XLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; + assign YFracE = {YLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; + assign ZFracE = {ZLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; + + assign XExpNonzero = |XLen1[`D_LEN-2:`D_NE]; + assign YExpNonzero = |YLen1[`D_LEN-2:`D_NE]; + assign ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE]; + + assign XExpMaxE = &XLen1[`D_LEN-2:`D_NE]; + assign YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; + assign ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; + end + 2'b00: begin + assign XSgnE = XLen2[`S_LEN-1]; + assign YSgnE = YLen2[`S_LEN-1]; + assign 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 + assign XExpE = {XLen2[`S_LEN-2], {`NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]}; + assign YExpE = {YLen2[`S_LEN-2], {`NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]}; + assign ZExpE = {ZLen2[`S_LEN-2], {`NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]}; + + assign XFracE = {XLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; + assign YFracE = {YLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; + assign ZFracE = {ZLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; + + assign XExpNonzero = |XLen2[`S_LEN-2:`S_NF]; + assign YExpNonzero = |YLen2[`S_LEN-2:`S_NF]; + assign ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF]; + + assign XExpMaxE = &XLen2[`S_LEN-2:`S_NF]; + assign YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; + assign ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; + end + 2'b10: begin + assign XSgnE = XLen3[`H_LEN-1]; + assign YSgnE = YLen3[`H_LEN-1]; + assign 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 + assign XExpE = {XLen3[`H_LEN-2], {`NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]}; + assign YExpE = {YLen3[`H_LEN-2], {`NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]}; + assign ZExpE = {ZLen3[`H_LEN-2], {`NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]}; + + assign XFracE = {XLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; + assign YFracE = {YLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; + assign ZFracE = {ZLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; + + assign XExpNonzero = |XLen3[`H_LEN-2:`H_NF]; + assign YExpNonzero = |YLen3[`H_LEN-2:`H_NF]; + assign ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF]; + + assign XExpMaxE = &XLen3[`H_LEN-2:`H_NF]; + assign YExpMaxE = &YLen3[`H_LEN-2:`H_NF]; + assign ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF]; + end + endcase + end + + end + + assign XExpZero = ~XExpNonzero; + assign YExpZero = ~YExpNonzero; + assign ZExpZero = ~ZExpNonzero; + + assign XFracZero = ~|XFracE; + assign YFracZero = ~|YFracE; + assign ZFracZero = ~|ZFracE; + + assign XManE = {XExpNonzero, XFracE}; + assign YManE = {YExpNonzero, YFracE}; + assign ZManE = {ZExpNonzero, ZFracE}; + + assign XNormE = ~(XExpMaxE|XExpZero); + + // force single precision input to be a NaN if it isn't properly Nan Boxed + assign XNaNE = XExpMaxE & ~XFracZero; + assign YNaNE = YExpMaxE & ~YFracZero; + assign ZNaNE = ZExpMaxE & ~ZFracZero; + + assign XSNaNE = XNaNE&~XFracE[`NF-1]; + assign YSNaNE = YNaNE&~YFracE[`NF-1]; + assign ZSNaNE = ZNaNE&~ZFracE[`NF-1]; + + assign XDenormE = XExpZero & ~XFracZero; + assign YDenormE = YExpZero & ~YFracZero; + assign ZDenormE = ZExpZero & ~ZFracZero; + + assign XInfE = XExpMaxE & XFracZero; + assign YInfE = YExpMaxE & YFracZero; + assign ZInfE = ZExpMaxE & ZFracZero; + + assign XZeroE = XExpZero & XFracZero; + assign YZeroE = YExpZero & YFracZero; + assign ZZeroE = ZExpZero & ZFracZero; + +endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/unpacking.sv b/pipelined/src/fpu/unpacking.sv deleted file mode 100644 index f503e47be..000000000 --- a/pipelined/src/fpu/unpacking.sv +++ /dev/null @@ -1,95 +0,0 @@ -`include "wally-config.vh" - -module unpack ( - input logic [63:0] X, Y, Z, - input logic FmtE, - input logic [2:0] FOpCtrlE, - output logic XSgnE, YSgnE, ZSgnE, - output logic [10:0] XExpE, YExpE, ZExpE, - output logic [52:0] XManE, YManE, ZManE, - output logic XNormE, - output logic XNaNE, YNaNE, ZNaNE, - output logic XSNaNE, YSNaNE, ZSNaNE, - output logic XDenormE, YDenormE, ZDenormE, - output logic XZeroE, YZeroE, ZZeroE, - output logic [10:0] BiasE, - output logic XInfE, YInfE, ZInfE, - output logic XExpMaxE -); - - logic [51:0] XFracE, YFracE, ZFracE; - logic XExpNonzero, YExpNonzero, ZExpNonzero; - logic XFracZero, YFracZero, ZFracZero; // input fraction zero - logic XExpZero, YExpZero, ZExpZero; // input exponent zero - logic YExpMaxE, ZExpMaxE; // input exponent all 1s - logic [31:0] XFloat, YFloat, ZFloat; // Bottom half or NaN, if RV64 and not properly NaN boxed - - // Determine if number is NaN as double precision to check single precision NaN boxing - if (`F_SUPPORTED & ~`D_SUPPORTED) begin // eventually this should change to FLEN when FLEN isn't hardwared to 64 - assign XFloat = X[31:0]; - assign YFloat = Y[31:0]; - assign ZFloat = Z[31:0]; - end else begin - assign XFloat = &X[`FLEN-1:32] ? X[31:0] : 32'h7fc00000; - assign YFloat = &Y[`FLEN-1:32] ? Y[31:0] : 32'h7fc00000; - assign ZFloat = &Z[`FLEN-1:32] ? Z[31:0] : 32'h7fc00000; - end - - assign XSgnE = FmtE ? X[63] : XFloat[31]; - assign YSgnE = FmtE ? Y[63] : YFloat[31]; - assign ZSgnE = FmtE ? Z[63] : ZFloat[31]; - - assign XExpE = FmtE ? X[62:52] : {XFloat[30], {3{~XFloat[30]&~XExpZero|XExpMaxE}}, XFloat[29:23]}; - assign YExpE = FmtE ? Y[62:52] : {YFloat[30], {3{~YFloat[30]&~YExpZero|YExpMaxE}}, YFloat[29:23]}; - assign ZExpE = FmtE ? Z[62:52] : {ZFloat[30], {3{~ZFloat[30]&~ZExpZero|ZExpMaxE}}, ZFloat[29:23]}; - - assign XFracE = FmtE ? X[51:0] : {XFloat[22:0], 29'b0}; - assign YFracE = FmtE ? Y[51:0] : {YFloat[22:0], 29'b0}; - assign ZFracE = FmtE ? Z[51:0] : {ZFloat[22:0], 29'b0}; - - assign XExpNonzero = FmtE ? |X[62:52] : |XFloat[30:23]; - assign YExpNonzero = FmtE ? |Y[62:52] : |YFloat[30:23]; - assign ZExpNonzero = FmtE ? |Z[62:52] : |ZFloat[30:23]; - - assign XExpZero = ~XExpNonzero; - assign YExpZero = ~YExpNonzero; - assign ZExpZero = ~ZExpNonzero; - - assign XFracZero = ~|XFracE; - assign YFracZero = ~|YFracE; - assign ZFracZero = ~|ZFracE; - - assign XManE = {XExpNonzero, XFracE}; - assign YManE = {YExpNonzero, YFracE}; - assign ZManE = {ZExpNonzero, ZFracE}; - - assign XExpMaxE = FmtE ? &X[62:52] : &XFloat[30:23]; - assign YExpMaxE = FmtE ? &Y[62:52] : &YFloat[30:23]; - assign ZExpMaxE = FmtE ? &Z[62:52] : &ZFloat[30:23]; - - assign XNormE = ~(XExpMaxE|XExpZero); - - // force single precision input to be a NaN if it isn't properly Nan Boxed - assign XNaNE = XExpMaxE & ~XFracZero; - assign YNaNE = YExpMaxE & ~YFracZero; - assign ZNaNE = ZExpMaxE & ~ZFracZero; - - assign XSNaNE = XNaNE&~XFracE[51]; - assign YSNaNE = YNaNE&~YFracE[51]; - assign ZSNaNE = ZNaNE&~ZFracE[51]; - - assign XDenormE = XExpZero & ~XFracZero; - assign YDenormE = YExpZero & ~YFracZero; - assign ZDenormE = ZExpZero & ~ZFracZero; - - assign XInfE = XExpMaxE & XFracZero; - assign YInfE = YExpMaxE & YFracZero; - assign ZInfE = ZExpMaxE & ZFracZero; - - assign XZeroE = XExpZero & XFracZero; - assign YZeroE = YExpZero & YFracZero; - assign ZZeroE = ZExpZero & ZFracZero; - - assign BiasE = 11'h3ff; // always use 1023 because exponents are unpacked to double precision - -endmodule \ No newline at end of file diff --git a/pipelined/testbench/fp/tests/fma-testbench.sv b/pipelined/testbench/fp/tests/fma-testbench.sv new file mode 100644 index 000000000..6ce50387d --- /dev/null +++ b/pipelined/testbench/fp/tests/fma-testbench.sv @@ -0,0 +1,279 @@ + +`include "wally-config.vh" +`define PATH "../../../../tests/fp/vectors/" + +string tests[] = '{ + "f16_mulAdd_rne.tv", + "f16_mulAdd_rz.tv", + "f16_mulAdd_ru.tv", + "f16_mulAdd_rd.tv", + "f16_mulAdd_rnm.tv", + "f32_mulAdd_rne.tv", + "f32_mulAdd_rz.tv", + "f32_mulAdd_ru.tv", + "f32_mulAdd_rd.tv", + "f32_mulAdd_rnm.tv", + "f64_mulAdd_rne.tv", + "f64_mulAdd_rz.tv", + "f64_mulAdd_ru.tv", + "f64_mulAdd_rd.tv", + "f64_mulAdd_rnm.tv", + "f128_mulAdd_rne.tv", + "f128_mulAdd_rz.tv", + "f128_mulAdd_ru.tv", + "f128_mulAdd_rd.tv", + "f128_mulAdd_rnm.tv" +}; + +// steps to run FMA tests +// 1) create test vectors in riscv-wally/tests/fp with: ./run-all.sh +// 2) go to riscv-wally/pipelined/testbench/fp/tests +// 3) run ./sim-wally-batch + +module fmatestbench(); + + logic clk; + logic [31:0] errors=0; + logic [31:0] vectornum=0; + logic [`FLEN*4+7+4+4:0] testvectors[6133248:0]; + int i = `ZFH_SUPPORTED ? 0 : `F_SUPPORTED ? 5 : `D_SUPPORTED ? 10 : 15; // set i to the first test that is run + + logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat + logic [`FLEN-1:0] ans; // result from TestFloat + logic [7:0] flags; // flags read form testfloat + logic [2:0] FrmE; // rounding mode + logic [`FPSIZES/3:0] FmtE; // format - 10 = half, 00 = single, 01 = double, 11 = quad + logic [3:0] FrmRead; // rounding mode read from testfloat + logic [3:0] FmtRead; // format read from testfloat + logic [`FLEN-1:0] FMAResM; // FMA's outputed result + logic [4:0] FMAFlgM; // FMA's outputed flags + logic [2:0] FOpCtrlE; // which opperation + logic wnan; // is the outputed result NaN + logic ansnan; // is the correct answer NaN + + // signals needed to connect modules + logic [`NE+1:0] ProdExpE; + logic AddendStickyE; + logic KillProdE; + logic XSgnE, YSgnE, ZSgnE; + logic [`NE-1:0] XExpE, YExpE, ZExpE; + logic [`NF:0] XManE, YManE, ZManE; + logic XNormE; + logic XExpMaxE; + logic XNaNE, YNaNE, ZNaNE; + logic XSNaNE, YSNaNE, ZSNaNE; + logic XDenormE, YDenormE, ZDenormE; + logic XInfE, YInfE, ZInfE; + logic XZeroE, YZeroE, ZZeroE; + logic YExpMaxE, ZExpMaxE, Mult; + logic [3*`NF+5:0] SumE; + logic InvZE; + logic NegSumE; + logic ZSgnEffE; + logic PSgnE; + logic [$clog2(3*`NF+7)-1:0] NormCntE; + + + assign FOpCtrlE = 3'b0; // set to 0 because test float only tests fMADD + assign Mult = 1'b0; // set to zero because not testing multiplication + + // check if the calculated result or correct answer is NaN + always_comb begin + case (FmtRead) + 4'b11: begin // quad + assign ansnan = &ans[`FLEN-2:`NF]&(|ans[`NF-1:0]); + assign wnan = &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]); + + end + 4'b01: begin // double + assign ansnan = &ans[`LEN1-2:`NF1]&(|ans[`NF1-1:0]); + assign wnan = &FMAResM[`LEN1-2:`NF1]&(|FMAResM[`NF1-1:0]); + + end + 4'b00: begin // single + assign ansnan = &ans[`LEN2-2:`NF2]&(|ans[`NF2-1:0]); + assign wnan = &FMAResM[`LEN2-2:`NF2]&(|FMAResM[`NF2-1:0]); + end + 4'b10: begin // half + assign ansnan = &ans[`H_LEN-2:`H_NF]&(|ans[`H_NF-1:0]); + assign wnan = &FMAResM[`H_LEN-2:`H_NF]&(|FMAResM[`H_NF-1:0]); + end + endcase + end + + // instantiate devices under test + unpack unpack(.X, .Y, .Z, .FmtE, .FOpCtrlE, .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, + .XManE, .YManE, .ZManE, .XNormE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, + .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, + .XExpMaxE); + fma1 fma1(.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, + .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, + .FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE, + .ProdExpE, .AddendStickyE, .KillProdE); + fma2 fma2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZExpE), .XManM(XManE), .YManM(YManE), .ZManM(ZManE), + .XNaNM(XNaNE), .YNaNM(YNaNE), .ZNaNM(ZNaNE), .XZeroM(XZeroE), .YZeroM(YZeroE), .ZZeroM(ZZeroE), .XInfM(XInfE), .YInfM(YInfE), .ZInfM(ZInfE), + .XSNaNM(XSNaNE), .YSNaNM(YSNaNE), .ZSNaNM(ZSNaNE), .KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE), + .SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .NormCntM(NormCntE), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), .FmtM(FmtE), .FrmM(FrmE), + .FMAFlgM, .FMAResM, .Mult); + + + // produce clock + always begin + clk = 1; #5; clk = 0; #5; + end + + // Read first test + initial begin + $display("\n\nRunning %s vectors", tests[i]); + $readmemh({`PATH, tests[i]}, testvectors); + end + + // apply test vectors on rising edge of clk + always @(posedge clk) begin + #1; + flags = testvectors[vectornum][15:8]; + FrmRead = testvectors[vectornum][7:4]; + FmtRead = testvectors[vectornum][3:0]; + if (FmtRead==4'b11 & `Q_SUPPORTED) begin // quad + X = testvectors[vectornum][16+4*(`Q_LEN)-1:16+3*(`Q_LEN)]; + Y = testvectors[vectornum][16+3*(`Q_LEN)-1:16+2*(`Q_LEN)]; + Z = testvectors[vectornum][16+2*(`Q_LEN)-1:16+`Q_LEN]; + ans = testvectors[vectornum][16+(`Q_LEN-1):16]; + end + else if (FmtRead==4'b01 & `D_SUPPORTED) begin // double + X = {{`FLEN-`D_LEN{1'b1}}, testvectors[vectornum][16+4*(`D_LEN)-1:16+3*(`D_LEN)]}; + Y = {{`FLEN-`D_LEN{1'b1}}, testvectors[vectornum][16+3*(`D_LEN)-1:16+2*(`D_LEN)]}; + Z = {{`FLEN-`D_LEN{1'b1}}, testvectors[vectornum][16+2*(`D_LEN)-1:16+`D_LEN]}; + ans = {{`FLEN-`D_LEN{1'b1}}, testvectors[vectornum][16+(`D_LEN-1):16]}; + end + else if (FmtRead==4'b00 & `F_SUPPORTED) begin // single + X = {{`FLEN-`S_LEN{1'b1}}, testvectors[vectornum][16+4*(`S_LEN)-1:16+3*(`S_LEN)]}; + Y = {{`FLEN-`S_LEN{1'b1}}, testvectors[vectornum][16+3*(`S_LEN)-1:16+2*(`S_LEN)]}; + Z = {{`FLEN-`S_LEN{1'b1}}, testvectors[vectornum][16+2*(`S_LEN)-1:16+`S_LEN]}; + ans = {{`FLEN-`S_LEN{1'b1}}, testvectors[vectornum][16+(`S_LEN-1):16]}; + end + else if (FmtRead==4'b10 & `ZFH_SUPPORTED) begin // half + X = {{`FLEN-`H_LEN{1'b1}}, testvectors[vectornum][16+4*(`H_LEN)-1:16+3*(`H_LEN)]}; + Y = {{`FLEN-`H_LEN{1'b1}}, testvectors[vectornum][16+3*(`H_LEN)-1:16+2*(`H_LEN)]}; + Z = {{`FLEN-`H_LEN{1'b1}}, testvectors[vectornum][16+2*(`H_LEN)-1:16+`H_LEN]}; + ans = {{`FLEN-`H_LEN{1'b1}}, testvectors[vectornum][16+(`H_LEN-1):16]}; + end + else begin + X = {`FLEN{1'bx}}; + Y = {`FLEN{1'bx}}; + Z = {`FLEN{1'bx}}; + ans = {`FLEN{1'bx}}; + end + + // trim format and rounding mode to appropriate size + if (`FPSIZES <= 2) FmtE = FmtRead === `FMT; // rewrite format if 2 or less floating formats are supported + else FmtE = FmtRead[1:0]; + FrmE = FrmRead[2:0]; + end + + // check results on falling edge of clk + always @(negedge clk) begin + // quad + if((FmtRead==4'b11) & ~((FMAFlgM === flags[4:0]) | (FMAResM === ans) | (wnan & (FMAResM[`FLEN-2:0] === ans[`FLEN-2:0] | (XNaNE&(FMAResM[`FLEN-2:0] === {X[`FLEN-2:`NF],1'b1,X[`NF-2:0]})) | (YNaNE&(FMAResM[`FLEN-2:0] === {Y[`FLEN-2:`NF],1'b1,Y[`NF-2:0]})) | (ZNaNE&(FMAResM[`FLEN-2:0] === {Z[`FLEN-2:`NF],1'b1,Z[`NF-2:0]})))))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(XDenormE) $display( "xdenorm "); + if(YDenormE) $display( "ydenorm "); + if(ZDenormE) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=-inf "); + if(~FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] === 0) $display( "FMAResM=+inf "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); + if(FMAResM[`FLEN-2:`NF] === {`NE{1'b1}} && FMAResM[`NF-1:0] !== 0 && FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); + if(ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=-inf "); + if(~ans[`FLEN] && ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] === 0) $display( "ans=+inf "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ~ans[`NF-1]) $display( "ans=sigNaN "); + if(ans[`FLEN-2:`NF] === {`NE{1'b1}} && ans[`NF-1:0] !== 0 && ans[`NF-1]) $display( "ans=qutNaN "); + errors = errors + 1; + if (errors === 1) $stop; + end + // double + if((FmtRead==4'b01) & ~((FMAFlgM === flags[4:0]) | (FMAResM === ans) | (wnan & (FMAResM[`D_LEN-2:0] === ans[`D_LEN-2:0] | (XNaNE&(FMAResM[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | (YNaNE&(FMAResM[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})) | (ZNaNE&(FMAResM[`D_LEN-2:0] === {Z[`D_LEN-2:`D_NF],1'b1,Z[`D_NF-2:0]})))))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + if (errors === 1) $stop; + end + // single + if((FmtRead==4'b00) & ~((FMAFlgM === flags[4:0]) | (FMAResM === ans) | (wnan & (FMAResM[`S_LEN-2:0] === ans[`S_LEN-2:0] | (XNaNE&(FMAResM[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | (YNaNE&(FMAResM[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})) | (ZNaNE&(FMAResM[`S_LEN-2:0] === {Z[`S_LEN-2:`S_NF],1'b1,Z[`S_NF-2:0]})))))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + if (errors === 1) $stop; + end + // half + if((FmtRead==4'b01) & ~((FMAFlgM === flags[4:0]) | (FMAResM === ans) | (wnan & (FMAResM[`H_LEN-2:0] === ans[`H_LEN-2:0] | (XNaNE&(FMAResM[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | (YNaNE&(FMAResM[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})) | (ZNaNE&(FMAResM[`H_LEN-2:0] === {Z[`H_LEN-2:`H_NF],1'b1,Z[`H_NF-2:0]})))))) begin + $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); + if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(FMAFlgM[4] !== 0) $display( "invld "); + if(FMAFlgM[2] !== 0) $display( "ovrflw "); + if(FMAFlgM[1] !== 0) $display( "unflw "); + if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + errors = errors + 1; + if (errors === 1) $stop; + end + + // if ( vectornum === 3165862) $stop; // uncomment for specific test + vectornum = vectornum + 1; // increment test + if (testvectors[vectornum][0] === 1'bx) begin // if reached the end of file + if (errors) begin // if there were errors + $display("%s completed with %d tests and %d errors", tests[i], vectornum, errors); + $stop; + end + else begin // if no errors + if(tests[i] === "") begin // if no more tests + $display("\nAll tests completed with %d errors\n", errors); + $stop; + end + + $display("%s completed successfully with %d tests and %d errors (across all tests)\n", tests[i], vectornum, errors); + + // increment tests - skip some precisions if needed + if ((i === 4 & ~`F_SUPPORTED) | (i === 9 & ~`D_SUPPORTED) | (i === 14 & ~`Q_SUPPORTED)) i = i+5; + if ((i === 9 & ~`D_SUPPORTED) | (i === 14 & ~`Q_SUPPORTED)) i = i+5; + if ((i === 14 & ~`Q_SUPPORTED)) i = i+5; + i = i+1; + + // if no more tests - finish + if(tests[i] === "") begin + $display("\nAll tests completed with %d errors\n", errors); + $stop; + end + + // read next files + $display("Running %s vectors", tests[i]); + $readmemh({`PATH, tests[i]}, testvectors); + vectornum = 0; + end + end + end +endmodule diff --git a/pipelined/testbench/fp/tests/fma.do b/pipelined/testbench/fp/tests/fma.do new file mode 100644 index 000000000..6349be0ef --- /dev/null +++ b/pipelined/testbench/fp/tests/fma.do @@ -0,0 +1,50 @@ +# wally-pipelined.do +# +# Modification by Oklahoma State University & Harvey Mudd College +# Use with Testbench +# James Stine, 2008; David Harris 2021 +# Go Cowboys!!!!!! +# +# Takes 1:10 to run RV64IC tests using gui + +# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m" + +# Use this wally-pipelined.do file to run this example. +# Either bring up ModelSim and type the following at the "ModelSim>" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +# $num = the added words after the call +vlog +incdir+../../../config/$1 +incdir+../../../config/shared fma-testbench.sv ../../../src/fpu/fma.sv ../../../src/fpu/unpack.sv -suppress 2583 -suppress 7063 + +vsim -voptargs=+acc work.fmatestbench + +view wave +#-- display input and output signals as hexidecimal values +#do ./wave-dos/peripheral-waves.do +#add log -recursive /* +#do wave.do deal with when ready + +#-- Run the Simulation +#run 3600 +run -all +noview fma-testbench.sv +view wave + diff --git a/pipelined/testbench/fp/tests/sim-fma b/pipelined/testbench/fp/tests/sim-fma new file mode 100755 index 000000000..5027d43e4 --- /dev/null +++ b/pipelined/testbench/fp/tests/sim-fma @@ -0,0 +1 @@ +vsim -do "do fma.do rv64fp" diff --git a/pipelined/testbench/fp/tests/sim-fma-batch b/pipelined/testbench/fp/tests/sim-fma-batch new file mode 100755 index 000000000..321e0678d --- /dev/null +++ b/pipelined/testbench/fp/tests/sim-fma-batch @@ -0,0 +1 @@ +vsim -c -do "do fma.do rv64fp" \ No newline at end of file diff --git a/tests/fp/create_vectors128fma.sh b/tests/fp/create_vectors128fma.sh new file mode 100755 index 000000000..361a4add7 --- /dev/null +++ b/tests/fp/create_vectors128fma.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +BUILD="./TestFloat-3e/build/Linux-x86_64-GCC" +OUTPUT="./vectors" + +$BUILD/testfloat_gen -rnear_even f128_mulAdd > $OUTPUT/f128_mulAdd_rne.tv +$BUILD/testfloat_gen -rminMag f128_mulAdd > $OUTPUT/f128_mulAdd_rz.tv +$BUILD/testfloat_gen -rmax f128_mulAdd > $OUTPUT/f128_mulAdd_ru.tv +$BUILD/testfloat_gen -rmin f128_mulAdd > $OUTPUT/f128_mulAdd_rd.tv +$BUILD/testfloat_gen -rnear_maxMag f128_mulAdd > $OUTPUT/f128_mulAdd_rnm.tv + +# format: X_Y_Z_answer_flags_Frm_Fmt +sed -i 's/ /_/g' $OUTPUT/f128_mulAdd_rne.tv +sed -ie 's/$/_0/' $OUTPUT/f128_mulAdd_rne.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_rne.tv + +sed -i 's/ /_/g' $OUTPUT/f128_mulAdd_rz.tv +sed -ie 's/$/_1/' $OUTPUT/f128_mulAdd_rz.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_rz.tv + +sed -i 's/ /_/g' $OUTPUT/f128_mulAdd_ru.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_ru.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_ru.tv + +sed -i 's/ /_/g' $OUTPUT/f128_mulAdd_rd.tv +sed -ie 's/$/_2/' $OUTPUT/f128_mulAdd_rd.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_rd.tv + +sed -i 's/ /_/g' $OUTPUT/f128_mulAdd_rnm.tv +sed -ie 's/$/_4/' $OUTPUT/f128_mulAdd_rnm.tv +sed -ie 's/$/_3/' $OUTPUT/f128_mulAdd_rnm.tv \ No newline at end of file diff --git a/tests/fp/create_vectors16fma.sh b/tests/fp/create_vectors16fma.sh new file mode 100755 index 000000000..d46e87680 --- /dev/null +++ b/tests/fp/create_vectors16fma.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +BUILD="./TestFloat-3e/build/Linux-x86_64-GCC" +OUTPUT="./vectors" + +$BUILD/testfloat_gen -rnear_even f16_mulAdd > $OUTPUT/f16_mulAdd_rne.tv +$BUILD/testfloat_gen -rminMag f16_mulAdd > $OUTPUT/f16_mulAdd_rz.tv +$BUILD/testfloat_gen -rmax f16_mulAdd > $OUTPUT/f16_mulAdd_ru.tv +$BUILD/testfloat_gen -rmin f16_mulAdd > $OUTPUT/f16_mulAdd_rd.tv +$BUILD/testfloat_gen -rnear_maxMag f16_mulAdd > $OUTPUT/f16_mulAdd_rnm.tv + +# format: X_Y_Z_answer_flags_Frm_Fmt +sed -i 's/ /_/g' $OUTPUT/f16_mulAdd_rne.tv +sed -ie 's/$/_0/' $OUTPUT/f16_mulAdd_rne.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_rne.tv + +sed -i 's/ /_/g' $OUTPUT/f16_mulAdd_rz.tv +sed -ie 's/$/_1/' $OUTPUT/f16_mulAdd_rz.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_rz.tv + +sed -i 's/ /_/g' $OUTPUT/f16_mulAdd_ru.tv +sed -ie 's/$/_3/' $OUTPUT/f16_mulAdd_ru.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_ru.tv + +sed -i 's/ /_/g' $OUTPUT/f16_mulAdd_rd.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_rd.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_rd.tv + +sed -i 's/ /_/g' $OUTPUT/f16_mulAdd_rnm.tv +sed -ie 's/$/_4/' $OUTPUT/f16_mulAdd_rnm.tv +sed -ie 's/$/_2/' $OUTPUT/f16_mulAdd_rnm.tv \ No newline at end of file diff --git a/tests/fp/create_vectors32fma.sh b/tests/fp/create_vectors32fma.sh new file mode 100755 index 000000000..7e48d1abe --- /dev/null +++ b/tests/fp/create_vectors32fma.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +BUILD="./TestFloat-3e/build/Linux-x86_64-GCC" +OUTPUT="./vectors" + +$BUILD/testfloat_gen -rnear_even f32_mulAdd > $OUTPUT/f32_mulAdd_rne.tv +$BUILD/testfloat_gen -rminMag f32_mulAdd > $OUTPUT/f32_mulAdd_rz.tv +$BUILD/testfloat_gen -rmax f32_mulAdd > $OUTPUT/f32_mulAdd_ru.tv +$BUILD/testfloat_gen -rmin f32_mulAdd > $OUTPUT/f32_mulAdd_rd.tv +$BUILD/testfloat_gen -rnear_maxMag f32_mulAdd > $OUTPUT/f32_mulAdd_rnm.tv + +# format: X_Y_Z_answer_flags_Frm_Fmt +sed -i 's/ /_/g' $OUTPUT/f32_mulAdd_rne.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_rne.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_rne.tv + +sed -i 's/ /_/g' $OUTPUT/f32_mulAdd_rz.tv +sed -ie 's/$/_1/' $OUTPUT/f32_mulAdd_rz.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_rz.tv + +sed -i 's/ /_/g' $OUTPUT/f32_mulAdd_ru.tv +sed -ie 's/$/_3/' $OUTPUT/f32_mulAdd_ru.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_ru.tv + +sed -i 's/ /_/g' $OUTPUT/f32_mulAdd_rd.tv +sed -ie 's/$/_2/' $OUTPUT/f32_mulAdd_rd.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_rd.tv + +sed -i 's/ /_/g' $OUTPUT/f32_mulAdd_rnm.tv +sed -ie 's/$/_4/' $OUTPUT/f32_mulAdd_rnm.tv +sed -ie 's/$/_0/' $OUTPUT/f32_mulAdd_rnm.tv \ No newline at end of file diff --git a/tests/fp/create_vectors64fma.sh b/tests/fp/create_vectors64fma.sh new file mode 100755 index 000000000..615245b30 --- /dev/null +++ b/tests/fp/create_vectors64fma.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +BUILD="./TestFloat-3e/build/Linux-x86_64-GCC" +OUTPUT="./vectors" + +$BUILD/testfloat_gen -rnear_even f64_mulAdd > $OUTPUT/f64_mulAdd_rne.tv +$BUILD/testfloat_gen -rminMag f64_mulAdd > $OUTPUT/f64_mulAdd_rz.tv +$BUILD/testfloat_gen -rmax f64_mulAdd > $OUTPUT/f64_mulAdd_ru.tv +$BUILD/testfloat_gen -rmin f64_mulAdd > $OUTPUT/f64_mulAdd_rd.tv +$BUILD/testfloat_gen -rnear_maxMag f64_mulAdd > $OUTPUT/f64_mulAdd_rnm.tv + +# format: X_Y_Z_answer_flags_Frm_Fmt +sed -i 's/ /_/g' $OUTPUT/f64_mulAdd_rne.tv +sed -ie 's/$/_0/' $OUTPUT/f64_mulAdd_rne.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_rne.tv + +sed -i 's/ /_/g' $OUTPUT/f64_mulAdd_rz.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_rz.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_rz.tv + +sed -i 's/ /_/g' $OUTPUT/f64_mulAdd_ru.tv +sed -ie 's/$/_3/' $OUTPUT/f64_mulAdd_ru.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_ru.tv + +sed -i 's/ /_/g' $OUTPUT/f64_mulAdd_rd.tv +sed -ie 's/$/_2/' $OUTPUT/f64_mulAdd_rd.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_rd.tv + +sed -i 's/ /_/g' $OUTPUT/f64_mulAdd_rnm.tv +sed -ie 's/$/_4/' $OUTPUT/f64_mulAdd_rnm.tv +sed -ie 's/$/_1/' $OUTPUT/f64_mulAdd_rnm.tv \ No newline at end of file diff --git a/tests/fp/run_all.sh b/tests/fp/run_all.sh index 8d2a17ceb..d34366b93 100755 --- a/tests/fp/run_all.sh +++ b/tests/fp/run_all.sh @@ -8,3 +8,7 @@ ./create_vectors64cmp.sh ./create_vectors64.sh ./create_vectorsi.sh +./create_vectors16fma.sh +./create_vectors32fma.sh +./create_vectors64fma.sh +./create_vectors128fma.sh From ca8fb45367b811cf9a4e31b7ffbde97c6cd30021 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 16:52:07 -0500 Subject: [PATCH 02/11] Added comment about needed fix to misaligned fault. --- pipelined/src/lsu/lsu.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index ddf0f77dc..c9ceb455e 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -161,7 +161,7 @@ module lsu ( .Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(), .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM, .InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM, - .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, + .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw. .DAPageFault(DataDAPageFaultM), // *** should use LSURWM as this is includes the lr/sc squash. However this introduces a combo loop // from squash, depends on LSUPAdrM, depends on TLBHit, depends on these *AccessM inputs. From e6b42cb10f706765aeea11e00f17f055112056dd Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 16:52:27 -0500 Subject: [PATCH 03/11] Added spoof of uart addresses +0x2 and +0x6. --- pipelined/testbench/testbench-linux.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 8723d6b9c..82742ff4b 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -475,7 +475,7 @@ module testbench; end \ if(`"STAGE`"=="M") begin \ // override on special conditions \ - if (dut.core.lsu.LSUPAdrM == 'h10000005) \ + if ((dut.core.lsu.LSUPAdrM == 'h10000002) | (dut.core.lsu.LSUPAdrM == 'h10000005) | (dut.core.lsu.LSUPAdrM == 'h10000006)) \ //$display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, InstrCountW-1); \ force dut.core.ieu.dp.ReadDataM = ExpectedMemReadDataM; \ else \ From 23adb2dd03d385cd1d09d19ccec0b4aae0fe791f Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Wed, 23 Mar 2022 01:53:37 +0000 Subject: [PATCH 04/11] unpack.sv cleanup --- pipelined/src/fpu/fpu.sv | 2 +- pipelined/src/fpu/unpack.sv | 446 ++++++++++++++++++++++-------------- 2 files changed, 280 insertions(+), 168 deletions(-) diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index f9472c9b5..2ffcb1264 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -175,7 +175,7 @@ module fpu ( // unpack unit // - splits FP inputs into their various parts // - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity) - unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FOpCtrlE, .FmtE, + unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FmtE, .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE); diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index 0db63fe91..1625b2fc2 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -1,58 +1,83 @@ `include "wally-config.vh" module unpack ( - input logic [`FLEN-1:0] X, Y, Z, - input logic [`FPSIZES/3:0] FmtE, - input logic [2:0] FOpCtrlE, - output logic XSgnE, YSgnE, ZSgnE, - output logic [`NE-1:0] XExpE, YExpE, ZExpE, - output logic [`NF:0] XManE, YManE, ZManE, - output logic XNormE, - output logic XNaNE, YNaNE, ZNaNE, - output logic XSNaNE, YSNaNE, ZSNaNE, - output logic XDenormE, YDenormE, ZDenormE, - output logic XZeroE, YZeroE, ZZeroE, - output logic XInfE, YInfE, ZInfE, - output logic XExpMaxE + input logic [`FLEN-1:0] X, Y, Z, // inputs from register file + input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 10 - double 11 - quad 10 - half + output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ + output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision) + output logic [`NF:0] XManE, YManE, ZManE, // mantissas of XYZ (converted to largest supported precision) + output logic XNormE, // is X a normalized number + output logic XNaNE, YNaNE, ZNaNE, // is XYZ a NaN + output logic XSNaNE, YSNaNE, ZSNaNE, // is XYZ a signaling NaN + output logic XDenormE, YDenormE, ZDenormE, // is XYZ denormalized + output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero + output logic XInfE, YInfE, ZInfE, // is XYZ infinity + output logic XExpMaxE // does X have the maximum exponent (NaN or Inf) ); - logic [`NF-1:0] XFracE, YFracE, ZFracE; - logic XExpNonzero, YExpNonzero, ZExpNonzero; - logic XFracZero, YFracZero, ZFracZero; // input fraction zero - logic XExpZero, YExpZero, ZExpZero; // input exponent zero - logic YExpMaxE, ZExpMaxE; // input exponent all 1s + logic [`NF-1:0] XFracE, YFracE, ZFracE; //Fraction of XYZ + logic XExpNonzero, YExpNonzero, ZExpNonzero; // is the exponent of XYZ non-zero + logic XFracZero, YFracZero, ZFracZero; // is the fraction zero + logic XExpZero, YExpZero, ZExpZero; // is the exponent zero + logic YExpMaxE, ZExpMaxE; // is the exponent all 1s - if (`FPSIZES == 1) begin + if (`FPSIZES == 1) begin // if there is only one floating point format supported + + // sign bit assign XSgnE = X[`FLEN-1]; assign YSgnE = Y[`FLEN-1]; assign ZSgnE = Z[`FLEN-1]; + // exponent assign XExpE = X[`FLEN-2:`NF]; assign YExpE = Y[`FLEN-2:`NF]; assign ZExpE = Z[`FLEN-2:`NF]; + // 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; - end else if (`FPSIZES == 2) begin + end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed + //***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]; @@ -64,63 +89,94 @@ module unpack ( // 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 assign XExpE = FmtE ? X[`FLEN-2:`NF] : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; assign YExpE = FmtE ? Y[`FLEN-2:`NF] : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + // 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 - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed - logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half or NaN, if not properly NaN boxed + 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 + // 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)}; always_comb begin case (FmtE) - `FMT: begin - assign XSgnE = X[`FLEN-1]; - assign YSgnE = Y[`FLEN-1]; - assign ZSgnE = Z[`FLEN-1]; + `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]; - assign XExpE = X[`FLEN-2:`NF]; - assign YExpE = Y[`FLEN-2:`NF]; - assign ZExpE = Z[`FLEN-2:`NF]; + // extract the exponent + XExpE = X[`FLEN-2:`NF]; + YExpE = Y[`FLEN-2:`NF]; + ZExpE = Z[`FLEN-2:`NF]; - assign XFracE = X[`NF-1:0]; - assign YFracE = Y[`NF-1:0]; - assign ZFracE = Z[`NF-1:0]; + // extract the fraction + XFracE = X[`NF-1:0]; + YFracE = Y[`NF-1:0]; + ZFracE = Z[`NF-1:0]; - assign XExpNonzero = |X[`FLEN-2:`NF]; - assign YExpNonzero = |Y[`FLEN-2:`NF]; - assign ZExpNonzero = |Z[`FLEN-2:`NF]; + // is the exponent non-zero + XExpNonzero = |X[`FLEN-2:`NF]; + YExpNonzero = |Y[`FLEN-2:`NF]; + ZExpNonzero = |Z[`FLEN-2:`NF]; - assign XExpMaxE = &X[`FLEN-2:`NF]; - assign YExpMaxE = &Y[`FLEN-2:`NF]; - assign ZExpMaxE = &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 - assign XSgnE = XLen1[`LEN1-1]; - assign YSgnE = YLen1[`LEN1-1]; - assign ZSgnE = ZLen1[`LEN1-1]; + `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 @@ -129,26 +185,33 @@ module unpack ( // 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 - assign XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; - assign YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; - assign ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; - assign XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - assign YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - assign ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)}; + // convert the larger precision's exponent to use the largest precision's bias + XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; + YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; + ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; - assign XExpNonzero = |XLen1[`LEN1-2:`NF1]; - assign YExpNonzero = |YLen1[`LEN1-2:`NF1]; - assign ZExpNonzero = |ZLen1[`LEN1-2:`NF1]; + // 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)}; - assign XExpMaxE = &XLen1[`LEN1-2:`NF1]; - assign YExpMaxE = &YLen1[`LEN1-2:`NF1]; - assign ZExpMaxE = &ZLen1[`LEN1-2:`NF1]; + // 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 - assign XSgnE = XLen2[`LEN2-1]; - assign YSgnE = YLen2[`LEN2-1]; - assign ZSgnE = ZLen2[`LEN2-1]; + `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 @@ -157,87 +220,110 @@ module unpack ( // 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 - assign XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]}; - assign YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]}; - assign ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]}; + + // convert the smallest precision's exponent to use the largest precision's bias + XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]}; + YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]}; + ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]}; - assign XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - assign YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - assign ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)}; + // 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)}; - assign XExpNonzero = |XLen2[`LEN2-2:`NF2]; - assign YExpNonzero = |YLen2[`LEN2-2:`NF2]; - assign ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; + // is the exponent non-zero + XExpNonzero = |XLen2[`LEN2-2:`NF2]; + YExpNonzero = |YLen2[`LEN2-2:`NF2]; + ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; - assign XExpMaxE = &XLen2[`LEN2-2:`NF2]; - assign YExpMaxE = &YLen2[`LEN2-2:`NF2]; - assign ZExpMaxE = &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 - assign XSgnE = 0; - assign YSgnE = 0; - assign ZSgnE = 0; - assign XExpE = 0; - assign YExpE = 0; - assign ZExpE = 0; - assign XFracE = 0; - assign YFracE = 0; - assign ZFracE = 0; - assign XExpNonzero = 0; - assign YExpNonzero = 0; - assign ZExpNonzero = 0; - assign XExpMaxE = 0; - assign YExpMaxE = 0; - assign ZExpMaxE = 0; + XSgnE = 0; + YSgnE = 0; + ZSgnE = 0; + XExpE = 0; + YExpE = 0; + ZExpE = 0; + XFracE = 0; + YFracE = 0; + ZFracE = 0; + XExpNonzero = 0; + YExpNonzero = 0; + ZExpNonzero = 0; + XExpMaxE = 0; + YExpMaxE = 0; + ZExpMaxE = 0; end endcase end - end else begin - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed - logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half or NaN, if not properly NaN boxed - logic [`LEN2-1:0] XLen3, YLen3, ZLen3; // Bottom half or NaN, if not properly NaN boxed + end else 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 [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision + logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision + logic [`LEN2-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 - assign XLen1 = &X[`FLEN-1:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; - assign YLen1 = &Y[`FLEN-1:`D_LEN] ? Y[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; - assign ZLen1 = &Z[`FLEN-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 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)}; - assign XLen2 = &X[`FLEN-1:`S_LEN] ? X[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)}; - assign YLen2 = &Y[`FLEN-1:`S_LEN] ? Y[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)}; - assign ZLen2 = &Z[`FLEN-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 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)}; - assign XLen3 = &X[`FLEN-1:`H_LEN] ? X[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; - assign YLen3 = &Y[`FLEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; - assign ZLen3 = &Z[`FLEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_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)}; always_comb begin case (FmtE) - 2'b11: begin - assign XSgnE = X[`FLEN-1]; - assign YSgnE = Y[`FLEN-1]; - assign ZSgnE = Z[`FLEN-1]; + `Q_BIAS: begin // if input is quad percision + // extract sign bit + XSgnE = X[`Q_LEN-1]; + YSgnE = Y[`Q_LEN-1]; + ZSgnE = Z[`Q_LEN-1]; - assign XExpE = X[`FLEN-2:`NF]; - assign YExpE = Y[`FLEN-2:`NF]; - assign ZExpE = Z[`FLEN-2:`NF]; + // extract the exponent + XExpE = X[`Q_LEN-2:`Q_NF]; + YExpE = Y[`Q_LEN-2:`Q_NF]; + ZExpE = Z[`Q_LEN-2:`Q_NF]; - assign XFracE = X[`NF-1:0]; - assign YFracE = Y[`NF-1:0]; - assign ZFracE = Z[`NF-1:0]; + // extract the fraction + XFracE = X[`Q_NF-1:0]; + YFracE = Y[`Q_NF-1:0]; + ZFracE = Z[`Q_NF-1:0]; - assign XExpNonzero = |X[`FLEN-2:`NF]; - assign YExpNonzero = |Y[`FLEN-2:`NF]; - assign ZExpNonzero = |Z[`FLEN-2:`NF]; + // 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]; - assign XExpMaxE = &X[`FLEN-2:`NF]; - assign YExpMaxE = &Y[`FLEN-2:`NF]; - assign ZExpMaxE = &Z[`FLEN-2:`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 - assign XSgnE = XLen1[`LEN1-1]; - assign YSgnE = YLen1[`LEN1-1]; - assign ZSgnE = ZLen1[`LEN1-1]; + `D_BIAS: 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 @@ -246,26 +332,32 @@ module unpack ( // 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 - assign XExpE = {XLen1[`D_LEN-2], {`NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]}; - assign YExpE = {YLen1[`D_LEN-2], {`NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]}; - assign ZExpE = {ZLen1[`D_LEN-2], {`NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; + + // convert the double precsion exponent into quad precsion + XExpE = {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]}; + YExpE = {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]}; + ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; - assign XFracE = {XLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; - assign YFracE = {YLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; - assign ZFracE = {ZLen1[`D_NE-1:0], (`NF-`D_NE)'(0)}; + // extract the fraction and add the nessesary trailing zeros + XFracE = {XLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; + YFracE = {YLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; + ZFracE = {ZLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; - assign XExpNonzero = |XLen1[`D_LEN-2:`D_NE]; - assign YExpNonzero = |YLen1[`D_LEN-2:`D_NE]; - assign ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE]; + // is the exponent non-zero + XExpNonzero = |XLen1[`D_LEN-2:`D_NE]; + YExpNonzero = |YLen1[`D_LEN-2:`D_NE]; + ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE]; - assign XExpMaxE = &XLen1[`D_LEN-2:`D_NE]; - assign YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; - assign ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; + // is the exponent all 1's + XExpMaxE = &XLen1[`D_LEN-2:`D_NE]; + YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; + ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; end - 2'b00: begin - assign XSgnE = XLen2[`S_LEN-1]; - assign YSgnE = YLen2[`S_LEN-1]; - assign ZSgnE = ZLen2[`S_LEN-1]; + `S_BIAS: 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 @@ -274,26 +366,32 @@ module unpack ( // 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 - assign XExpE = {XLen2[`S_LEN-2], {`NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]}; - assign YExpE = {YLen2[`S_LEN-2], {`NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]}; - assign ZExpE = {ZLen2[`S_LEN-2], {`NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]}; + + // convert the single precsion exponent into quad precsion + XExpE = {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]}; + YExpE = {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]}; + ZExpE = {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]}; - assign XFracE = {XLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; - assign YFracE = {YLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; - assign ZFracE = {ZLen2[`S_NF-1:0], (`NF-`S_NF)'(0)}; + // 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)}; - assign XExpNonzero = |XLen2[`S_LEN-2:`S_NF]; - assign YExpNonzero = |YLen2[`S_LEN-2:`S_NF]; - assign ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF]; + // 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]; - assign XExpMaxE = &XLen2[`S_LEN-2:`S_NF]; - assign YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; - assign ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; + // 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]; end - 2'b10: begin - assign XSgnE = XLen3[`H_LEN-1]; - assign YSgnE = YLen3[`H_LEN-1]; - assign ZSgnE = ZLen3[`H_LEN-1]; + `H_BIAS: 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 @@ -302,58 +400,72 @@ module unpack ( // 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 - assign XExpE = {XLen3[`H_LEN-2], {`NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]}; - assign YExpE = {YLen3[`H_LEN-2], {`NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]}; - assign ZExpE = {ZLen3[`H_LEN-2], {`NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]}; + + // convert the half precsion exponent into quad precsion + XExpE = {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]}; + YExpE = {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]}; + ZExpE = {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]}; - assign XFracE = {XLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; - assign YFracE = {YLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; - assign ZFracE = {ZLen3[`H_NF-1:0], (`NF-`H_NF)'(0)}; + // 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)}; - assign XExpNonzero = |XLen3[`H_LEN-2:`H_NF]; - assign YExpNonzero = |YLen3[`H_LEN-2:`H_NF]; - assign ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF]; + // 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]; - assign XExpMaxE = &XLen3[`H_LEN-2:`H_NF]; - assign YExpMaxE = &YLen3[`H_LEN-2:`H_NF]; - assign ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF]; + // 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]; 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}; + // is X normalized assign XNormE = ~(XExpMaxE|XExpZero); - // force single precision input to be a NaN if it isn't properly Nan Boxed + // 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; From 4ca94585341cb714b3333007a59fe5c8b75af192 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 21:28:34 -0500 Subject: [PATCH 05/11] added SIP, SIE, and SSTATUS to checkpoints. Can't seem to get the linux testbench to force SIP. --- .../testvector-generation/parseGDBtoTrace.py | 4 +- linux/testvector-generation/parseState.py | 2 +- pipelined/testbench/testbench-linux.sv | 69 +++++++++++++++++-- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/linux/testvector-generation/parseGDBtoTrace.py b/linux/testvector-generation/parseGDBtoTrace.py index db444f696..412db5bb5 100755 --- a/linux/testvector-generation/parseGDBtoTrace.py +++ b/linux/testvector-generation/parseGDBtoTrace.py @@ -138,9 +138,9 @@ if len(sys.argv) != 2: sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n >') interruptFname = sys.argv[1] # reg number -RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45} +RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45, 'sstatus': 46, 'sip': 47, 'sie': 48} # initial state -CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0}, {}, None, None, None] +CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0, 'sstatus': 0, 'sip': 0, 'sie': 0}, {}, None, None, None] #with open (InputFile, 'r') as InputFileFP: #lines = InputFileFP.readlines() diff --git a/linux/testvector-generation/parseState.py b/linux/testvector-generation/parseState.py index abc36fb2f..1f7e93c09 100755 --- a/linux/testvector-generation/parseState.py +++ b/linux/testvector-generation/parseState.py @@ -34,7 +34,7 @@ stateGDBpath = outDir+'stateGDB.txt' if not os.path.exists(stateGDBpath): sys.exit('Error input file '+stateGDBpath+'not found') -singleCSRs = ['pc','mip','mie','mscratch','mcause','mepc','mtvec','medeleg','mideleg','sscratch','scause','sepc','stvec','sedeleg','sideleg','satp','mstatus','priv'] +singleCSRs = ['pc','mip','mie','mscratch','mcause','mepc','mtvec','medeleg','mideleg','sscratch','scause','sepc','stvec','sedeleg','sideleg','satp','mstatus','priv','sie','sip','sstatus'] # priv (current privilege mode) isn't technically a CSR but we can log it with the same machinery thirtyTwoBitCSRs = ['mcounteren','scounteren'] listCSRs = ['hpmcounter','pmpaddr'] diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 82742ff4b..a85c5672c 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -141,11 +141,11 @@ module testbench; logic [`XLEN-1:0] ExpectedCSRArrayValue``STAGE[10:0]; `DECLARE_TRACE_SCANNER_SIGNALS(E) `DECLARE_TRACE_SCANNER_SIGNALS(M) - integer NextMIPexpected; + integer NextMIPexpected, NextSIPexpected; integer NextMepcExpected; // Memory stage expected values from trace logic checkInstrM; - integer MIPexpected; + integer MIPexpected, SIPexpected; string name; logic [`AHBW-1:0] readDataExpected; // Write back stage expected values from trace @@ -168,11 +168,14 @@ module testbench; integer NumCSRPostWIndex; logic [`XLEN-1:0] InstrCountW; integer RequestDelayedMIP; + integer RequestDelayedSIP; integer ForceMIPFuture; integer CSRIndex; longint MepcExpected; integer CheckMIPFutureE; integer CheckMIPFutureM; + integer CheckSIPFutureE; + integer CheckSIPFutureM; // Useful Aliases `define RF dut.core.ieu.dp.regf.rf `define PC dut.core.ifu.pcreg.q @@ -185,6 +188,8 @@ module testbench; `define MIDELEG `CSR_BASE.csrm.deleg.MIDELEGreg.q `define MIE `CSR_BASE.csri.MIE_REGW `define MIP `CSR_BASE.csri.MIP_REGW + `define SIE `CSR_BASE.csri.SIE_REGW + `define SIP `CSR_BASE.csri.SIP_REGW `define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q `define SCAUSE `CSR_BASE.csrs.csrs.SCAUSEreg.q `define MEPC `CSR_BASE.csrm.MEPCreg.q @@ -197,6 +202,7 @@ module testbench; `define STVEC `CSR_BASE.csrs.csrs.STVECreg.q `define SATP `CSR_BASE.csrs.csrs.genblk1.SATPreg.q `define MSTATUS `CSR_BASE.csrsr.MSTATUS_REGW + `define SSTATUS `CSR_BASE.csrsr.SSTATUS_REGW `define STATUS_TSR `CSR_BASE.csrsr.STATUS_TSR_INT `define STATUS_TW `CSR_BASE.csrsr.STATUS_TW_INT `define STATUS_TVM `CSR_BASE.csrsr.STATUS_TVM_INT @@ -297,6 +303,8 @@ module testbench; `INIT_CHECKPOINT_VAL(MIDELEG, [`XLEN-1:0]); `INIT_CHECKPOINT_VAL(MIE, [11:0]); `INIT_CHECKPOINT_VAL(MIP, [11:0]); + `INIT_CHECKPOINT_VAL(SIE, [11:0]); + `INIT_CHECKPOINT_VAL(SIP, [11:0]); `INIT_CHECKPOINT_VAL(MCAUSE, [`XLEN-1:0]); `INIT_CHECKPOINT_VAL(SCAUSE, [`XLEN-1:0]); `INIT_CHECKPOINT_VAL(MEPC, [`XLEN-1:0]); @@ -310,6 +318,7 @@ module testbench; `INIT_CHECKPOINT_VAL(SATP, [`XLEN-1:0]); `INIT_CHECKPOINT_VAL(PRIV, [1:0]); `MAKE_CHECKPOINT_INIT_SIGNAL(MSTATUS, [`XLEN-1:0],0,0); + `MAKE_CHECKPOINT_INIT_SIGNAL(SSTATUS, [`XLEN-1:0],0,0); // Many UART registers are difficult to initialize because under the hood // they are not simple registers. Instead some are generated by interesting // combinational blocks such that they depend upon a variety of different @@ -463,6 +472,10 @@ module testbench; CheckMIPFutureE = 1; \ NextMIPexpected = ExpectedCSRArrayValueE[NumCSRE]; \ end \ + if(ExpectedCSRArrayE[NumCSRE].substr(0, 2) == "sip") begin \ + CheckSIPFutureE = 1; \ + NextSIPexpected = ExpectedCSRArrayValueE[NumCSRE]; \ + end \ if(ExpectedCSRArrayE[NumCSRE].substr(0,3) == "mepc") begin \ // $display("hello! we are here."); \ MepcExpected = ExpectedCSRArrayValueE[NumCSRE]; \ @@ -501,6 +514,7 @@ module testbench; if(CheckMIPFutureE) CheckMIPFutureE <= 0; CheckMIPFutureM <= CheckMIPFutureE; if(CheckMIPFutureM) begin + $display("DEBUG DEBUG DEBUG DEBUG"); // $display("%tns: ExpectedPCM %x",$time,ExpectedPCM); // $display("%tns: ExpectedPCE %x",$time,ExpectedPCE); // $display("%tns: ExpectedPCW %x",$time,ExpectedPCW); @@ -508,9 +522,12 @@ module testbench; RequestDelayedMIP <= 1; $display("%tns: Requesting Delayed MIP. Current MEPC value is %x",$time,MepcExpected); end else begin // update MIP immediately + $display("One One One One"); $display("%tns: Updating MIP to %x",$time,NextMIPexpected); MIPexpected = NextMIPexpected; - force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; + //force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; + //force dut.core.priv.priv.csr.csri.SIP_REGW = MIPexpected; + force dut.core.priv.priv.csr.csri.IP_REGW = MIPexpected; end // $display("%tn: ExpectedCSRArrayM = %p",$time,ExpectedCSRArrayM); // $display("%tn: ExpectedCSRArrayValueM = %p",$time,ExpectedCSRArrayValueM); @@ -524,13 +541,54 @@ module testbench; if(RequestDelayedMIP & checkInstrM) begin $display("%tns: Executing Delayed MIP. Current MEPC value is %x",$time,dut.core.priv.priv.csr.csrm.MEPC_REGW); $display("%tns: Updating MIP to %x",$time,NextMIPexpected); + $display("Two Two Two Two"); MIPexpected = NextMIPexpected; - force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; + //force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; + //force dut.core.priv.priv.csr.csri.SIP_REGW = MIPexpected; + force dut.core.priv.priv.csr.csri.IP_REGW = MIPexpected; $display("%tns: Finished Executing Delayed MIP. Current MEPC value is %x",$time,dut.core.priv.priv.csr.csrm.MEPC_REGW); RequestDelayedMIP = 0; end end + // SIP spoofing +/* -----\/----- EXCLUDED -----\/----- + always @(posedge clk) begin + #1; + if(CheckSIPFutureE) CheckSIPFutureE <= 0; + CheckSIPFutureM <= CheckSIPFutureE; + if(CheckSIPFutureM) begin + // $display("%tns: ExpectedPCM %x",$time,ExpectedPCM); + // $display("%tns: ExpectedPCE %x",$time,ExpectedPCE); + // $display("%tns: ExpectedPCW %x",$time,ExpectedPCW); + if((ExpectedPCE != MepcExpected) & ((MepcExpected - ExpectedPCE) * (MepcExpected - ExpectedPCE) <= 200) | ~dut.core.ieu.c.InstrValidM) begin + RequestDelayedSIP <= 1; + $display("%tns: Requesting Delayed SIP. Current MEPC value is %x",$time,MepcExpected); + end else begin // update SIP immediately + $display("%tns: Updating SIP to %x",$time,NextSIPexpected); + SIPexpected = NextSIPexpected; + force dut.core.priv.priv.csr.csri.SIP_REGW = SIPexpected; + end + // $display("%tn: ExpectedCSRArrayM = %p",$time,ExpectedCSRArrayM); + // $display("%tn: ExpectedCSRArrayValueM = %p",$time,ExpectedCSRArrayValueM); + // $display("%tn: ExpectedTokens = %p",$time,ExpectedTokensM); + // $display("%tn: MepcExpected = %x",$time,MepcExpected); + // $display("%tn: ExpectedPCE = %x",$time,ExpectedPCE); + // $display("%tns: Difference/multiplication thing: %x",$time,(MepcExpected - ExpectedPCE) * (MepcExpected - ExpectedPCE)); + // $display("%tn: ExpectedCSRArrayM[NumCSRM] %x",$time,ExpectedCSRArrayM[NumCSRM]); + // $display("%tn: ExpectedCSRArrayValueM[NumCSRM] %x",$time,ExpectedCSRArrayValueM[NumCSRM]); + end + if(RequestDelayedSIP & checkInstrM) begin + $display("%tns: Executing Delayed SIP. Current MEPC value is %x",$time,dut.core.priv.priv.csr.csrm.MEPC_REGW); + $display("%tns: Updating SIP to %x",$time,NextSIPexpected); + SIPexpected = NextSIPexpected; + force dut.core.priv.priv.csr.csri.SIP_REGW = SIPexpected; + $display("%tns: Finished Executing Delayed SIP. Current MEPC value is %x",$time,dut.core.priv.priv.csr.csrm.MEPC_REGW); + RequestDelayedSIP = 0; + end + end + -----/\----- EXCLUDED -----/\----- */ + // step 1: register expected state into the write back stage. always @(posedge clk) begin if (reset) begin @@ -634,9 +692,12 @@ module testbench; case(ExpectedCSRArrayW[NumCSRPostWIndex]) "mhartid": `checkCSR(dut.core.priv.priv.csr.csrm.MHARTID_REGW) "mstatus": `checkCSR(dut.core.priv.priv.csr.csrm.MSTATUS_REGW) + "sstatus": `checkCSR(dut.core.priv.priv.csr.csrs.SSTATUS_REGW) "mtvec": `checkCSR(dut.core.priv.priv.csr.csrm.MTVEC_REGW) "mip": `checkCSR(dut.core.priv.priv.csr.csrm.MIP_REGW) "mie": `checkCSR(dut.core.priv.priv.csr.csrm.MIE_REGW) + "sip": `checkCSR(dut.core.priv.priv.csr.csrs.SIP_REGW) + "sie": `checkCSR(dut.core.priv.priv.csr.csrs.SIE_REGW) "mideleg": `checkCSR(dut.core.priv.priv.csr.csrm.MIDELEG_REGW) "medeleg": `checkCSR(dut.core.priv.priv.csr.csrm.MEDELEG_REGW) "mepc": `checkCSR(dut.core.priv.priv.csr.csrm.MEPC_REGW) From c233ef97682aed5c635de9f08567aca215036819 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 21:44:08 -0500 Subject: [PATCH 06/11] Reverted change to configuration which caused issue with lint. --- pipelined/config/shared/wally-shared.vh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pipelined/config/shared/wally-shared.vh b/pipelined/config/shared/wally-shared.vh index 198a4ab2e..117d745f1 100644 --- a/pipelined/config/shared/wally-shared.vh +++ b/pipelined/config/shared/wally-shared.vh @@ -74,8 +74,10 @@ // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits `define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN) -`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) -`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) +//`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) +`define NE 11//(`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) +//`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) +`define NF 52//(`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) `define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2) `define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS) From 849707f1614d85f80cbfc01b756e5b45d76fdbcc Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 22:04:06 -0500 Subject: [PATCH 07/11] Switched csri IP_REGW to use assignements rather than always_comb as this is incompatible with forcing. --- pipelined/src/privileged/csri.sv | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 974b3616f..8a3f42fdf 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -95,21 +95,20 @@ module csri #(parameter // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field // restricted views of registers - always_comb begin:regs - // Add MEIP read-only signal - IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; + // Add MEIP read-only signal + assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; // Machine Mode - MIP_REGW = IP_REGW; - MIE_REGW = IE_REGW; + assign MIP_REGW = IP_REGW; + assign MIE_REGW = IE_REGW; - // Supervisor mode - if (`S_SUPPORTED) begin - SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible - SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; - end else begin - SIP_REGW = 12'b0; - SIE_REGW = 12'b0; - end + // Supervisor mode + if (`S_SUPPORTED) begin + assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible + assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; + end else begin + assign SIP_REGW = 12'b0; + assign SIE_REGW = 12'b0; end + endmodule From fcd23a006e1f59c729532926a341f111d8e03fc2 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Wed, 23 Mar 2022 03:24:41 +0000 Subject: [PATCH 08/11] fixed lint error in fpudivsqrtrecur.sv --- pipelined/src/fpu/fpudivsqrtrecur.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelined/src/fpu/fpudivsqrtrecur.sv b/pipelined/src/fpu/fpudivsqrtrecur.sv index fd47d2d87..62a441367 100644 --- a/pipelined/src/fpu/fpudivsqrtrecur.sv +++ b/pipelined/src/fpu/fpudivsqrtrecur.sv @@ -64,8 +64,8 @@ module fpudivsqrtrecur ( always_comb begin if (FSqrtE & XSgnE | FDivE & XZeroE & YZeroE | XNaNE | FDivE & YNaNE) FDivSqrtResM = 0; // ***replace with NAN; // *** which one - else if (FDivE & YZeroE | XInfE) FDivSqrtResM = {FDivSqrtResSgn, `NE'b1, `NF'b0}; // infinity - else if (FDivE & YInfE) FDivSqrtResM = {FDivSqrtResSgn, `NE'b0, `NF'b0}; // zero + else if (FDivE & YZeroE | XInfE) FDivSqrtResM = {FDivSqrtResSgn, (`NE)'(1), (`NF)'(0)}; // infinity + else if (FDivE & YInfE) FDivSqrtResM = {FDivSqrtResSgn, (`NE)'(0), (`NF)'(0)}; // zero else FDivSqrtResM = FDivSqrtRecurRes; end From 33b9b5423dd469c16ae2fcbff3b5ec4c9c3cb568 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 22:31:34 -0500 Subject: [PATCH 09/11] reverted temporary change to configs. --- pipelined/config/shared/wally-shared.vh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pipelined/config/shared/wally-shared.vh b/pipelined/config/shared/wally-shared.vh index 117d745f1..198a4ab2e 100644 --- a/pipelined/config/shared/wally-shared.vh +++ b/pipelined/config/shared/wally-shared.vh @@ -74,10 +74,8 @@ // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits `define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN) -//`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) -`define NE 11//(`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) -//`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) -`define NF 52//(`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) +`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE) +`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF) `define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2) `define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS) From aa60b57fb39cb6a89826638827b3987c34999f70 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 22 Mar 2022 22:34:38 -0500 Subject: [PATCH 10/11] Cleanup in testbench-linux.sv. --- pipelined/testbench/testbench-linux.sv | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index a85c5672c..62d13a1a3 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -514,15 +514,14 @@ module testbench; if(CheckMIPFutureE) CheckMIPFutureE <= 0; CheckMIPFutureM <= CheckMIPFutureE; if(CheckMIPFutureM) begin - $display("DEBUG DEBUG DEBUG DEBUG"); // $display("%tns: ExpectedPCM %x",$time,ExpectedPCM); // $display("%tns: ExpectedPCE %x",$time,ExpectedPCE); // $display("%tns: ExpectedPCW %x",$time,ExpectedPCW); + // *** this is probably not right anymore since either MIP or SIP can be forced. if((ExpectedPCE != MepcExpected) & ((MepcExpected - ExpectedPCE) * (MepcExpected - ExpectedPCE) <= 200) | ~dut.core.ieu.c.InstrValidM) begin RequestDelayedMIP <= 1; $display("%tns: Requesting Delayed MIP. Current MEPC value is %x",$time,MepcExpected); end else begin // update MIP immediately - $display("One One One One"); $display("%tns: Updating MIP to %x",$time,NextMIPexpected); MIPexpected = NextMIPexpected; //force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; @@ -541,7 +540,6 @@ module testbench; if(RequestDelayedMIP & checkInstrM) begin $display("%tns: Executing Delayed MIP. Current MEPC value is %x",$time,dut.core.priv.priv.csr.csrm.MEPC_REGW); $display("%tns: Updating MIP to %x",$time,NextMIPexpected); - $display("Two Two Two Two"); MIPexpected = NextMIPexpected; //force dut.core.priv.priv.csr.csri.MIP_REGW = MIPexpected; //force dut.core.priv.priv.csr.csri.SIP_REGW = MIPexpected; From 7cf994526ac4699374a16904312167aee9f20908 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Wed, 23 Mar 2022 18:26:59 +0000 Subject: [PATCH 11/11] fixed typo in unpack.sv --- pipelined/src/fpu/fma.sv | 352 ++++++++++++++++++------------------ pipelined/src/fpu/unpack.sv | 8 +- 2 files changed, 180 insertions(+), 180 deletions(-) diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 2b2a6b9ed..8d1ae344a 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -186,20 +186,20 @@ module expadd( end else if (`FPSIZES == 3) begin always_comb begin case (FmtE) - `FMT: assign Denorm = 1; - `FMT1: assign Denorm = `BIAS-`BIAS1+1; - `FMT2: assign Denorm = `BIAS-`BIAS2+1; - default: assign Denorm = 1'bx; + `FMT: Denorm = 1; + `FMT1: Denorm = `BIAS-`BIAS1+1; + `FMT2: Denorm = `BIAS-`BIAS2+1; + default: Denorm = 1'bx; endcase end end else begin always_comb begin case (FmtE) - 2'h3: assign Denorm = 1; - 2'h1: assign Denorm = `BIAS-`D_BIAS+1; - 2'h0: assign Denorm = `BIAS-`S_BIAS+1; - 2'h2: assign Denorm = `BIAS-`H_BIAS+1; + 2'h3: Denorm = 1; + 2'h1: Denorm = `BIAS-`D_BIAS+1; + 2'h0: Denorm = `BIAS-`S_BIAS+1; + 2'h2: Denorm = `BIAS-`H_BIAS+1; endcase end @@ -612,20 +612,20 @@ module normalize( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign SumExpTmp = SumExpTmpTmp; - `FMT1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS1)&{`NE+2{|SumExpTmpTmp}}; - `FMT2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS2)&{`NE+2{|SumExpTmpTmp}}; - default: assign SumExpTmp = `NE+2'bx; + `FMT: SumExpTmp = SumExpTmpTmp; + `FMT1: SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS1)&{`NE+2{|SumExpTmpTmp}}; + `FMT2: SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS2)&{`NE+2{|SumExpTmpTmp}}; + default: SumExpTmp = `NE+2'bx; endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign SumExpTmp = SumExpTmpTmp; - 2'h1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`D_BIAS)&{`NE+2{|SumExpTmpTmp}}; - 2'h0: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`S_BIAS)&{`NE+2{|SumExpTmpTmp}}; - 2'h2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`H_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h3: SumExpTmp = SumExpTmpTmp; + 2'h1: SumExpTmp = (SumExpTmpTmp-`BIAS+`D_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h0: SumExpTmp = (SumExpTmpTmp-`BIAS+`S_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h2: SumExpTmp = (SumExpTmpTmp-`BIAS+`H_BIAS)&{`NE+2{|SumExpTmpTmp}}; endcase end @@ -657,10 +657,10 @@ module normalize( assign Sum2GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|SumExpTmpTmp; always_comb begin case (FmtM) - `FMT: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; - `FMT1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; - `FMT2: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; - default: assign PreResultDenorm = 1'bx; + `FMT: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + `FMT1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + `FMT2: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + default: PreResultDenorm = 1'bx; endcase end @@ -676,10 +676,10 @@ module normalize( assign Sum3GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|SumExpTmpTmp; always_comb begin case (FmtM) - 2'h3: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; - 2'h1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; - 2'h0: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; - 2'h2: assign PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; + 2'h3: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + 2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + 2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + 2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; endcase end @@ -830,48 +830,48 @@ module fmaround( case (FmtM) `FMT: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[2]; - assign Round = NormSum[1]; - assign LSBNormSum = NormSum[3]; + Guard = NormSum[2]; + Round = NormSum[1]; + LSBNormSum = NormSum[3]; // used to determine underflow flag - assign UfGuard = NormSum[1]; - assign UfRound = NormSum[0]; - assign UfLSBNormSum = NormSum[2]; + UfGuard = NormSum[1]; + UfRound = NormSum[0]; + UfLSBNormSum = NormSum[2]; // determine sticky - assign Sticky = UfSticky | NormSum[0]; + Sticky = UfSticky | NormSum[0]; end `FMT1: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`NF1+2]; - assign Round = NormSum[`NF-`NF1+1]; - assign LSBNormSum = NormSum[`NF-`NF1+3]; + Guard = NormSum[`NF-`NF1+2]; + Round = NormSum[`NF-`NF1+1]; + LSBNormSum = NormSum[`NF-`NF1+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`NF1+1]; - assign UfRound = NormSum[`NF-`NF1]; - assign UfLSBNormSum = NormSum[`NF-`NF1+2]; + UfGuard = NormSum[`NF-`NF1+1]; + UfRound = NormSum[`NF-`NF1]; + UfLSBNormSum = NormSum[`NF-`NF1+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`NF1]; + Sticky = UfSticky | NormSum[`NF-`NF1]; end `FMT2: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`NF2+2]; - assign Round = NormSum[`NF-`NF2+1]; - assign LSBNormSum = NormSum[`NF-`NF2+3]; + Guard = NormSum[`NF-`NF2+2]; + Round = NormSum[`NF-`NF2+1]; + LSBNormSum = NormSum[`NF-`NF2+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`NF2+1]; - assign UfRound = NormSum[`NF-`NF2]; - assign UfLSBNormSum = NormSum[`NF-`NF2+2]; + UfGuard = NormSum[`NF-`NF2+1]; + UfRound = NormSum[`NF-`NF2]; + UfLSBNormSum = NormSum[`NF-`NF2+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`NF2]; + Sticky = UfSticky | NormSum[`NF-`NF2]; end default: begin - assign Guard = 1'bx; - assign Round = 1'bx; - assign LSBNormSum = 1'bx; - assign UfGuard = 1'bx; - assign UfRound = 1'bx; - assign UfLSBNormSum = 1'bx; - assign Sticky = 1'bx; + Guard = 1'bx; + Round = 1'bx; + LSBNormSum = 1'bx; + UfGuard = 1'bx; + UfRound = 1'bx; + UfLSBNormSum = 1'bx; + Sticky = 1'bx; end endcase end @@ -881,51 +881,51 @@ module fmaround( case (FmtM) 2'h3: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[2]; - assign Round = NormSum[1]; - assign LSBNormSum = NormSum[3]; + Guard = NormSum[2]; + Round = NormSum[1]; + LSBNormSum = NormSum[3]; // used to determine underflow flag - assign UfGuard = NormSum[1]; - assign UfRound = NormSum[0]; - assign UfLSBNormSum = NormSum[2]; + UfGuard = NormSum[1]; + UfRound = NormSum[0]; + UfLSBNormSum = NormSum[2]; // determine sticky - assign Sticky = UfSticky | NormSum[0]; + Sticky = UfSticky | NormSum[0]; end 2'h1: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`D_NF+2]; - assign Round = NormSum[`NF-`D_NF+1]; - assign LSBNormSum = NormSum[`NF-`D_NF+3]; + Guard = NormSum[`NF-`D_NF+2]; + Round = NormSum[`NF-`D_NF+1]; + LSBNormSum = NormSum[`NF-`D_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`D_NF+1]; - assign UfRound = NormSum[`NF-`D_NF]; - assign UfLSBNormSum = NormSum[`NF-`D_NF+2]; + UfGuard = NormSum[`NF-`D_NF+1]; + UfRound = NormSum[`NF-`D_NF]; + UfLSBNormSum = NormSum[`NF-`D_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`D_NF]; + Sticky = UfSticky | NormSum[`NF-`D_NF]; end 2'h0: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`S_NF+2]; - assign Round = NormSum[`NF-`S_NF+1]; - assign LSBNormSum = NormSum[`NF-`S_NF+3]; + Guard = NormSum[`NF-`S_NF+2]; + Round = NormSum[`NF-`S_NF+1]; + LSBNormSum = NormSum[`NF-`S_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`S_NF+1]; - assign UfRound = NormSum[`NF-`S_NF]; - assign UfLSBNormSum = NormSum[`NF-`S_NF+2]; + UfGuard = NormSum[`NF-`S_NF+1]; + UfRound = NormSum[`NF-`S_NF]; + UfLSBNormSum = NormSum[`NF-`S_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`S_NF]; + Sticky = UfSticky | NormSum[`NF-`S_NF]; end 2'h2: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`H_NF+2]; - assign Round = NormSum[`NF-`H_NF+1]; - assign LSBNormSum = NormSum[`NF-`H_NF+3]; + Guard = NormSum[`NF-`H_NF+2]; + Round = NormSum[`NF-`H_NF+1]; + LSBNormSum = NormSum[`NF-`H_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`H_NF+1]; - assign UfRound = NormSum[`NF-`H_NF]; - assign UfLSBNormSum = NormSum[`NF-`H_NF+2]; + UfGuard = NormSum[`NF-`H_NF+1]; + UfRound = NormSum[`NF-`H_NF]; + UfLSBNormSum = NormSum[`NF-`H_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`H_NF]; + Sticky = UfSticky | NormSum[`NF-`H_NF]; end endcase end @@ -988,20 +988,20 @@ module fmaround( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; - `FMT1: assign RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; - `FMT2: assign RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), Plus1, (`FLEN-1-`NE-`NF2)'(0)}; - default: assign RoundAdd = (`FLEN+1)'(0); + `FMT: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + `FMT1: RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; + `FMT2: RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), Plus1, (`FLEN-1-`NE-`NF2)'(0)}; + default: RoundAdd = (`FLEN+1)'(0); endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; - 2'h1: assign RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), Plus1, (`FLEN-1-`NE-`D_NF)'(0)}; - 2'h0: assign RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), Plus1, (`FLEN-1-`NE-`S_NF)'(0)}; - 2'h2: assign RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), Plus1, (`FLEN-1-`NE-`H_NF)'(0)}; + 2'h3: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + 2'h1: RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), Plus1, (`FLEN-1-`NE-`D_NF)'(0)}; + 2'h0: RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), Plus1, (`FLEN-1-`NE-`S_NF)'(0)}; + 2'h2: RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), Plus1, (`FLEN-1-`NE-`H_NF)'(0)}; endcase end @@ -1056,20 +1056,20 @@ module fmaflags( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; - `FMT1: assign GtMaxExp = &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; - `FMT2: assign GtMaxExp = &FullResultExp[`NE2-1:0] | FullResultExp[`NE2]; - default: assign GtMaxExp = 1'bx; + `FMT: GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + `FMT1: GtMaxExp = &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; + `FMT2: GtMaxExp = &FullResultExp[`NE2-1:0] | FullResultExp[`NE2]; + default: GtMaxExp = 1'bx; endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; - 2'h1: assign GtMaxExp = &FullResultExp[`D_NE-1:0] | FullResultExp[`D_NE]; - 2'h0: assign GtMaxExp = &FullResultExp[`S_NE-1:0] | FullResultExp[`S_NE]; - 2'h2: assign GtMaxExp = &FullResultExp[`H_NE-1:0] | FullResultExp[`H_NE]; + 2'h3: GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + 2'h1: GtMaxExp = &FullResultExp[`D_NE-1:0] | FullResultExp[`D_NE]; + 2'h0: GtMaxExp = &FullResultExp[`S_NE-1:0] | FullResultExp[`S_NE]; + 2'h2: GtMaxExp = &FullResultExp[`H_NE-1:0] | FullResultExp[`H_NE]; endcase end @@ -1157,68 +1157,68 @@ module resultselect( case (FmtM) `FMT: begin if(`IEEE754) begin - assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; - assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; - assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin - assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; - assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; - assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; - assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; - assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + NormResult = {ResultSgn, ResultExp, ResultFrac}; end `FMT1: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; - assign YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; - assign ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; - assign InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; + YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; + ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; + InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - assign KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - assign NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; + KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; end `FMT2: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; - assign YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; - assign ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; - assign InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; + YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; + ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; + InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, (`NF2)'(0)}; - assign KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; - assign NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; + KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; + NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; end default: begin if(`IEEE754) begin - assign XNaNResult = (`FLEN)'(0); - assign YNaNResult = (`FLEN)'(0); - assign ZNaNResult = (`FLEN)'(0); - assign InvalidResult = (`FLEN)'(0); + XNaNResult = (`FLEN)'(0); + YNaNResult = (`FLEN)'(0); + ZNaNResult = (`FLEN)'(0); + InvalidResult = (`FLEN)'(0); end else begin - assign XNaNResult = (`FLEN)'(0); + XNaNResult = (`FLEN)'(0); end - assign OverflowResult = (`FLEN)'(0); - assign KillProdResult = (`FLEN)'(0); - assign UnderflowResult = (`FLEN)'(0); - assign InfResult = (`FLEN)'(0); - assign NormResult = (`FLEN)'(0); + OverflowResult = (`FLEN)'(0); + KillProdResult = (`FLEN)'(0); + UnderflowResult = (`FLEN)'(0); + InfResult = (`FLEN)'(0); + NormResult = (`FLEN)'(0); end endcase end @@ -1228,71 +1228,71 @@ module resultselect( case (FmtM) 2'h3: begin if(`IEEE754) begin - assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; - assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; - assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin - assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; - assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; - assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; - assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; - assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + NormResult = {ResultSgn, ResultExp, ResultFrac}; end 2'h1: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; - assign YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; - assign ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; - assign InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; + YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; + ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; + InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; - assign KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; - assign NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; + KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; + NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; end 2'h0: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; - assign YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; - assign ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; - assign InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; + YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; + ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; + InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; - assign KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; - assign NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; + KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; + NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; end 2'h2: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, XSgnM, {`H_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`H_NF]}; - assign YNaNResult = {{`FLEN-`H_LEN{1'b1}}, YSgnM, {`H_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`H_NF]}; - assign ZNaNResult = {{`FLEN-`H_LEN{1'b1}}, ZSgnEffM, {`H_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`H_NF]}; - assign InvalidResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + XNaNResult = {{`FLEN-`H_LEN{1'b1}}, XSgnM, {`H_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`H_NF]}; + YNaNResult = {{`FLEN-`H_LEN{1'b1}}, YSgnM, {`H_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`H_NF]}; + ZNaNResult = {{`FLEN-`H_LEN{1'b1}}, ZSgnEffM, {`H_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`H_NF]}; + InvalidResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + XNaNResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; - assign KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; - assign NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; + KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; + NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; end endcase end diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index 1625b2fc2..3041cd72f 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -293,7 +293,7 @@ module unpack ( always_comb begin case (FmtE) - `Q_BIAS: begin // if input is quad percision + 2'b11: begin // if input is quad percision // extract sign bit XSgnE = X[`Q_LEN-1]; YSgnE = Y[`Q_LEN-1]; @@ -319,7 +319,7 @@ module unpack ( YExpMaxE = &Y[`Q_LEN-2:`Q_NF]; ZExpMaxE = &Z[`Q_LEN-2:`Q_NF]; end - `D_BIAS: begin // if input is double percision + 2'b01: begin // if input is double percision // extract sign bit XSgnE = XLen1[`D_LEN-1]; YSgnE = YLen1[`D_LEN-1]; @@ -353,7 +353,7 @@ module unpack ( YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; end - `S_BIAS: begin // if input is single percision + 2'b00: begin // if input is single percision // extract sign bit XSgnE = XLen2[`S_LEN-1]; YSgnE = YLen2[`S_LEN-1]; @@ -387,7 +387,7 @@ module unpack ( YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; end - `H_BIAS: begin // if input is half percision + 2'b10: begin // if input is half percision // extract sign bit XSgnE = XLen3[`H_LEN-1]; YSgnE = YLen3[`H_LEN-1];