acvarif 0 February 6, 2014 Posted February 6, 2014 · Report post Честно говоря, статья "для галочки". Самое главное там не расписано, а как вычислить саму бабочку Вы и так уже знаете. Если вычислять бабочку по конвейерной схеме, как предлагается в статье, и действительно экономить ресурсы, то "выравнивающий" FIFO совершенно лишний. Я Вам как-то писал, что есть преобразование Фурье, есть разные способы его вычисления и каждый из этих способов может иметь множество разных реализаций. Предлагаю Вам поразмыслить над этим. Схемы, которые Вы приводите это способы вычисления, каждый из которых может иметь много вариантов реализации. Схема с замещением (равно как и потоковая) - это лишь один из способов реализации. Суть лишь в том, что есть нечто для хранения входных отсчетов. По мере вычисления ячейки "освобождаются" и могут быть использованы для хранения промежуточных данных и выходных отсчетов. Вам нужно понять в какой момент какие ячейки "свободны" и обобщить это в виде алгоритма коммутации. Таким образом, я считаю, что на данный момент у Вас есть вся необходимая информация и даже уже некоторый положительный опыт, чтобы решить задачу. Дерзайте. Да, небольшой опыт есть. Спасибо Вам. БПФ32 работает. Нареканий нет. Но напрягает довольно большой объем ресурсов. С наскоку все было сделано по своему разумению, не оптимально. Сейчас пытаюсь сделать то же но уменьшив ресурсы ПЛИС. Пока попробую реализовать потоковый БПФ8. Если прокатит и сэкономит ресурсы, по сравнению с тем, что был сделан, то и БПФ32 можно попробовать тем же способом. Код выставлю. Просьба просмотреть бабочку (прореживание по частоте) b_size - 15 w_size - 12 -- бабочка (прореживание по частоте) procedure BUTTERFLY( signal clk : in std_logic; signal a_re : in signed(b_size downto 0); signal a_im : in signed(b_size downto 0); signal b_re : in signed(b_size downto 0); signal b_im : in signed(b_size downto 0); signal w_re : in signed(w_size - 1 downto 0); signal w_im : in signed(w_size - 1 downto 0); signal a_res_re : out signed(b_size downto 0); signal a_res_im : out signed(b_size downto 0); signal b_res_re : out signed(b_size downto 0); signal b_res_im : out signed(b_size downto 0) ) is variable xa_re : signed(b_size downto 0); variable xa_im : signed(b_size downto 0); variable xb_re : signed(b_size downto 0); variable xb_im : signed(b_size downto 0); begin if clk'event and clk = '1' then xa_re := a_re + b_re; xa_im := a_im + b_im; xb_re := a_re - b_re; xb_im := a_im - b_im; a_res_re <= xa_re; a_res_im <= xa_im; b_res_re <= resize((xb_re*w_re - xb_im*w_im), b_size + 1); b_res_im <= resize((xb_re*w_im + xb_re*w_re), b_size + 1); end if; end procedure; Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 7, 2014 Posted February 7, 2014 (edited) · Report post Бабочка работает. В смысле суммирует, вычитает, умножает. Но не понятен один момент: Код b_res_re <= resize((xb_re*w_re - xb_im*w_im), b_size + 1); При вычислении дает странную ошибку Если, например xb_re = 1448 w_re = 724 xb_im = 1448 w_im = -724 Результат на калькуляторе будет 2096704 Если его привести к разрядности менее 16 (например разделить на 64) то получится 32761 А реально данный код дает результат 32320 Разница существенная. Интересно почему? Edited February 7, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 7, 2014 Posted February 7, 2014 · Report post . Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 7, 2014 Posted February 7, 2014 · Report post . Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 7, 2014 Posted February 7, 2014 (edited) · Report post . Информация отсутствует. Прошу подправить. Что означает точка? Edited February 7, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
Sefo 0 February 7, 2014 Posted February 7, 2014 · Report post Бабочка работает. В смысле суммирует, вычитает, умножает. Но не понятен один момент: Код b_res_re <= resize((xb_re*w_re - xb_im*w_im), b_size + 1); При вычислении дает странную ошибку Если, например xb_re = 1448 w_re = 724 xb_im = 1448 w_im = -724 Результат на калькуляторе будет 2096704 Если его привести к разрядности менее 16 (например разделить на 64) то получится 32761 А реально данный код дает результат 32320 Разница существенная. Интересно почему? Очень просто: resize берет указанное количество младших бит. С чего Вы взяли, что она берет старшие биты? 2096704 = 1 1111 1111 1110 0100 0000 32320 = 111 1110 0100 0000 :smile3046: БПФ32 работает. Нареканий нет. Но напрягает довольно большой объем ресурсов. С наскоку все было сделано по своему разумению, не оптимально. Сейчас пытаюсь сделать то же но уменьшив ресурсы ПЛИС. Пока попробую реализовать потоковый БПФ8. Если прокатит и сэкономит ресурсы, по сравнению с тем, что был сделан, то и БПФ32 можно попробовать тем же способом. Код выставлю. Я Вам все же настоятельно рекомендую сначала оптимизировать код вашего БПФ32. Что для этого нужно сделать и с чего начать я уже писал. В вашем случае код занимает много ресурсов не потому что схема БПФ прожорлива по своей природе, а потому что код написан, не обижайтесь, кривее некуда. Поэтому пока Вы не научитесь писать оптимальный код - продуманный, хорошо структурированный - Вы не будете удовлетворены результатами своей работы если будете оценивать их критически. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 7, 2014 Posted February 7, 2014 · Report post Информация отсутствует. Прошу подправить. Что означает точка? значит что написал я какую то глупость, а потом мне стало стыдно и я все стер. А когда глупость пишешь, форум еще как на зло ее 2 раза постит:) Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 8, 2014 Posted February 8, 2014 (edited) · Report post Очень просто: resize берет указанное количество младших бит. С чего Вы взяли, что она берет старшие биты? 2096704 = 1 1111 1111 1110 0100 0000 32320 = 111 1110 0100 0000 Понятно. Спасибо. Я Вам все же настоятельно рекомендую сначала оптимизировать код вашего БПФ32. Что для этого нужно сделать и с чего начать я уже писал.Оптимизацией я займусь. Код действительно не в дугу. Прежде чем приступить пытаюсь осмыслить другие варианты подобных автоматов - типа потоковый БПФ8. Думаю в процессе и появятся мысли для оптипизации. Пока застрял на простейшем многоразрядном сдвиговом регистре (переключатель для потоковой схемы). Тоесть типа procedure SW( signal clk : in std_logic; signal dir : in std_logic; signal a_re : in signed(b_size downto 0); signal b_re : in signed(b_size downto 0); signal a_res_re : out signed(b_size downto 0); signal b_res_re : out signed(b_size downto 0); ) is variable b_sw_re : signed(b_size downto 0); subtype bm_re is signed(b_size downto 0); type mem_bm_re is array(1 downto 0) of bm_re; variable b_s_re : mem_bm_re; subtype am_re is signed(b_size downto 0); type mem_am_re is array(1 downto 0) of am_re; variable a_s_re : mem_am_re; begin b_s_re(0) := b_re; if clk'event and clk = '0' then if dir = '1' then a_s_re(0) := a_re; b_sw_re := b_s_re(1); else a_s_re(0) := b_s_re(1); b_sw_re := a_re; end if; a_s_re(1) := a_s_re(0); b_s_re(1) := b_s_re(0); end if; a_res_re <= a_s_re(1); b_res_re <= b_sw_re; end procedure; Если сделать то же самое но в виде процесса или компонента, а не процедуры, где вместо vaiable можно использовать signal то все сдвигает как и задумано. Не врубаюсь почему variable не работает таже? Edited February 8, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
Sefo 0 February 8, 2014 Posted February 8, 2014 · Report post Понятно. Спасибо. Оптимизацией я займусь. Код действительно не в дугу. Прежде чем приступить пытаюсь осмыслить другие варианты подобных автоматов - типа потоковый БПФ8. Думаю в процессе и появятся мысли для оптипизации. Пока застрял на простейшем многоразрядном сдвиговом регистре (переключатель для потоковой схемы). Тоесть типа Если сделать то же самое но в виде процесса или компонента, а не процедуры, где вместо vaiable можно использовать signal то все сдвигает как и задумано. Не врубаюсь почему variable не работает таже? Вы напрасно в такие дебри полезли. Уже много раз говорил и еще раз повторю: variable в VHDL строго для опытных инженеров - всем остальным стоит забыть про существование variable. Код не работает потому что Вы не понимаете всех тонкостей и подводных камней использования variable. Возвращайтесь к сигналам и забудьте про variable до поры, до времени. Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 10, 2014 Posted February 10, 2014 (edited) · Report post Вы напрасно в такие дебри полезли. Уже много раз говорил и еще раз повторю: variable в VHDL строго для опытных инженеров - всем остальным стоит забыть про существование variable. Код не работает потому что Вы не понимаете всех тонкостей и подводных камней использования variable. Возвращайтесь к сигналам и забудьте про variable до поры, до времени. Понял. Спасибо. Перешел на сигналы. Работает как задумано. Но пока непонятка с бабочкой. Прописал код в матлабе для бпф8 по этому графу На выходе получилась полная ерунда Похоже бабочку я не правильно считаю Поскольку все входные данные комплексные, то на выходе должно быть так A = a + b = (a_re + ja_im) + (b_re + jb_im) = (a_re + b_re) + j(a_im + b_im); B = a - b*w = ((a_re + ja_im) - (b_re + jb_im)) * (w_re + jw_im) = ((a_re - b_re) + j(a_im - b_im))*(w_re + jw_im) = ((a_re - b_re)*w_re - (a_im - b_im)*w_im) + j((a_re - b_re)*w_im + (a_im - b_im) )*w_re) Значит бабочка должна вычисляться так: A_re = a_re + b_re; A_im = a_im + b_im; B_re = (a_re - b_re)*w_re - (a_im - b_im)*w_im; B_im = (a_re - b_re)*w_im + (a_im - b_im) *w_re; Порошу поддтвердить, что все верно. Если верно, буду искать механичекие ошибки в коде матлаб. Пока получилось так: ================================================== Коэффициенты fft8 реал round(cos(2*pi*n/8)*1024) n=0...3 1024, 724, 0, -724, Коэффициенты fft8 мним -round(sin(2*pi*n/8)*1024) n=0...3 0, -724, -1024, -724, ================================================== Входные данные реал FFT8 0, 724, 1024, 724, 0, -724, -1024, -724, Входные данные мним FFT8 1024, 724, 0, -724, -1024, -724, 0, 724, ================================================== Выходные данные st1_re 0, 0, 0, 0, 0, 32761, 0, -32761, Выходные данные st1_im 0, 0, 0, 0, 32768, 0, -32768, 0, ================================================== Выходные данные b_st2_re 0, 0, 0, 0, 0, 0, 0, 0, Выходные данные b_st2_im 0, 0, 0, 0, 0, 0, 524288, -1048352, ================================================== Выходные данные b_st3_re 0, 0, 0, 0, 0, 0, 0, 8388608, Выходные данные b_st3_im 0, 0, 0, 0, 0, 0, 0, 8388608, Все выходные данные после каждой стадии поделены на 64 Edited February 10, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 11, 2014 Posted February 11, 2014 (edited) · Report post Бабокча не работает. Похоже, что схитрить и выполнить за один такт все операции типа b_re_out <= resize(((a_re_in - b_re_in)*w_re - (a_im_in - b_im_in)*w_im), b_size + 1); b_re_out <= resize(((a_re_in - b_re_in)*w_re - (a_im_in - b_im_in)*w_im), b_size + 1); не получается. Не понимаю, что в этом случае нужно делать. Разделять операции вычитания и умножения по разным тактам? Edited February 11, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...
_sda 2 February 12, 2014 Posted February 12, 2014 · Report post Ключевое слово - pipelining. Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 12, 2014 Posted February 12, 2014 · Report post Ключевое слово - pipelining. В атрибутах к entity? Можно подробнее? pipelining это как? Поток? Тоесть первый клок готовит сумму, второй умножает и готовит вторую сумму, третий умножает и готовит.. Quote Share this post Link to post Share on other sites More sharing options...
_sda 2 February 12, 2014 Posted February 12, 2014 · Report post В атрибутах к entity? Можно подробнее? pipelining это как? Поток? Тоесть первый клок готовит сумму, второй умножает и готовит вторую сумму, третий умножает и готовит.. Нужны дополнительные слои регистров для хранения промежуточных результатов. См. ссылки. pipelining ссылка Quote Share this post Link to post Share on other sites More sharing options...
acvarif 0 February 12, 2014 Posted February 12, 2014 (edited) · Report post Нужны дополнительные слои регистров для хранения промежуточных результатов. См. ссылки. pipelining ссылка Спасибо. Понятно. Это значит, что мой номер не пройдет. Тоесть прежде, чем умножить два числа, которые в свою очередь сформировани из разности четерех предшествующих чисел, нужно их подготовить в каком-то промежуточном регистре. Одновременно (по одному клоку) выполнить вычитание и умножение не удастся. И тем не менее симулятор показывает, что все может работать, кроме одного (a - b ) (когда b отрицательное число). Если все числа положительные то код (как ни странно) b_re_out <= resize(((a_re_in + b_re_in)*w_re + (a_im_in + b_im_in)*w_im), b_size + 1); работает по одному клоку. Edited February 12, 2014 by Acvarif Quote Share this post Link to post Share on other sites More sharing options...