diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/wavelet3d/gfx_fpint.sv | 9 | ||||
| -rw-r--r-- | platform/wavelet3d/gfx_fpint_lane.sv | 54 | ||||
| -rw-r--r-- | platform/wavelet3d/gfx_pkg.sv | 3 | ||||
| -rw-r--r-- | platform/wavelet3d/gfx_top.sv | 3 | ||||
| -rw-r--r-- | platform/wavelet3d/main.cpp | 45 |
5 files changed, 99 insertions, 15 deletions
diff --git a/platform/wavelet3d/gfx_fpint.sv b/platform/wavelet3d/gfx_fpint.sv index e5c457c..b3108a4 100644 --- a/platform/wavelet3d/gfx_fpint.sv +++ b/platform/wavelet3d/gfx_fpint.sv @@ -13,6 +13,9 @@ module gfx_fpint mnorm_put_mul, mnorm_zero_b, mnorm_zero_flags, + minmax_abs, + minmax_swap, + minmax_zero_min, minmax_copy_flags, shiftr_int_signed, addsub_copy_flags, @@ -42,6 +45,9 @@ module gfx_fpint assign op.mnorm_put_mul = mnorm_put_mul; assign op.mnorm_zero_b = mnorm_zero_b; assign op.mnorm_zero_flags = mnorm_zero_flags; + assign op.minmax_abs = minmax_abs; + assign op.minmax_swap = minmax_swap; + assign op.minmax_zero_min = minmax_zero_min; assign op.minmax_copy_flags = minmax_copy_flags; assign op.shiftr_int_signed = shiftr_int_signed; assign op.addsub_copy_flags = addsub_copy_flags; @@ -68,6 +74,9 @@ module gfx_fpint .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), + .abs_3(stage_op[3].minmax_abs), + .swap_3(stage_op[3].minmax_swap), + .zero_min_3(stage_op[3].minmax_zero_min), .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), diff --git a/platform/wavelet3d/gfx_fpint_lane.sv b/platform/wavelet3d/gfx_fpint_lane.sv index 8cb77a8..b52a393 100644 --- a/platform/wavelet3d/gfx_fpint_lane.sv +++ b/platform/wavelet3d/gfx_fpint_lane.sv @@ -25,6 +25,9 @@ module gfx_fpint_lane put_mul_2, zero_b_2, zero_flags_2, + abs_3, + swap_3, + zero_min_3, copy_flags_3, int_signed_5, copy_flags_6, @@ -128,6 +131,9 @@ module gfx_fpint_lane .clk(clk), .in(mnorm_minmax), .out(minmax_expdiff), + .abs(abs_3), + .swap(swap_3), + .zero_min(zero_min_3), .copy_flags(copy_flags_3) ); @@ -351,25 +357,44 @@ module gfx_fpint_lane_minmax input logic clk, input gfx::fpint_mnorm_minmax in, - input logic copy_flags, + input logic abs, + swap, + zero_min, + copy_flags, output gfx::fpint_minmax_expdiff out ); import gfx::*; + logic abs_b_gt_abs_a, b_gt_a; + + /* Wiki dice: + * + * A property of the single- and double-precision formats is that + * their encoding allows one to easily sort them without using + * floating-point hardware, as if the bits represented sign-magnitude + * integers, although it is unclear whether this was a design + * consideration (it seems noteworthy that the earlier IBM hexadecimal + * floating-point representation also had this property for normalized + * numbers). + */ + assign abs_b_gt_abs_a = {in.b.exp, in.b.mant} > {in.a.exp, in.a.mant}; + + always_comb begin + unique case ({in.b.sign, in.a.sign}) + 2'b00: b_gt_a = abs_b_gt_abs_a; + 2'b01: b_gt_a = 1; + 2'b10: b_gt_a = 0; + 2'b11: b_gt_a = abs_b_gt_abs_a; + endcase + + if (abs) + b_gt_a = abs_b_gt_abs_a; + end + always_ff @(posedge clk) begin - /* Wiki dice: - * - * A property of the single- and double-precision formats is that - * their encoding allows one to easily sort them without using - * floating-point hardware, as if the bits represented sign-magnitude - * integers, although it is unclear whether this was a design - * consideration (it seems noteworthy that the earlier IBM hexadecimal - * floating-point representation also had this property for normalized - * numbers). - */ - if ({in.b.exp, in.b.mant} > {in.a.exp, in.a.mant}) begin + if (b_gt_a ^ swap) begin out.max <= in.b; out.min <= in.a; out.max_class <= in.b_class; @@ -381,6 +406,11 @@ module gfx_fpint_lane_minmax out.min_class <= in.b_class; end + if (zero_min) begin + out.min <= 0; + out.min_class <= classify_float(0); + end + out.guard <= in.guard; out.round <= in.round; out.sticky <= in.sticky; diff --git a/platform/wavelet3d/gfx_pkg.sv b/platform/wavelet3d/gfx_pkg.sv index bd71eff..72c8f80 100644 --- a/platform/wavelet3d/gfx_pkg.sv +++ b/platform/wavelet3d/gfx_pkg.sv @@ -84,6 +84,9 @@ package gfx; mnorm_put_mul, mnorm_zero_b, mnorm_zero_flags, + minmax_abs, + minmax_swap, + minmax_zero_min, minmax_copy_flags, shiftr_int_signed, addsub_copy_flags, diff --git a/platform/wavelet3d/gfx_top.sv b/platform/wavelet3d/gfx_top.sv index 79ffc2d..77126b9 100644 --- a/platform/wavelet3d/gfx_top.sv +++ b/platform/wavelet3d/gfx_top.sv @@ -13,6 +13,9 @@ module gfx_top mnorm_put_mul, mnorm_zero_b, mnorm_zero_flags, + minmax_abs, + minmax_swap, + minmax_zero_min, minmax_copy_flags, shiftr_int_signed, addsub_copy_flags, diff --git a/platform/wavelet3d/main.cpp b/platform/wavelet3d/main.cpp index 2555d1d..74435fd 100644 --- a/platform/wavelet3d/main.cpp +++ b/platform/wavelet3d/main.cpp @@ -41,7 +41,7 @@ int main(int argc, char **argv) { std::printf ( - "[%03d] %s %s %s\n", + "[%03d] <= %s %s %s\n", time, std::to_string(a).c_str(), op, std::to_string(b).c_str() ); @@ -64,6 +64,9 @@ int main(int argc, char **argv) top.mnorm_put_mul = 0; top.mnorm_zero_flags = 1; top.mnorm_zero_b = 1; + top.minmax_abs = 1; + top.minmax_swap = 0; + top.minmax_zero_min = 0; top.minmax_copy_flags = 0; top.shiftr_int_signed = 1; top.addsub_int_operand = 1; @@ -86,6 +89,9 @@ int main(int argc, char **argv) top.mnorm_put_mul = 0; top.mnorm_zero_flags = 1; top.mnorm_zero_b = 1; + top.minmax_abs = 1; + top.minmax_swap = 0; + top.minmax_zero_min = 0; top.minmax_copy_flags = 1; top.shiftr_int_signed = 0; top.addsub_int_operand = 0; @@ -109,6 +115,9 @@ int main(int argc, char **argv) top.mnorm_put_mul = 1; top.mnorm_zero_flags = 0; top.mnorm_zero_b = 1; + top.minmax_abs = 1; + top.minmax_swap = 0; + top.minmax_zero_min = 0; top.minmax_copy_flags = 1; top.shiftr_int_signed = 0; top.addsub_int_operand = 0; @@ -131,6 +140,9 @@ int main(int argc, char **argv) top.mnorm_put_mul = 0; top.mnorm_zero_flags = 0; top.mnorm_zero_b = 0; + top.minmax_abs = 1; + top.minmax_swap = 0; + top.minmax_zero_min = 0; top.minmax_copy_flags = 0; top.shiftr_int_signed = 0; top.addsub_int_operand = 0; @@ -144,6 +156,31 @@ int main(int argc, char **argv) send_op(a, "+", b); }; + auto min_max_fp = [&](float a, float b, bool min = false) + { + 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_abs = 0; + top.minmax_swap = min; + top.minmax_zero_min = 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, min ? "min" : "max", b); + }; + top.rst_n = 0; top.in_valid = 0; cycle(); @@ -167,8 +204,10 @@ int main(int argc, char **argv) mul_int(a, b); mul_fp(a_flt, b_flt); add_fp(a_flt, b_flt); + min_max_fp(a_flt, b_flt); + min_max_fp(a_flt, b_flt, true); - while (time < 20) { + while (time < 50) { cycle(); if (!top.out_valid) @@ -180,7 +219,7 @@ int main(int argc, char **argv) std::printf ( - "[%03d] q=0x%08x, q_flt=%g, q_int=%d, q_uint=%u\n", + "[%03d] => q=0x%08x, q_flt=%g, q_int=%d, q_uint=%u\n", time, q_bits, q_flt, q_int, q_bits ); } |
