Эффективный синтез функции 4 к 1 в Verilog
-
09-06-2019 - |
Вопрос
Мне нужно реализовать функцию 4 к 1 в Veriog.Входные данные состоят из 4 бит, это число от 0 до 15.Выходной сигнал представляет собой один бит, 0 или 1.Каждый вход выдает разные выходные данные, и отображение от входов к выходам известно, но сами входы и выходы неизвестны.Я хочу, чтобы vcs успешно оптимизировала код, а также сделала его как можно более коротким и аккуратным.Мое решение на данный момент:
wire [3:0] a;
wire b;
wire [15:0] c;
assign c = 16'b0100110010111010; //for example but could be any constant
assign b = c[a];
Необходимость объявлять c уродлива, и я не знаю, распознает ли vcs там K-карту.Будет ли это работать так же хорошо, как оператор case или присваивание в конъюнктивной нормальной форме?
Решение
То, что у тебя есть, прекрасно.Оператор case также будет работать не менее хорошо.Все просто зависит от того, насколько выразительным вы хотите быть.
Ваше решение, индексирование, работает нормально, если выбранные кодировки не имеют какого-либо особого значения (например, селектор адресов памяти).Если выбранные кодировки действительно имеют какое-то особое семантическое значение для вас, дизайнера (а их не так уж много), тогда используйте оператор case и перечисления.
С точки зрения синтеза, не имеет значения, какой из них вы используете.Любой приличный инструмент синтеза даст тот же результат.
Другие советы
Я полностью согласен с Далласом.Используйте инструкцию case - это прояснит ваше намерение.Инструмент синтеза построит его как справочную таблицу (если она параллельна) и оптимизирует все, что сможет.
Кроме того, я бы не стал так сильно беспокоиться о том, чтобы ваш RTL-код был коротким.Я бы сначала выстрелил для ясности.Инструменты синтеза умнее, чем вы думаете...
Мое предпочтение - если это имеет смысл для вашей проблемы - для оператора case, который использует перечисления или `defines .Все, что угодно, лишь бы упростить просмотр кода, его обслуживание и верификацию.
Для подобных вещей ясность RTL превосходит все с большим отрывом.SystemVerilog имеет специальные директивы always block, чтобы было ясно, когда блок должен синтезироваться с комбинационной логикой, защелками или провалами (и ваш инструмент синтеза должен выдавать ошибку, если вы написали RTL, который конфликтует с этим (напримерне включая все сигналы в список чувствительности блока always).Также имейте в виду, что инструмент, вероятно, заменит любую имеющуюся у вас кодировку наиболее аппаратно эффективной кодировкой (той, которая минимизирует площадь вашего общего дизайна), если только сама кодировка не распространяется на контакты вашего модуля верхнего уровня.
Этот совет также применим в целом.Сделайте ваш код простым для понимания людьми, и он, вероятно, будет более понятным и для инструмента синтеза, что позволит ему более эффективно передавать буквально тысячи человеко-годы исследований алгоритмов, которые повлияют на ваш RTL.
Вы также можете закодировать его с помощью троичных операторов, если хотите, но я бы предпочел что-то вроде:
always_comb //or "always @*" if you don't have an SV-enabled tool flow
begin
case(a)
begin
4'b0000: b = 1'b0;
4'b0001: b = 1'b1;
...
4'b1111: b = 1'b0;
//If you don't specify a "default" clause, your synthesis tool
//Should scream at you if you didn't specify all cases,
//Which is a good thing (tm)
endcase //a
end //always
Очевидно, я использую паршивый инструмент синтеза.:-) Я только что синтезировал обе версии (только модуль, использующий модель, основанную на разветвлениях для проволочных задержек), и версия индексации из вопроса дала лучшие результаты по времени и площади, чем заявления case.Используя Synopsys DC Z-2007.03-SP.