lexx 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 1 minute ago, pavlovconst said: По каким правилам он "адаптирует"? И как разработчик должен быть уверен, что при очередной перекомпиляции эта адаптация не приведет к другому результату? А нет этих правил, можно интерпретировать как баг синтеза. Бывали случаи когда синтезатор даже неправильно интерпретировал имена регистров, только для одной версии. Для FPGA можно и так посмотреть, в случае с ASIC есть Formality. В последнем проекте: ncsim, vivado, dc и Formality, как один пакет (по чипу потом все сошлось) выдавали одно, а вот результат Zebu отличался. Причем это был как SystemVerilog (в чем я еще могу согласится), но и чистый Verilog. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 5 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 3 hours ago, dxp said: Синтез имеет другую исполнительную модель - "тру параллел", там гонок в этом смысле нет. Пока что получается, что синтезатор имплементирует код именно так, как задумал разработчик. А симуляторы, для того, чтобы воспроизвести тот же результат, что и в реальности - требуют переписать код и соблюсти много дополнительных условий. Видите ли, у них там "сложная временная модель"... =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 34 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба Приветствую! 1 hour ago, pavlovconst said: Пока что получается, что синтезатор имплементирует код именно так, как задумал разработчик. Синтезатор и симулятор выполняют разные задачи. Синтез физической структуры обработки дизайна и симуляция поведения во времени. Отсюда и возможные разные результаты при одном и том же входном коде. Ну и опять же - чтобы симулятор правильно отображал реальную действительность модель симуляции должна быть полной. А чисто функциональная симуляция грешит упрощениями (0 задержки) для ускорения этого процесса. Вот сим и не понял что задумал разработчик. 1 hour ago, lexx said: По каким правилам он "адаптирует"? И как разработчик должен быть уверен, что при очередной перекомпиляции эта адаптация не приведет к другому результату? Как обычно - разработчик делает pots-synthesis/post-P&R симуляцию и сравнивает поведение с функциональной golden reference моделью. Да еще и формальная верификация добавляется. И если вдруг будут разные результаты - то начинает копать, чтобы понять где именно (в синтезаторе или в симе) он нако... был неправильно понят . Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 1 hour ago, pavlovconst said: По каким правилам он "адаптирует"? Насколько мне известно изначально происходит распознавание синтаксических структур и прагм. потом на основе этих данных происходит синтезирование примитивов и элементов, ну а дальше map, place&route. Чтобы быть уверенным в каждом проходе компиляции достаточно выдерживать одни и те же правила описания (которые описаны в стандарте) и никаких проблем не должно возникнуть (если только вы не перешли на другой, свежий и новый синтезатор - старые игроки обычно не грешат изменением поддержки стандартов) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 56 minutes ago, RobFPGA said: Как обычно - разработчик делает pots-synthesis/post-P&R симуляцию и сравнивает поведение с функциональной golden reference моделью. Симуляция не покрывает, только формальная верификация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 5 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 8 hours ago, dxp said: почитайте про планировщик виртуальной машины симулятора (по ссылкам выше про это тоже есть), например, тут Почитал, и мне даже удалось заставить симулятор сделать задержку в два такта. Но такой код, с перемешанными блокирующими и неблокирующими присваиваниями, оставлять в проекте мне было бы стыдно. =( 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; brd_err2[3: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]; 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 18 minutes ago, pavlovconst said: Почитал, и мне даже удалось заставить симулятор сделать задержку в два такта. Но такой код, с перемешанными блокирующими и неблокирующими присваиваниями, оставлять в проекте мне было бы стыдно. =( уберите блокирующие. они, в вашем случае роли не играют абсолютно. так будет не стыдно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 6 минут назад, pavlovconst сказал: Почитал, и мне даже удалось заставить симулятор сделать задержку в два такта. А почему сразу не сделать это в явном виде. Ведь Вам дали ссылку на Клиффа: Guideline: Use blocking assignments in always blocks that are written to generate combinational logic [1]. Guideline: Use nonblocking assignments in always blocks that are written to generate sequential logic [1]. Но Вы это игнорируете... И еще. Вам действительно надо сделать что-то вроде этого: brd_err2[3] = in_data[3] || in_data[2] || in_data[1] || in_data[0]; только за один такт? С какой скоростью в проект "прибывают" данные и какая частота у "clk"? Может быть можно успеть все эти вычисления сделать и по-другому? А главный вопрос вот какой: какой смысл делать вот так: " Намеренно использую при этом блокирующее присваивание, так код получается коротким и хорошо читаемым."? Если потом приходится более 20-то часов выяснять как преодолеть проблему данного кода. И проблема еще не решена. Потому как если даже Вы заставите программные инструменты сделать "как надо" сегодня, то через полгода-год появится новая версия софта и возможно проблемы выплывет снова. IMXO, за 20 часов можно переделать проект так, чтобы наверняка не было никаких проблем... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 25 minutes ago, iosifk said: А почему сразу не сделать это в явном виде. ну лень ему писать красиво always @(posedge clk) begin if( ~nrst ) begin brd_err2 <= '0; brd_err2_cntr <= '0; end else begin brd_err2[3] <= |{ in_data[3 : 0]}; brd_err2[2] <= |{in_data[4], in_data[2 : 0]}; brd_err2[1] <= |{in_data[5], in_data[2 : 0]}; brd_err2[0] <= |{in_data[3], in_data[1]}; // brd_err2_cntr <= brd_err2_cntr + brd_err2[3] + brd_err2[2] + brd_err2[1] + brd_err2[0]; end end да и обычный декодер флагов это, со счетчиком событий Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flood 13 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба Попробуйте еще добавить задержки в неблокирующие присваивания. Так проще смотреть значения выходов при движении курсора по фронту клока. Например, так: `timescale 1ns/100ps ... brd_err2_cntr[7:0] <= #1 brd_err2_cntr[7:0] + ... Пишут что это не всегда хорошо. За и против взвешены в этой статье: http://www.sunburst-design.com/papers/CummingsSNUG2002Boston_NBAwithDelays.pdf Я пока не сталкивался со случаями, когда бы это вредило. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavlovconst 5 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 49 minutes ago, des00 said: ну лень ему писать красиво des00, Спасибо за "красивый" вариант, но в целевом проекте все несколько сложнее устроено. Поэтому я и пытаюсь дожать вариант с блокирующими. 1 hour ago, iosifk said: если даже Вы заставите программные инструменты сделать "как надо" сегодня, то через полгода-год появится новая версия софта и возможно проблемы выплывет снова Порядок обработки событий планировщиком симулятора, описанный в стандарте, поменяется наврядли =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 19 minutes ago, pavlovconst said: des00, Спасибо за "красивый" вариант, но в целевом проекте все несколько сложнее устроено. Поэтому я и пытаюсь дожать вариант с блокирующими. тогда выкладывайте полный код, что же у вас там такое, что потребовало блокирующего присваивания в процессе, работающем по клоку. за 20 лет не припомню такой ситуации. Точнее не так, что там такое, что непременно требует блокирующее присваивание, без возможности реализации на внутренних, для процесса, переменных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 4 минуты назад, des00 сказал: Точнее не так, что там такое, что непременно требует блокирующее присваивание, без возможности реализации на внутренних, для процесса, переменных? Я дополню... Хотя бы даже не код, а словесное описание или блок-схему алгоритма... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 30 сентября, 2019 Опубликовано 30 сентября, 2019 · Жалоба 8 hours ago, des00 said: Точнее не так, что там такое, что непременно требует блокирующее присваивание, без возможности реализации на внутренних, для процесса, переменных? При синтезе все равно будет как блокируещее, так что не понимаю упорства. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 1 октября, 2019 Опубликовано 1 октября, 2019 · Жалоба В 30.09.2019 в 14:48, pavlovconst сказал: Пока что получается, что синтезатор имплементирует код именно так, как задумал разработчик. А симуляторы, для того, чтобы воспроизвести тот же результат, что и в реальности - требуют переписать код и соблюсти много дополнительных условий. Видите ли, у них там "сложная временная модель"... =) Несколько не так. Исходно HDL (верилог, в частности) разрабатывались как языки для моделирования. Отсюда и возникла концепция исполнительной виртуальной машины, обеспечивающей корректное моделирование параллельно выполняемых процессов, и машина эта работает по определённым правилам - например, те же самые блокирующие и неблокирующие присваивания, которые работают в разных регионах событий и позволяют более гибко описывать процесс моделирования. Идея использовать синтез из верилог-описания возникла позднее, и не все средства языка для этого поддерживаются - существует некое синтезируемое подмножество. Естественно, что синтезированная реализация работает на другой исполнительной платформе, где нет виртуальной машины, соответственно, нет и ограничений, связанных с ней. С другой стороны возникает набор своих требований - например, не всякое даже в принципе синтезируемое описание может быть реализовано на конкретной платформе - например, если вы напишите: always @(posedge clk or negedge clk) ... и попытаетесь скормить это синтезатору практически любой современной ПЛИС, то получите отлуп, т.к. такая конструкция предполагает реализацию в виде флопа, работающего по обоим фронтам, а таких в нынешних ПЛИС просто нет (вроде были в Spartan или Spartan2), в то время как симулятор это съест без проблем. Собственно именно логика работы неблокирующих присваиваний в тактируемых поведенческих блоках и ложится нативно на поведение флопов - по фронту записывается значение, которые было на входе до фронта (на момент его возникновения). А блокирующее присваивание нарушает эту логику - там выстраивается цепочка присваиваний - это как раз хорошо ложится на описание комбинационной логики - там важен порядок следования сигналов по логическим переменным. Отсюда и возникло простое правило: для описания флопов - тактируемые блоки с неблокирующими присваиваниями, для комбинационной - нетактируемые блоки с блокирующими. Это порождает корректное поведение с точки зрения соответствия "виртуальная машина симулятора - аппаратное исполнительной устройство". Отсюда простой вывод: если хочется иметь в арсенале мощный инструмент для моделирования (симулятор) и иметь от него пользу, надо просто соблюдать пару простых правил. Блокирующие присваивания, кстати, очень даже применимы в тактируемых блоках, но только для вычисления значений переменных, используемых в правой части неблокирующих присваиваний - нередко это просто удобно и повышает читабельность, когда логика развесистая и нетривиальная. Для симулятора тут всё корректно: сперва вычисляются значения блокирующих (Active Region), причём итеративно (учитывая изменения переменных в других блоках в текущем дельта-цикле), затем они присваиваются через неблокирующие (NBA Region). Синтез тоже понимает эту логику и прекрасно разносит реализацию на комбинационную логику и флопы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться