本帖最后由 浩然若枫 于 2013-10-21 16:20 编辑
回复 1# joebaibai
这个是通过仿真的,你可以参考一下。你先要搞明白浮点数据的结构是什么样的,哪些位都分别代表什么,在去做加法器,就比较简单了!附件不支持.v文件??? 直接写吧
- `timescale 1ns / 100ps
- module fpu_add( clk, rst, enable, opa, opb, sign, sum_2, exponent_2);
- input clk;
- input rst;
- input enable;
- input [63:0] opa, opb;
- output sign;
- output [55:0] sum_2;
- output [10:0] exponent_2;
- reg sign;
- reg [10:0] exponent_a;
- reg [10:0] exponent_b;
- reg [51:0] mantissa_a;
- reg [51:0] mantissa_b;
- reg expa_gt_expb;
- reg [10:0] exponent_small;
- reg [10:0] exponent_large;
- reg [51:0] mantissa_small;
- reg [51:0] mantissa_large;
- reg small_is_denorm;
- reg large_is_denorm;
- reg large_norm_small_denorm;
- reg [10:0] exponent_diff;
- reg [55:0] large_add;
- reg [55:0] small_add;
- reg [55:0] small_shift;
- wire small_shift_nonzero = |small_shift[55:0];
- wire small_is_nonzero = (exponent_small > 0) | |mantissa_small[51:0];
- wire small_fraction_enable = small_is_nonzero & !small_shift_nonzero;
- wire [55:0] small_shift_2 = { 55'b0, 1'b1 };
- reg [55:0] small_shift_3;
- reg [55:0] sum;
- wire sum_overflow = sum[55]; // sum[55] will be 0 if there was no carry from adding the 2 numbers
- reg [55:0] sum_2;
- reg [10:0] exponent;
- wire sum_leading_one = sum_2[54]; // this is where the leading one resides, unless denorm
- reg denorm_to_norm;
- reg [10:0] exponent_2;
- always @(posedge clk)
- begin
- if (rst) begin
- sign <= 0;
- exponent_a <= 0;
- exponent_b <= 0;
- mantissa_a <= 0;
- mantissa_b <= 0;
- expa_gt_expb <= 0;
- exponent_small <= 0;
- exponent_large <= 0;
- mantissa_small <= 0;
- mantissa_large <= 0;
- small_is_denorm <= 0;
- large_is_denorm <= 0;
- large_norm_small_denorm <= 0;
- exponent_diff <= 0;
- large_add <= 0;
- small_add <= 0;
- small_shift <= 0;
- small_shift_3 <= 0;
- sum <= 0;
- sum_2 <= 0;
- exponent <= 0;
- denorm_to_norm <= 0;
- exponent_2 <= 0;
- end
- else if (enable) begin
- sign <= opa[63];
- exponent_a <= opa[62:52];
- exponent_b <= opb[62:52];
- mantissa_a <= opa[51:0];
- mantissa_b <= opb[51:0];
- expa_gt_expb <= exponent_a > exponent_b;
- exponent_small <= expa_gt_expb ? exponent_b : exponent_a;
- exponent_large <= expa_gt_expb ? exponent_a : exponent_b;
- mantissa_small <= expa_gt_expb ? mantissa_b : mantissa_a;
- mantissa_large <= expa_gt_expb ? mantissa_a : mantissa_b;
- small_is_denorm <= !(exponent_small > 0);
- large_is_denorm <= !(exponent_large > 0);
- large_norm_small_denorm <= (small_is_denorm && !large_is_denorm);
- exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm;
- large_add <= { 1'b0, !large_is_denorm, mantissa_large, 2'b0 };
- small_add <= { 1'b0, !small_is_denorm, mantissa_small, 2'b0 };
- small_shift <= small_add >> exponent_diff;
- small_shift_3 <= small_fraction_enable ? small_shift_2 : small_shift;
- sum <= large_add + small_shift_3;
- sum_2 <= sum_overflow ? sum >> 1 : sum;
- exponent <= sum_overflow ? exponent_large + 1: exponent_large;
- denorm_to_norm <= sum_leading_one & large_is_denorm;
- exponent_2 <= denorm_to_norm ? exponent + 1 : exponent;
- end
- end
- endmodule
复制代码 |