summaryrefslogtreecommitdiff
path: root/platform/wavelet3d
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2024-03-09 05:19:39 -0600
committerAlejandro Soto <alejandro@34project.org>2024-03-09 05:19:39 -0600
commit5737a5e27f63e284a9e0402cdab7f86d9194457d (patch)
tree99e615c1c86deb052371d46555f15e5a0fe1ffbe /platform/wavelet3d
parent0a9d2b7209ffeac4aaa55ed8bc5d333d2519db6e (diff)
platform/wavelet3d: implement floating-point min/max
Diffstat (limited to 'platform/wavelet3d')
-rw-r--r--platform/wavelet3d/gfx_fpint.sv9
-rw-r--r--platform/wavelet3d/gfx_fpint_lane.sv54
-rw-r--r--platform/wavelet3d/gfx_pkg.sv3
-rw-r--r--platform/wavelet3d/gfx_top.sv3
-rw-r--r--platform/wavelet3d/main.cpp45
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
);
}