pavlovconst 2 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба Здравствуйте! Пишу в проекте примерно такой код. В одном блоке вычисляю несколько типов аварий. Намеренно использую при этом блокирующее присваивание, так код получается коротким и хорошо читаемым. Во втором блоке накапливаю полученные аварии. module main( input clk, input nrst, input [7:0] in_data, output [7:0] out_data ); reg [3:0] brd_err2 = 0; reg [7:0] brd_err2_cntr = 0; always @(posedge clk) begin if( ~nrst ) begin brd_err2_cntr[7:0] <= 0; end else begin brd_err2_cntr[7:0] <= brd_err2_cntr[7:0] + brd_err2[3] + brd_err2[2] + brd_err2[1] + brd_err2[0]; end end always @(posedge clk) begin if( ~nrst ) begin brd_err2[3:0] = 0; end else begin brd_err2[3] = in_data[3] || in_data[2] || in_data[1] || in_data[0]; brd_err2[2] = in_data[4] || in_data[2] || in_data[1] || in_data[0]; brd_err2[1] = in_data[5] || in_data[2] || in_data[1] || in_data[0]; brd_err2[0] = in_data[3] || in_data[1]; end end assign out_data[7:0] = brd_err2_cntr[7:0]; endmodule При синтезе и для brd_err2, и для brd_err2_cntr создаются регистры, выходы задержаны относительно входов на 2 такта. А вот на симуляции получаю очень странные результаты, которые, к тому же, меняются при изменении порядка always`ов. Что можно сделать, чтобы поправить симуляцию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба Приветствую! 1 hour ago, pavlovconst said: В одном блоке вычисляю несколько типов аварий. Намеренно использую при этом блокирующее присваивание, так код получается коротким и хорошо читаемым. А зачем? Замена "brd_err2... = .." на "brd_err2... <= .." сделает код всего лишь немного длиннее, но не менее читаемым. И при этом более предсказуемым при симе и синтезе. Вообще применять bloking assigment нужно аккуратно обычно в синтезе его используют для описания комбинаторики в always @(*) или при вычислении локальных переменных в функциях или в блоках кода begin end. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба Советую почитать вот эту книженцию: https://www.springer.com/gp/book/9780387717142 Там очень детально разжовано и показано на примерах почему нужно писать так, а не иначе. В основном там как раз такие случаи и рассматриваются - когда синтезируется одно, а на симуляции совсем другое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 2 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба 5 hours ago, one_eight_seven said: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf Спасибо, прочитал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 2 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба one_eight_seven, RobFPGA, Nick_K Я понимаю, что основной совет - это сделать все присваивания неблокирующими. Всегда тоже так делал. Но вот сейчас столкнулся с ситуацией, когда мне действительно удобнее использовать блокирующее. В стандарте есть блокирующие присваивания, так почему я, как разработчик, должен ограничиваться и не использовать максимум выразительных средств языка? Больше всего я не понимаю, как могут симуляторы и синтезаторы давать различные результаты, если и те, и другие - опираются на один стандарт? Кто виноват в расхождении? Стандарт плохой? Или его имплементации? Конечная цель разработчика - получить верную синтезированную схему. И симуляцией мы занимаемся опосредованно, чтобы отладить синтез. А если результаты не совпадают, то зачем вообще заниматься симуляцией? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 29 сентября, 2019 Опубликовано 29 сентября, 2019 · Жалоба Приветствую! Проблема в том что параллельный мир приходится симулировать на последовательном симуляторе. Соответственно возникают некоторые конфликты и неопределенности в последовательности операций при такой симуляции. Ведь в симуляторе, в отличие от реального мира, возможна ситуация выполнения операций за 0 время. Добавьте задержку в ваше блокирующее присвоении и увидите как поменяется поведение при симе. 23 minutes ago, pavlovconst said: А если результаты не совпадают, то зачем вообще заниматься симуляцией? А вот для того что бы исключить (или хотя бы значительно уменьшить) вероятность таких различий и существуют правила правильного применения конструкций языка для корректного описания поведения при симуляции и синтезе. Ну а зачем заниматься симуляцией? Не знаю Если вы уверены что сможете в слепую, без сима, сваять корректную логику дизайна то тогда действительно незачем. Но вот что вы будете делать если работать будет не так как хотелось. Или как доказывать что вы сделали то что вас просили? Лазать Chipscope/SignalTap по чипу? Так не всегда это возможно. Как тогда быть? Поэтому делаете дизайн использую некоторые правила применения конструкций языка. Проверяете результат в симе, а затем и в железе. И корректируете дизайн (а иногда и правила) так, чтобы поведение сима и дизайна совпадали. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 (изменено) · Жалоба 4 hours ago, pavlovconst said: В стандарте есть блокирующие присваивания, так почему я, как разработчик, должен ограничиваться и не использовать максимум выразительных средств языка? Верилог сам по себе не чёткий язык. Он позволяет слишком многое, даже то что невозможно сделать в реальности. Вы используете неправильные конструкции языка, однако синтезатор предполагает это и адаптирует ваш код. Если же, к примеру, запустите линт, то он уже в свою очередь выдаст это как ошибка. Кстати SystemVerilog и использование always_ff (и так далее) как раз запретят такое применение, с этой точки зрения он более строг, чем чистый Verilog. Изменено 30 сентября, 2019 пользователем lexx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 2 часа назад, lexx сказал: SystemVerilog и использование always_ff (и так далее) как раз запретят такое применение Ой ли? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 13 hours ago, pavlovconst said: В одном блоке вычисляю несколько типов аварий. Намеренно использую при этом блокирующее присваивание, так код получается коротким и хорошо читаемым. Ну, читаемость на любителя(зачем в битовых операциях вместо битового используется логическое или...), а вообще, объявите внутри процесса переменную tmp и после всех пертурбаций, присвойте ее значение к "регистру" с помощью неблокирующего присваивания) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 5 часов назад, pavlovconst сказал: В стандарте есть блокирующие присваивания, так почему я, как разработчик, должен ограничиваться и не использовать максимум выразительных средств языка? Потому что для всякого выразительного (или не очень) средства языка есть свой контекст применения. @RobFPGA уже достаточно внятно объяснил, что к чему. Добавлю только, что если хотите понимать, что там "под капотом", почитайте про планировщик виртуальной машины симулятора (по ссылкам выше про это тоже есть), например, тут. Вы увидите, что блокирующие и неблокирующие присваивания обрабатываются в разных стадиях (регионах событий) цикла планировщика (блокирующие раньше), из-за этого возникают гонки и странное поведение на симуляторе. Синтез имеет другую исполнительную модель - "тру параллел", там гонок в этом смысле нет. Симулятор является мощным инструментом отладки логики дизайна, отказ от его использования резко понижает "потолок" сложности. Но чтобы от инструмента была польза, надо пользоваться им правильно, понимая условности и ограничения метода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 7 hours ago, pavlovconst said: Больше всего я не понимаю, как могут симуляторы и синтезаторы давать различные результаты, если и те, и другие - опираются на один стандарт? Кто виноват в расхождении? Стандарт плохой? Или его имплементации? А ещё любые программы очень часто пишут индусские быдлокодеры со всеми вытекающими. Я, например, натыкался на ситуацию, когда абсолютно верную конструкцию (на VHDL, но не суть) совершенно верно симулировал ModelSim (он вообще меня пока что не подводил ни разу) и совершенно верно синтезировал Xilinx'овый синтезатор для 6-го семейства, а вот Xilinx'овый же, но для 3-го, то ли синтезировал криво, то ли просто выдавал ошибку на пустом месте, уже не помню подробности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 33 minutes ago, SII said: А ещё любые программы очень часто пишут индусские быдлокодеры со всеми вытекающими Не стоит все гнать на индусов, этих достаточно по обе стороны. Если продукт прошёл внутреннее тестирование, то дело не в кодинге. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 1 hour ago, SII said: совершенно верно синтезировал Xilinx'овый синтезатор для 6-го семейства, а вот Xilinx'овый же, но для 3-го, Тут разговор за ISE/PlanAhead и в часности VHDL код под него. Так вот за 5+ лет разработки я таких ядовых приколов навидался на этой связке, что упаси Элон! Там и вправду то ли криворукие пишут, то ли в какой-то момент все поняли, что переход на Vivado неминуем и делали на отъеб*тесь. В любом случае это не показатель и нужно как минимум смотреть годинг гайд для производителя. Что касается синтезируемости и моделирования SystemVerilog собственно всё было сказано и непридерживание правил описания влечёт за собой всякого рода неожиданное поведение. А сделано это для того, чтобы на симуляции можно было просимулировать процессы, которые в реальности могли бы возникать только при определённых состояниях кристалла, как метастабильности или неопределённости. С одной стороны это излишнее усложнение стандартов, которым будут пользоваться единицы (для них можно написать отдельные библиотеки), с другой - это мощнейший инструмент, доступный в любой версии. Увы если дать этот инструмент инженеру, не доконца понимающему его возможностей, могут возникнуть непредвиденные симуляции Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 2 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 6 hours ago, lexx said: синтезатор предполагает это и адаптирует ваш код По каким правилам он "адаптирует"? И как разработчик должен быть уверен, что при очередной перекомпиляции эта адаптация не приведет к другому результату? 6 hours ago, lexx said: Кстати SystemVerilog и использование always_ff (и так далее) как раз запретят такое применение, с этой точки зрения он более строг, чем чистый Verilog. Не заметил. Изначально этот код был написан на SV Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться