Гаражный движ 👩🔧
По вопросам рекламы и сотрудничества - [email protected]
Last updated 5 days, 20 hours ago
В комментах товарищ @Xtyll спросил, не упала ли скорость симуляции в Вериляторе после добавления событийного шедулинга. Сообщаю: не упала.
Добавил тест Верилятора 4-й версии в свой бенчмарк - разница в результатах с версией 5 на уровне погрешности. Для надежности сделал ещё тест на реальном проекте. Там тоже разницы нет. Вот как-то так.
Про асинхронный сброс и Verilator.
Вот типичный код асинхронного сброса:
always\_ff @(posedge clk or negedge rst\_n) begin
if (!rst\_n) ...
else ...
end
Обычно, код работает так же, как в железе. Однако, если в начале симуляции нет клока, то сброс может не сработать. Так выйдет, если rst_n
присвоить 0 в нулевом времени через инициализацию в объявлении. Как можно догадаться, в этом случае события negedge rst_n
не случится, т.к. по стандарту присвоение в объявлении выполняется раньше присвоения в процессах.
Очевидное решение - в объявлении rst_n
присвоить 1 (или вообще ничего не присваивать, X->0 тоже считается за negedge
), а в initial
- 0:
logic rst\_n = 1'b1;
initial rst\_n = 1'b0;
Или так:
logic rst\_n;
initial begin
rst\_n = 1'b1;
rst\_n = 1'b0;
end
Однако, и здесь есть нюанс: Verilator не захотел регистрировать это событие, и не выполнил код процесса. Раньше такого в Вериляторе быть не могло, потому что до недавнего времени он был чисто clock-accurate симулятором. А раз клок всегда был, то события negedge rst_n
можно было не дожидаться, процесс вызвался бы при первом posedge clk
. Но сейчас он стал фактически полноценным event-driven, по этому наверное дожен справляться с такими вещами.
В связи со всем вышесказанным думаю самым правильным решением было бы присвоение rst_n
единицы, а как минимум в следующем цикле симуляции сбрасывать его в ноль:
logic rst\_n = 1'b1;
initial \#1 rst\_n = 1'b0;
Запилил issue
Вы наверное знаете, что в стандарте верилога есть ключевое слово macromodule
, которое ничем не отличается от module
, за исключением того, что "An implementation may choose to treat module definitions beginning with the macromodule keyword differently". Интересно, откуда растут ноги у этого macromodule
и используется ли где нибудь возможность интерпретировать его отлично от module
?
Я нашел документ, в котором сказано, что в macromodule
можно описывать только wire
и операции с ними. Никаких переменных/регистров и процедурных присваиваний, только assign
. Интересно, откуда эта информация, если в стандарте об этом ни слова?
Столкнулся с очередным багом Верилятора: функция $random
(и $urandom
тоже) с одинаковым начальным сидом генерит разные последовательности. Этого конечно не должно быть, и другие симы это подтверждают - проверил на Икарусе и Квесте. Однако, семейство функций $dist_*
работает правильно. Так что если вам понадобится в одной программе генерить одинаковые случайные последовательности, пользуйтесь $dist_uniform
вместо $random
/$urandom
.
Запостил issue.
PS: Ни слова про опенсорс. Уверен, что ошибку быстро исправят ;)
Дополнение. Такое поведение наблюдается только при seed == 0. Посмотрел исходники, там есть тест на равенство $random
с одинаковым seed, но seed устанавливается в 10.
GitHub
$random sequences with the same seed do not equal · Issue #5074 · verilator/verilator
Generating random numbers using $random and $urandom with the same seed produces different sequences. At the same time, $dist\_* functions with the same seed produces identical numbers. Test code: `...
Возможно это глупый вопрос, но я рискну. Представьте, что у вас есть слейв, принимающий 32 бита по AXIS-подобной шине (хендшейк valid/ready) и выполняющий обработку данных побайтно. Возможны два варианта действий:
В режиме ожидания вы держите ready в единице. Как только приходит valid, защелкиваете все 32 бита в регистр, снимаете ready и начитаете побайтную обработку. По окончании поднимаете ready.
В режиме ожидания держите ready в нуле. По приходу valid начитаете побайтную обработку, снимая байты непоследственно с шины. По окончании дергаете ready.
В общем, оба варианта приемлемы, т.к. в спеке на AXI не требуется, чтобы ready был активен до прихода valid, а однажды выставленный valid не может быть снят до прихода ready. С другой стороны, второй вариант может порушить времянки, если данные от мастера формируются через комбинационные цепи. И возможны проблемы с арбитражем, если арбитр полагается на ready.
Что вы думаете по этому поводу? В комментах создам опрос, заходите.
Не стесняемся, заказываем ?
Оказывается несколько лет назад кто-то даже открыл issue на этот счёт и попутно предложил использовать case equality (===). Это, наверное, самое правильное решение, т.к. по стандарту этот оператор всегда возвращает 0 или 1, никаких иксов.
GitHub
conditional operator with enum's require explicit cast · Issue #280 · steveicarus/iverilog
The following code does not compile in iverilog. I believe this is valid systemVerilog code. At least one commercial tool accepts this happily. iverilog seems to be unhappy about the datatype and w...
Гаражный движ 👩🔧
По вопросам рекламы и сотрудничества - [email protected]
Last updated 5 days, 20 hours ago