From e0980bbcd94aaa4c020236411c6483173a599193 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 6 Feb 2025 18:20:07 -0800 Subject: [PATCH] Initial FMA commit --- examples/exercises/fma16/fma.do | 23 +++++++++++ examples/exercises/fma16/lint-fma | 13 ++++++ examples/exercises/fma16/sim-fma | 2 + examples/exercises/fma16/sim-fma-batch | 1 + examples/exercises/fma16/testbench.sv | 52 ++++++++++++++++++++++++ examples/exercises/fma16/tests/fmul_0.tv | 5 +++ 6 files changed, 96 insertions(+) create mode 100644 examples/exercises/fma16/fma.do create mode 100755 examples/exercises/fma16/lint-fma create mode 100755 examples/exercises/fma16/sim-fma create mode 100755 examples/exercises/fma16/sim-fma-batch create mode 100644 examples/exercises/fma16/testbench.sv create mode 100644 examples/exercises/fma16/tests/fmul_0.tv diff --git a/examples/exercises/fma16/fma.do b/examples/exercises/fma16/fma.do new file mode 100644 index 000000000..111b393ca --- /dev/null +++ b/examples/exercises/fma16/fma.do @@ -0,0 +1,23 @@ +# fma.do +# +# run with vsim -do "do fma.do" +# add -c before -do for batch simulation + +onbreak {resume} + +# create library +vlib worklib + +vlog -lint -sv -work worklib fma16.sv testbench.sv +vopt +acc worklib.testbench_fma16 -work worklib -o testbenchopt +vsim -lib worklib testbenchopt + +add wave sim:/testbench_fma16/clk +add wave sim:/testbench_fma16/reset +add wave sim:/testbench_fma16/x +add wave sim:/testbench_fma16/y +add wave sim:/testbench_fma16/z +add wave sim:/testbench_fma16/result +add wave sim:/testbench_fma16/rexpected + +run -all diff --git a/examples/exercises/fma16/lint-fma b/examples/exercises/fma16/lint-fma new file mode 100755 index 000000000..b577bbd33 --- /dev/null +++ b/examples/exercises/fma16/lint-fma @@ -0,0 +1,13 @@ +#!/bin/bash +# check for warnings in Verilog code +# The verilator lint tool is faster and better than Questa so it is best to run this first. +export PATH=$PATH:/usr/local/bin/ +verilator=`which verilator` + +basepath=$(dirname $0)/.. +if ($verilator --lint-only --top-module fma16 fma16.sv); then + echo "fma16 passed lint" +else + echo "fma16 failed lint" +fi + diff --git a/examples/exercises/fma16/sim-fma b/examples/exercises/fma16/sim-fma new file mode 100755 index 000000000..bf55614c5 --- /dev/null +++ b/examples/exercises/fma16/sim-fma @@ -0,0 +1,2 @@ +vsim -do "do fma.do" + diff --git a/examples/exercises/fma16/sim-fma-batch b/examples/exercises/fma16/sim-fma-batch new file mode 100755 index 000000000..01c2472e9 --- /dev/null +++ b/examples/exercises/fma16/sim-fma-batch @@ -0,0 +1 @@ +vsim -c -do "do fma.do" diff --git a/examples/exercises/fma16/testbench.sv b/examples/exercises/fma16/testbench.sv new file mode 100644 index 000000000..ce4097abc --- /dev/null +++ b/examples/exercises/fma16/testbench.sv @@ -0,0 +1,52 @@ +/* verilator lint_off STMTDLY */ +module testbench_fma16; + logic clk, reset; + logic [15:0] x, y, z, rexpected, result; + logic [7:0] ctrl; + logic mul, add, negp, negz; + logic [1:0] roundmode; + logic [31:0] vectornum, errors; + logic [75:0] testvectors[10000:0]; + logic [3:0] flags, flagsexpected; // Invalid, Overflow, Underflow, Inexact + + // instantiate device under test + fma16 dut(x, y, z, mul, add, negp, negz, roundmode, result, flags); + + // generate clock + always + begin + clk = 1; #5; clk = 0; #5; + end + + // at start of test, load vectors and pulse reset + initial + begin + $readmemh("tests/fmul_2.tv", testvectors); + vectornum = 0; errors = 0; + reset = 1; #22; reset = 0; + end + + // apply test vectors on rising edge of clk + always @(posedge clk) + begin + #1; {x, y, z, ctrl, rexpected, flagsexpected} = testvectors[vectornum]; + {roundmode, mul, add, negp, negz} = ctrl[5:0]; + end + + // check results on falling edge of clk + always @(negedge clk) + if (~reset) begin // skip during reset + if (result !== rexpected | flags !== flagsexpected) begin // check result + $display("Error: inputs %h * %h + %h", x, y, z); + $display(" result = %h (%h expected) flags = %b (%b expected)", + result, rexpected, flags, flagsexpected); + errors = errors + 1; + end + vectornum = vectornum + 1; + if (testvectors[vectornum] === 'x) begin + $display("%d tests completed with %d errors", + vectornum, errors); + $stop; + end + end +endmodule diff --git a/examples/exercises/fma16/tests/fmul_0.tv b/examples/exercises/fma16/tests/fmul_0.tv new file mode 100644 index 000000000..b139db2a3 --- /dev/null +++ b/examples/exercises/fma16/tests/fmul_0.tv @@ -0,0 +1,5 @@ +// Multiply with exponent of 0, significand of 1.0 and 1.1, RZ +3c00_3c00_0000_08_3c00_0 // 1.000000 * 1.000000 = 1.000000 NV: 0 OF: 0 UF: 0 NX: 0 +3c00_3e00_0000_08_3e00_0 // 1.000000 * 1.500000 = 1.500000 NV: 0 OF: 0 UF: 0 NX: 0 +3e00_3c00_0000_08_3e00_0 // 1.500000 * 1.000000 = 1.500000 NV: 0 OF: 0 UF: 0 NX: 0 +3e00_3e00_0000_08_4080_0 // 1.500000 * 1.500000 = 2.250000 NV: 0 OF: 0 UF: 0 NX: 0