VHDL XST неправильно синтезирует

Я работал над конвейером сортировки пакетов в VHDL, используя Xilinx ISE 14.2. Чтобы сделать структуру общей, я написал несколько алгоритмов в пакете, которые будут определять, как соединять сортировочные узлы. Интересно, что когда я разрабатываю тестовый стенд вокруг функций, результаты верны. Когда я моделирую свой дизайн в проекте, используя комбинацию генераций и функций, аппаратное обеспечение подключено правильно. (использовал 'assert false report' & integer'image(layer);'для проверки в симуляции) Однако, когда я генерирую схему RTL, я вижу, что некоторые узлы НЕ ПОДКЛЮЧАЮТСЯ правильно.

Я на 90% уверен, что это ошибка, но говорю, что я не ветеран с этим программным обеспечением. Функции работают, на данном этапе может быть использовано 2% доступных ресурсов. Есть ли какие-нибудь секретные флаги или особенности, о которых кто-нибудь знает?

Большое спасибо всем. С уважением, Стив

3 ответа

XST довольно надежный.

Единственная подлинная ошибка в аппаратном обеспечении, которую я видел в XST, связана с сигналами, передаваемыми в качестве параметров OUT процедурам внутри процесса... сигналы были назначены с использованием семантики назначения переменных (немедленного назначения)!

В ISE14 эта ошибка все еще присутствует - при нацеливании на Spartan-3 и более старые устройства, но не при нацеливании на Spartan-6 и более новые устройства. Оказывается, у XST есть два разных парсера VHDL, новый кажется лучше.

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

Вы также можете подключить post-synth netlist в свой тестовый стенд и воспроизвести (или нет!) Ошибки в симуляции. (IMO единственное практическое использование для моделирования после синтеза и после PAR - подтверждение или устранение возможных ошибок инструмента!)

И, как говорит Филипп, разделяй и властвуй в дизайне, пока у тебя не появится крошечный демонстратор, или ты не поймешь, в чем реальная проблема!

РЕДАКТИРОВАТЬ:

Добавлено для демонстрации пары моментов...

Учитывая правильные целочисленные значения для l, n, мы можем охарактеризовать эту проблему более близко... Из утверждений выше, мы можем вывести, что n = 8, l = 3.

    library IEEE;
    use ieee.math_real.all;

    entity count is
    end count;

    architecture Behavioral of count is

    constant n : integer := 8;
    constant l : integer := 3;

    begin

       report "n: " & integer'image(8) severity Note;
       assert false report "r: " & real'image(8.0) severity Note;
       report "Border a: " & real'image(real(n) + ( real(n) mod 2.0)) severity Note;
       report "Border b: " & real'image(2.0**(real(l+1) - 1.0)) severity Note;
       report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))) severity Note;
       report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)))) severity Note;
       report "Residual a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)) - 1.0 ) severity Note;

    end Behavioral;

1) "Утверждать Ложь" не обязательно (с 1993 года)

2) Вопреки распространенному мифу, утверждения МОГУТ быть синтезированы при условии, что их условия статически определены. Таким образом, в приведенном выше коде, где l, n являются константами, XST синтезирует, сообщая...

Ориентируясь на Спартанец-3, мы получаем:

INFO:Xst:1749 - "count.vhd" line 15: note: n: 8
INFO:Xst:1749 - "count.vhd" line 16: note: r: 0

поэтому использование старого синтаксического анализатора, использование Math.Real в синтезе не было хорошо поддержано. В частности, реальное изображение вернуло 0!

Таргетинг Спартанец-6,

Elaborating entity <count> (architecture <Behavioral>) from library <work>.
Note: "n: 8"
Note: "r: 8.0"
Note: "Border a: 8.0"
Note: "Border b: 8.0"
Note: "Border a/b: 1.0"
Note: "Ceil a/b: 2.0"
Note: "Residual a/b: 2.22044604925031E-16"

поэтому мы воспроизвели "ошибку". Но принципиально, если я вычту 1.0 из выражения вместо того, чтобы взять его потолок, мы можем увидеть остаток (введенный посредством округления). И мы видим, что, хотя он крошечный, он позитивный.

Поэтому Ceil() ведет себя правильно при возвращении 2.0, и это определенно НЕ является ошибкой инструмента синтеза.

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

Посмотрите эту и другие статьи профессора Кахана о числах с плавающей запятой - это не проблема инструмента или даже проблема VHDL, а гораздо большая банка червей...

Итак, последнее слово: если вы можете найти какой-либо способ выполнить ту же задачу в целочисленной арифметике, это будет лучшим решением.

Спасибо, ребята, за ваше время и мысли. В конце концов это привело к "затруднению" с функцией CEIL в IEEE.MATH_REAL, поскольку она ведет себя по-разному в Simulation и Synthesis.

Я решил эту проблему, оштукатурив свой код с помощью операторов ASSERT (обратите внимание: они работают только в моделировании). У меня была идея, где это могло бы пойти не так, и поэтому я обнаружил одну из функций с такими утверждениями ASSERT, как показано ниже. Таким образом, цель этого подхода к отладке состоит в том, чтобы сравнить выходные данные функции pre-synth с выходными данными post-synth, я использовал обычное моделирование поведения, а затем "Generate Post-Synth Simulation", используя операторы assert, выведет значения в окно консоли во время моделирования. период инициализации.

Пример кода подтверждения: (примечание: integer'image преобразует число в строку. Утверждение ложных сил для вывода оператора (необходимо в более ранних версиях VHDL))

assert false report "Border Value: " & integer'image(Border(l+1, n));
assert false report "Border a: " & real'image(real(n) + ( real(n) mod 2.0));
assert false report "Border b: " & real'image(2.0**(real(l+1) - 1.0));
assert false report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)));
assert false report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))));

Результаты:

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

Error: ""
Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 4 - 8"
Error: "Dst Port: 1"
Error: "Border Value: 4"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 1.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 55 - 63"
Error: ""

Вот вывод post synth, снова посмотрите на функцию ceil

Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 8 - 12"
Error: "Dst Port: 0"
Error: "Border Value: 12"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 2.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 62 - 70"
Error: ""

Заключение:

В симуляции, если целое число, такое как 1.0, подается в CEIL, он вернет 1.0. Однако во время синтеза 1,0 округляется до следующего целого числа (2,0), поскольку оно удаляет нецелую часть и добавляет 1 (например, 0,75 -> 0 -> 1). Разрешение (по крайней мере, в моем случае) состоит в том, чтобы вычесть 0,01 из значения накормленный на ceil (например, 1 -> 0.99 -> 1) Это не было отмечено ни в одной из встреченных мной документов, и я не верю, что это было задумано. Verilog поддерживает команду $ display, которая была бы очень полезна в этом случае, поэтому я создал обходной путь.

Если никому нечего добавить, я сообщу об этом в службу поддержки XILINX.

Еще раз спасибо. Стив

Возможно, вы неправильно понимаете сгенерированную схему RTL. Современные инструменты синтеза для ПЛИС выполняют ОЧЕНЬ МНОГО оптимизаций, включая продвижение логики через границы триггеров, репликацию логики и различные другие приемы для повышения скорости и уменьшения размера скомпилированной логики. Хотя возможно, что в этой логике оптимизации есть ошибка, я подозреваю, что если ваш дизайн совсем не тривиален, вы просто не до конца понимаете искажение, которое инструмент синтеза сделал, чтобы "улучшить" вещи. Если есть различие в поведении, в инструментах есть ошибка, или ваш код неоднозначен, и синтезатор и симулятор делают разные вещи... вам придется опубликовать некоторый код, чтобы мы могли помочь с этим.

Другие вопросы по тегам