|
@@ -3,21 +3,19 @@
|
|
|
//2013-12-12
|
|
//2013-12-12
|
|
|
|
|
|
|
|
typedef enum logic [3:0] {
|
|
typedef enum logic [3:0] {
|
|
|
- get_a,
|
|
|
|
|
- get_b,
|
|
|
|
|
- unpack,
|
|
|
|
|
- special_cases,
|
|
|
|
|
- align,
|
|
|
|
|
|
|
+ add_unpack,
|
|
|
|
|
+ add_special,
|
|
|
|
|
+ add_align,
|
|
|
add_0,
|
|
add_0,
|
|
|
add_1,
|
|
add_1,
|
|
|
- normalise_1,
|
|
|
|
|
- normalise_2,
|
|
|
|
|
- round,
|
|
|
|
|
- pack,
|
|
|
|
|
- put_z,
|
|
|
|
|
- get_input
|
|
|
|
|
|
|
+ add_norm_0,
|
|
|
|
|
+ add_norm_1,
|
|
|
|
|
+ add_round,
|
|
|
|
|
+ add_pack,
|
|
|
|
|
+ add_output,
|
|
|
|
|
+ add_input
|
|
|
|
|
|
|
|
-} state_type;
|
|
|
|
|
|
|
+} adder_state;
|
|
|
|
|
|
|
|
|
|
|
|
|
module adder(
|
|
module adder(
|
|
@@ -49,7 +47,7 @@ module adder(
|
|
|
reg [31:0] s_output_z;
|
|
reg [31:0] s_output_z;
|
|
|
reg s_input_ack;
|
|
reg s_input_ack;
|
|
|
|
|
|
|
|
- state_type state;
|
|
|
|
|
|
|
+ adder_state state;
|
|
|
|
|
|
|
|
reg [31:0] a, b, z;
|
|
reg [31:0] a, b, z;
|
|
|
reg [26:0] a_m, b_m;
|
|
reg [26:0] a_m, b_m;
|
|
@@ -82,20 +80,20 @@ module adder(
|
|
|
// end
|
|
// end
|
|
|
// end
|
|
// end
|
|
|
|
|
|
|
|
- get_input:
|
|
|
|
|
|
|
+ add_input:
|
|
|
begin
|
|
begin
|
|
|
s_input_ack <= 1;
|
|
s_input_ack <= 1;
|
|
|
if (s_input_ack && input_stb) begin
|
|
if (s_input_ack && input_stb) begin
|
|
|
a <= input_a;
|
|
a <= input_a;
|
|
|
b <= input_b;
|
|
b <= input_b;
|
|
|
s_input_ack <= 0;
|
|
s_input_ack <= 0;
|
|
|
- state <= unpack;
|
|
|
|
|
|
|
+ state <= add_unpack;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- unpack:
|
|
|
|
|
|
|
+ add_unpack:
|
|
|
begin
|
|
begin
|
|
|
a_m <= {a[22 : 0], 3'd0};
|
|
a_m <= {a[22 : 0], 3'd0};
|
|
|
b_m <= {b[22 : 0], 3'd0};
|
|
b_m <= {b[22 : 0], 3'd0};
|
|
@@ -103,18 +101,18 @@ module adder(
|
|
|
b_e <= b[30 : 23] - 127;
|
|
b_e <= b[30 : 23] - 127;
|
|
|
a_s <= a[31];
|
|
a_s <= a[31];
|
|
|
b_s <= b[31];
|
|
b_s <= b[31];
|
|
|
- state <= special_cases;
|
|
|
|
|
|
|
+ state <= add_special;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- special_cases:
|
|
|
|
|
|
|
+ add_special:
|
|
|
begin
|
|
begin
|
|
|
//if a is NaN return a
|
|
//if a is NaN return a
|
|
|
if (a_e == 128 && a_m != 0) begin
|
|
if (a_e == 128 && a_m != 0) begin
|
|
|
z <= {a_s, 8'hff, a[22], a[21:0]};
|
|
z <= {a_s, 8'hff, a[22], a[21:0]};
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
end else if (b_e == 128 && b_m != 0) begin
|
|
end else if (b_e == 128 && b_m != 0) begin
|
|
|
z <= {b_s, 8'hff, b[22:0]};
|
|
z <= {b_s, 8'hff, b[22:0]};
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
//if a is inf return inf
|
|
//if a is inf return inf
|
|
|
end else if (a_e == 128 && a_m == 0) begin
|
|
end else if (a_e == 128 && a_m == 0) begin
|
|
|
z[31] <= a_s;
|
|
z[31] <= a_s;
|
|
@@ -127,31 +125,31 @@ module adder(
|
|
|
z[22] <= 1;
|
|
z[22] <= 1;
|
|
|
z[21:0] <= 0;
|
|
z[21:0] <= 0;
|
|
|
end
|
|
end
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
//if b is inf return inf
|
|
//if b is inf return inf
|
|
|
end else if (b_e == 128 && b_m == 0) begin
|
|
end else if (b_e == 128 && b_m == 0) begin
|
|
|
z[31] <= b_s;
|
|
z[31] <= b_s;
|
|
|
z[30:23] <= 255;
|
|
z[30:23] <= 255;
|
|
|
z[22:0] <= 0;
|
|
z[22:0] <= 0;
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
//if a is zero return b
|
|
//if a is zero return b
|
|
|
end else if ((($signed(a_e) == -127) && (a_m == 0)) && (($signed(b_e) == -127) && (b_m == 0))) begin
|
|
end else if ((($signed(a_e) == -127) && (a_m == 0)) && (($signed(b_e) == -127) && (b_m == 0))) begin
|
|
|
z[31] <= a_s & b_s;
|
|
z[31] <= a_s & b_s;
|
|
|
z[30:23] <= b_e[7:0] + 127;
|
|
z[30:23] <= b_e[7:0] + 127;
|
|
|
z[22:0] <= b_m[26:3];
|
|
z[22:0] <= b_m[26:3];
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
//if a is zero return b
|
|
//if a is zero return b
|
|
|
end else if (($signed(a_e) == -127) && (a_m == 0)) begin
|
|
end else if (($signed(a_e) == -127) && (a_m == 0)) begin
|
|
|
z[31] <= b_s;
|
|
z[31] <= b_s;
|
|
|
z[30:23] <= b_e[7:0] + 127;
|
|
z[30:23] <= b_e[7:0] + 127;
|
|
|
z[22:0] <= b_m[26:3];
|
|
z[22:0] <= b_m[26:3];
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
//if b is zero return a
|
|
//if b is zero return a
|
|
|
end else if (($signed(b_e) == -127) && (b_m == 0)) begin
|
|
end else if (($signed(b_e) == -127) && (b_m == 0)) begin
|
|
|
z[31] <= a_s;
|
|
z[31] <= a_s;
|
|
|
z[30:23] <= a_e[7:0] + 127;
|
|
z[30:23] <= a_e[7:0] + 127;
|
|
|
z[22:0] <= a_m[26:3];
|
|
z[22:0] <= a_m[26:3];
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
end else begin
|
|
end else begin
|
|
|
//Denormalised Number
|
|
//Denormalised Number
|
|
|
if ($signed(a_e) == -127) begin
|
|
if ($signed(a_e) == -127) begin
|
|
@@ -165,11 +163,11 @@ module adder(
|
|
|
end else begin
|
|
end else begin
|
|
|
b_m[26] <= 1;
|
|
b_m[26] <= 1;
|
|
|
end
|
|
end
|
|
|
- state <= align;
|
|
|
|
|
|
|
+ state <= add_align;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- align:
|
|
|
|
|
|
|
+ add_align:
|
|
|
begin
|
|
begin
|
|
|
if ($signed(a_e) > $signed(b_e)) begin
|
|
if ($signed(a_e) > $signed(b_e)) begin
|
|
|
b_e <= b_e + 1;
|
|
b_e <= b_e + 1;
|
|
@@ -216,10 +214,10 @@ module adder(
|
|
|
round_bit <= sum[1];
|
|
round_bit <= sum[1];
|
|
|
sticky <= sum[0];
|
|
sticky <= sum[0];
|
|
|
end
|
|
end
|
|
|
- state <= normalise_1;
|
|
|
|
|
|
|
+ state <= add_norm_0;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- normalise_1:
|
|
|
|
|
|
|
+ add_norm_0:
|
|
|
begin
|
|
begin
|
|
|
if (z_m[23] == 0 && $signed(z_e) > -126) begin
|
|
if (z_m[23] == 0 && $signed(z_e) > -126) begin
|
|
|
z_e <= z_e - 1;
|
|
z_e <= z_e - 1;
|
|
@@ -228,11 +226,11 @@ module adder(
|
|
|
guard <= round_bit;
|
|
guard <= round_bit;
|
|
|
round_bit <= 0;
|
|
round_bit <= 0;
|
|
|
end else begin
|
|
end else begin
|
|
|
- state <= normalise_2;
|
|
|
|
|
|
|
+ state <= add_norm_1;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- normalise_2:
|
|
|
|
|
|
|
+ add_norm_1:
|
|
|
begin
|
|
begin
|
|
|
if ($signed(z_e) < -126) begin
|
|
if ($signed(z_e) < -126) begin
|
|
|
z_e <= z_e + 1;
|
|
z_e <= z_e + 1;
|
|
@@ -241,11 +239,11 @@ module adder(
|
|
|
round_bit <= guard;
|
|
round_bit <= guard;
|
|
|
sticky <= sticky | round_bit;
|
|
sticky <= sticky | round_bit;
|
|
|
end else begin
|
|
end else begin
|
|
|
- state <= round;
|
|
|
|
|
|
|
+ state <= add_round;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- round:
|
|
|
|
|
|
|
+ add_round:
|
|
|
begin
|
|
begin
|
|
|
if (guard && (round_bit | sticky | z_m[0])) begin
|
|
if (guard && (round_bit | sticky | z_m[0])) begin
|
|
|
z_m <= z_m + 1;
|
|
z_m <= z_m + 1;
|
|
@@ -253,10 +251,10 @@ module adder(
|
|
|
z_e <=z_e + 1;
|
|
z_e <=z_e + 1;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
- state <= pack;
|
|
|
|
|
|
|
+ state <= add_pack;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- pack:
|
|
|
|
|
|
|
+ add_pack:
|
|
|
begin
|
|
begin
|
|
|
z[22 : 0] <= z_m[22:0];
|
|
z[22 : 0] <= z_m[22:0];
|
|
|
z[30 : 23] <= z_e[7:0] + 127;
|
|
z[30 : 23] <= z_e[7:0] + 127;
|
|
@@ -273,23 +271,23 @@ module adder(
|
|
|
z[30 : 23] <= 255;
|
|
z[30 : 23] <= 255;
|
|
|
z[31] <= z_s;
|
|
z[31] <= z_s;
|
|
|
end
|
|
end
|
|
|
- state <= put_z;
|
|
|
|
|
|
|
+ state <= add_output;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
- put_z:
|
|
|
|
|
|
|
+ add_output:
|
|
|
begin
|
|
begin
|
|
|
s_output_z_stb <= 1;
|
|
s_output_z_stb <= 1;
|
|
|
s_output_z <= z;
|
|
s_output_z <= z;
|
|
|
if (s_output_z_stb && output_z_ack) begin
|
|
if (s_output_z_stb && output_z_ack) begin
|
|
|
s_output_z_stb <= 0;
|
|
s_output_z_stb <= 0;
|
|
|
- state <= get_input;
|
|
|
|
|
|
|
+ state <= add_input;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
endcase
|
|
endcase
|
|
|
|
|
|
|
|
if (rst == 1) begin
|
|
if (rst == 1) begin
|
|
|
- state <= get_input;
|
|
|
|
|
|
|
+ state <= add_input;
|
|
|
s_input_ack <= 0;
|
|
s_input_ack <= 0;
|
|
|
s_output_z_stb <= 0;
|
|
s_output_z_stb <= 0;
|
|
|
end
|
|
end
|