Перейти к содержанию
    

flipflop и Maverick спасибо за информацию, интересно довольно таки.

 

Во-первых в общем случае Вы никогда заранее не знаете порядок прихода данных и, поэтому, для применимости модуля в разных проектах необходимо предоставить внешнему модулю полное управление памятью. Во-вторых, Вы собирались обрабатывать данные с АЦП - таким образом на вход БПФ данные пойдут по порядку.

Вам нужно сначала заполнить 0-вой банк не трогая остальные и только потом переходить к 1-ому.

Я так понял, что для каждого банка нужно вывести свой WE.

Как дела с ROM для коэффициентов?

Если мы сгенерим Квартусовским визардом, то как мы запихнем ее в ModelSim? А описания применения RAM в качестве ROM на форуме я не нашел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так понял, что для каждого банка нужно вывести свой WE.

 

и ADDR_WR тоже, для общности.

 

Если мы сгенерим Квартусовским визардом, то как мы запихнем ее в ModelSim? А описания применения RAM в качестве ROM на форуме я не нашел.

 

Вообще-то с этим проблем быть не должно - Квартус для Моделсима сгенерирует модель ROM, но даже если, вдруг, и не сгенерирует, то Моделсиму можно самопальную модель подставить. Ведь главное, чтобы на ее ножках было бы тоже самое, что и у плисовского блока, а каким кодом Вы это обеспечите в симуляции не имеет значения - хоть через case.

 

 

Еще у Вас в коде верхнего уровня встречаются использования таких однострочных блоков, как mux.vhd. Я бы их прямым кодом заменил - так, на мой взгляд, проще код читать. Ведь выражение y <= x_1 when sel = '0' else x_2; настолько простое для понимания, что нет никакого смысла его в отдельный блок выделять физически, несмотря на то, что на блок-схеме этом мультиплексор может быть отдельно обозначен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я переделал, файл прикрепляю. Коэффициенты не подставлял.

У меня возникли следующие вопросы по ходу выполнения:

 

1. Выдает Warning:

Warning (14320): Synthesized away node full_butterfly:butterfly|block_multipliers:multipliers|complex_multiplier:mul_3|lpm_mult:Mult1|mult_9g01:auto_generated|le2a[17]"

Не могу понять как его устранить.

 

2. Код

y <= x_1 when sel = '0' else x_2;

Сгенерит Мультиплексор без регистра, а нам по идее нужны мультиплексоры с регистрами.

 

3. Хотел посмотреть на какой частоте работает бабочка, так вот обнаружился странный парадокс. Если на выходе самой бабочки ставить регистры, перед блоком умножителей она работает на частоте 88 МГц, при отсутствии регистров частота 300 МГц:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

use work.fft_pkg.all;

entity butterfly_complex is
    port(CLK: in std_logic;
    switch: in std_logic;
    x: in complex_data_vector;
    y: out complex_data_vector
    );
end entity butterfly_complex;

architecture beh_butter of butterfly_complex is

type complex_p2 is record
    re: std_logic_vector(complex_data.re'high + 2 downto 0);
    im: std_logic_vector(complex_data.im'high + 2 downto 0);
end record complex_p2;

type complex_data_p2_vector is array(complex_data_vector'range) of complex_p2;

signal x_sig: complex_data_p2_vector;
signal y_sig: complex_data_p2_vector;

signal y_reg: complex_data_vector;

Begin --=======================================================

x_sig(0).re <= (1 downto 0 => x(0).re(data_size-1)) & x(0).re;
x_sig(0).im <= (1 downto 0 => x(0).im(data_size-1)) & x(0).im;
x_sig(1).re <= (1 downto 0 => x(1).re(data_size-1)) & x(1).re;
x_sig(1).im <= (1 downto 0 => x(1).im(data_size-1)) & x(1).im;
x_sig(2).re <= (1 downto 0 => x(2).re(data_size-1)) & x(2).re;
x_sig(2).im <= (1 downto 0 => x(2).im(data_size-1)) & x(2).im;
x_sig(3).re <= (1 downto 0 => x(3).re(data_size-1)) & x(3).re;
x_sig(3).im <= (1 downto 0 => x(3).im(data_size-1)) & x(3).im;

--------------------------------------

process (switch, x_sig, y_sig)
begin
    if (switch = '0') then

        -- Вычисление y0
        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;

        -- Вычисление y1
        y_sig(1).re <= x_sig(0).re + x_sig(1).re - x_sig(2).re - x_sig(3).re + 2;
        y_sig(1).im <= x_sig(0).im - x_sig(1).im - x_sig(2).im + x_sig(3).im + 2;

        -- Вычисление y2
        y_sig(2).re <= x_sig(0).re - x_sig(1).re + x_sig(2).re - x_sig(3).re + 2;
        y_sig(2).im <= x_sig(0).im - x_sig(1).im + x_sig(2).im - x_sig(3).im + 2;

        -- Вычисление y3
        y_sig(3).re <= x_sig(0).re - x_sig(1).re - x_sig(2).re + x_sig(3).re + 2;
        y_sig(3).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);
        y_reg(1).re <= y_sig(1).re(data_size-1 + 2 downto 2);
        y_reg(1).im <= y_sig(1).im(data_size-1 + 2 downto 2);
        y_reg(2).re <= y_sig(2).re(data_size-1 + 2 downto 2);
        y_reg(2).im <= y_sig(2).im(data_size-1 + 2 downto 2);
        y_reg(3).re <= y_sig(3).re(data_size-1 + 2 downto 2);
        y_reg(3).im <= y_sig(3).im(data_size-1 + 2 downto 2);

    else
        -- Вычисление y0
        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;

        -- Вычисление y1
        y_sig(1).re <= x_sig(0).re - x_sig(1).re + 1;
        y_sig(1).im <= x_sig(0).im - x_sig(1).im + 1;
        
        
        -- Вычисление y2
        y_sig(2).re <= x_sig(2).re + x_sig(3).re + 1;
        y_sig(2).im <= x_sig(2).im + x_sig(3).im + 1;

        -- Вычисление y3
        y_sig(3).re <= x_sig(2).re - x_sig(3).re + 1;
        y_sig(3).im <= x_sig(2).im - x_sig(3).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);
        y_reg(1).re <= y_sig(1).re(data_size-1 + 1 downto 1);
        y_reg(1).im <= y_sig(1).im(data_size-1 + 1 downto 1);
        y_reg(2).re <= y_sig(2).re(data_size-1 + 1 downto 1);
        y_reg(2).im <= y_sig(2).im(data_size-1 + 1 downto 1);
        y_reg(3).re <= y_sig(3).re(data_size-1 + 1 downto 1);
        y_reg(3).im <= y_sig(3).im(data_size-1 + 1 downto 1);
    end if;
end process;

-- Выходной Регистр:
    process
    begin
        wait until (rising_edge(CLK));
            y <= y_reg;
    end process;
end beh_butter;

 

3. Я походу напутал с адресами для памяти коэффициентов ROM: нужно не

10 downto 0

, а

8 downto 0

 

4. И еще (возможно глупый вопрос), когда мы округляем после суммирования в бабочке, мы фактически делаем так: (A+B+C+D)/4 для 4-х точечной бабочки или (A+B)/2 для 2-х точечной. Так вот, когда мы делим на 4 или на 2 мы не теряем ли часть полезного сигнала? Ведь на вход поступает сигнал+шум, а если отношение С/Ш маленькое мы можем потерять полезную информацию.

Может было проще расширить данные до 32-х знаковыми разрядами и после суммирования не нужно было бы округлять и выбирать разряды.

Так вот вопрос все ли мы делаем правомерно? И как вообще лучше делать?

 

FFT_2048

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. Код
y <= x_1 when sel = '0' else x_2;

Сгенерит Мультиплексор без регистра, а нам по идее нужны мультиплексоры с регистрами.

 

Код в файлах mux.vhd, mux_ADDR.vhd и mux_WE.vhd тоже генерировал мультиплексор без регистров (входной сигнал CLK не использовался). Кроме того нам не все мультиплексоры нужны с регистрами на выходе - см. блок-схему и сообщения по этому поводу.

 

 

 

 

3. Хотел посмотреть на какой частоте работает бабочка, так вот обнаружился странный парадокс. Если на выходе самой бабочки ставить регистры, перед блоком умножителей она работает на частоте 88 МГц, при отсутствии регистров частота 300 МГц

 

В такие чудеса я не верю, поэтому скорее всего, убрав регистры Вы вообще ничего не подали на выход бабочки и 95% проекта была выкинута Квартусом. Оставшаяся часть была блоком управления, для которого 300 МГц не проблема.

 

Код приведенный в сообщении и в проекте отличаются. Раньше у Вас проект был для Stratix, а теперь для APEX20 - совсем не подходящая ПЛИС для ЦОС, да и вообще не для новых проектов.

 

Ваш проект для APEX у меня дал 38 МГц с регистрами на выходе бабочки и 24 МГц без регистров - никаких чудес.

 

Определитесь с ПЛИС, плиз :) Возьмите хотя бы Цыклон - нам нужна нормальная память и DSP блоки.

 

3. Я походу напутал с адресами для памяти коэффициентов ROM: нужно не
10 downto 0

, а

8 downto 0

 

Угу, и со счета сбились :) - 3-тий пункт уже был.

 

4. И еще (возможно глупый вопрос), когда мы округляем после суммирования в бабочке, мы фактически делаем так: (A+B+C+D)/4 для 4-х точечной бабочки или (A+B)/2 для 2-х точечной. Так вот, когда мы делим на 4 или на 2 мы не теряем ли часть полезного сигнала? Ведь на вход поступает сигнал+шум, а если отношение С/Ш маленькое мы можем потерять полезную информацию.

Может было проще расширить данные до 32-х знаковыми разрядами и после суммирования не нужно было бы округлять и выбирать разряды.

Так вот вопрос все ли мы делаем правомерно? И как вообще лучше делать?

 

Точность это всегда болезненная тема. В бабочке мы фактически делаем не так как Вы написали а так: (A+B+C+D)/4 + 0.5. Это округление, а не отбрасывание дробной части. Правильнее говорить об ухудшении отношения С/Ш. Увеличение разрядности до 32 Вам не поможет - Вы забыли про комплексные умножители, где мы тоже берем не все разряды. А при умножении, между прочим, разрядность увеличивается в 2 раза, а не на 2 разряда. Ту не помогут даже 320-ти разрядные числа :(

 

Рекомендую перечитать сообщения по этому вопросу в данной (и не только) теме. Когда все заработает так как спроектировано сейчас, тогда и будете думать что улучшить, а что и так удовлетворяет потребности.

 

И как вообще лучше делать?

 

Не инженерная постановка вопроса :) Можно арифметику с плавающей точкой вставить - точность повысится, ресурсы возрастут, а в результате окажется, что для решения задачи достаточно было не 16-ти разрядного АЦП, а 8-ми разрядного и при вычислениях в бабочке и умножителях даже округлять не надо, а достаточно просто отбрасывать дробную часть и т.д. и т.п.

 

Поскольку из-за нехватки времени я от Вас теперь явно отстаю и уже даже имею "долги" придется Вам набраться терпения. Сорри.:(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел я ваш код внимательно и вот какие ошибки там обнаружились:

 

Входной и выходной вращатель абсолютно одинаковые. Это не правильно. Я уже объяснял в чем между ними разница, поэтому, пожалуйста, найдите эти объяснения в теме и исправьте код выходного вращателя.

 

Далее про логику управления.

 

Сигналы управление обоими вращателями приходят раньше положенного времени. Например управление входным вращателем синхронно с адресом чтения данных, а должно быть на 1 такт позже него. Собственно говоря, задержки сигналов управления мной были расписаны на временной диаграмме, да и на блок-схеме БПФ они также хорошо видны. Могли бы и сами проверить соотношения.

 

Сигналы SEL_MUX_IN и STOP не работают. Сигнал STATE работает не правильно.

 

Сигналы разрешения записи WE_1 и WE_2 работают не правильно. Сейчас у Вас в любой момент времени один из них обязательно активен, но запись происходит не постоянно. Между каждым этапом обязательно есть пауза в записи. Когда БПФ записывает последний набор точек с предыдущего этапа начинается новый этап и вот тут оба сигнала записи д. б. деактивированы т.к. в самом начале нового этапа нам еще нечего записывать - результаты будут готовы только через несколько тактов, пока первые данные, прочитанные из памяти на новом этапе пройдут весь тракт обработки и появятся на входе памяти на запись.

 

Ну и наконец, на последнем этапе у Вас БПФ стоит наглухо. Таким образом, результатов Вам не видать.

 

Как и обещал, прилагаю свою версию блока управления БПФ. В ней хоть и больше строчек, чем в вашей, но, на мой взгляд, она более читаема и значительно проще поддается модификациям, чем ваша. В частности, чтобы "подвинуть" любой сигнал управления необходимо лишь поменять константу, определяющую его задержку.

 

FFT_Control.rar

 

Еще мы с вами, "забраковав" реализацию блока управления с помощь CASE, не разобрали одно существенное преимущество нынешнего подхода. Нынешняя архитектура блока управления обладает хорошей масштабируемостью - как статической, так и динамической.

 

Статическая масштабируемостью означает, что всего лишь изменив разрядность сигналов вы получите код БПФ для другого количества точек. Конечно, и в Ваш код и в мой нужно внести некоторые изменения чтобы было удобно перестраивать управление БПФ, но они весьма незначительные. Разрядности всех сигналов должны быть заданы через константы, которые вычисляются отталкиваясь от какой-нибудь базовой константы изменение которой и перестраивает всю логику управления на новое количество точек. Еще нужно проконтролировать, чтобы начальные значения задавались способом, который дает правильные результаты независимо от разрядности.

 

Динамическая масштабируемостью означает, что если в блок управления передавать извне начальные значения, то вы сможете менять количество точек БПФ прямо на лету. Разумеется, что разрядности всех сигналов должны быть заданы на этапе синтеза исходя из максимального количества точек. Изменения кода для динамического управления кол-вом точек так же достаточно просты в выбранной на данный момент архитектуре блока управления.

 

А вот в случае использования CASE реализация статической масштабируемости весьма затруднительна, а динамической практически невозможна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При компиляции Warning:

Warning (10036): Verilog HDL or VHDL warning at FFT_Control.vhd(54): object "BIC_WR_ENABLE_p1" assigned a value but never read

.

 

А так очень порадовало, что константы в package вынесены, очень удобно. пока буду дальше разбираться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При компиляции Warning:

Warning (10036): Verilog HDL or VHDL warning at FFT_Control.vhd(54): object "BIC_WR_ENABLE_p1" assigned a value but never read

.

 

BIC_WR_ENABLE_p1 на самом деле лишний сигнал. Видимо, когда прикидывал какие сигналы потребуются, решил, что он будет нужен, а когда код написал, то забыл удалить за ненадобностью.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Если можно напишите по подробнее про сигнал ENABLE_d. Хитрая такая задумка... Я вроде так понимаю, но не уверен, что до конца.

Вот как я понимаю: Это фактически сдвиговый регистр, при начале этапа мы записываем в него '1' на каждом такте, а в конце '0'. Таким образом формируя с какого триггера (этого регистра) считывать (constant Addr_Rd_Dly и т.д) мы формируем сигналы разрешения (ADDR_RD_ENABLE и т.д.).

2) BIC это я так понял пометка вращателя, а можно спросить почему именно BIC? ну так для лучшего восприятия? Также интересно узнать смысл обозначений fr, fc, f, ro i, c, dи т.д.

3)И еще, а что там за комментарий -- 517?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) BIC это я так понял пометка вращателя, а можно спросить почему именно BIC? ну так для лучшего восприятия? Также интересно узнать смысл обозначений fr, fc, f, ro i, c, dи т.д.

 

BIC это первые буквы от Block_Interval_Counter. Просто даже длина имени BLOCK_INTRVL_CNTR_xx уже на грани адекватной, а BLOCK_INTRVL_CNTR_xx_ENABLE эту грань пересекает, а самое главное, на мой взгляд, перестает "читаться". При беглом просмотре кода уже очень сложно отличить основной BLOCK_INTRVL_CNTR_xx от его "разрешающего" сигнала. Посмотрел свежим взглядом код и пришел к выводу, что это пример совсем неудачного названия, т.к. сам счетчик блоков у нас вообще виртуальный (в том смысле, что значение счетчика собирается из значений других сигналов) и BIC_xx_ENABLE к BLOCK_INTRVL_CNTR_xx вообще не имеет никакого отношения. Так что, Вы правы, что не восприняли этот сигнал.

 

Суффикс f означает флаг. fc - комбинаторный, fr - регистровый. Это, собственно говоря, все к вопросу о кодовых стандартах. Помнится, такая тема на форуме уже поднималась. Я флагами называю те сигналы, которые всего лишь отражают истинность или ложность какого-либо одного условия и, что очень важно, строго следуют за изменением истинности/ложности условия. Например, сигнал ENABLE этим критериям не отвечает т.к. он не отражает истинность какого-либо одного условия - он по одному условию устанавливается в 1, а по другому сбрасывается в 0. Он как раз использует флаги - по одному флагу устанавливается в 1, а по другому сбрасывается. Комбинаторный флаг отражает истинность условия синхронно ("мгновенно"), а регистровый с задержкой на один(несколько) такт(ов). Использование комбинаторных флагов дает более медленный код, но зато с ними проще работать. Использование регистровых флагов дает более быстрый код, но работать с ними сложнее - в случаях, когда задержка недопустима и регистровый флаг должен отражать истинность условия синхронно с ним требуется предсказание истинности условия за 1 такт, что, иногда, представляется затруднительным или невозможным.

 

Входные и выходные сигналы я всегда помечаю постфиксом i и o соответственно. r означает регистровый, c - комбинаторный. Соответственно SIGNAL_ro - это выходной сигнал, "взятый" с регистра, а SIGNAL_co - выходной сигнал, формируемый комбинаторной логикой.

 

d (delayed) я использую для обозначения задержанных копий. Есть три варианта. 1) пара SIGNAL и SIGNAL_d(n downto 1) т.е. основной и его копии, задержанные на 1 ... n тактов. 2) SIGNAL и SIGNAL_d1, SIGNAL_d2 ... 3) SIGNAL_d(n downto 0) т.е. основным является SIGNAL(0). Выбор зависит от того какой удобнее в конкретной ситуации.

 

p, соответственно, обозначает сигналы предшествующие n тактов основному.

 

Выбор между постфиксами p и d делается исходя их смысла кода.

 

a - асинхронный, s - синхронный (т.е. RESETsn - синхронный сброс)

 

Чтобы постфиксы и суффиксы не сливались с самим именем сигнала я имя сигнала всегда пишу большими буквами, а суффиксы и постфиксы - маленькими и часто отделяю _.

 

В синхронном дизайне внутри модуля все сигналы по умолчанию я считаю регистровыми и помечаю только комбинаторные постфиксом c. Весьма полезно - хорошо обнаруживает длинные цепочки комбинаторной логики понижающие тактовую частоту. Иногда замечаешь их еще во время написания кода до синтеза. Ну а если до синтеза не обратил внимания и увидел только в отчете, то значительно легче эту цепочку проследить и проанализировать, чем без постфикса с.

 

Кроме того, постфиксы i и o автоматически устраняют то неудобство, что в VHDL выходной сигнал не может участвовать в выражениях в качестве источника данных - ему можно только присваивать.

 

1) Если можно напишите по подробнее про сигнал ENABLE_d. Хитрая такая задумка... Я вроде так понимаю, но не уверен, что до конца.

Вот как я понимаю: Это фактически сдвиговый регистр, при начале этапа мы записываем в него '1' на каждом такте, а в конце '0'. Таким образом формируя с какого триггера (этого регистра) считывать (constant Addr_Rd_Dly и т.д) мы формируем сигналы разрешения (ADDR_RD_ENABLE и т.д.).

 

3)И еще, а что там за комментарий -- 517?

 

На эти вопросы отвечу чуть позже.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Если можно напишите по подробнее про сигнал ENABLE_d. Хитрая такая задумка... Я вроде так понимаю, но не уверен, что до конца.

Вот как я понимаю: Это фактически сдвиговый регистр, при начале этапа мы записываем в него '1' на каждом такте, а в конце '0'. Таким образом формируя с какого триггера (этого регистра) считывать (constant Addr_Rd_Dly и т.д) мы формируем сигналы разрешения (ADDR_RD_ENABLE и т.д.).

 

Вы правильно поняли принцип, но я немного придерусь к сказанному Вами. Интерпретация, что мы записываем в него '1' на каждом такте неверна. Это действительно сдвиговый регистр. Нулевой бит "задает" форму сигнала, а все остальные ее повторяют с соответствующей задержкой. Что касается нулевого бита, то мы лишь в двух тактах изменяем его значение. При активном флаге fr_START_OF_STAGE мы устанавливаем его в '1', а при активном fr_END_OF_STAGE мы сбрасываем его в '0'. В течение всех остальных тактов мы его не трогаем и он просто сохраняет последнее свое состояние.

 

post-7537-1264367323_thumb.png

 

3)И еще, а что там за комментарий -- 517?

 

На самом деле полное время вычисления одного этапа составляет 519 тактов (0…518). На временной диаграмме в сообщении

список сигналов заканчивается адресом записи. Надо еще учесть, что сама память запомнит поданные на нее данные только на следующем такте. Таким образом, если этапы совсем по-честному разделять, то диаграмма будет следующей:

post-7537-1264367358_thumb.png

 

Но учитывая, что даже если мы на следующем такте попытаемся прочитать данные, записанные по адресу AW511, мы получим правильные данные (D511) нам не обязательно ждать целый такт. А если учесть, что адрес чтения формируется с задержкой на 1 такт от начала этапа, то получается, что мы можем наложить этапы друг на друга на 2 такта. Значение 517 дает честное разнесение этапов во времени, а значение 515 обеспечивает безопасное перекрытие этапов.

post-7537-1264367366_thumb.png

 

Подобные вещи нужно делать осознанно, чтобы в случае каких-то изменений (типа памяти, например) сразу понимать, что теперь перекрытие не прокатит и здесь нужно честно разнести этапы.

Пара замечаний про флаги. Поскольку флаг fr_START_OF_STAGE регистровый, то нам, как раз, нужно предсказать его значение за 1 такт . В данном случае это делается просто т.к. мы ориентируемся на значение непрерывно инкрементирующегося счетчика. Это гарантирует, что значению 516 будет всегда предшествовать значение 515. В синхронном дизайне практически везде стробы вроде START становятся активными за такт, до реального начала. Стробы типа END активны в самый последний такт, а не за такт до конца. Это достаточно удобно. В моем коде именно так: fr_START_OF_STAGE - за такт до начала этапе, а fr_END_OF_STAGE активен в последний такт этапа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот, выдалась свободная минутка, прикрепляю собранный проект пока без коэффициентов ROM:

http://webfile.ru/4281201

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот, выдалась свободная минутка, прикрепляю собранный проект пока без коэффициентов ROM:

http://webfile.ru/4281201

 

Я не нашел никаких исправлений, касающихся вращателей, о которых я писал 7 января. Входной и выходной по-прежнему одинаковые. Без правильного выходного вращателя ничего не выйдет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, совсем забыл, вот поправил: http://webfile.ru/4286215

 

P.S. Что-то у меня сюда не хотят файлы заливаться...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то затихло это Великое Дело? :(

 

Кстати вопрос, а почему такие формулы вычисления гармоник?

--

-- -- Вычисление y1

-- y_sig(1).re <= x_sig(0).re + x_sig(1).re - x_sig(2).re - x_sig(3).re + 2;

-- y_sig(1).im <= x_sig(0).im - x_sig(1).im - x_sig(2).im + x_sig(3).im + 2;

 

а не такое:

--

-- -- Вычисление y1

-- y_sig(1).re <= x_sig(0).re + x_sig(1).im - x_sig(2).re - x_sig(3).im + 2;

-- y_sig(1).im <= x_sig(0).im - x_sig(1).re - x_sig(2).im + x_sig(3).re + 2;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати вопрос, а почему такие формулы вычисления гармоник?

Да, все верно, спасибо за замечание!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...