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

EvgenyNik

Свой
  • Постов

    592
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные EvgenyNik


  1. и как с этим бороться?
    Как выше подсказали - попробовать подгрузить выход драйвера.

    Встретился мне как-то (давно ещё) такой случай, когда вместо обычного шинного формирователя (АП5, АП6, 244, 245) поставили какой-то очень быстрый и на шине данных стали возникать ошибки. Оказалось всё просто - сигналы RD и WR приобрели излишнюю колебательность и как бы поступали дважды на управляющие входы.

  2. внутренней памяти fpga для обработки данных не хватает, поэтому было решено задействовать оставшуюся память флешки (сейчас стоит epcs16)
    А Вы её для хранения и считывания констант хотите использовать? А то из текста можно подумать, что в качестве ОЗУ.
  3. Если допустить, что аналоги имеют иное значение конфигурационных ячеек, нежели исходные чипы, то логично запросить у производителя. Но компилятор то чей? Если забугорный, то он просто не сможет генерировать "дополнительные биты" и тогда всё стандартно.

    А гадать по начинке кристалла бессмысленно. В комнате 2 светильника по 5 плафонов - сколько клавиш у выключателя? :)

    К тому же, если не включать компрессию, то возможно, файл всегда создаётся максимального размера. Это надо проверить. Загрузочный автомат же может быть очень тупым - перекидал n бит и остановился.

  4. Можно и RC фильтром преобразовать в аналоговый сигнал и подать на АЦП.
    Можно. Но сначала надо решить вопрос с требуемой точностью. Результат на выходе фильтра будет зависеть не только от заполнения ШИМ, но и от амплитуды генератора, а та, в свою очередь, может зависеть не только от стабильности источника питания, но и от напряжения на конденсаторе фильтра (если выход слабый).

    Опять же, автор не указал - насколько быстро меняется заполнение во времени. Фильтр даст усреднённое значение, фактически, за несколько периодов. А вдруг, у него ШИМ генерирует сложный процесс и ему нужен каждый период.

  5. Приходится угадывать, конечно... Шина, случаем, не 5В?

    Сталкивался с похожей ситуацией, когда в результате ошибного подключения через пин попадало повышенной напряжение на локальное питание ПЛИС, отчего это питание задиралось и часть логических сигналов просто "проваливались" ниже уровня единицы, т.к. недотягивали.

    Есть ещё вариант - всплески напряжения в шине при коммутациях, которые теоретически могут приводить ко всякого рода защёлкиваниям.

  6. а у вас недурная подпись в сообщениях :) так почему?
    Ага. Потому что, имея ТЗ на коловорот и подключив всё своё представление о том как бывает плохо, когда что-то не учтено, изобретают дрель с вентильным движком :)

    RobFPGA слушать надо :) , дело говорит :)
    А я с тем, что он говорит и не спорю.

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

    MegaVolt, а Вы можете написать - в каких пределах могут быть clk1 и clk2?

  7. Надеюсь, что будет понятно в продолжение о двух счётчиках, сама идея:

    Простой пример (clk1 < clk2)

    У нас бегущий секундомер натикивает за 5 секунд значение 7.

    Но мы то знаем (по синхросигналу), что должно быть 5.

    Делим 7/5=1.4.

    Происходит 1ый тик нашего неточного генератора, суммируем

    0+1 = 1, это меньше чем 1.4, поэтому счёт вычисленных тиков пока 0.

    Происходит 2ой тик, суммируем:

    1+1 = 2, что более, чем 1.4, поэтому вычитаем 2-1.4=0.6 и увеличиваем счётчик вычисленных тик 0+1 = 1

    3ий:

    0.6+1=1.6, 1.6-1.4=0.2, вычисленный 1+1=2

    4ый:

    0.2+1=1.2, вычисленный сохраняем 2

    5ый:

    1.2+1=2.2, 2.2-1.4=0.8, вычисленный 2+1=3

    6ой:

    0.8+1=1.8, 1.8-1.4=0.4, вычисленный 3+1=4

    7ой:

    0.4+1=1.4, 1.4-1.4=0 (сошлось!), вычисленный 4+1=5 (тоже получили что надо)

    Таким образом, мы на 7 тиках вычислили 5 требуемых с каким-то более-менее равномерным распределением.

    Другой случай (clk1 > clk2)

    Тоже самое, но сейчас наш секундомер отстаёт и за 5 секунд натикивает всего 3.

    Делим 3/5 = 0.6

    1ый тик: 0+1 = 1, что больше чем 0.6, поэтому считаем 1, разница 1-0.6=0.4

    2ой тик: 0.4+1 = 1.4, что более, чем 0.6, поэтому 1+1 = 2, разница 1.4-0.6=0.8, что снова больше, чем 0.6, значит считаем 2+1=3, остаток 0.8-0.6=0.2

    3ий тик: 0.2+1 = 1.2, 3+1=4, 1.2-0.6=0.6, 4+1=5, 0.6-0.6=0.

    Снова сошлось: за 3 тика насчитали 5.

    ---

    Разница в том, что на ПЛИСке один из счётчиков (тот, на чьё значение надо делить) удобно сделать с фиксированным порогом счёта до числа равно двум в некой целой степени, чтобы делить простым сдвигом.

  8. Пропуски и повторы допустимы если они вызываны разностью частот. И не допустимы если они вызваны тормозами синхронизатора.

    Интересует решение и для второго случая когда clk1 > clk2

    А если так:

    1. В домене clk2 создаём счётчик cnt2 (пусть от 0 до 127)

    2. В домене clk1 создаём счётчик cnt1, разрядность которого позволяет с некоторым запасом не "кувыркнуться" через ноль, пока счетчик (cnt2) досчитает до 127

    3. При достижении счётчиком cnt2 значения 127, сбрасываемся в 0 и формируем запрос в домен clk1 о передаче значения cnt1.

    4. Получив запрос, счётчик cnt1 пересылает своё значение и сбрасывается в 0.

    5. Таким образом, мы получаем какое количество тактов clk1 накапливается в счётчике cnt1 за время, пока счётчик cnt2 считает интервал в 128 тактов clk2.

    6. Представив это значение в формате с фиксированной точкой мы получаем масштабный коэффициент, позволяющий вести эквивалентный счёт от тактов clk2 с представлением времени в домене clk1 в течении следующего интервала, пока не произойдёт обновление информации.

    Пример:

    cnt2 пробежал интервал в 128 тактов clk2, присланное значение cnt1 = 2309 clk1

    Считаем 7 младших бит - дробной частью, тогда в десятичных получаем cnt1/cnt2 = 18,0390625.

    Теперь на каждый такт clk2 мы прибавляем к образе cnt1 значение 18,0390625:

    18,0390625, 36,078125 и т.д.

    На следующем интервале cnt1 покажет число 2314, к примеру, и мы скорректируем наш масштабный коэффициент.

  9. Это я так понял запрос ответ с синхронизацией. Многовато кодов пропускает :(
    Да, это запрос-ответ. Но и

    Для однобитного счётчика это позволяет реализовать обычный синхронизатор правда при условии что первая частота меньше второй.
    работало бы на такой же "скорости обмена".

    Чтобы пропускало меньше кода надо для счёта использовать не саму частоту тактирования, а поделенную на 2..4.

  10. FIFO не подойдёт, т.к. подразумевается разница частот, а значит буфер или переполнится или будет пустым.

    module cnt_copy
    (    input    clk1,
         input    clk2,             
         output reg    [7:0]    cnt1,
         output reg    [7:0]    copy2 );
    reg    ready1 = 0;
    reg    ready2 = 0;
    reg    ready1_l1, ready1_l2;
    reg    ready2_l1, ready2_l2;
    reg    [7:0]    cnt1_l;
    always @ (posedge clk1)
         begin
         ready2_l1 <= ready2; ready2_l2 <= ready2_l1;
         cnt1 <= cnt1 + 1;
         if (ready2_l2)
             begin
             if (~ready1)
                 begin
                 cnt1_l <= cnt1;    ready1 <= 1'b1;
                 end
             end
         else
             begin
             ready1 <= 1'b0;
             end
         end    
    always @ (posedge clk2)
         begin
         ready1_l1 <= ready1;    ready1_l2 <= ready1_l1;    
         if (ready1_l2)
             begin
             if (ready2)
                 begin
                 copy2 <= cnt1_l; ready2 <= 1'b0;
                 end
             end
         else
             begin
             ready2 <= 1'b1;
             end
         end
    endmodule

    Результат

    post-17402-1445340651_thumb.png

    Указать таймбара стоит, как раз, на моменте, начиная с которого происходит передача значения "3". Далее тоже видно как передаются значения. С пропусками из-за синхронизации, но без искажения передаваемого значения.

  11. У MAX 10 есть на борту PLL. У него есть выход Locked. Даже если Вам "услуги" PLL не нужны, то можно завести клок на него только ради этого сигнала, чтобы обеспечить начальный сброс регистров в исходное положение стандартными средствами (подобие ресета).

    Не факт, что в дальнейшей поддержке не придётся в угоду фиттеру играться с настройками компилятора. Обнаружите, к примеру, что с галочкой Ignore initial проект весит меньше, обрадуетесь. И только когда-нибудь где-нибудь вылезет некорретная работа.

  12. Ток всего 2 миллиампера - но почему так мало? LVTTL не многим лучше - даже до 16 ма не дотягивает :(

    Насколько я понимаю - это не ошибка, и 3.3 вольтовые драйвера очень слабые?

    Первая мысль, которая возникла - ограничивают мощность на выходе (потому и на более низком TTL ток можно развить выше). Но величина 16мА уже на 3.0В указывает, что дело не просто в ограничении мощности.

    Вероятно, дело в том, что последние поколения ПЛИС всё хуже и хуже справляются с перенапряжением (пусть и кратковременным) на выводах. И чтобы не создавать перенапряжения при коммутациях в области уровней, близких к критическим, ток там ограничивается.

    Как-то убил Циклон, вогнав в резонанс RLC-нагрузку на выходе 24МГц. На живом другом глянул - примерно 6В в амлитуде от выхода 3.3! Снизил ток в порядке эксперимента - помогло.

    А вообще, от силового применения выходных каскадов ПЛИС надо уходить.

    Встроенный осциллятор тоже расстроил - генерирует частоту в диапазоне 55-116 МГц, без возможности выбрать более точное значение.
    У MAXII/V тоже разброс был неслабый 3.33-5.66МГц. Для простых вещей хватает. Кстати, если есть некий внешний периодический низкочастотный сигнал, то при расположенности к искусственным трудностям :), можно заделать цифровую подстройку, потратив десятков 5-7 логических ячеек.
  13.     always    @ (negedge clk)
             begin
             if (stage_r == 0)    wramag_r <= 1; // это нужно, чтобы избавиться от глитча при возврате из режима записи (см. формирование wram_o)
             else    wramag_r <= 0;
             end

    Подскажите вот это как в граф редакторе на триггере реализовать?

    Фактически, здесь написано: всегда при отрицательном фронте clk присваивать wramag=1, если stage равен 0 и, если иначе, то обнулять этот wramag.

    Так и делаем:

    1. инвертируем clk (надо же по отрицательному фронту защёлкивать) и подаём на тактовый вход DFF

    2. биты stage заводим на ИЛИ-НЕ и подаём на вход данных D

    3. защёлкивам в DFF

    4. снимаем результат с Q

    post-17402-1443602365_thumb.jpg

    p.s. А зачем Вам манипуляции с OE и CS? Если используется один чип памяти и его порты работают через ПЛИС, то пусть по умолчанию всегда будет выбран и всегда в режиме выдачи данных с текущего адреса. Ему (чипу ОЗУ) всё равно, а Вам - экономия ресурсов на ПЛИСке.

  14. Спасибо. Понятно. Думал за 1 такт можно ухитриться, но видать нет (

    Попытка - не пытка.

    post-17402-1443509406_thumb.jpg

    module sram
    #(    parameter wdata = 8,
        parameter waddr = 10    )
    (    input clk,
        input    [waddr-1:0]    ara_i, arb_i, awa_i,
        input    [wdata-1:0] dw_i,
        output    reg    [wdata-1:0]    da_or, db_or,
        inout    [wdata-1:0]    dram_io,
        output    reg    [waddr-1:0]    aram_or,
        output    oeram_o,
        output    wram_o,
        output    reg    dataready_or
    );
        assign    oeram_o = 0;
        assign    dram_io = (we_r ? rwram : {waddr{1'bz}});
        assign    wram_o = (we_r ? ~clk | wramag_r : 1'b1);
    
        reg    [wdata-1:0] rwram;
        reg    we_r;
        reg    wramag_r;
        reg    [1:0]    stage_r;
        
        always @ (posedge clk)
            begin
            if (stage_r == 2'b10)    stage_r <= 0;
            else    stage_r <= stage_r + 1;
            
            case    (stage_r)
                2'b00:    begin
                        aram_or <= ara_i;
                        we_r <= 0;
                        dataready_or <= 0;
                        end
                2'b01:    begin
                        aram_or <= arb_i;
                        da_or <= dram_io;
                        rwram <= dw_i;
                        end
                2'b10:    begin
                        aram_or    <= awa_i;
                        db_or <= dram_io;
                        we_r <= 1;
                        dataready_or <= 1;
                        end
            endcase
            end    
            
        always    @ (negedge clk)
            begin
            if (stage_r == 0)    wramag_r <= 1; // это нужно, чтобы избавиться от глитча при возврате из режима записи (см. формирование wram_o)
            else    wramag_r <= 0;
            end
    endmodule

    С времянками, конечно, получается вольно и лишь бы сама ОЗУшка успевала.

  15. Повторюсь: возможно, я чего-то не понял.
    Возможно. Потому что сейчас не понял я :biggrin:

    Покажу с помощью "наскальной живописи".

    post-17402-1443184376_thumb.jpg

    Вот результат подачи ступеньки на режекторный фильтр. Вырезанная часть специально приподнята к средней линии.

    Фактически, если сложить то, что вырезано с тем, что осталось, то получится исходный сигнал (за вычетом округлений, т.к. в процессе фильтрации приходится разрядность увеличивать в "дробную сторону", а потом возвращать обратно округлением, и прочего по-мелочи навроде ограничения от выходов в минус и за пределы разрядности вверх), естественно, смещённый по времени.

    Однако, если задача поставлена - оставшиеся компоненты поместить в те позиции, где они были, то фронт получившегося отклика мы подтаскиваем к фронту исходного и вот теперь виден "хвост до собаки" :)

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

    Но смотрите, вот какой пример. У нас есть некий массив с последовательностью, описывающей мгновенные значения многокомпонентного сигнала. Задача - вырезать какую-то частоту, сохранив для остальных одинаковое время групповой задержки. Создаём режекторный фильтр. Прогоняем через него массив и (а вот это важно!) складываем результат так, чтобы оставшиеся компоненты легли по тем же местам, где находились до режекции. Результат - из прежней последовательности удалена ненужная компонента, а остальное не тронуто.

    Что ожидаемо, но, всё равно, интересно - если из исходного массива поточечно вычесть новый, то получится вырезанная компонента. Причём, иногда таким "косвенным" способом её получается выделить даже лучше, чем полосовым фильтром.

    Понятно, что такое возможно только в отложенном времени. И даже когда делается налету, то только через буферизацию.

    Однако, если если в этот алгоритм подсунуть ступеньку, то будет то, о чём я писал ранее - реакция появится "ранее".

  17. Надо понимать, что не зная частоты, считать сколько периодов сигнала имеется в наличии весьма интересный подход из разряда "если сейчас из ямы не вылезу - побегу домой за лестницей")))
    ТС в середине темы уточнил:

    Речь идет об электрораспределительной сети.

    В сети всегда есть основная гармоника и гармоники до 13-й, но основная всегда около 50 Гц, например 45-55 Гц.

    А это значит, что примерно, всё-таки, известно. Более того, более-менее стандартны интервалы времени, на которые энергосистема может вываливаться на величину конкретного отклонения.
  18. Правильный ответ таков: отклик идеального фильтра на любое воздействие наступит раньше (Sic!) этого самого воздействия.
    Так же, как и при разложении в ряд Фурье, составляющие компоненты начинаются раньше, чем фронт раскладываемого сигнала. И только, будучи сложенными вместе, образуют его в первозданном виде. А если мы часть из них вырезаем, то, как раз, и получаем "хвост спереди".

    В современности, когда многие задачи решаются в цифре и в отложенном времени, это "раньше самого воздействия" уже не только возможно, но и даже используется.

    Сделав однажды подобный фильтр и демонстрируя заказчику его переходную функцию, тоже получил вопрос: как это так - ступеньки на входе ещё нет, а какие-то колебания уже есть? Предложил ему разложить прямоугольный импульс в ряд Фурье, исключить оттуда вырезаемые частоты и снова сложить... А поскольку вычислению с массивами неведомо прошлое и будущее, то там гром раньше молнии - явление вполне реальное.

  19. Читать я буду на частоте 10Mhz вот такой расклад получается, но проблема то в том что у меня 2 клоковых домина пересекающийся между собой!
    Ну тогда читать Вам надо по системе "запрос-ответ". Т.е. некий мастер выставляет запрос на чтение по определённому адресу, ваша ПЛИС "принимает" этот запрос и ожидает паузы между записями. Наступает пауза максимум через 4 такта, Вы читаете из ОЗУ и выставляете готовность - "забирай" :)

    Более того, учитывая, что читаете Вы на 10МГц, у Вас, как навскидку думается, есть все шансы - обработать "запрос на чтение" в этом же цикле чтения, не заставляя читающее устройство ждать.

  20. Если основной клок 100МГц и данные поступают на каждом втором такте - то у Вас просто нет шансов даже на запись - каким образом сформировать управляющие сигналы?
    Но данные приходят по 8 бит, а ширина шины данных ОЗУ 16 бит, что даёт ему возможность накопить слово и записать его одним махом. А пока оно копится - прочитать 16 бит для выдачи.
×
×
  • Создать...