dxp 58 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Это просто катастрофическая ошибка принципов верилога!!!! "b=..." не может выполнятся до окончания "a=..", так как "a=.." блокирующее.. ", а "Evaluation of RHS a+b" не может выполняться до окончания "b=", так как b= тоже блокирующее. Это беспрекословное правило из пункта 9.2.1. Никакой ошибки принципов нету. Блокирующие присваивания помещаются в очередь событий по своей очередности - они представляют собой единый тип active events. И выполняются строго в указанной очередности. А вот вычисление RHS - это другой тип active events. И выборка из очереди событий этих двух типов может быть произвольной, они друг друга никак не блокируют. Это самое "Evaluation of RHS" заблокировано в очереди событий находящимся перед ним блокирующим "b=", и пока "b=" не исполнено полностью, начинаться исполнение "Evaluation of RHS" не имеет права. Как вы до сих пор не поймете, что "Evaluation of RHS" - это не statement! И никто его заблокировать не может. Блокирующие присваивания блокируют нижеидущие statement'ы, но таковыми являются по сути только выражения с блокирующими присваиваниями. Запись значения в LHS при неблокирующем присваивании происходит на третьей фазе обработки очереди событий, а обработка блокирующих присваиваний - на первой фазе. Поэтому запись значения в LHS выражения с неблокирующим присваиванием даже не конкурирует с формированием значения в выражении с блокирующим присваиванием. Формирование значения в выражении с блокирующим присваиванием происходит на той же фазе, что и вычисление RHS для выражений с неблокирующими присваиваниями, но это вычисление RHS - это не statement, поэтому оно не может быть заблокировано. И очередность тут определяется сугубо реализацией: "...source of nondeterminism is the fact that active events can be taken off the queue and processed in any order". Квартус, в частности, просто строит очередь активных событий в том порядке, как описаны соответствующие выражения в блоке, а иной синтезатор/симулятор может сначала в очередь поместить все блокирующие присваивания, а потом вычисления RHS, а может сделать наоборот. Это его право. По Стандарту языка Verilog. И именно поэтому писать код со смешанными присваиваниями - это большой моветон и аццки bad style. Поэтому приличные тулзы выдают предупреждение на эту тему - неопределенное поведение, потенциальная ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба ... Blocking assigment: a = ... Blocking assigment: b = ... Evaluation RHS of nonblocking assigment: a + b Они могут выполняться в произвольном порядке, но синтезатор тут не мудрит - в каком порядке они описаны в блоке, в таком он их в очередь и помещает. ... Эээ... :07: Вы же сами недавно цитаты из IEEE Std 1364-2001 приводили. Там же написано: 9.2.1 Blocking procedural assignments A blocking procedural assignment statement shall be executed before the execution of the statements that follow it in a sequential block (see 9.8.1). A blocking procedural assignment statement shall not prevent the execution of statements that follow it in a parallel block (see 9.8.2). 9.8 Block statements The block statements are a means of grouping two or more statements together so that they act syntactically like a single statement. There are two types of blocks in the Verilog HDL: Sequential block, also called begin-end block Parallel block, also called fork-join block The sequential block shall be delimited by the keywords begin and end. The procedural statements in sequential block shall be executed sequentially in the given order. The parallel block shall be delimited by the keywords fork and join. The procedural statements in parallel block shall be executed concurrently. 9.8.1 Sequential blocks A sequential block shall have the following characteristics: Statements shall be executed in sequence, one after another Delay values for each statement shall be treated relative to the simulation time of the execution of the previous statement Control shall pass out of the block after the last statement executes begin areg = breg; creg = areg; // creg stores the value of breg end The first assignment is performed and areg is updated before control passes to the second assignment. Отсюда явно не следует то, что Вы написали. Точнее явно следаует, что то, что Вы написали не является истиной. UDP. Не видел, что SM уже такой вопрос задавал - извиняюсь. :) dxp: Ну, во-первых, Вы писали что все три выражения могут быть выполнены в произвольном порядке - но это не так важно, видать, описались. А по теме - в стандарте еще есть такой вот пример: //non_block1.v module non_block1; reg a, b; initial begin a = 0; b = 1; a <= b; // evaluates, schedules, and b <= a; // executes in two steps end initial begin $monitor ($time, ,"a = %b b = %b", a, B); #100 $finish; end endmodule с такими комментариями: Step1 The simulator evaluates the righthand side of the non blocking assignments and schedules the assignments for the end of the current time step Step 2: At the end of the current time step, the simulator updates the left-hand side of each non blocking assignment statement. assignment values are: a = 1 b = 0 можете сами посмотреть на странице 123 - а то его цитировать неудобно - форматирование не сохранить. Так вот, у них почему-то нигде не написано, что a и b могут в итоге получить значение иные, чем у них указано. Что реально, если считать, что Ваши предположения верны. Почему? Вот еще большой кусок стандарта, который, на мой взгляд, отвечает на все наши вопросы: 5.3 The stratified event queue The Verilog event queue is logically segmented into five different regions. Events are added to any of the five regions but are only removed from the active region. 1) Events that occur at the current simulation time and can be processed in any order. These are the active events. 2) Events that occur at the current simulation time, but that shall be processed after all the active events are processed. These are the inactive events. 3) Events that have been evaluated during some previous simulation time, but that shall be assigned at this simulation time after all the active and inactive events are processed. These are the non blocking assign update events. 4) Events that shall be processed after all the active, inactive, and non blocking assign update events are processed. These are the monitor events. 5) Events that occur at some future simulation time. These are the future events. Future events are divided into future inactive events, and future non blocking assignment update events. The processing of all the active events is called a simulation cycle. The freedom to choose any active event for immediate processing is an essential source of nondeterminism in the Verilog HDL. An explicit zero delay (#0) requires that the process be suspended and added as an inactive event for the current time so that the process is resumed in the next simulation cycle in the current time. A non blocking assignment (see 9.2.2) creates a non blocking assign update event, scheduled for current or a later simulation time. The $monitor and $strobe system tasks (see 17.1) create monitor events for their arguments. These events are continuously re-enabled in every successive time step. The monitor events are unique in that they cannot create any other events. The call back procedures scheduled with PLI routines such as tf_synchronize() (see 25.58) or vpi_register_cb(cb_readwrite) (see 27.33) shall be treated as inactive events. 5.4 The Verilog simulation reference model In all the examples that follow, T refers to the current simulation time, and all events are held in the event queue, ordered by simulation time. while (there are events) { if (no active events) { if (there are inactive events) { activate all inactive events; } else if (there are non blocking assign update events) { activate all non blocking assign update events; } else if (there are monitor events) { activate all monitor events; } else { advance T to the next event time; activate all inactive events for time T; } } E = any active event; if (E is an update event) { update the modified object; add evaluation events for sensitive processes to event queue; } else { /* shall be an evaluation event */ evaluate the process; add update events to the event queue; } } 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. 2) Non blocking assignments shall be performed in the order the statements were executed. Consider the following example: initial begin a <= 0; a <= 1; end When this block is executed, there will be two events added to the non blocking assign update queue. The previous rule requires that they be entered on the queue in source order; this rule requires that they be taken from the queue and performed in source order as well. Hence, at the end of time step 1, the variable a will be assigned 0 and then 1. 5.4.2 Nondeterminism One source of nondeterminism is the fact that active events can be taken off the queue and processed in any order. Another source of nondeterminism is that statements without time-control constructs in behavioral blocks do not have to be executed as one event. Time control statements are the # expression and @ expression constructs (see 9.7). At any time while evaluating a behavioral statement, the simulator may suspend execution and place the partially completed event as a pending active event on the event queue. The effect of this is to allow the interleaving of process execution. Note that the order of interleaved execution is nondeterministic and not under control of the user. dxp: Е-мае, Вы же недавно цитировали теже куски стандарта (опять извиняюсь, болею, поэтому видать тоже проморгал) :) Только вот цитаты приводим одни и теже, а понимание смысла этих цитат у нас координально разное. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Я говорил не о регистрах, а об обязательности регистрового типа - в данном случае "output integer с". ... так что тут, с "output c", никакого результата, кроме ошибки компиляции, получиться не должно было. Пока не указать тип-регистр - reg, integer... Так как по умолчанию подразумевается "output wire c" Как же не получилось? Я же картинку привел с результатом. Не верите глазам? По поводу работы компилятора. Естественно, компилятору нет смысла скакать по операторам вверх-вниз. Идет попорядку. Нашел = вычислил, присвоил, нашел <= вычислил, запомнил до выхода из блока. Практически всегда можно предсказать результат. Нельзя предсказать результат в блоках такого типа: a <= b; a <= c; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Как же не получилось? Я же картинку привел с результатом. Не верите глазам? По поводу работы компилятора. Естественно, компилятору нет смысла скакать по операторам вверх-вниз. Идет попорядку. Нашел = вычислил, присвоил, нашел <= вычислил, запомнил до выхода из блока. Практически всегда можно предсказать результат. Нельзя предсказать результат в блоках такого типа: a <= b; a <= c; В блоках такого типа вообще ничего понять нельзя. Напишите код, в котором будет одназначно понятно, где Вы используете эти строчки: между begin/end или между fork/join или вообще проста так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Как же не получилось? Я же картинку привел с результатом. Не верите глазам? Для кода из поста #256 без каких либо изменений - извините, но не верю. А я говорил про ошибку именно в том коде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба ... Как вы до сих пор не поймете, что "Evaluation of RHS" - это не statement! ... С чего Вы взяли? Из стандарта: The Verilog HDL contains two types of procedural assignment statements: Blocking procedural assignment statements Non blocking procedural assignment statements Так как: The non blocking procedural assignments shall be evaluated in two steps as discussed in Clause 5. These two steps are shown in the following example. Step1 At posedge c, the simulator evaluates the right-hand sides of the non blocking assignments and schedules the assignments of the new values at the end of the non blocking assign update events (see 5.4). То "Evaluation of RHS" есть один из этапов "Non blocking procedural assignment statements". А данное утверждение: The procedural statements in sequential block shall be executed sequentially in the given order. Применимо ко всем "procedural statements". И, следовательно, к "Non blocking procedural assignment statements". И, следовательно, к "Evaluation of RHS". Мне кажется, эти цитаты все объясняют. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KWIer 0 24 марта, 2010 Опубликовано 24 марта, 2010 (изменено) · Жалоба Начитавшись баек про светлое будущее, которое пророчит нам CatapultC о разработке системы на плис за пару часов, паралельно раскладывая на 2 мониторе косынку... Решил все-таки на это чудо посмотреть... а не тут то было... Скачать хоть какую-нибудь версию (пусть даже не крякнутую :) мне за час гугления так и не удалось :( Пока в голове только мысль, что КатапультаСи - это "Лохнесское чудовище" RTL дизайнеров. Детей пугают, взрослые в него не верят, а в природе его так вообще не существует :) Кто-нибудь может поделится дистрибутивом? :) Изменено 24 марта, 2010 пользователем KWIer Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба А вот вычисление RHS - это другой тип active events. И выборка из очереди событий этих двух типов может быть произвольной, они друг друга никак не блокируют. Это где такое написано? Именно в стандарте? Ссылку плиз на пункт. В стандарте совершенно наоборот написано: - Statements within a begin-end block shall be executed in the order in which they appear in that begin-end block. - A blocking assignment statement (see 9.2.1) with a delay computes the right-hand side value using the current values, then causes the executing process to be suspended and scheduled as a future event. If the delay is 0, the process is scheduled as an inactive event for the current time. When the process is returned (or if it returns immediately if no delay is specified), the process performs the assignment to the left-hand side and enables any events based upon the update of the left-hand side. The values at the time the process resumes are used to determine the target(s). Execution may then continue with the next sequential statement or with other active events. Еще посмотрите на Example 3 в 9.2.2. Он, этот example не допускает никаких разночтений в результатах. В общем жду от Вас цитату из стандарта, где явно написано, что вычисление RHS у statement-ов, следующих за блокирующим присваиванием, это нечто такое "отдельно взятое" и не подчиняется 9.2.1. Поэтому запись значения в LHS выражения с неблокирующим присваиванием даже не конкурирует с формированием значения в выражении с блокирующим присваиванием. Запись в LHS еще как конкурирует. Потому как блокирующие присваивания могут его изменять между вычислениями RHS-ов как блокирующих, так и неблокирующих присваиваний, в зависимости от того, в какой последовательности они проследовали, и это явно определено. Если Вы этого не понимаете из стандарта, приведите хоть один пример какого нибудь тула, это правило нарушающего, докучи с подтверждением от техподдержки, что это не баг. UPD: все таки 5.6.3 и 5.6.4 говорят однозначно о том, что блокирующие присваивания блокируют (перешедуливая процесс в inactive или future) все дальнейшие вычисления в нем, включая RHS неблокирующих, при этом делая update для своего LHS перед дальнейшим вычислением всего остального. И суть в том, что update блокирующие делают в той очереди и в единой последовательности с рассчетами RHS-ов неблокирующих, причем делают немедленно, не откладывая на конец процесса, чем и обеспечивают то, что в следующих RHSах как блокирующих, так и неблокирующих, будет обновленное значение. А вот другая непонятка есть: если сделать begin a<=1; a=2; end то если я что-то понимаю в стандартах - результат должен быть однозначно 1, что по логике как бы совсем не очевидно. (так как неблокирующее зашедулит апдейт-эвент в конец очереди, а блокирующее проапдейтит мгновенно по факту вычисления его RHSа еще до исполнения того отложенного на конец процесса апдейта от неблокирующего) UPD2: Cadence IUS это подтвердил. Результат 1 UPD3: Questa тоже единичку дала UPD4: Квартус облажался. Еррор - низзя миксовать блокирующие и неблокирующие одной переменной. UPD5: синопсис DC тоже облажался с той же ошибкой... Это несинтезируемо что-ли... А было бы полезно... как бы отложенная запись в переменную, рассчитываемую итерационно. в общем никакой неоднозначности нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 марта, 2010 Опубликовано 24 марта, 2010 (изменено) · Жалоба Для кода из поста #256 без каких либо изменений - извините, но не верю. А я говорил про ошибку именно в том коде. Именно! Зуб даю! Шоб я сдох! Век воли не видать! Чем еще поклясться? Впрочем, можете проверить. И признать свою ошибку. P.S. Похоже, профессия RTL Designer все-таки имеет будущее? :) Изменено 24 марта, 2010 пользователем ViKo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба В SV-2005 другие умолчания, чем в Verilog-2001. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Des333 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Именно! Зуб даю! Шоб я сдох! Век воли не видать! Чем еще поклясться? Впрочем, можете проверить. И признать свою ошибку. P.S. Похоже, профессия RTL Designer все-таки имеет будущее? :) А Вы чем компилили? Кварту материться, если стоит 2001. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 24 марта, 2010 Опубликовано 24 марта, 2010 · Жалоба Впрочем, можете проверить. И признать свою ошибку. Да и не буду проверять. Стандарт V этого не позволяет и все тут. В SV-2005 другие умолчания, чем в Verilog-2001. Вот именно. Товарищ небось и не заметил, что галка SV-шная включена по недоразумению :) И думает, что в верилоге это можно... Нельзя предсказать результат в блоках такого типа: a <= b; a <= c; Неверно. Читаем стандарт очень внимательно и вдумчиво: 5.4.1. Determinism 1) Statements within a begin-end block shall be executed in the order in which they appear in that begin-end block ...... 2) Non blocking assignments shall be performed in the order the statements were executed. Consider the following example: [экзампл смотрите сами в стандарте] выбросьте из головы все те неопределенности, которых нет. Неопределенности есть, но связаны они с другим: 5.4.2. Indeterminism: - эвенты могут выбираться из очереди в любом порядке. НО! Эвент - это событие, т.е. факт запуска (или продолжения после блокировки) исполнения блока целиком. А не исполнения отдельного statement-а внутри блока. Например, что если есть два блока always, и у обоих сработал евент, то кто из них будет рассчитан первым - стандартом не определено. Но это никак не относится к последовательности утверждений внутри одного блока, с ними все однозначно. - Все конструкции при не определенной или одинаковой задержке исполняются не параллельно и единовременно, как должно быть в идеале, а последовательно. И еще гонки из-за того, что обновление цепей происходит не мгновенно (это пример который привел Leka со счетчиком вместо константы) - п. 5.5 стандарта. Короче этого можно бояться при каких-то особо хитрых межблочных связях, но никогда не внутри одного блока. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба dxp: Е-мае, Вы же недавно цитировали теже куски стандарта (опять извиняюсь, болею, поэтому видать тоже проморгал) :) Только вот цитаты приводим одни и теже, а понимание смысла этих цитат у нас координально разное. :) Посмотрите внимательно на картинку, которую я уже приводил: http://electronix.ru/forum/index.php?act=a...st&id=42124 Посмотрите внимательно на выделенное красным. Соотнесите с текстом про stratified event queue. Вот у меня понимание такое. А у вас? Что касается примера с initial begin a = 0; b = 1; a <= b; // evaluates, schedules, and b <= a; // executes in two steps end Я не могу вам объяснить, почему они приводят такой горбатый пример, который кочует из самого первого Стандарта без изменений. Я вообще не понимаю смысла использования неблокирующих присваиваний в initial блоках. Справедливости ради надо отметить, что в реальном коде такого ни разу не видел. До кучи картинка как раз на эту тему: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба Посмотрите внимательно на выделенное красным. Соотнесите с текстом про stratified event queue. Вот у меня понимание такое. Выделенное красным верно. Не верна трактовка - event-ом является сигнал к запуску вычисления блока begin...end целиком (The evaluation of a process is also an event, known as an evaluation event), а не отдельно взятого statement-а из него. т.е. вот ДВА евента, и сигналом к помещению в очередь их является "posedge clk": always @(posedge clk) begin a=b; b<=a+c; end; always @(posedge clk) c<=d; Да, симулятор может сначала обсчитать первый always, потом второй. А может и наоборот, сначала второй потом первый. А может вообще впаралелль двумя тредами обоих. Это и есть тот самый indeterminism из 5.4.2. Но то, что в первом a=b выполнится сначала, а вычисление RHS от b <= a+c после него (это все внутри одного евента - евент описывается командой always или assign) - безоговорочно гарантируется совместно пунктом 5.4.1, часть 1, про обязанность последовательного исполнения утверждений внутри блока, совместно с 5.6.3/5.6.4 которые обязывают выполнять вычисления RHS неблокирующего на том же уровне, где и вычисление блокирующего целиком), и докучи с 9.2.1, запрещающего вычислять что угодно внутри блока после блокирующего, пока блокирующее полностью не вычислено. Вообще не все картинки одинаково полезны. Некоторые вводят в откровенное заблуждение, как самая последняя. В отличие от примеров стандарта - которые полезны все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 25 марта, 2010 Опубликовано 25 марта, 2010 (изменено) · Жалоба А Вы чем компилили? Кварту материться, если стоит 2001. Чем я компилил, я написал, еще до того поста, на который ссылается SM. Там и результат работы приведен. Повторю - Quartus 9.0, Verilog-2005. По поводу замечания SM, что "товарищ галку на Verilog-2005 не заметил" - должно было бы обидеть, но почему-то рассмешило. Вам бы в адвокатуру податься, SM. Там такое "словоблудие" в ходу. Изменено 25 марта, 2010 пользователем ViKo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться