-
Notifications
You must be signed in to change notification settings - Fork 0
/
FAdd.vhd
191 lines (155 loc) · 8.11 KB
/
FAdd.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity FAdd is
port (
clk : in std_logic;
flt_in1 : in std_logic_vector(31 downto 0);
flt_in2 : in std_logic_vector(31 downto 0);
flt_out : out std_logic_vector(31 downto 0));
end FAdd;
architecture dataflow_pipeline of FAdd is
component FractionLeftTrimming
port (
frc_in : in std_logic_vector(23 downto 0);
nlz : out std_logic_vector( 4 downto 0);
frc_out : out std_logic_vector(22 downto 0));
end component;
component FractionRightShifter is
port (
frc_in : in std_logic_vector(23 downto 0);
len : in std_logic_vector( 4 downto 0);
frc_out : out std_logic_vector(23 downto 0);
fst_over_out : out std_logic;
snd_over_out : out std_logic;
tail_any_out : out std_logic);
end component;
signal s1_sgn1, s1_sgn2 : std_logic;
signal s1_exp1, s1_exp2 : std_logic_vector( 7 downto 0);
signal s1_frc1, s1_frc2 : std_logic_vector(23 downto 0);
signal s1_raw_len_pos_sft, s1_raw_len_neg_sft : std_logic_vector(8 downto 0);
signal s1_len_sft : std_logic_vector(4 downto 0);
signal s1_valid_pos_sft, s1_valid_neg_sft : boolean;
signal s1_pos_sft : boolean;
signal s1_fst_over, s1_snd_over, s1_tail_any : std_logic;
signal s1_sgn_sup, s1_sgn_inf : std_logic;
signal s1_exp_unif : std_logic_vector(7 downto 0);
signal s1_frc_inf : std_logic_vector(23 downto 0);
signal s1_frc_unif_sup, s1_frc_unif_inf : std_logic_vector(23 downto 0);
signal s1_zero_sft, s1_is_add : boolean := false;
signal s2_sgn_sup, s2_sgn_inf : std_logic := '0';
signal s2_exp_unif : std_logic_vector(7 downto 0) := (others => '0');
signal s2_frc_unif_sup, s2_frc_unif_inf : std_logic_vector(23 downto 0) := (others => '0');
signal s2_fst_over, s2_snd_over, s2_tail_any : std_logic := '0';
signal s2_zero_sft, s2_is_add : boolean := false;
signal s2_round_further, s2_round_further_dbl, s2_round_further_hlf : std_logic;
signal s2_frc_out_adder1, s2_frc_out_adder2 : std_logic_vector(24 downto 0);
signal s2_frc_ireg : std_logic_vector(23 downto 0);
signal s2_frc_out_noinf_add : std_logic_vector(22 downto 0);
signal s2_no_flow, s2_no_down, s2_exact : boolean;
signal s3_sgn_sup, s3_sgn_inf : std_logic := '0';
signal s3_exp_unif : std_logic_vector(7 downto 0) := (others => '0');
signal s3_frc_ireg : std_logic_vector(23 downto 0) := (others => '0');
signal s3_frc_out_noinf_add : std_logic_vector(22 downto 0) := (others => '0');
signal s3_no_flow, s3_no_down, s3_exact, s3_zero_sft, s3_is_add : boolean := false;
signal s3_nlz : std_logic_vector(4 downto 0);
signal s3_down_frc : std_logic;
signal s3_exp_out_sub_raw : std_logic_vector(8 downto 0);
signal s3_exp_out_add, s3_exp_out_sub : std_logic_vector(7 downto 0);
signal s3_frc_out_add, s3_frc_out_sub : std_logic_vector(22 downto 0);
signal s3_sgn_out_sub : std_logic;
begin
s1_sgn1 <= flt_in1(31);
s1_exp1 <= flt_in1(30 downto 23);
s1_frc1 <= '0' & flt_in1(22 downto 0) when s1_exp1 = 0 else '1' & flt_in1(22 downto 0);
s1_sgn2 <= flt_in2(31);
s1_exp2 <= flt_in2(30 downto 23);
s1_frc2 <= '0' & flt_in2(22 downto 0) when s1_exp2 = 0 else '1' & flt_in2(22 downto 0);
s1_raw_len_pos_sft <= ('0' & s1_exp1) - ('0' & s1_exp2);
s1_raw_len_neg_sft <= ('0' & s1_exp2) - ('0' & s1_exp1);
s1_valid_pos_sft <= s1_raw_len_pos_sft(8 downto 5) = "0000";
s1_valid_neg_sft <= s1_raw_len_neg_sft(8 downto 5) = "0000";
s1_pos_sft <= s1_raw_len_pos_sft(8) = '0';
s1_len_sft <= s1_raw_len_neg_sft(4 downto 0) when s1_valid_neg_sft else
s1_raw_len_pos_sft(4 downto 0) when s1_valid_pos_sft else
"11111";
s1_sgn_sup <= s1_sgn1 when s1_pos_sft else s1_sgn2;
s1_sgn_inf <= s1_sgn2 when s1_pos_sft else s1_sgn1;
s1_exp_unif <= s1_exp1 when s1_pos_sft else s1_exp2;
s1_frc_unif_sup <= s1_frc1 when s1_pos_sft else s1_frc2;
s1_frc_inf <= s1_frc2 when s1_pos_sft else s1_frc1;
s1_zero_sft <= s1_raw_len_pos_sft(8) = '0' and s1_raw_len_neg_sft(8) = '0';
s1_is_add <= s1_sgn1 = s1_sgn2;
sft_unif_frc_map : FractionRightShifter port map (
frc_in => s1_frc_inf,
len => s1_len_sft,
frc_out => s1_frc_unif_inf,
fst_over_out => s1_fst_over,
snd_over_out => s1_snd_over,
tail_any_out => s1_tail_any);
pipe1: process(clk)
begin
if rising_edge(clk) then
s2_sgn_sup <= s1_sgn_sup;
s2_sgn_inf <= s1_sgn_inf;
s2_exp_unif <= s1_exp_unif;
s2_frc_unif_sup <= s1_frc_unif_sup;
s2_frc_unif_inf <= s1_frc_unif_inf;
s2_fst_over <= s1_fst_over;
s2_snd_over <= s1_snd_over;
s2_tail_any <= s1_tail_any;
s2_zero_sft <= s1_zero_sft;
s2_is_add <= s1_is_add;
end if;
end process;
s2_round_further_hlf <= s2_snd_over and (s2_tail_any or s2_fst_over);
s2_round_further <= s2_fst_over and ((s2_snd_over or s2_tail_any) or (s2_frc_unif_sup(0) xor s2_frc_unif_inf(0)));
s2_round_further_dbl <= (s2_frc_unif_sup(0) and s2_frc_unif_inf(0)) or
( (s2_frc_unif_sup(0) or s2_frc_unif_inf(0)) and
(((s2_fst_over or s2_snd_over) or s2_tail_any) or (s2_frc_unif_sup(1) xor s2_frc_unif_inf(1))));
s2_frc_out_adder1 <= ('0' & s2_frc_unif_sup) + ('0' & s2_frc_unif_inf) + s2_round_further when s2_is_add else
('0' & s2_frc_unif_sup) - ('0' & s2_frc_unif_inf) - s2_round_further;
s2_frc_out_adder2 <= ("00" & (s2_frc_unif_sup(23 downto 1))) + ("00" & (s2_frc_unif_inf(23 downto 1))) + s2_round_further_dbl when s2_is_add else
('0' & s2_frc_unif_inf) - ('0' & s2_frc_unif_sup) - s2_round_further when s2_zero_sft else
('0' & (s2_frc_unif_sup(22 downto 0)) & '0') - ('0' & (s2_frc_unif_inf(22 downto 0) & s2_fst_over)) - s2_round_further_hlf;
s2_no_flow <= s2_frc_out_adder1(24) = '0';
s2_exact <= s2_frc_out_adder2(24) = '0' and s2_no_flow and s2_zero_sft;
s2_no_down <= s2_frc_out_adder1(23) = '1';
s2_frc_ireg <= s2_frc_out_adder1(23 downto 0) when s2_zero_sft and s2_no_flow else
s2_frc_out_adder2(23 downto 0) when s2_zero_sft and not s2_no_flow else
s2_frc_out_adder1(23 downto 0) when s2_no_down else
s2_frc_out_adder2(23 downto 0);
s2_frc_out_noinf_add <= s2_frc_out_adder1(22 downto 0) when s2_no_flow else
s2_frc_out_adder2(22 downto 0);
pipe2: process(clk)
begin
if rising_edge(clk) then
s3_sgn_sup <= s2_sgn_sup;
s3_sgn_inf <= s2_sgn_inf;
s3_exp_unif <= s2_exp_unif;
s3_frc_ireg <= s2_frc_ireg;
s3_frc_out_noinf_add <= s2_frc_out_noinf_add;
s3_no_flow <= s2_no_flow;
s3_exact <= s2_exact;
s3_no_down <= s2_no_down;
s3_zero_sft <= s2_zero_sft;
s3_is_add <= s2_is_add;
end if;
end process;
s3_exp_out_add <= s3_exp_unif when s3_no_flow else s3_exp_unif+1;
s3_frc_out_add <= (others => '0') when s3_exp_out_add = "11111111" else
s3_frc_out_noinf_add;
s3_sgn_out_sub <= '0' when s3_exact else
s3_sgn_sup when not s3_zero_sft or s3_no_flow else
s3_sgn_inf;
pad_frc_ireg_map : FractionLeftTrimming port map (
frc_in => s3_frc_ireg,
nlz => s3_nlz,
frc_out => s3_frc_out_sub);
s3_down_frc <= '0' when s3_zero_sft or s3_no_down else '1';
s3_exp_out_sub_raw <= ('0' & s3_exp_unif) - ("0000" & s3_nlz) - s3_down_frc;
s3_exp_out_sub <= "00000000" when (s3_nlz(4) = '1' and s3_nlz(3) = '1') or s3_exp_out_sub_raw(8) = '1' else
s3_exp_out_sub_raw(7 downto 0);
flt_out <= s3_sgn_sup & s3_exp_out_add & s3_frc_out_add(22 downto 0) when s3_is_add else
s3_sgn_out_sub & s3_exp_out_sub & s3_frc_out_sub(22 downto 0);
end dataflow_pipeline;