Цитата(ZED @ Apr 13 2009, 21:12)

Resize не нужен т.к. мы расширили до 17 разрядов отчсеты и до 12 разрядов поворачивающие множители, убрал...
К сожалению, объяснить отсутствие переполнения только лишь увеличением разрядности недостаточно. Представьте, к примеру, что x_re = 32768, x_im = 32768, w_re = 1024 и w_im = 1024. В этом случае result_im = (x_re *w_im + x_im *w_re)/1024 = 65536 - однозначно переполнение... Здесь дело в свойствах БПФ. Если все реализовано правильно, то точки, поступающие на вход БПФ всегда находятся внутри единичной окружности на комплексной плоскости. Коеффициенты - это точки лежащие на краю единичной окружности ( w_re = cos(a), w_im = sin(a) ). Так что если w_re = 1024, то w_im неизбежно будет = 0. Поворачивающими их называют не случайно - при умножении на них точка всего лишь поворачивается на угол a.
Она никогда не выйдет за пределы этой единичной окружности - это и есть главная причина отсутствия переполнения. Таким образом, если все сделано правильно, то случай x_re = x_im = 32768 исключен так же как и w_re = w_im = 1024.
С record Вы все сделали правильно за исключением ненужных услохнений с именами членов record. Достаточно так:
CODE
type complex_data is record
re: std_logic_vector(b_size - 1 downto 0);
im: std_logic_vector(b_size - 1 downto 0);
end record;
Что касается complex_data_vector / complex_coef_vector, то я имел ввиду следующее:
type complex_data_vector is array (natural range <>) of complex_data;
type complex_coef_vector is array (natural range <>) of complex_coef;
Впрочем, (natural range <>) – это больше для тренировки в освоении языка. При таком задании типа complex_data_vector Вы размерность указываете при использовании. т.е. Вы можете написать
CODE
entity full_butterfly is
port
(
CLK : in std_logic;
switch : in std_logic;
x : in complex_data_vector(3 downto 0);
w : in complex_coef_vector(3 downto 1);
y : out complex_data_vector(3 downto 0)
);
end full_butterfly;
В нашем случае, я, все же, склоняюсь задать размерность жестко. Т.е.
type complex_data_vector is array (3 downto 0) of complex_data;
type complex_coef_vector is array (3 downto 1) of complex_coef;
тогда
CODE
entity full_butterfly is
port
(
CLK : in std_logic;
switch : in std_logic;
x : in complex_data_vector;
w : in complex_coef_vector;
y : out complex_data_vector
);
end full_butterfly;
обратите внимание, что y, являясь выходным сигналом, тоже может быть complex_data_vector.
К сожалению, в record не возможно параметризовать размерность членов (как можно параметризовать размерность самого array) - ее приходится задавать жестко или с помощью констант. Поэтому, что касается внутренних сигналов в бабочке, то ввиду необходимости сделать их на 2 разряда больше не остается ничего другого, как прямо внутри бабочки задать "служебный" тип complex_data_p2_vector:
CODE
architecture beh_butter of butterfly_complex is
type complex_p2 is record
re : std_logic_vector(complex.re'high + 2 downto 0);
im : std_logic_vector(complex.im'high + 2 downto 0);
end record complex_p2;
type complex_data_p2_vector is array (complex_data_vector'range) of complex2;
Выносить его в общий package нет никакого смысла т.к. нигде кроме бабочки он не будет востребован.
В результате вместо замысловатого x.x0.x_re будет x(0).re, что по-моему, весьма читаемо и удобно.
Про память. Т.к. память у нас не тривиальная, то нарисуйте, пожалуйста, блок-схему ее реализации, как Вы ее себе представляете. Могу сразу сказать, что т.к. мы должны вычитывать/сохранять по 4 точки за такт, то без четырех блоков памяти не обойтись, но и 4 блока это далеко не все. Чтобы понять что там еще нужно посмотрите внимательно схему вычисления БПФ.