diff options
Diffstat (limited to '')
| -rw-r--r-- | platform/wavelet3d/gfx_fpint.sv | 103 | ||||
| -rw-r--r-- | platform/wavelet3d/gfx_pkg.sv | 2 | ||||
| -rw-r--r-- | platform/wavelet3d/main.cpp | 238 |
3 files changed, 215 insertions, 128 deletions
diff --git a/platform/wavelet3d/gfx_fpint.sv b/platform/wavelet3d/gfx_fpint.sv index babc916..e5c457c 100644 --- a/platform/wavelet3d/gfx_fpint.sv +++ b/platform/wavelet3d/gfx_fpint.sv @@ -1,34 +1,39 @@ module gfx_fpint ( - input logic clk, + input logic clk, + rst_n, - input gfx::word a, - b, - input logic setup_mul_float, - setup_unit_b, - mnorm_put_hi, - mnorm_put_lo, - mnorm_put_mul, - mnorm_zero_b, - mnorm_zero_flags, - minmax_copy_flags, - shiftr_int_signed, - addsub_copy_flags, - addsub_int_operand, - clz_force_nop, - shiftl_copy_flags, - round_copy_flags, - round_enable, - encode_enable, + input gfx::word a[gfx::SHADER_LANES], + b[gfx::SHADER_LANES], + input logic in_valid, + setup_mul_float, + setup_unit_b, + mnorm_put_hi, + mnorm_put_lo, + mnorm_put_mul, + mnorm_zero_b, + mnorm_zero_flags, + minmax_copy_flags, + shiftr_int_signed, + addsub_copy_flags, + addsub_int_operand, + clz_force_nop, + shiftl_copy_flags, + round_copy_flags, + round_enable, + encode_enable, - output gfx::word q + output logic out_valid, + output gfx::word q[gfx::SHADER_LANES] ); import gfx::*; + logic stage_valid[FPINT_STAGES]; fpint_op op, stage_op[FPINT_STAGES]; assign stage_op[0] = op; + assign stage_valid[0] = in_valid; assign op.setup_mul_float = setup_mul_float; assign op.setup_unit_b = setup_unit_b; @@ -47,32 +52,44 @@ module gfx_fpint assign op.round_enable = round_enable; assign op.encode_enable = encode_enable; - gfx_fpint_lane lane - ( - .clk(clk), - .a(a), - .b(b), - .q(q), - .mul_float_0(stage_op[0].setup_mul_float), - .unit_b_0(stage_op[0].setup_unit_b), - .put_hi_2(stage_op[2].mnorm_put_hi), - .put_lo_2(stage_op[2].mnorm_put_lo), - .put_mul_2(stage_op[2].mnorm_put_mul), - .zero_b_2(stage_op[2].mnorm_zero_b), - .zero_flags_2(stage_op[2].mnorm_zero_flags), - .copy_flags_3(stage_op[3].minmax_copy_flags), - .int_signed_5(stage_op[5].shiftr_int_signed), - .copy_flags_6(stage_op[6].addsub_copy_flags), - .int_operand_6(stage_op[6].addsub_int_operand), - .force_nop_7(stage_op[7].clz_force_nop), - .copy_flags_11(stage_op[11].shiftl_copy_flags), - .copy_flags_12(stage_op[12].round_copy_flags), - .enable_12(stage_op[12].round_enable), - .enable_14(stage_op[14].encode_enable) - ); + genvar lane; + generate + for (lane = 0; lane < SHADER_LANES; ++lane) begin: lanes + gfx_fpint_lane unit + ( + .clk(clk), + .a(a[lane]), + .b(b[lane]), + .q(q[lane]), + .mul_float_0(stage_op[0].setup_mul_float), + .unit_b_0(stage_op[0].setup_unit_b), + .put_hi_2(stage_op[2].mnorm_put_hi), + .put_lo_2(stage_op[2].mnorm_put_lo), + .put_mul_2(stage_op[2].mnorm_put_mul), + .zero_b_2(stage_op[2].mnorm_zero_b), + .zero_flags_2(stage_op[2].mnorm_zero_flags), + .copy_flags_3(stage_op[3].minmax_copy_flags), + .int_signed_5(stage_op[5].shiftr_int_signed), + .copy_flags_6(stage_op[6].addsub_copy_flags), + .int_operand_6(stage_op[6].addsub_int_operand), + .force_nop_7(stage_op[7].clz_force_nop), + .copy_flags_11(stage_op[11].shiftl_copy_flags), + .copy_flags_12(stage_op[12].round_copy_flags), + .enable_12(stage_op[12].round_enable), + .enable_14(stage_op[14].encode_enable) + ); + end + endgenerate always_ff @(posedge clk) for (int i = 1; i < FPINT_STAGES; ++i) stage_op[i] <= stage_op[i - 1]; + always_ff @(posedge clk or negedge rst_n) begin + for (int i = 1; i < FPINT_STAGES; ++i) + stage_valid[i] <= !rst_n ? 0 : stage_valid[i - 1]; + + out_valid <= !rst_n ? 0 : stage_valid[FPINT_STAGES - 1]; + end + endmodule diff --git a/platform/wavelet3d/gfx_pkg.sv b/platform/wavelet3d/gfx_pkg.sv index 5c420cc..75a564a 100644 --- a/platform/wavelet3d/gfx_pkg.sv +++ b/platform/wavelet3d/gfx_pkg.sv @@ -1,5 +1,7 @@ package gfx; + localparam int SHADER_LANES = 4; + typedef logic[31:0] word; typedef logic[63:0] dword; typedef logic[7:0] float_exp; diff --git a/platform/wavelet3d/main.cpp b/platform/wavelet3d/main.cpp index 49c96c1..2555d1d 100644 --- a/platform/wavelet3d/main.cpp +++ b/platform/wavelet3d/main.cpp @@ -2,6 +2,7 @@ #include <cstddef> #include <cstdio> #include <cstdlib> +#include <string> #include <Python.h> #include <verilated.h> @@ -23,99 +24,166 @@ int main(int argc, char **argv) Py_Initialize(); - float q; - int a, b; - const char *op = "int->fp"; - - std::cin >> a >> b; - - // int->fp - top.setup_mul_float = 0; - top.setup_unit_b = 1; - top.mnorm_put_hi = 0; - top.mnorm_put_lo = 1; - top.mnorm_put_mul = 0; - top.mnorm_zero_flags = 1; - top.mnorm_zero_b = 1; - top.minmax_copy_flags = 0; - top.shiftr_int_signed = 1; - top.addsub_int_operand = 1; - top.addsub_copy_flags = 1; - top.clz_force_nop = 1; - top.shiftl_copy_flags = 0; - top.round_copy_flags = 0; - top.round_enable = 1; - top.encode_enable = 1; - - // mul int - //top.setup_mul_float = 0; - //top.setup_unit_b = 0; - //top.mnorm_put_hi = 0; - //top.mnorm_put_lo = 1; - //top.mnorm_put_mul = 0; - //top.mnorm_zero_flags = 1; - //top.mnorm_zero_b = 1; - //top.minmax_copy_flags = 1; - //top.shiftr_int_signed = 0; - //top.addsub_int_operand = 0; - //top.addsub_copy_flags = 1; - //top.clz_force_nop = 0; - //top.shiftl_copy_flags = 1; - //top.round_copy_flags = 1; - //top.round_enable = 0; - //top.encode_enable = 0; + int time = 0; - // mul fp - //top.setup_mul_float = 1; - //top.setup_unit_b = 0; - //top.mnorm_put_hi = 0; - //top.mnorm_put_lo = 0; - //top.mnorm_put_mul = 1; - //top.mnorm_zero_flags = 0; - //top.mnorm_zero_b = 1; - //top.minmax_copy_flags = 1; - //top.shiftr_int_signed = 0; - //top.addsub_int_operand = 0; - //top.addsub_copy_flags = 1; - //top.clz_force_nop = 1; - //top.shiftl_copy_flags = 1; - //top.round_copy_flags = 1; - //top.round_enable = 1; - //top.encode_enable = 1; - - // suma/resta - //top.setup_mul_float = 0; - //top.setup_unit_b = 1; - //top.mnorm_put_hi = 0; - //top.mnorm_put_lo = 1; - //top.mnorm_put_mul = 0; - //top.mnorm_zero_flags = 0; - //top.mnorm_zero_b = 0; - //top.minmax_copy_flags = 0; - //top.shiftr_int_signed = 0; - //top.addsub_int_operand = 0; - //top.addsub_copy_flags = 0; - //top.clz_force_nop = 1; - //top.shiftl_copy_flags = 0; - //top.round_copy_flags = 0; - //top.round_enable = 1; - //top.encode_enable = 1; - - top.a = *reinterpret_cast<unsigned*>(&a); - top.b = *reinterpret_cast<unsigned*>(&b); - - for (int i = 0; i < 1000; ++i) { + auto cycle = [&]() + { top.clk = 0; top.eval(); top.clk = 1; top.eval(); - } - unsigned q_bits = top.q; - q = *reinterpret_cast<decltype(q)*>(&q_bits); + ++time; + }; + + auto send_op = [&](auto a, const char *op, auto b) + { + std::printf + ( + "[%03d] %s %s %s\n", + time, std::to_string(a).c_str(), op, std::to_string(b).c_str() + ); + + top.a[0] = *reinterpret_cast<unsigned*>(&a); + top.b[0] = *reinterpret_cast<unsigned*>(&b); + top.in_valid = 1; + cycle(); + + top.a[0] = 0; + top.b[0] = 0; + top.in_valid = 0; + }; + + auto int_to_fp = [&](int a) + { + top.setup_mul_float = 0; + top.setup_unit_b = 1; + top.mnorm_put_hi = 0; + top.mnorm_put_lo = 1; + top.mnorm_put_mul = 0; + top.mnorm_zero_flags = 1; + top.mnorm_zero_b = 1; + top.minmax_copy_flags = 0; + top.shiftr_int_signed = 1; + top.addsub_int_operand = 1; + top.addsub_copy_flags = 1; + top.clz_force_nop = 0; + top.shiftl_copy_flags = 0; + top.round_copy_flags = 0; + top.round_enable = 1; + top.encode_enable = 1; + + send_op(a, "fp->int", 0); + }; + + auto mul_int = [&](unsigned a, unsigned b) + { + top.setup_mul_float = 0; + top.setup_unit_b = 0; + top.mnorm_put_hi = 0; + top.mnorm_put_lo = 1; + top.mnorm_put_mul = 0; + top.mnorm_zero_flags = 1; + top.mnorm_zero_b = 1; + top.minmax_copy_flags = 1; + top.shiftr_int_signed = 0; + top.addsub_int_operand = 0; + top.addsub_copy_flags = 1; + top.clz_force_nop = 1; + top.shiftl_copy_flags = 1; + top.round_copy_flags = 1; + top.round_enable = 0; + top.encode_enable = 0; + + send_op(a, "*", b); + }; - std::cout << a << ' ' << op << ' ' << b << " = " << q << '\n'; + // mul fp + auto mul_fp = [&](float a, float b) + { + top.setup_mul_float = 1; + top.setup_unit_b = 0; + top.mnorm_put_hi = 0; + top.mnorm_put_lo = 0; + top.mnorm_put_mul = 1; + top.mnorm_zero_flags = 0; + top.mnorm_zero_b = 1; + top.minmax_copy_flags = 1; + top.shiftr_int_signed = 0; + top.addsub_int_operand = 0; + top.addsub_copy_flags = 1; + top.clz_force_nop = 1; + top.shiftl_copy_flags = 1; + top.round_copy_flags = 1; + top.round_enable = 1; + top.encode_enable = 1; + + send_op(a, "*", b); + }; + + auto add_fp = [&](float a, float b) + { + top.setup_mul_float = 0; + top.setup_unit_b = 1; + top.mnorm_put_hi = 0; + top.mnorm_put_lo = 1; + top.mnorm_put_mul = 0; + top.mnorm_zero_flags = 0; + top.mnorm_zero_b = 0; + top.minmax_copy_flags = 0; + top.shiftr_int_signed = 0; + top.addsub_int_operand = 0; + top.addsub_copy_flags = 0; + top.clz_force_nop = 0; + top.shiftl_copy_flags = 0; + top.round_copy_flags = 0; + top.round_enable = 1; + top.encode_enable = 1; + + send_op(a, "+", b); + }; + + top.rst_n = 0; + top.in_valid = 0; + cycle(); + + top.rst_n = 1; + cycle(); + + int a, b; + float a_flt, b_flt; + + std::cout << "a_int: "; + std::cin >> a; + std::cout << "b_int: "; + std::cin >> b; + std::cout << "a_flt: "; + std::cin >> a_flt; + std::cout << "b_flt: "; + std::cin >> b_flt; + + int_to_fp(a); + mul_int(a, b); + mul_fp(a_flt, b_flt); + add_fp(a_flt, b_flt); + + while (time < 20) { + cycle(); + + if (!top.out_valid) + continue; + + unsigned q_bits = top.q[0]; + int q_int = *reinterpret_cast<int*>(&q_bits); + float q_flt = *reinterpret_cast<float*>(&q_bits); + + std::printf + ( + "[%03d] q=0x%08x, q_flt=%g, q_int=%d, q_uint=%u\n", + time, q_bits, q_flt, q_int, q_bits + ); + } bool failed = Py_FinalizeEx() < 0; |
