Des333 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба В общем, надо писать нормальные конструкции и никаких проблем тогда не будет. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 марта, 2010 Опубликовано 26 марта, 2010 (изменено) · Жалоба Компилил то, что Вы предложили (т.е. не Вы, а Leka). module tst( a, b ); output reg a=0; output reg b=0; always@* begin a <= b; b <= 0; b <= 1; end endmodule Происходит вот что, как я думаю. Поначалу a=0, b=0. Блок должен сработать, когда b<=1. Задаст a<=b=1, потом b<=0, потом b<=1. После этого никаких событий (изменений) больше не возникает. Никаких вечных циклов. Вечное ожидание. Изменено 26 марта, 2010 пользователем ViKo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Синтезаторы-то нормально воспринимают такую конструкцию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Никаких вечных циклов. По стандарту - вечный цикл. always @* в данном случае эквивалентно always @( b ) далее происходит так. 1) "reg b = 0" вызывает update event для b. 2) always срабатывает. 3) выполняетися evaluation event для begin...end 4) и 5) и 6) выполняются три update event-а для a, b и b, порожденные evaluation event-ом 3) 7) update евент для b активирует always. ну и GOTO 2) так как никаких "#" не стоит, и все это происходит внутри одного момента-кванта времени и опять есть активный евент. Синтезаторы-то нормально воспринимают такую конструкцию. так на то они и синтезаторы, что у них нет этого геморроя с event-ами, их очередью и активацией. Это все чисто для моделирования, и ни для чего более. А синтез идет по правилам вычисления statement-ов, которые вполне прозрачны. Расставляйте #-ки, и проблем не будет. b <= #1 0; Синтезатор их проигнорит, а симулятор не зависнет - это азы. UPD: У синтезаторов и стандарт свой - IEEE 1364.1-2002 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Вечного цикла быть не должно: a <= b; b <= 0; b <= 1; вроде как эквивалентно: a <= b; RHS = 0; RHS = 1; b <= RHS; а этот код воспринимается симулятором без проблем, выдавая: a=1 b=1, как и в случае: a <= b; b <= 1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Что вызывает начальный заход в блок? Висели себе a и b в нуле, никого не трогали. Событие - это изменение сигналов, к которым чувствителен блок. Дальше, действительно, при выходе из блока b=0, тут же b=1 - вот и событие. А началось с чего? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Инициализация? Было "x", стало "0". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Инициализация? Было "x", стало "0". Похоже. Причем, даже такой модуль module tst( a, b ); output reg a; output reg b = 0; always @(a) begin b = 1; end endmodule Синтезируется в a=0, b=1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Событие - это изменение сигналов, к которым чувствителен блок. Так оно было... Вначале, при инициализации, "x" -> "0", запустившее весь процесс. А потом внутри блока стоит явный перепад, хоть и мгновенный, сначала "b <= 0" потом "b <= 1". Именно поэтому убийство "b <= 0" и устраняет вечный цикл. И в этом есть еще разница между "b=0; b=1;" и "b<=0; b<=1;" - то в первом случае два апдейта происходят внутри вычисления одного и так активного эвалюшн-евента (вычисления блока begin...end), соотв. value change ничего не делает (евент и так активный, ну и еще раз ему статус активности установили), и не висим, ну а при неблокирующих - по любому два отдельных апдейт-евента, выполняющихся уже после того, как евалюшн-евент полностью вычислен, вот и все вешаются - запускаем все заново. Синтезируется в a=0, b=1 На самом деле в "a=x" - ноль это просто совпадение... Что "x" нулем оказался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба module tst(a, b); output reg a = 0; output reg b = 0; always @* begin a <= a | b; b <= 1; b <= 0; end синтезируется в a=0 b=0, так что можно считать, что b <= 1 никогда не исполняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба module tst(a, b); output reg a = 0; output reg b = 0; always @* begin a <= a | b; b <= 1; b <= 0; end синтезируется в a=0 b=0, так что можно считать, что b <= 1 никогда не исполняется. А как оно должно исполняться то? Что, сигнал b должен чуть-чуть времени побыть нулем, потом чуть-чуть единицей? :) Вы представляете схему того, что Вы пишите? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба А как оно должно исполняться то? Точно так-же, как и: module tst(a, b); output reg a = 0; output reg b = 0; always @* begin a <= a | b; b <= 0; end те наличие/отсутствие "b <= 1;" перед "b <= 0;" не должно влиять на синтез и симуляцию. А на практике - влияет: вечный цикл в симуляторе с "b <= 1;". В-общем, для себя решил не подмешивать ложку "=" в бочку "<=" только ради симуляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба ... В-общем, для себя решил не подмешивать ложку "=" в бочку "<=" только ради симуляции. Так у Вас тут нигде "=" и не используются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 53 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба В общем, надо писать нормальные конструкции и никаких проблем тогда не будет. :) +1000! Все эти always @(posedge clk) if(...) count = ...; else count <= ...; не более, чем плод неаккуратности - нету тут ни смысла, ни замысла, обыкновенный г..внокод. Это пример того, как не надо писать, после него и остальные примеры не вызывают ни доверия, ни желания рассматривать их в качестве референтных. * * * Что касается плясок с начальным запуском always @*, то давно существует приличная альтернатива в виде always_comb, который всегда в нулевой момент времени (начало симуляции) производит один прогон, не зависимо от того, изменялись ли объекты, которые входят в его список чувствительности. Есть и другие полезные преимущества always_comb перед always @* - такие как более четкие правила посторения списка чувствительности (у always @* список чувствительности может быть неполным в случае применения функций, использующих чтение переменных, не переданных в качестве аргументов в функцию). Имеет смысл использовать возможности SystemVerilog'а - он не только для верификации полезен, но и усовершенствовал подобные вещи. * * * des333 К вам вопрос. Возвращась к нашей дискуссии. Вот смотрите, допустим, что ваша трактовка правильна - т.е. событие "вычисление RHS" является частью выражения, и поэтому блокирующие присваивания в силу того, что блокируют все нижеидущие выражения, гарантировано выполняются вперед. Т.е.: always @(posedge clk) begin ... a = x; b <= a; ... end a гаранировано получает значение x до вычисления RHS следующего присваивания, т.е. по сути этот код эквивалентен: always @(posedge clk) begin ... a = x; b <= x; ... end Тогда рассмотрим такой вариант: always @(posedge clk) begin ... b <= a; a = x; ... end Каков будет тут порядок по вашему мнению? Т.е. тут, как видите, блокирующее присваивание идет после, и вычисление RHS не блокируется выражением a = x. Но блокирует ли событие "вычисление RHS" идущее ниже выражение a = x? Про это ничего, вроде, не сказано (я не нашел). Т.е. гарантируется ли порядок вычисления, описанный в этом варианте? Или имеем неоднозначность? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба des333 К вам вопрос. ... Каков будет тут порядок по вашему мнению? Т.е. тут, как видите, блокирующее присваивание идет после, и вычисление RHS не блокируется выражением a = x. Но блокирует ли событие "вычисление RHS" идущее ниже выражение a = x? Про это ничего, вроде, не сказано (я не нашел). Т.е. гарантируется ли порядок вычисления, описанный в этом варианте? Или имеем неоднозначность? :) На мой взгляд, неоднозначности не будет. Вначале произойдет "вычисление RHS", затем блокирующее присваивание, а после "non blocking assign update event". В итоге a будет равно x, а b будте равно предыдущему значению a. Основываюсь на том, что "non blocking assign update event" менее приоритетный, чем "active events"(которые как раз и могут выполняться в любом порядке, если они не в последовательном блоке) и чем "inactive events". Пункты 5.3 - 5.4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться