ViKo 1 27 марта, 2010 Опубликовано 27 марта, 2010 (изменено) · Жалоба не более, чем плод неаккуратности - нету тут ни смысла, ни замысла... Если это ко мне претензия... Раскинув мозгами, я тоже пришел к такому выводу. Не связана никак структура ПЛИС и подобные "присваивания". Но и очень плохого ничего в таком коде не вижу. Работает. На референсные примеры кода я уж точно не претендую. Вообще эти присваивания - чисто облегчить жизнь "писателю". Можно обойтись одними = (интересно, несогласные с этим есть?) Чтобы писать "нормальные" конструкции, надо понять, как и почему возникают "ненормальные" :) Рискну даже высказать мысль, что можно обойтись и одними <= :) Изменено 27 марта, 2010 пользователем ViKo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба На мой взгляд, неоднозначности не будет. Вначале произойдет "вычисление RHS", затем блокирующее присваивание, а после "non blocking assign update event". А почему "вычисление RHS" будет вперед блокирующего присваивания? Где это регламентировано? Ведь если сказано, что блокирующее присваивание блокирует все идущие за ним выражения, то про неблокирующее ничего такого не сказано, в том числе и то, что "вычисление RHS" что-то блокирует. Таким образом, почему a = x; не может быть помещено в очедедь перед RHS? Основываюсь на том, что "non blocking assign update event" менее приоритетный, чем "active events"(которые как раз и могут выполняться в любом Апдейт-то - да, он выполняется на третьей фазе обработки очереди событий и тут не мешает. Но я не про апдейт LHS, а про вычисление RHS. Если это ко мне претензия... Что вы, какая к вам может быть претензия, когда и пример-то не ваш (а, как было объявлено, из экзамплов квесты, рекомендованных в качестве референтных). Чтобы писать "нормальные" конструкции, надо понять, как и почему возникают "ненормальные" :) Лучше и не скажешь, совершенно согласен! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба А почему "вычисление RHS" будет вперед блокирующего присваивания? Где это регламентировано? Ведь если сказано, что блокирующее присваивание блокирует все идущие за ним выражения, то про неблокирующее ничего такого не сказано, в том числе и то, что "вычисление RHS" что-то блокирует. Таким образом, почему a = x; не может быть помещено в очедедь перед RHS? ... Так неблокирующее присваивание в коде расположено до блокирующего. А в последовательном блоке присваивания должны выполняться по порядку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Так неблокирующее присваивание в коде расположено до блокирующего. А в последовательном блоке присваивания должны выполняться по порядку. Именно так. В очередной раз, к слову, повторю пункт стандарта, который почему-то никто не хочет прочитать. И который не делает никаких поблажек никаким типам statement-ов. Вообще, на самом деле, единственная видимая "сверху", не углубляясь в устройство симуляторов, разница между блокирующим и неблокирующим присваиванием то, что первый присваивает в той фазе, когда производятся все вычисления RHS-ов, таким образом каждый следующий RHS гарантировано получает значение от каждого предыдущего блокирующего присваивания, ну а второй откладывает присваивание результата на "после того, как все RHS-ы вычислены", тем самым обеспечивая наоборот, неизменность значения в последующих RHSах. В остальном их выполнение полностью идентично и на равных подчиняется 5.4.1. 5.4.1 Determinism This standard guarantees a certain scheduling order. 1) Statements within a begin-end block shall be executed in the order in which they appear in that begin-end block. Execution of statements in a particular begin-end block can be suspended in favor of other processes in the model; however, in no case shall the statements in a begin-end block be executed in any order other than that in which they appear in the source. Аж дважды написано - сначала что statement-ы должны выполняться последовательно, а потом - что никак они не должны выполняться, кроме как последовательно :) Чтобы все поняли это однозначно, и что никаких лазеек мимо нет :), и что если что-то попало между begin и end - то последовательно, последовательно, и только последовательно :) те наличие/отсутствие "b <= 1;" перед "b <= 0;" не должно влиять на синтез и симуляцию. А на практике - влияет: вечный цикл в симуляторе с "b <= 1;". И на практике должно влиять на симуляцию, именно запуском всех событий, чувствительных к перепаду на "b", хоть этот перепад и формальный, длительностью в ноль единиц времени. А на синтез, все верно, влиять не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Кстати... Вот очень простой и яркий пример неоднозначности из синопсисовских док. always @(posedge clk) a=b; always @(posedge clk) b=a; Имеет право при симуляции равновероятно обменять a с b, занести в обе "a", или занести в обе "b", в зависимости от того, последовательно ли были обработаны эти эвенты, в какой последовательности, или вообще параллельно. Однако при синтезе - гарантирована однозначность - обмен. И, заметим, опять пример никак не связан с гарантировано-последовательным исполнением внутри begin...end. Те самые гадкие межблочные связи. Отсюда напрашивается вполне логичный вывод - блокирующие присваивания не стоит использовать в том случае, если переменная, которой происходит присваивание, используется в другом блоке или конструкции, нежели присваивается. Причем не важно, комбинаторный это блок, или регистровый. Потому что это всегда вызовет неоднозначность из серии описанной в этом посте - какой блок вычислен раньше, такой и результат. А отсюда - еще вывод. Присваивать окончательный результат, предназначенный для использования в других блоках, если внутри блока он итерационно или последовательно вычислялся с использованием блокирующих присваиваний, желательно всегда неблокирующим, и именно в том же блоке (иначе гонки!!).... Если не хотите на synthesis/simulation mismatch нарваться. Вот так получается. Как-то так: begin temp1 = .....; temp2 = ....; temp3 = f(temp1); if (sel) temp4 = temp3; else temp4 = temp2; real_out <= temp4; end если использовать в других блоках real_out - будет все гарантировано однозначно. А вот если temp4... Как судьба распорядится :) Я лично с синопсисом тут полностью согласен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 (изменено) · Жалоба При помощи `define можно описывать в стиле ЯП, так сейчас выглядит синтезируемое описание N-ферзей с циклами, и тп: module tb(); wire [31:0] q; reg clk = 0; tst _1(q, clk); always #1 clk <= ~clk; always @( posedge clk ) begin if ( q == -2 ) $finish; else if ( q != -1 ) $display( "%d", q ); end endmodule 'define sys ... ... module tst( output reg [31:0] q = -1, input clk ); wire [31:0] count; wire [15:0] pos; reg [15:0] N = 0; reg rst = 0; queens _1(count, pos, N, rst, clk); `sys always@(posedge clk) begin `seq `p rst <= 1; `for( 1, 11 ); `p N <= `var; `p rst <= 1; `p q <= count; `s rst <= 0; `p q <= -1; `repeat `until( pos == 0 ); `endfor `p q <= count; `s q <= -2; end endmodule module queens( ... Осталось прикрутить printd() из "устройства печати", слегка поправить надо... Рискну даже высказать мысль, что можно обойтись и одними <= :) :a14: Изменено 27 марта, 2010 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Рискну даже высказать мысль, что можно обойтись и одними <= :) Тогда, пожалуй... Приведите пожалуйста пример цикла for (не generate) или while с использованием одних "<=". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 (изменено) · Жалоба ... вывод. Присваивать окончательный результат, предназначенный для использования в других блоках, ... желательно всегда неблокирующим ... Полностью согласен. Тогда, пожалуй... Приведите пожалуйста пример цикла for (не generate) или while с использованием одних "<=". Готов попробовать преобразовать исходный с "=" на "<=" (кроме "=" в "for(i = ...; ...; i = i+1)"), на небольшом примере с tb(). Изменено 27 марта, 2010 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба При помощи `define можно описывать в стиле ЯП, ... Лично мне кажется, что Вы занимаетесь неблагодарным и ненужным делом. Можно писать на С в стиле С++ (в стиле ООП) или на С++ в стиле С (не используя ООП), можно также пытаться писать на С как на LISP. Но, на мой взгляд, самый хороший результат будет достигаться, если писать на С когда нужен чисто императивный язык, для ООП испоьзовать С++, и использовать LISP, когда Вам нужен функциональный язык. Каждый инструмент создан, чтобы решать определенные задачи, и, скорее всего (если он создан с умом), именно он будет решать эти задачи лучше всего. HDL созданы, чтобы описывать устройства. Если Вам нужно описать устройство - Ваш выбор HDL. По-моему, лучше потратить больше времени на глубокое (или очень глубокое) изучение языка. Или на практику. Но не на то, чтобы сделать из HDL подобие императивных ЯП, чтобы потом этим "подобием" пытаться решать задачи, для которых HDL изначально создавались. А иначе получается "микроскопом гвозди заколачивать", да при этом еще к нему деревянную ручку вначале нужно прикрутить, чтобы удобней держать было. :) Надеюсь, без обид. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба (кроме "=" в "for(i = ...; ...; i = i+1)") С таким "кроме" каждый может. В свое время на AHDL, где только generate, очень много "на-кроме-лся". А Вы без "кроме" :), так как "i" такая же полноправная переменная, участвующая в вычислении блока, как и остальные, и, более того, обычно участвует в RHS-ах, или как индекс, или как номер итерации, или еще как.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба "i" такая же полноправная переменная, участвующая в вычислении блока, как и остальные, и, более того, обычно участвует в RHS-ах, или как индекс, или как номер итерации, или еще как.... Это пожалуйста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Это пожалуйста. Так с чего бы "пожалуйста"-то :) Одним переменным, типа позволительно блокирующими присваиваниями присваиваться... А другим, что же, нет? Дискриминация. Так что никаких "кроме". Или только "<=", или уж полноправно и везде и "=" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба ...HDL созданы, чтобы описывать устройства. Если Вам нужно описать устройство - Ваш выбор HDL. ...Но не на то, чтобы сделать из HDL подобие императивных ЯП, чтобы потом этим "подобием" пытаться решать задачи, для которых HDL изначально создавались. Тема то - про высокоуровневое описание синтезируемых устройств. А синтезируемое подмножество VHDL/Verilog/SV - весьма низкоуровневый язык наподобие ассемблера в ЯП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба А синтезируемое подмножество VHDL/Verilog/SV - весьма низкоуровневый язык наподобие ассемблера в ЯП. Это от синтезатора зависит... Вот у этого например посмотрите, каково это подмножество. Вот там - да, высокоуровневое описание. http://www.bluespec.com/products/bsc.htm И я думаю, он не последний (не первый точно, тот же Synopsys BC был в свое время). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Тема то - про высокоуровневое описание синтезируемых устройств. А синтезируемое подмножество VHDL/Verilog/SV - весьма низкоуровневый язык наподобие ассемблера в ЯП. Так то оно так, но вот Ваш код, приведенный выше, я бы не назвал более высокоуровневым, чем синтезируемое подмножество V/SV. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться