Я хочу сделать разделитель vhdl

сейчас я использую FPGA spartan3,

я хочу рассчитать «результат», который представлен ниже формулой. и «результат» должен быть возвращен как целочисленный тип. Итак, я установил все переменные с целочисленным типом, но это не работает.

    result <=((a*b*7894*7)/(w*temp_constant));

я установил a,b,c,w,temp_constant как переменные

    variable a : integer range 0 to 99;
    variable b : integer range 0 to 9999;
    variable w : integer range 0 to 200;
    variable temp_constant : integer range 0 to 99;

но оператор '/' при этом синтезе не работает. сообщение об ошибке было «Оператор '/' должен иметь константные операнды или первый операнд должен быть степенью 2"'


person hailey94    schedule 08.12.2017    source источник
comment
Ничего себе, это довольно сложный расчет. Даже если вы заставите его синтезировать, это потребует много ресурсов и будет иметь очень большую задержку. Не ждите высоких тактовых частот. Если вы исходите из программного обеспечения: вы не можете программировать FPGA, как микроконтроллер. Вам нужно реализовать конвейерную обработку и тому подобное.   -  person JHBonarius    schedule 08.12.2017


Ответы (1)


Сообщение об ошибке почти (см. примечание ниже) ясно на 100%: деления не поддерживаются вашим инструментом синтеза, за исключением постоянных операндов (результат вычисляется синтезатором в фазе постоянного распространения) или делителей, которые являются степенью двойки. (деление представляет собой простой сдвиг вправо).

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

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

Примечание. Я нахожу полученное сообщение об ошибке (первый операнд должен быть степенью 2) несколько неожиданным. Если термин первый операнд не предназначен для обозначения делителя, что встречается не так часто, вероятно, это ошибка, и правильное сообщение об ошибке должно быть таким: второй операнд должен быть степенью 2. Или, что еще лучше: делитель должен быть степенью 2.

person Renaud Pacalet    schedule 08.12.2017
comment
a,b,w,temp_constant — это входы, заданные DIP-переключателем, поэтому они постоянно меняются. как я могу сделать их фиксированной точкой??? - person hailey94; 10.12.2017
comment
Вы не делаете фиксированную точку. Вы вычисляете w*temp_constantи используете результат как адрес постоянной памяти (ПЗУ). Содержимое ПЗУ таково, что по адресу X вы найдете обратное X, умноженное на постоянную степень 2 и округленное до ближайшего целого числа. Умножьте значение, считанное из ПЗУ (2**N/(w*temp_constant), на a*b*7894*7, отбросьте N младших разрядов, и все (почти) готово. - person Renaud Pacalet; 10.12.2017
comment
Поскольку ваши входы поступают от коммутаторов, у вас будет очень низкая пропускная способность. Одного деления в секунду будет достаточно. Таким образом, лучшая реализация, вероятно, не на основе ПЗУ. Посмотрите на серийные делители и выберите самый маленький. То же самое для ваших множителей: используйте только один и выберите небольшую последовательно-параллельную архитектуру. Вычисление займет десятки или даже сотни тактов, но все равно будет достаточно быстрым. - person Renaud Pacalet; 10.12.2017