Продолжим, по-тихоньку. Сейчас написано много кода и, как я уже писал, пора его "причесать" и оформить в проект. Начнем с package. В БПФ у нас есть необходимость выполнять некоторые промежуточные вычисления с "повышенной" разрядностью – поэтому есть необходимость в 2-х операциях расширение знака и извлечение определенных бит (как правило это старшие разряды). Чтобы избежать неудобоваримых выражений вроде
"b_size + w_size - 3 downto w_size – 2" (complex_multiplier) в коде, перенесем их в функции, где они никого с толку сбивать не будут. Напишем 2 простые функции
expand_sign и
get_msb. Добавим в них проверку на корректность параметров. Проверим, что нумерация бит в передаваемом векторе имеет нисходящий порядок ( a
downto b ) и что кол-во бит во входном векторе и результате правильно соотносятся друг с другом.
FFT_Project.rar ( 3.4 килобайт )
Кол-во скачиваний: 177Теперь поработаем над бабочкой. В синхронном дизайне не стоит оставлять регистры без Reset. Регистры без Reset также могут доставить массу неудобств и при моделировании. В начальный момент выходы регистров устанавливаются в неопределенное состояние
'U'. Далее лавинообразно все зависимые цепи также переходят в
'U', причем
'U' имеет приоритет. К примеру,
"0000" and "UUUU" = "UUUU". В результате значительная часть или весь проект быстро переходит в состояние
'U'. Не самое лучшее состояние для анализа

. Выходит проект из этого состояния гораздо медленнее (тривиальные случаи не в счет), чем попадает, что так же не упрощает анализ. Тип сброса (синхронный/асинхронный) следует выбирать исходя из конкретной задачи и платформы для ее решения. Поскольку в нашем случае никаких ограничений нет, то выбираем синхронный сброс.
Посмотрим на нынешний код бабочки:
Код
process (switch, x_sig, y_sig)
begin
if (switch = '0') then
y_sig(0).re <= x_sig(0).re + x_sig(1).re + x_sig(2).re + x_sig(3).re + 2;
y_sig(0).im <= x_sig(0).im + x_sig(1).im + x_sig(2).im + x_sig(3).im + 2;
...
y_reg(0).re <= y_sig(0).re(data_size-1 + 2 downto 2);
y_reg(0).im <= y_sig(0).im(data_size-1 + 2 downto 2);
...
else
y_sig(0).re <= x_sig(0).re + x_sig(1).re + 1;
y_sig(0).im <= x_sig(0).im + x_sig(1).im + 1;
...
y_reg(0).re <= y_sig(0).re(data_size-1 + 1 downto 1);
y_reg(0).im <= y_sig(0).im(data_size-1 + 1 downto 1);
...
end if;
end process;
process
begin
wait until (rising_edge(CLK));
y <= y_reg;
end process;
Чтобы избежать лишних промежуточных регистро ZED разделил код на 2 process – комбинаторный, где производятся все операции и регистровый, где защелкивается результат. В этом случае, упростить код помогает использование variable.
В коде есть копирование в вектор с большей разрядностью с расширением знака:
Код
x_sig(0).re <= (1 downto 0 => x(0).re(b_size-1)) & x(0).re;
x_sig(0).im <= (1 downto 0 => x(0).im(b_size-1)) & x(0).im;
...
и извлечение старших бит:
Код
y(0).re <= y_sig(0).re(b_size-1 + 2 downto 2);
y(0).im <= y_sig(0).im(b_size-1 + 2 downto 2);
...
Для того, чтобы избавиться от множества одинаковых строк с разными индексами мы не ограничимся использованием функций expand_sign и get_msb из FFT_Package. Добавим в Butterfly свои
expand_sign и
get_msb, которые будут вызывать функции из FFT_Package для всех членов complex_data_bus.
FFT_Project.rar ( 3.4 килобайт )
Кол-во скачиваний: 177