Извиняюсь за длительную паузу. Прием очень простой. Если обоим операндам приписать по одному разряду справа равному '1', то при сложении неизбежно образуется перенос, который сложится со младшим разрядом (точнее, бывшим младшим разрядом) суммы, а т.к. результат самого сложения двух констант, равных '1' никогда использоваться не будет, то Квартус в процессе оптимизации эту ячейку удалит. Да даже если и не удалит, то такой "довесок" в n раз меньше, чем второй сумматор на n разрядов.
signal A : std_logic_vector(n-1 downto 0);
signal B : std_logic_vector(n-1 downto 0);
signal SUM : std_logic_vector(n-1 downto 0); -- SUM = (A + B + 1);
Объявляем промежуточный сигна на один разряд больше.
signal S std_logic_vector(n downto 0);
Тогда
S <= (A & '1') + (B & '1');
SUM <= S(n downto 1);
Кстати, к A+B+m, где m > 1 описанный прием уже не применить.
Предлагаю Вам с этим немного поэкспериментировать на досуге.
Идем дальше. К сожалению, все вышесказанное (не только конкретно в этом сообщении) про сложение не работает для вычитания. Для A-B+1 придется ставить 2 сумматора.
Кроме того, в отличие от A+B, A-B уже не гарантирует '0' в младшем разряде в крайних случаях. Для сложения крайние случаи это когда оба слагаемых либо максимальны, либо минимальны, а для вычитания – когда одна переменная имеет максимальное значение, а другая минимальное. А поскольку '0' не гарантирован, то при отбрасывании младшего разряда при сдвиге вправо ничего страшного не произойдет, а вот при округлении (т.е. прибавлении 1 перед сдвигом) результат может переполнится больше чем на 1 разряд по сравнению с разрядностью исходных переменных.
Пример:
( (-32768) – (32767) + 1 ) >> 1 = (-65535 + 1) >> 1 = -65534 >> 1 = -32767 все в порядке - разность переполнилась на один "законный" разряд, после сложения переполнения не произошло и после деления на 2 все вернулось обратно к 16-ти разрядам.
Теперь другой пример:
( (32767) – (-32768) + 1 ) >> 1 = (65535 + 1) >> 1 = -65536 >> 1 = -32768 фигня получилась - разность переполнилась на один "законный" разряд, а после добавления 1 переполнилась еще раз, превратившись в отрицательное число.
Такое поведение вычитания обусловлено как раз несимметричностью дополнительного кода – модуль максимального числа на 1 меньше модуля минимального. При вычитании, так скажем, самого отрицательного числа

оно меняет знак, станивится положительным и... для его представления нужно уже на 1 разряд больше т.к. оно становится всего на единицу больше максимального положительного числа.
Какие отсюда следуют выводы?
1) избавиться от лишних сумматоров нам удасться лишь для y0_re и y0_im (для случая 2-х Т.Б. еще и y2), где у нас сплошное суммирование. С этим должно быть все понятно.
2) при вычислении y1,2,3 у нас может возникнуть переполнение. Тут нужно учесть, что локально увеличить разрядность мы не можем т.к. это переполнение не устраняется делением на 4 или 2.
Есть 2 варианта:
Первый, увеличить разрядность данных повсеместно на 1 и расширить диапазон значений только на нехватающую 1 т.е. 16-ти разрядные данные сделать 17-ти разрядными, а диапазон сделать от -32768 до +32768. Этот способ очень прост т.к. достаточно 16-ти разрядные данные АЦП расширить знаком до 17-ти разрядных и все.
Второй, это на выходе из АЦП заменять -32768 на 32767. Не очень "честно", но если сохранять разрядность, то "честно" все равно не получится, а резать в бабочке гораздо более затратно по ресурсам ПЛИС.
Что касается оптимизации сумматоров в бабочке, то предлагаю ее сейчас не делать чтобы сохранить легкость чтения кода – этим можно заняться потом. Главное, что на ее примере Вы увидели где и как можно экономить.
Что касается переполнения, то выбирайте, увеличим разрядность или срежем на выходе АЦП?
Вопросы есть?