summaryrefslogtreecommitdiff
path: root/rtl/fpu/float/fp_exe.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/fpu/float/fp_exe.sv')
-rw-r--r--rtl/fpu/float/fp_exe.sv215
1 files changed, 215 insertions, 0 deletions
diff --git a/rtl/fpu/float/fp_exe.sv b/rtl/fpu/float/fp_exe.sv
new file mode 100644
index 0000000..f61038a
--- /dev/null
+++ b/rtl/fpu/float/fp_exe.sv
@@ -0,0 +1,215 @@
+import fp_wire::*;
+
+module fp_exe (
+ input fp_exe_in_type fp_exe_i,
+ output fp_exe_out_type fp_exe_o,
+ input fp_ext_out_type fp_ext1_o,
+ output fp_ext_in_type fp_ext1_i,
+ input fp_ext_out_type fp_ext2_o,
+ output fp_ext_in_type fp_ext2_i,
+ input fp_ext_out_type fp_ext3_o,
+ output fp_ext_in_type fp_ext3_i,
+ input fp_cmp_out_type fp_cmp_o,
+ output fp_cmp_in_type fp_cmp_i,
+ input fp_max_out_type fp_max_o,
+ output fp_max_in_type fp_max_i,
+ input fp_sgnj_out_type fp_sgnj_o,
+ output fp_sgnj_in_type fp_sgnj_i,
+ input fp_cvt_f2f_out_type fp_cvt_f2f_o,
+ output fp_cvt_f2f_in_type fp_cvt_f2f_i,
+ input fp_cvt_f2i_out_type fp_cvt_f2i_o,
+ output fp_cvt_f2i_in_type fp_cvt_f2i_i,
+ input fp_cvt_i2f_out_type fp_cvt_i2f_o,
+ output fp_cvt_i2f_in_type fp_cvt_i2f_i,
+ input fp_fma_out_type fp_fma_o,
+ output fp_fma_in_type fp_fma_i,
+ input fp_fdiv_out_type fp_fdiv_o,
+ output fp_fdiv_in_type fp_fdiv_i,
+ input fp_rnd_out_type fp_rnd_o,
+ output fp_rnd_in_type fp_rnd_i
+);
+
+ logic [63:0] data1;
+ logic [63:0] data2;
+ logic [63:0] data3;
+ fp_operation_type op;
+ logic [1:0] fmt;
+ logic [2:0] rm;
+
+ logic [63:0] result;
+ logic [4:0] flags;
+ logic ready;
+
+ logic [1:0] fmt_ext;
+
+ logic [64:0] extend1;
+ logic [64:0] extend2;
+ logic [64:0] extend3;
+
+ logic [9:0] class1;
+ logic [9:0] class2;
+ logic [9:0] class3;
+
+ fp_rnd_in_type fp_rnd;
+
+ always_comb begin
+
+ if (fp_exe_i.enable) begin
+ data1 = fp_exe_i.data1;
+ data2 = fp_exe_i.data2;
+ data3 = fp_exe_i.data3;
+ op = fp_exe_i.op;
+ fmt = fp_exe_i.fmt;
+ rm = fp_exe_i.rm;
+ end else begin
+ data1 = 0;
+ data2 = 0;
+ data3 = 0;
+ op = 0;
+ fmt = 0;
+ rm = 0;
+ end
+
+ result = 0;
+ flags = 0;
+ ready = fp_exe_i.enable;
+
+ if (op.fcvt_f2f) begin
+ fmt_ext = fp_exe_i.op.fcvt_op;
+ end else begin
+ fmt_ext = fp_exe_i.fmt;
+ end
+
+ fp_ext1_i.data = data1;
+ fp_ext1_i.fmt = fmt_ext;
+ fp_ext2_i.data = data2;
+ fp_ext2_i.fmt = fmt_ext;
+ fp_ext3_i.data = data3;
+ fp_ext3_i.fmt = fmt_ext;
+
+ extend1 = fp_ext1_o.result;
+ extend2 = fp_ext2_o.result;
+ extend3 = fp_ext3_o.result;
+
+ class2 = fp_ext2_o.classification;
+ class1 = fp_ext1_o.classification;
+ class3 = fp_ext3_o.classification;
+
+ fp_cmp_i.data1 = extend1;
+ fp_cmp_i.data2 = extend2;
+ fp_cmp_i.rm = rm;
+ fp_cmp_i.class1 = class1;
+ fp_cmp_i.class2 = class2;
+
+ fp_max_i.data1 = data1;
+ fp_max_i.data2 = data2;
+ fp_max_i.ext1 = extend1;
+ fp_max_i.ext2 = extend2;
+ fp_max_i.fmt = fmt;
+ fp_max_i.rm = rm;
+ fp_max_i.class1 = class1;
+ fp_max_i.class2 = class2;
+
+ fp_sgnj_i.data1 = data1;
+ fp_sgnj_i.data2 = data2;
+ fp_sgnj_i.fmt = fmt;
+ fp_sgnj_i.rm = rm;
+
+ fp_fma_i.data1 = extend1;
+ fp_fma_i.data2 = extend2;
+ fp_fma_i.data3 = extend3;
+ fp_fma_i.fmt = fmt;
+ fp_fma_i.rm = rm;
+ fp_fma_i.op = op;
+ fp_fma_i.class1 = class1;
+ fp_fma_i.class2 = class2;
+ fp_fma_i.class3 = class3;
+
+ fp_fdiv_i.data1 = extend1;
+ fp_fdiv_i.data2 = extend2;
+ fp_fdiv_i.fmt = fmt;
+ fp_fdiv_i.rm = rm;
+ fp_fdiv_i.op = op;
+ fp_fdiv_i.class1 = class1;
+ fp_fdiv_i.class2 = class2;
+
+ fp_cvt_i2f_i.data = data1;
+ fp_cvt_i2f_i.op = op;
+ fp_cvt_i2f_i.fmt = fmt;
+ fp_cvt_i2f_i.rm = rm;
+
+ fp_cvt_f2f_i.data = extend1;
+ fp_cvt_f2f_i.fmt = fmt;
+ fp_cvt_f2f_i.rm = rm;
+ fp_cvt_f2f_i.classification = class1;
+
+ fp_cvt_f2i_i.data = extend1;
+ fp_cvt_f2i_i.op = op;
+ fp_cvt_f2i_i.rm = rm;
+ fp_cvt_f2i_i.classification = class1;
+
+ fp_rnd = init_fp_rnd_in;
+
+ if (fp_fma_o.ready) begin
+ fp_rnd = fp_fma_o.fp_rnd;
+ end else if (fp_fdiv_o.ready) begin
+ fp_rnd = fp_fdiv_o.fp_rnd;
+ end else if (op.fcvt_f2f) begin
+ fp_rnd = fp_cvt_f2f_o.fp_rnd;
+ end else if (op.fcvt_i2f) begin
+ fp_rnd = fp_cvt_i2f_o.fp_rnd;
+ end
+
+ fp_rnd_i = fp_rnd;
+
+ if (fp_fma_o.ready) begin
+ result = fp_rnd_o.result;
+ flags = fp_rnd_o.flags;
+ ready = 1;
+ end else if (fp_fdiv_o.ready) begin
+ result = fp_rnd_o.result;
+ flags = fp_rnd_o.flags;
+ ready = 1;
+ end else if (op.fmadd | op.fmsub | op.fnmadd | op.fnmsub | op.fadd | op.fadd | op.fsub | op.fmul) begin
+ ready = 0;
+ end else if (op.fdiv | op.fsqrt) begin
+ ready = 0;
+ end else if (op.fcmp) begin
+ result = fp_cmp_o.result;
+ flags = fp_cmp_o.flags;
+ end else if (op.fsgnj) begin
+ result = fp_sgnj_o.result;
+ flags = 0;
+ end else if (op.fmax) begin
+ result = fp_max_o.result;
+ flags = fp_max_o.flags;
+ end else if (op.fcmp) begin
+ result = fp_cmp_o.result;
+ flags = fp_cmp_o.flags;
+ end else if (op.fclass) begin
+ result = {54'h0, class1};
+ flags = 0;
+ end else if (op.fmv_f2i) begin
+ result = data1;
+ flags = 0;
+ end else if (op.fmv_i2f) begin
+ result = data1;
+ flags = 0;
+ end else if (op.fcvt_f2f) begin
+ result = fp_rnd_o.result;
+ flags = fp_rnd_o.flags;
+ end else if (op.fcvt_i2f) begin
+ result = fp_rnd_o.result;
+ flags = fp_rnd_o.flags;
+ end else if (op.fcvt_f2i) begin
+ result = fp_cvt_f2i_o.result;
+ flags = fp_cvt_f2i_o.flags;
+ end
+
+ fp_exe_o.result = result;
+ fp_exe_o.flags = flags;
+ fp_exe_o.ready = ready;
+
+ end
+
+endmodule