1 |
2 |
plutonium |
---------------------------------------------------------------------------------------------
|
2 |
|
|
-- Author: Jens Willkomm, Martin Kumm
|
3 |
|
|
-- Contact: jens.willkomm@student.uni-kassel.de, kumm@uni-kassel.de
|
4 |
|
|
-- License: LGPL
|
5 |
|
|
-- Date: 15.03.2013
|
6 |
|
|
-- Compatibility: Xilinx FPGAs of Virtex 5-7, Spartan 6 and Series 7 architectures
|
7 |
|
|
--
|
8 |
|
|
-- Description:
|
9 |
|
|
-- Low level implementation of a ternary adder according to U.S. Patent No 7274211
|
10 |
|
|
-- from Xilinx, which uses the same no of slices than a two input adder.
|
11 |
|
|
-- The output coresponds to sum_o = x_i + y_i + z_i, where the inputs have a word size of
|
12 |
|
|
-- 'input_word_size' while the output has a word size of input_word_size+2.
|
13 |
|
|
--
|
14 |
|
|
-- Flipflops at the outputs can be activated by setting 'use_output_ff' to true.
|
15 |
|
|
-- Signed operation is activated by using the 'is_signed' generic.
|
16 |
|
|
-- The inputs y_i and z_i can be negated by setting 'subtract_y' or 'subtract_z'
|
17 |
|
|
-- to realize sum_o = x_i +/- y_i +/- z_i. The negation requires no extra resources.
|
18 |
|
|
---------------------------------------------------------------------------------------------
|
19 |
|
|
|
20 |
|
|
library ieee;
|
21 |
|
|
use ieee.std_logic_1164.all;
|
22 |
|
|
|
23 |
|
|
entity ternary_add_sub_prim is
|
24 |
|
|
generic(
|
25 |
|
|
input_word_size : integer := 10;
|
26 |
|
|
subtract_y : boolean := false;
|
27 |
|
|
subtract_z : boolean := false;
|
28 |
|
|
use_output_ff : boolean := true;
|
29 |
|
|
is_signed : boolean := true
|
30 |
|
|
);
|
31 |
|
|
port(
|
32 |
|
|
clk_i : in std_logic;
|
33 |
|
|
rst_i : in std_logic;
|
34 |
|
|
x_i : in std_logic_vector((input_word_size - 1) downto 0);
|
35 |
|
|
y_i : in std_logic_vector((input_word_size - 1) downto 0);
|
36 |
|
|
z_i : in std_logic_vector((input_word_size - 1) downto 0);
|
37 |
|
|
sum_o : out std_logic_vector((input_word_size + 1) downto 0)
|
38 |
|
|
);
|
39 |
|
|
end entity;
|
40 |
|
|
|
41 |
|
|
architecture behavior of ternary_add_sub_prim is
|
42 |
|
|
-- this function calculates the initial carry bit for the bbus
|
43 |
|
|
function bbus_init
|
44 |
|
|
return std_logic is
|
45 |
|
|
variable result : std_logic;
|
46 |
|
|
begin
|
47 |
|
|
result := '0';
|
48 |
|
|
|
49 |
|
|
if subtract_y or subtract_z then
|
50 |
|
|
result := '1';
|
51 |
|
|
end if;
|
52 |
|
|
|
53 |
|
|
return result;
|
54 |
|
|
end function;
|
55 |
|
|
|
56 |
|
|
-- this function calculates the initial carry bit for the carry chain
|
57 |
|
|
function cc_init
|
58 |
|
|
return std_logic is
|
59 |
|
|
variable result : std_logic;
|
60 |
|
|
begin
|
61 |
|
|
result := '0';
|
62 |
|
|
|
63 |
|
|
if subtract_y and subtract_z then
|
64 |
|
|
result := '1';
|
65 |
|
|
end if;
|
66 |
|
|
|
67 |
|
|
return result;
|
68 |
|
|
end function;
|
69 |
|
|
|
70 |
|
|
component slice_setup
|
71 |
|
|
generic(
|
72 |
|
|
input_word_size : integer := 4;
|
73 |
|
|
use_output_ff : boolean := false;
|
74 |
|
|
is_initial_slice : boolean := true;
|
75 |
|
|
subtract_y : boolean := false;
|
76 |
|
|
subtract_z : boolean := false
|
77 |
|
|
);
|
78 |
|
|
port(
|
79 |
|
|
-- signals for a synchronous circuit
|
80 |
|
|
clock : in std_logic;
|
81 |
|
|
clock_enable : in std_logic;
|
82 |
|
|
clear : in std_logic;
|
83 |
|
|
-- the three addends
|
84 |
|
|
x_in : in std_logic_vector((input_word_size - 1) downto 0);
|
85 |
|
|
y_in : in std_logic_vector((input_word_size - 1) downto 0);
|
86 |
|
|
z_in : in std_logic_vector((input_word_size - 1) downto 0);
|
87 |
|
|
-- the upper entity is mapping the bbus correctly
|
88 |
|
|
-- in initial slice bbus(0) ^= sub / ~add
|
89 |
|
|
bbus_in : in std_logic_vector((input_word_size - 1) downto 0);
|
90 |
|
|
bbus_out : out std_logic_vector((input_word_size - 1) downto 0);
|
91 |
|
|
-- both carrys are for and from the carry chain
|
92 |
|
|
-- in the initial slice use carry_in <= '0' always
|
93 |
|
|
-- sub/add is done by the bbus(0) from the initial slice
|
94 |
|
|
carry_in : in std_logic;
|
95 |
|
|
carry_out : out std_logic;
|
96 |
|
|
-- the sum of the three addends (x_in + y_in + z_in)
|
97 |
|
|
sum_out : out std_logic_vector((input_word_size - 1) downto 0)
|
98 |
|
|
);
|
99 |
|
|
end component;
|
100 |
|
|
|
101 |
|
|
-- calculate the needed number of slices
|
102 |
|
|
constant num_slices : integer := ((input_word_size + 1) / 4) + 1;
|
103 |
|
|
|
104 |
|
|
-- defines the initial carry values
|
105 |
|
|
-- in the pure addition mode both constants are '0'
|
106 |
|
|
-- if one of the input signal is subtracted the carry_bbus is '1'
|
107 |
|
|
-- if two input signal are subtracted both constants are '1'
|
108 |
|
|
constant carry_bbus : std_logic := bbus_init;
|
109 |
|
|
constant carry_cc : std_logic := cc_init;
|
110 |
|
|
|
111 |
|
|
-- the input addends with sign extention
|
112 |
|
|
signal x : std_logic_vector((input_word_size + 1) downto 0);
|
113 |
|
|
signal y : std_logic_vector((input_word_size + 1) downto 0);
|
114 |
|
|
signal z : std_logic_vector((input_word_size + 1) downto 0);
|
115 |
|
|
|
116 |
|
|
-- the bbus that is routed around the slice
|
117 |
|
|
-- this bbus differs from the one in the xilinx paper,
|
118 |
|
|
-- per position the input is bbus(n) and the output is bbus(n + 1)
|
119 |
|
|
-- this is because of the sub/~add, which is bbus(0) and all the other
|
120 |
|
|
-- bbus signals are scrolled one position up
|
121 |
|
|
signal bbus : std_logic_vector(input_word_size + 2 downto 0);
|
122 |
|
|
-- the carry from every slice to the next one
|
123 |
|
|
-- the last slice gives the carry output for the adder
|
124 |
|
|
-- carry(n) is the carry of the carry chain of slice n
|
125 |
|
|
signal carry : std_logic_vector((num_slices - 1) downto 0);
|
126 |
|
|
begin
|
127 |
|
|
-- checking the parameter input_word_size
|
128 |
|
|
assert (input_word_size > 0) report "an adder with a bit width of "
|
129 |
|
|
& integer'image(input_word_size) & " is not possible." severity failure;
|
130 |
|
|
|
131 |
|
|
-- adding two bit sign extention to the input addends
|
132 |
|
|
extention_signed: if is_signed = true generate
|
133 |
|
|
x <= x_i(input_word_size - 1) & x_i(input_word_size - 1) & x_i;
|
134 |
|
|
y <= y_i(input_word_size - 1) & y_i(input_word_size - 1) & y_i;
|
135 |
|
|
z <= z_i(input_word_size - 1) & z_i(input_word_size - 1) & z_i;
|
136 |
|
|
end generate;
|
137 |
|
|
|
138 |
|
|
extention_unsigned: if is_signed = false generate
|
139 |
|
|
x <= '0' & '0' & x_i;
|
140 |
|
|
y <= '0' & '0' & y_i;
|
141 |
|
|
z <= '0' & '0' & z_i;
|
142 |
|
|
end generate;
|
143 |
|
|
|
144 |
|
|
-- the initial bbus carry signal
|
145 |
|
|
bbus(0) <= carry_bbus;
|
146 |
|
|
|
147 |
|
|
-- generating the slice setups
|
148 |
|
|
-- getting all signals into one slice
|
149 |
|
|
single_slice: if num_slices = 1 generate
|
150 |
|
|
slice_i: slice_setup
|
151 |
|
|
generic map(
|
152 |
|
|
input_word_size => input_word_size + 2,
|
153 |
|
|
use_output_ff => use_output_ff,
|
154 |
|
|
is_initial_slice => true,
|
155 |
|
|
subtract_y => subtract_y,
|
156 |
|
|
subtract_z => subtract_z
|
157 |
|
|
)
|
158 |
|
|
port map(
|
159 |
|
|
clock => clk_i,
|
160 |
|
|
clock_enable => '1',
|
161 |
|
|
clear => rst_i,
|
162 |
|
|
x_in => x,
|
163 |
|
|
y_in => y,
|
164 |
|
|
z_in => z,
|
165 |
|
|
bbus_in => bbus(input_word_size + 1 downto 0),
|
166 |
|
|
-- scrolling bbus_out one position up
|
167 |
|
|
bbus_out => bbus(input_word_size + 2 downto 1),
|
168 |
|
|
carry_in => carry_cc,
|
169 |
|
|
carry_out => carry(0),
|
170 |
|
|
sum_out => sum_o(input_word_size + 1 downto 0)
|
171 |
|
|
);
|
172 |
|
|
end generate;
|
173 |
|
|
|
174 |
|
|
-- make more slices to calculate all signals
|
175 |
|
|
multiple_slices: if num_slices > 1 generate
|
176 |
|
|
slices: for i in 0 to (num_slices - 1) generate
|
177 |
|
|
-- generate the first slice
|
178 |
|
|
first_slice: if i = 0 generate
|
179 |
|
|
slice_i: slice_setup
|
180 |
|
|
generic map(
|
181 |
|
|
input_word_size => 4,
|
182 |
|
|
use_output_ff => use_output_ff,
|
183 |
|
|
is_initial_slice => true,
|
184 |
|
|
subtract_y => subtract_y,
|
185 |
|
|
subtract_z => subtract_z
|
186 |
|
|
)
|
187 |
|
|
port map(
|
188 |
|
|
clock => clk_i,
|
189 |
|
|
clock_enable => '1',
|
190 |
|
|
clear => rst_i,
|
191 |
|
|
x_in => x(3 downto 0),
|
192 |
|
|
y_in => y(3 downto 0),
|
193 |
|
|
z_in => z(3 downto 0),
|
194 |
|
|
bbus_in => bbus(3 downto 0),
|
195 |
|
|
-- scrolling bbus_out one position upwards
|
196 |
|
|
bbus_out => bbus(4 downto 1),
|
197 |
|
|
carry_in => carry_cc,
|
198 |
|
|
carry_out => carry(0),
|
199 |
|
|
sum_out => sum_o(3 downto 0)
|
200 |
|
|
);
|
201 |
|
|
end generate;
|
202 |
|
|
|
203 |
|
|
-- generate all full slices
|
204 |
|
|
full_slice: if i > 0 and i < (num_slices - 1) generate
|
205 |
|
|
slice_i: slice_setup
|
206 |
|
|
generic map(
|
207 |
|
|
input_word_size => 4,
|
208 |
|
|
use_output_ff => use_output_ff,
|
209 |
|
|
is_initial_slice => false,
|
210 |
|
|
subtract_y => subtract_y,
|
211 |
|
|
subtract_z => subtract_z
|
212 |
|
|
)
|
213 |
|
|
port map(
|
214 |
|
|
clock => clk_i,
|
215 |
|
|
clock_enable => '1',
|
216 |
|
|
clear => rst_i,
|
217 |
|
|
x_in => x((4 * i) + 3 downto 4 * i),
|
218 |
|
|
y_in => y((4 * i) + 3 downto 4 * i),
|
219 |
|
|
z_in => z((4 * i) + 3 downto 4 * i),
|
220 |
|
|
bbus_in => bbus((4 * i) + 3 downto 4 * i),
|
221 |
|
|
-- scrolling bbus_out one position upwards
|
222 |
|
|
bbus_out => bbus((4 * i) + 4 downto (4 * i) + 1),
|
223 |
|
|
carry_in => carry(i - 1),
|
224 |
|
|
carry_out => carry(i),
|
225 |
|
|
sum_out => sum_o((4 * i) + 3 downto 4 * i)
|
226 |
|
|
);
|
227 |
|
|
end generate;
|
228 |
|
|
|
229 |
|
|
-- generate the last slice
|
230 |
|
|
last_slice: if i = (num_slices - 1) generate
|
231 |
|
|
slice_i: slice_setup
|
232 |
|
|
generic map(
|
233 |
|
|
input_word_size => (input_word_size + 2) - (i * 4),
|
234 |
|
|
use_output_ff => use_output_ff,
|
235 |
|
|
is_initial_slice => false,
|
236 |
|
|
subtract_y => subtract_y,
|
237 |
|
|
subtract_z => subtract_z
|
238 |
|
|
)
|
239 |
|
|
port map(
|
240 |
|
|
clock => clk_i,
|
241 |
|
|
clock_enable => '1',
|
242 |
|
|
clear => rst_i,
|
243 |
|
|
x_in => x(input_word_size + 1 downto 4 * i),
|
244 |
|
|
y_in => y(input_word_size + 1 downto 4 * i),
|
245 |
|
|
z_in => z(input_word_size + 1 downto 4 * i),
|
246 |
|
|
bbus_in => bbus(input_word_size + 1 downto 4 * i),
|
247 |
|
|
-- scrolling bbus_out one position up
|
248 |
|
|
bbus_out => bbus(input_word_size + 2 downto (4 * i) + 1),
|
249 |
|
|
carry_in => carry(i - 1),
|
250 |
|
|
carry_out => carry(i),
|
251 |
|
|
sum_out => sum_o(input_word_size + 1 downto 4 * i)
|
252 |
|
|
);
|
253 |
|
|
end generate;
|
254 |
|
|
end generate;
|
255 |
|
|
end generate;
|
256 |
|
|
end architecture;
|
257 |
|
|
|
258 |
|
|
--- Definition of the slice_setup component which configures a single slice ---
|
259 |
|
|
|
260 |
|
|
library unisim;
|
261 |
|
|
use unisim.vcomponents.all; -- loading xilinx primitives
|
262 |
|
|
|
263 |
|
|
library ieee;
|
264 |
|
|
use ieee.std_logic_1164.all; -- loading std_logic & std_logic_vector
|
265 |
|
|
|
266 |
|
|
entity slice_setup is
|
267 |
|
|
generic(
|
268 |
|
|
input_word_size : integer := 4;
|
269 |
|
|
use_output_ff : boolean := false;
|
270 |
|
|
is_initial_slice : boolean := true;
|
271 |
|
|
subtract_y : boolean := false;
|
272 |
|
|
subtract_z : boolean := false
|
273 |
|
|
);
|
274 |
|
|
port(
|
275 |
|
|
-- signals for a synchronous circuit
|
276 |
|
|
clock : in std_logic;
|
277 |
|
|
clock_enable : in std_logic;
|
278 |
|
|
clear : in std_logic;
|
279 |
|
|
-- the three addends
|
280 |
|
|
x_in : in std_logic_vector((input_word_size - 1) downto 0);
|
281 |
|
|
y_in : in std_logic_vector((input_word_size - 1) downto 0);
|
282 |
|
|
z_in : in std_logic_vector((input_word_size - 1) downto 0);
|
283 |
|
|
-- the upper entity is mapping the bbus correctly
|
284 |
|
|
-- in initial slice bbus(0) ^= sub / ~add
|
285 |
|
|
bbus_in : in std_logic_vector((input_word_size - 1) downto 0);
|
286 |
|
|
bbus_out : out std_logic_vector((input_word_size - 1) downto 0);
|
287 |
|
|
-- both carrys are for and from the carry chain
|
288 |
|
|
-- in the initial slice use carry_in <= '0' always
|
289 |
|
|
-- sub/add is done by the bbus(0) from the initial slice
|
290 |
|
|
carry_in : in std_logic;
|
291 |
|
|
carry_out : out std_logic;
|
292 |
|
|
-- the sum of the three addends (x_in + y_in + z_in)
|
293 |
|
|
sum_out : out std_logic_vector((input_word_size - 1) downto 0)
|
294 |
|
|
);
|
295 |
|
|
end entity;
|
296 |
|
|
|
297 |
|
|
architecture behavior of slice_setup is
|
298 |
|
|
-- this function returns the lut initialization
|
299 |
|
|
function get_lut_init
|
300 |
|
|
return bit_vector is
|
301 |
|
|
-- defines several lut configurations
|
302 |
|
|
-- for init calculation see "initializing_primitives.ods"
|
303 |
|
|
constant lut_init_no_sub : bit_vector(63 downto 0) := x"3cc3c33cfcc0fcc0";
|
304 |
|
|
constant lut_init_sub_y : bit_vector(63 downto 0) := x"c33c3cc3cf0ccf0c";
|
305 |
|
|
constant lut_init_sub_z : bit_vector(63 downto 0) := x"c33c3cc3f330f330";
|
306 |
|
|
constant lut_init_sub_yz : bit_vector(63 downto 0) := x"3cc3c33c3f033f03";
|
307 |
|
|
variable curr_lut : bit_vector(63 downto 0) := lut_init_no_sub;
|
308 |
|
|
begin
|
309 |
|
|
curr_lut := lut_init_no_sub;
|
310 |
|
|
|
311 |
|
|
if subtract_y then
|
312 |
|
|
curr_lut := lut_init_sub_y;
|
313 |
|
|
end if;
|
314 |
|
|
|
315 |
|
|
if subtract_z then
|
316 |
|
|
curr_lut := lut_init_sub_z;
|
317 |
|
|
end if;
|
318 |
|
|
|
319 |
|
|
if subtract_y and subtract_z then
|
320 |
|
|
curr_lut := lut_init_sub_yz;
|
321 |
|
|
end if;
|
322 |
|
|
|
323 |
|
|
return curr_lut;
|
324 |
|
|
end function;
|
325 |
|
|
|
326 |
|
|
-- calculate how many bits to fill up with zeros for the carry chain
|
327 |
|
|
constant fillup_width : integer := 4 - input_word_size;
|
328 |
|
|
|
329 |
|
|
-- holds the lut configuration used in this slice
|
330 |
|
|
constant current_lut_init : bit_vector := get_lut_init;
|
331 |
|
|
|
332 |
|
|
-- output o6 of the luts
|
333 |
|
|
signal lut_o6 : std_logic_vector((input_word_size - 1) downto 0);
|
334 |
|
|
-- the signals for and from the carry chain have to be wrapped into signals
|
335 |
|
|
-- with a width of four, to fill them up with zeros and prevent synthesis
|
336 |
|
|
-- warnings when doing this in the port map of the carry chain
|
337 |
|
|
-- input di of the carry chain (have to be four bits width)
|
338 |
|
|
signal cc_di : std_logic_vector(3 downto 0);
|
339 |
|
|
-- input s of the carry chain (have to be four bits width)
|
340 |
|
|
signal cc_s : std_logic_vector(3 downto 0);
|
341 |
|
|
-- output o of the carry chain (have to be four bits width)
|
342 |
|
|
signal cc_o : std_logic_vector(3 downto 0);
|
343 |
|
|
-- output co of the carry chain (have to be four bits width)
|
344 |
|
|
signal cc_co : std_logic_vector(3 downto 0);
|
345 |
|
|
begin
|
346 |
|
|
-- check the generic parameter
|
347 |
|
|
assert (input_word_size > 0 and input_word_size < 5) report "a slice with a bit width of "
|
348 |
|
|
& integer'image(input_word_size) & " is not possible." severity failure;
|
349 |
|
|
|
350 |
|
|
-- prepairing singals for the carry chain
|
351 |
|
|
full_slice_assignment: if input_word_size = 4 generate
|
352 |
|
|
cc_di <= bbus_in;
|
353 |
|
|
cc_s <= lut_o6;
|
354 |
|
|
end generate;
|
355 |
|
|
|
356 |
|
|
last_slice_assignment: if input_word_size < 4 generate
|
357 |
|
|
cc_di <= (fillup_width downto 1 => '0') & bbus_in;
|
358 |
|
|
cc_s <= (fillup_width downto 1 => '0') & lut_o6;
|
359 |
|
|
end generate;
|
360 |
|
|
|
361 |
|
|
-- creating the lookup tables
|
362 |
|
|
luts: for i in 0 to (input_word_size - 1) generate
|
363 |
|
|
-- lut6_2 primitive is described in virtex 6 user guide on page 215:
|
364 |
|
|
-- http://www.xilinx.com/support/documentation/sw_manuals/xilinx12_3/virtex6_hdl.pdf
|
365 |
|
|
lut_bit_i: lut6_2
|
366 |
|
|
generic map(
|
367 |
|
|
init => current_lut_init
|
368 |
|
|
)
|
369 |
|
|
-------------------------------------------------------------------
|
370 |
|
|
-- table of names and connections
|
371 |
|
|
-- user guide us 7,274,211 usage in adder
|
372 |
|
|
-- ---------- ------------ --------------
|
373 |
|
|
-- i0 in1 gnd
|
374 |
|
|
-- i1 in2 z(n)
|
375 |
|
|
-- i2 in3 y(n)
|
376 |
|
|
-- i3 in4 x(n)
|
377 |
|
|
-- i4 in5 bbus(n-1)
|
378 |
|
|
-- i5 in6 vdd
|
379 |
|
|
-- o5 o5
|
380 |
|
|
-- o6 o6
|
381 |
|
|
-------------------------------------------------------------------
|
382 |
|
|
port map(
|
383 |
|
|
i0 => '0',
|
384 |
|
|
i1 => z_in(i),
|
385 |
|
|
i2 => y_in(i),
|
386 |
|
|
i3 => x_in(i),
|
387 |
|
|
i4 => bbus_in(i),
|
388 |
|
|
i5 => '1',
|
389 |
|
|
o5 => bbus_out(i),
|
390 |
|
|
o6 => lut_o6(i)
|
391 |
|
|
);
|
392 |
|
|
end generate;
|
393 |
|
|
|
394 |
|
|
-- creating the carry chain
|
395 |
|
|
-- carry4 primitive is described in virtex 6 user guide on page 108:
|
396 |
|
|
-- http://www.xilinx.com/support/documentation/sw_manuals/xilinx12_3/virtex6_hdl.pdf
|
397 |
|
|
initial_slice: if is_initial_slice = true generate
|
398 |
|
|
init_cc: carry4
|
399 |
|
|
-------------------------------------------------------------------
|
400 |
|
|
-- table of names and connections
|
401 |
|
|
-- user guide usage in adder
|
402 |
|
|
-- ---------- --------------
|
403 |
|
|
-- co msb is carry out, rest is not connected
|
404 |
|
|
-- o sum
|
405 |
|
|
-- ci in the initial slice: not connected
|
406 |
|
|
-- cyinit in the initial slice: add / ~sub
|
407 |
|
|
-- di bbus(n-1)
|
408 |
|
|
-- s lut_o6(n)
|
409 |
|
|
-------------------------------------------------------------------
|
410 |
|
|
port map(
|
411 |
|
|
co => cc_co,
|
412 |
|
|
o => cc_o,
|
413 |
|
|
cyinit => '0',
|
414 |
|
|
ci => carry_in,
|
415 |
|
|
di => cc_di,
|
416 |
|
|
s => cc_s
|
417 |
|
|
);
|
418 |
|
|
end generate;
|
419 |
|
|
|
420 |
|
|
further_slice: if is_initial_slice = false generate
|
421 |
|
|
further_cc: carry4
|
422 |
|
|
-------------------------------------------------------------------
|
423 |
|
|
-- table of names and connections
|
424 |
|
|
-- user guide usage in adder
|
425 |
|
|
-- ---------- --------------
|
426 |
|
|
-- co msb is carry out, rest is not connected
|
427 |
|
|
-- o sum
|
428 |
|
|
-- ci carry from previous slice
|
429 |
|
|
-- cyinit in further slices: not connected
|
430 |
|
|
-- di bbus(n-1)
|
431 |
|
|
-- s lut_o6(n)
|
432 |
|
|
-------------------------------------------------------------------
|
433 |
|
|
port map(
|
434 |
|
|
co => cc_co,
|
435 |
|
|
o => cc_o,
|
436 |
|
|
cyinit => '0',
|
437 |
|
|
ci => carry_in,
|
438 |
|
|
di => cc_di,
|
439 |
|
|
s => cc_s
|
440 |
|
|
);
|
441 |
|
|
end generate;
|
442 |
|
|
|
443 |
|
|
-- connect the last used output of the carry chain to the slice output
|
444 |
|
|
carry_out <= cc_co(input_word_size - 1);
|
445 |
|
|
|
446 |
|
|
-- creating the flip flops
|
447 |
|
|
sum_register: if use_output_ff = true generate
|
448 |
|
|
ffs: for i in 0 to (input_word_size - 1) generate
|
449 |
|
|
ff_i: fdce
|
450 |
|
|
generic map(
|
451 |
|
|
-- initialize all flip flops with '0'
|
452 |
|
|
init => '0'
|
453 |
|
|
)
|
454 |
|
|
-------------------------------------------------------------------
|
455 |
|
|
-- table of names and connections
|
456 |
|
|
-- user guide usage in adder
|
457 |
|
|
-- ---------- --------------
|
458 |
|
|
-- clr clear
|
459 |
|
|
-- ce clock_enable, always '1'
|
460 |
|
|
-- d cc_o
|
461 |
|
|
-- c clock
|
462 |
|
|
-- q sum(n)
|
463 |
|
|
-------------------------------------------------------------------
|
464 |
|
|
port map(
|
465 |
|
|
clr => clear,
|
466 |
|
|
ce => clock_enable,
|
467 |
|
|
d => cc_o(i),
|
468 |
|
|
c => clock,
|
469 |
|
|
q => sum_out(i)
|
470 |
|
|
);
|
471 |
|
|
end generate;
|
472 |
|
|
end generate;
|
473 |
|
|
|
474 |
|
|
-- bypassing the flip flops in case of a asynchronous circuit
|
475 |
|
|
bypass: if use_output_ff = false generate
|
476 |
|
|
sum_out <= cc_o(input_word_size - 1 downto 0);
|
477 |
|
|
end generate;
|
478 |
|
|
end architecture;
|