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

sallador

Свой
  • Постов

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

  • Посещение

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


  1. О! Тут уже давали на мой гитхаб ссылку. В общем, если коротко - у меня почти платформонезависимая корка БПФ на любую длину. Radix-2 и 2-х параллелизм. Можно заменить узлы, где делается умножение и сложение на DSP48 узлах Xilinx на то, что есть в альтере - и оно заработает (главное задержки такие же соблюсти). Или тупо переписать код влоб, типа:

    X_RE = A_RE * W_RE - A_IM * W_IM;

    X_IM = A_RE * W_IM + A_IM * W_RE;

    Разумеется, эти операции лучше разбить на несколько стадий. И дать синтезатору указание разводить это не на логике, а на встроенных узлах DSP. 

     

    Если АЦП не очень скоростная, то двухкратный параллелизм - избыточен. В таком случае нужно делать БПФ по схеме single path delay feedback - оно проще и легче. 

  2. Можно поступить так:

     

    В entity этого компонента, который мапите, присвоить входным сигналам исходное значение. Например:

     

    entity bla_bla_bla is
      port(
        aa  : in std_logic_vector(N-1 downto 0):=(others=>'0');
        bb  : in std_logic:='0';
        ...
      );    
    end bla_bla_bla;

     

    Тогда не надо входным портам присваивать значения. А про выходные уже ответили: либо вообще ничего не писать, либо => open.

     

    да но у меня не очень много места. экономлю на каждом сигнале.

     

    У меня уже total logic elements заняты на 70%. а мне еще кучу кода надо запихать.

    Условная запись:

     

    signal test : std_logic_vector(3 downto 0):="0000";

     

    Не тратит логические ресурсы и триггеры совсем, если далее в коде значение сигнала нигде не меняется.

     

    А чтобы наверняка не менять это значение - вместо signal напишите constant и мапьте к компонентам константы значений.

     

     

  3. Интересная тема.

    Такое ощущение, что в какой-то команде пожалели денег на разработчика.

     

    По теме:

    Всё реально. Реализовали SRIO на кристаллах Xilinx: V6, K7, сейчас делаем на KU. Например, для V6 скорость: 1ГБ/c туда, 1Гб/c обратно. Тесты обмена данными следующие:

    FPGA <> FPGA,

    FPGA <> DSP,

    FPGA <> HOST (компьютер).

     

    В первом варианте для V6 задействован SRIO SWITCH для обмена между удаленными друг от друга устройствами (т.к. на 1 плате - 1 ПЛИС, на скорость это не влияет). Для K7 свитча нет.

  4. А кто-нибудь сталкивался со следующей проблемой при активации Training Credits после покупки софта от Xilinx?

     

    Мы недавно приобрели лицензию на Vivado и получили 30 training credits. Сегодня я попытался их активировать на странице XPA Training Credits.

    Выдает следующую проблему:

    We cannot fulfill your request as your account has failed export compliance verification. Please visit http://www.xilinx.com/support/answers/44043.html for a possible solution to resolve this error.

    То есть, лицензию с моего аккаунта дали купить месяц назад, санкций никаких не было. А обменять кредиты на курсы - нельзя. Интересно...

  5. На ПЛИС можно делать практически, что угодно. Конфигурируйте как захотите, проекты делайте - какие хотите. Кто-то даже нейронные сети на FPGA пытается сделать. По большей части на вопрос тут уже ответили. Добавлю от себя немного, если позволите.

     

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

     

    Если интересно, почитайте мои статьи на хабре. Для новичков они в самый раз. К проектам на отладочной плате также есть исходники на гитхабе, можете поковыряться в них. :)

  6. Вам правильно подсказали - делайте независимый синтез каждого узла и создавайте отдельно *.ngc блоки. А на верхнем уровне их подцепляйте как black-box.

    Тогда перекомпилировать придется только конкретный узел.

     

    Для Implementation в PlanAhead есть удобная штука: "Promote Partitions". Суть такая:

    1) закрепляем в виде p-blocks нужные узлы, которые не будут изменяться.

    2) разводим проект N раз и выбираем удовлетворяющую вас разводку.

    3) разводку неизменных p-block оставляем с помощью "promote".

    4) делаем сколько угодно другие изменения и разводим проект заново, с учетом уже разведенных блоков.

    5) ...

    6) PROFIT!!!

     

    Ну и как уже верно заметили - читать нужно Hier. design rules. Что-то типа такого: первый попавшийся юзергайд.

  7. Приветствую в описании памяти встретил такую шину, что это и в чем ее смысл. Заранее спасибо.

    Удобная штука. Пример: в зависимости от какого-нибудь числа каналов нужно сделать 1, 2, 4, 8, 16 и т.д. сигналов валидности.

    signal Nchan_valid : std_logic_vector(Nchan-1 downto 0)

    Если канал 1 - то так и получится (0 downto 0);

     

    А про остальное - Вам уже верно ответили.

    Xilinx для памяти любит делать такие шины. Зачем и почему? Лезем в библиотеку unisim и unimacro, и смотрим, как у них конфигурируются какие-нибудь примитивы памяти типа BRAM_TDP_MACRO, RAMB16_S1_S1, RAMB36E1 и т.д.

  8. Нужно получить сигнал стринг, вычленить из него символ и отправить в порт.

    В таком варианте ISE выдает ошибку, но не говорит в какой строке.

     

    Unknown identifier "current_simbol".

     

    Замените на цифру - 1, 2, 3... - все работает.

  9. Кстати вы надеюсь смотрите technologic view а не rtl view? В ртл он отсебятину несет, эта схема не соответствует действительности.... надо технологик смотреть

    Конечно.

    Плюс я смотрю уже результат после стадии PAR, а там он уже точно делает после всех оптимизаций окончательный вариант.

     

    Вчера очень долго читал даташиты. Похоже, что нельзя инициализировать RAMB36E как ROM 72x512 таким способом.

    Остается вариант - либо делать через CoreGEN, либо unimacro подключать.

    Первое не устраивает, второе еще терпимо.

     

  10. Вы бы не выделывались, а написали бы нормальный процесс. Глядишь, и xst тупить бы перестал. Это первое.

    А второе, xst не умел использовать двухпортовую память для двух идентичных блоков ROM. Видать, так и не научили ещё.

    Для уменьшения кода я написал без процесса. С процессом тоже пробовал, суть та же. Результаты одинаковые.

     

    Ладно, попробую через примитив из unimacro, где можно определенным образом задать INIT векторы.

     

    может не мочь на 1 блоке. там есть ограничения, надо доки читать...

    Хм. Ничего не понимаю. ROM не хочет делать, а RAM влегкую. Такие дела, переписал код: удалил инициализацию, добавил порт для записи в память. Итого, RAM 512x64 он сделал без проблем на 1 RAMB36. Пруф из FPGA_Editor:

    post-64903-1444215294_thumb.png

    Чудеса.

  11. В Симплифае один раз так накололся, написав атрибут syn_ramstyle вместо syn_romstyle.

    Посомтрите в XST, возможно в этом проблема - мне лень.

     

    Нет, это не влияет.

     

    сделайте регистр и в него явно по клоку защелкните данные из массива. Такое описание рождает РОМ, никаких доп регистров не появиться... С ксалинксом в свое время мне удалось договориться без проблем...

    Ура. Удалось сделать не на рассыпухе, а на 2 блоках RAMB36. Причем, без атрибутов ram_style.

    Но все равно он не хочет в 1 блок упихивать.

     

    Код такой:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity rams_21b is
        generic (
            Data_w    : integer:=64;
            Data_d    : integer:=512
            );
        
        port (
            CLK     : in  std_logic;
            EN         : in  std_logic;
            ADDR     : in  std_logic_vector(8 downto 0);
            DATA     : out std_logic_vector(Data_w-1 downto 0)
        );
    end rams_21b;
    
    architecture syn of rams_21b is
        type rom_type is array (Data_d-1 downto 0) of std_logic_vector (Data_w-1 downto 0);                 
        signal ROM : rom_type:= ( ТУТ 512 ОТСЧЕТОВ  );                        
    
    signal rdata : std_logic_vector(Data_w-1 downto 0);    
    
    begin
    
    rdata <= ROM(conv_integer(ADDR));
    
    process (CLK)
    begin
        if (CLK'event and CLK = '1') then
            if (EN = '1') then
                DATA <= rdata;
            end if;
        end if;
    end process;
    
    end syn;

  12. добавлено

    Если индентично, тогда совет работайте дальше и не обращайте пока на это внимание...

    В том то и дело, что работать дальше могу, но и с этим хотелось бы решить вопрос.

     

    Похоже, что остается подключать unimacro и тащить оттуда большой примитив.

     

     

  13. в генерике надо задать параметры для памяти

    У вас dual-port, а мне нужен single-port.

     

    Например, в Aldec Active-HDL из Language Assistance для single port RAM предлагается такой код:

    process (clk)
        variable ram : ram_t;
    begin
        if clk'event and clk = '1' then
            if wr_en = '1' then
                ram(conv_integer(addr)) := data_in;
            end if;
            data_out <= ram(conv_integer(addr));
        end if;
    end process;

    Что совпадает с моими желаниями, за исключением того, что мне не нужна запись, т.к. я делаю ROM.

     

    Добавлено: для Template language из ISE - код практически идентичный.

  14. А почему не хочешь генератор использовать? Он точно всё как надо сделает и сразу покажет сколько блоков памяти будет использовать.

    Только что попробовал - элементарно делает и 1 блок RAMB36E1 использует.

    Потому что я хочу сделать параметризируемый блок ROM разной глубины.

    В зависимости от условий, он может быть 64х1к, 64х8к или, например 64х128к...

     

    Делать кучу корок - не хочется совсем. Хочется понять, как заставить XST не умничать.

     

    P.S. примечательно то, что если я делаю разрядность данных не 64, а например 44, то он делает на 1 RAMB36 и 1 RAMB18. В FPGA Editore - вижу, что сделал на RAMB, но режимы выставил им TDP, а не SDP. Зачем ему лишний RAMB18 понадобился, не пойму.

     

    Но это не решает проблему для разрядности данных = 64.

  15. Есть вот такой кусочек кода:

     

    type std_logic_array_64xNN is array (511 downto 0) of std_logic_vector(63 downto 0);
    
    -- Инициализирую массив 512х64 функцией read_ini_file.
    constant const_init : std_logic_array_64xNN:=read_ini_file(stage_num);
    
    attribute RAM_STYLE : string;
    attribute RAM_STYLE of d_out : signal is "block";
    
    begin    
        -- адрес = выход обычного счетчика
        addr <= cnt(stage_num-2 downto 0);    
        -- здесь я пытаюсь сделать ROM 512х64 на BRAM:
        d_out <= const_init(conv_integer(addr)) when rising_edge(clk);

    Хочу: чтобы синтезатор сделал Simple dual-port ROM на одном примитиве RAMB36E1.

    Из даташита на 7 серию: Each 36 Kb block RAM can be configured as a ... 512 x 72 in simple dual-port mode.

     

    То есть теоретически это реально, но синтезатор ни в какую не хочет задействовать примитив и делает на рассыпухе.

    Причем, атрибуты он игнорирует. XST пишет следующее:

     

    The RAM <...> will be implemented on LUTs either because you have described an asynchronous read or because of currently unsupported block RAM features. If you have described an asynchronous read, making it synchronous would allow you to take advantage of available block RAM resources, for optimized device usage and improved timings. Please refer to your documentation for coding guidelines.

    Но асинхронного чтения нет, все по клоку. Да и возможности BRAM из 7 серии позволяют использовать режим SDP 512x72.

    Пробовал расширять разрядность до 72 - безрезультатно!

     

    Использовать coregenerator не хочу, вставлять напрямую библиотеку unisim/unimacro - тоже. Как быть? Почему XST тупит?

     

  16. Теперь вот самый обычный сумматор не хочет на DSP-блоках синтезироваться... то ли лыжи не едут по запарке...

    // separating I and Q components of the local beamformers signal and the one from adjacent FPGA
    wire signed [bEAM_BW-1 : 0] loc_i, loc_q, adj_i, adj_q;
    assign loc_i = fifo_out         [bEAM_BW   -1 : 0      ];
    assign loc_q = fifo_out         [bEAM_BW*2 -1 : BEAM_BW];
    assign adj_i = adj_data_f_al    [bEAM_BW   -1 : 0      ];
    assign adj_q = adj_data_f_al    [bEAM_BW*2 -1 : BEAM_BW];
    
    // pipeline registers inside of adder DSP block
    (* use_dsp48 = "yes" *) reg signed [bEAM_BW-1 : 0] loc_i_int, loc_q_int, adj_i_int, adj_q_int;
    always @(posedge clk) begin
       loc_i_int <= loc_i;
       loc_q_int <= loc_q;
       adj_i_int <= adj_i;
       adj_q_int <= adj_q;
    end
    // adder itself
    (* use_dsp48 = "yes" *) reg signed [bEAM_BW-1 : 0] sum_i, sum_q;
    always @(posedge clk) begin                                     
       sum_i <= loc_i_int + adj_i_int;
       sum_q <= loc_q_int + adj_q_int;
    end
    

    BEAM_BW = 16. Предположил, что синтезатор "считает", что слишком жирно ставить сумматор для складывания 16 битов. Поставил 30 - не полегчало.

    В настройках синтеза в ISE стоит -use_dsp48 = Auto. Предположил, что в коде что-то криво описано, и такой сумматор в принципе невпихуем в DSP. Поставил Auto Max - реализовало на DSP. Т.е. код получается нормальный? Тогда почему же не синтезирует при Auto? Ему же русским по белому написано в коде:

    (* use_dsp48 = "yes" *)

     

    Не знаю, как на verilog, а на VHDL мне помогло атрибут прописать не для сигнала, а для entity, в котором сделал обычный сумматор как отдельный компонент.

     

    attribute use_dsp48 : string;
    attribute use_dsp48 of add_example : entity is "yes";

  17. вопрос из любопытства зачем для обычного счетчика использовать ресурсы DSP48?

    Ответ: да просто интересно было, правильно ли отработают атрибуты.

    Плюс в некоторых проектах я зачастую счетчик делаю на DSP48, где достаточно ресурсов.

     

    Вообще мне привычнее взять unisim, выдрать оттуда DSP48E1 и все ручками пробить, чтобы было уже наверняка. :)

     

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

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

    В теме по вашей ссылке - ответил про сумматор.

  18. Работаю в Xilinx ISE 13.3 проект для Spartan6.Сделал с помощью Block Memory Generator 6.2

    элемент памяти с именем 'buf_cor'.В Translate ошибка : "Symbol 'buf_cor' is not supported in target

    'spartan6'".Кто скажет в чём дело,как решить проблему.

    Что еще пишет?

     

    Причин может быть несколько:

    1) В корегенераторе установили не Spartan6,

    2) Не скопировали (не создался) NGC вместе с HDL-файлом, (можно еще проверить в самом файле, что установлено в "family")

    3) В самом проекте установлен не Spartan6.

     

     

  19. там вроде был где-то параметр указания типа сброса: синхронный или нет. Хотя могу путать. Ну и конечно ничто не мешает всё равно на этом месте синтезатору спотыкаться. Просто не умеет корректно обрабатывать, возможно. Так что Вы может быть очень даже правы ))

    Это уже в настройках синтеза и имплемента можно поставить. Но мне не нужно весь проект переводить строго на синхронный или асинхронный сброс. :)

     

    кстати

    надо отчет читать и схематик смотреть.

     

    В РТЛ он иногда делает не то что на самом деле. У него какие-то эквивалетные схемы есть, то есть там тоже может участвовать ДСП блок, но регистры будут внешними, а потом в отчете он напишет, что и прочее внутырь попихал, в схематике более объективная картина.

    Так я и читал отчет синтеза, имплемента и в FPGA Editor смотрел. И пока не добился засовывания PREG внутрь - он всегда писал, что Used 32 Flip-flops...

  20. расширение даст только варнинг о возможном превышении разрядности, ИМХО...

     

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

    Бинго!

     

    Причем,

     

    а) Если так сделать для разводки только одного компонента счетчтика он триггеры помещает в IOBы :)

    б) Если так сделать для разводки полного проекта - то видит PREG для счетчика! Все заработало.

     

    Проблема решена, спасибо.

     

    Более того, удалось для выражения:

     

    data <= data_a * data_b + data_с after td;

     

    Задействовать PREG и MREG.

  21. А вообще в Вашей конструкции DSP48 хоть в каком-то виде вставляется, но без PREG? Или он вообще ни в каком виде не вставляется, а суммирование делается на рассыпухе?

    Возможно, его смущает "after td". А возможно, ena. Попробуйте для начала убрать оба.

    Возможно, тип сигнала data должен быть signed, а прибавляемая величина - ту же разрядность (т.е. надо единичку расширить), хотя последнее - вряд ли должно влиять.

    1) да, синтезирует в DSP48 блок, но без PREG.

    2) after td - чисто для моделирования, оно выбрасывается синтезатором (проверено 100% на всех проектах, которые я делал)

    3) ena - убирал, результат тот же.

    4) попробую - о результатах сообщу.

     

  22. Добрый день, уважаемые коллеги!

     

    В нашем узком кругу разработчиков на ПЛИС возникла необходимость сразу в нескольких вещах.

     

    1) Регламент и правила для описания компонентов VHDL в процессе разработки.

    Каким образом именовать те или иные сигналы, порты, компоненты, как делать описание шапки файла и т.д.

    В интернете на эту тему очень много документов, например:

    а) https://wiki.electroniciens.cnrs.fr/images/...oding_style.pdf

    б) http://www.irtc-hq.com/wp-content/uploads/...-2014-02-05.pdf

     

    Интересует, как это сделано у форумчан в ваших командах?

     

    2) Сопроводительная документация к компонентам и законченным узлам.

    Дабы не плодить огромный зоопарк однотипных компонентов и узлов, хотелось бы сопровождать код краткой документацией. В настоящий момент мы не пишем документацию к блокам, но активно пользуемся SVN и VSS.

    В идеале хотим разработать правило, которое гласит: "компонент RTL считается законченным только тогда, когда на него написана сопроводительная документация". В документации хотим видеть как минимум а) таблицу портов из entity, с направлением и описанием. б) временную диаграмму в разных режимах работы. (По аналогии с тем, как сделано в даташитах у Xilinx).

    Может быть, еще RTL-компонент сопровождать тестбенчем.

     

    Каким образом сопровождаете RTL-компоненты вы?

     

    Поделитесь опытом. :smile3046:

     

    P.S. бонусный вопрос - пользутесь ли вы doxygen для документации vhdl? (на первых порах хотим применить у себя, но боимся, что потратим время впустую).

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