Планирование оценочных событий - стратифицированная очередь событий Verilog

Я пытаюсь реализовать простой симулятор Verilog на основе событий на Python, но мне действительно трудно найти некоторые детали в спецификации (раздел 11 IEEE 1364-2005).

Скажем, я только что выполнил событие обновления на clk, которое теперь получило новое значение 1 (ранее 0). Согласно спецификации, это требует от меня запланировать «оценочные мероприятия» для чувствительных процессов.

Должен ли я планировать оценку always @(posedge clk) блока как активного или неактивного события? Я предполагаю, что последнее верно?

Или вообще говоря. В основном все события запланированы как неактивные, за следующими исключениями:

  • Неблокирующие обновления назначения как неблокирующие события назначения
  • непрерывные назначения как активные события

Большое спасибо!


person Alex    schedule 02.04.2014    source источник
comment
Сортировка есть в стороне, но следующий пост в блоге и его предшественники представляют собой интересное чтение о планировании в Verilog и VHDL ... sigasi.com/content/vhdls-crown-jewel   -  person Marty    schedule 02.04.2014
comment
Из любопытства, какова цель вашего проекта? Если вы пытаетесь использовать Python для разработки FPGA, я предполагаю, что вы видели myHDL и cocotb?   -  person Chiggs    schedule 03.04.2014
comment
@Chiggs MyHDL и у меня действительно жесткие отношения ;-) Итак, я пытаюсь воспроизвести это, но с другим подходом (меньше магии и больше ориентировано на пользователя)   -  person Alex    schedule 03.04.2014
comment
@Alex Итак, вы пытаетесь упростить MyHDL и, следовательно, смотрите на планирование Verilog. Интересный :-)   -  person Jan Decaluwe    schedule 05.04.2014


Ответы (1)


По умолчанию все работает в области Активный. Исключениями являются:

  • Назначения блокировки №0 находятся в области Неактивно.
  • Неблокирующие назначения относятся к региону NBA.
  • $ monitor, $ strobe и PLI / VPI находятся в области Monitor.

Мы можем доказать, что @ происходит в активной области, выполнив следующее в любом существующем симуляторе:

int x; 
initial begin 
   $monitor("From    $monitor: x is %0d",x); 
   #0 x = 5; // inactive event 
   x = 3; // active event (after inactive event)
   #1; // go to next time stamp
   fork
     #0 x = 7; // inactive event 
     x = 11; // active event 
   join
   #0 fork // inactive region
     #0 x = 2; // inactive event 
     x = 5; // active event 
     x <= 4; // NBA event 
   join
end 
// active event region
always @* $display("From @* $display: x is %0d",x); 

Выходы:

 From @* $display: x is 3
 From $monitor: x is 3
 From @* $display: x is 11
 From @* $display: x is 7
 From @* $display: x is 5
 From @* $display: x is 2
 From @* $display: x is 4
 From $monitor: x is 4

Отображайте отчеты больше раз, чем отслеживайте. Это исключает @ накопление в регионе Monitor или Future. Дисплей сообщает по каждому региону событий. Каждая область событий может возвращаться только в активную область. Поэтому @ должен обрабатываться в активной области, и каждая область, которая обновляет переменную x, запускает новое событие активной области.

Это также можно доказать, зная, глядя на историю Verilog. К сожалению, это плохо документировано. Я узнал об этом через людей, которые использовали / разрабатывали Verilog в конце 80-х - начале 90-х годов. Общее объяснение таково: неактивные регионы и регионы NBA были добавлены в Verilog до IEEE Std 1364-1995, @ предшествует этим двум регионам. Области были добавлены, чтобы добавить детерминизма к недетерминированному симулятору.

always @(posedge clk) pipe0 = in;
always @(posedge clk) pipe1 = pipe0; // unpredictable, non-deterministic order
always @(posedge clk) #0 pipe0 = in; // Inactive region added some determinism
always @(posedge clk) pipe1 = pipe0; 
always @(posedge clk) #0 pipe0 = in; // But was fragile
always @(posedge clk) #0 pipe1 = pipe0; // unpredictable order again
always @(posedge clk) pipe2 = pipe1; 
always @(posedge clk) pipe0 <= in; 
always @(posedge clk) pipe1 <= pipe0; 
always @(posedge clk) pipe2 <= pipe1; // NBA region fixed it 
 ...
always @(posedge clk) pipeN <= pipeM; //             and made it scalable



разъяснение на основе отзывов из комментариев

Events are activated, not moved. Activated NBA events enter the true condition of if (E is an update event), modified object and schedule new evaluation events (handled the next time Active region entered). Once all the activated events are completed, the schedule goes back to the top of the while-loop. The NBA region only assigns values, the evaluation was actually done in an earlier Active region stage.
From your example:

module TEST;
   reg test = 0;
   reg test2 = 0;
   reg clk = 0;

   initial begin
      clk <= 1;
      test <= 1;
   end

   always @(posedge clk) begin
      test2 <= test;
   end
endmodule

Каждая итерация цикла while будет выглядеть примерно так:

Iteration:0
  Active: <----- This is region is executing
      clk$tmp = eval(1)
      test$tmp = eval(1)
  Inactive:
  NBA:
      clk = clk$tmp
      test = test$tmp
Iteration:1
  Active:
  Inactive:
  NBA: <----- This is region is executing
      clk = clk$tmp
      test = test$tmp
      Active.schedule( eval( "@(posedge clk)" )
Iteration:2
  Active: <----- This is region is executing
      eval( "@(posedge clk)" )
      Active.schedule( "test2$tmp = eval(test)" )
      NBA.schedule( "test2 = test2$tmp" )
  Inactive:
  NBA:
Iteration:3
  Active: <----- This is region is executing
      test2$tmp = eval(test)
  Inactive:
  NBA:
      test2 = test2$tmp
Iteration:4
  Active:
  Inactive:
  NBA: <----- This is region is executing
      test2 = test2$tmp
Iteration:5 --> next simulation cycle
person Greg    schedule 03.04.2014
comment
Большое спасибо за ваш ответ! Но я не совсем убежден и борюсь с этим примером. Если события обрабатываются так, как вы это описали, результат test2 должен быть непредсказуемым? - person Alex; 03.04.2014
comment
Пример детерминированный. Регион NBA назначает все запланированные неблокирующие значения перед возвратом в активный регион. @(posedge clk) блокирует test2 <= test из очереди в планировщике. #, @ и wait откладывают оценку. <= оценивается в активном регионе, но его назначение откладывается в регион NBA. Примеру x=1;y=3;z<=x+y;x=7 z будет присвоено 4. - person Greg; 03.04.2014
comment
Примечание: если вы добавите к примеру always @(posedge clk) test = ~test;, то результат test2 снова станет (или может быть) недетерминированным. test сам по себе предсказуем. - person Greg; 03.04.2014
comment
не могли бы вы взглянуть на эту ссылку, где я записал, как я понял, что симулятор выполняет свои события? Потому что в спецификации в примере алгоритма (раздел 11.4) говорится, что события NBA фактически перемещаются в активную область, как только не остается других событий. - person Alex; 04.04.2014
comment
@Alex, я расширил свой ответ, объясняя ваш тестовый пример. - person Greg; 05.04.2014
comment
Исходный пример недетерминирован. См. Код на игровой площадке EDA здесь и обратите внимание, как GPLCver ведет себя иначе, чем другие симуляторы. После того, как происходит NBA to clk, Verilog может немедленно или не может запускать синхронизированный блок всегда. - person Jan Decaluwe; 05.04.2014
comment
@JanDecaluwe, это может быть ошибкой в ​​GPLCver. Все остальные симуляторы говорят test2 = 1, включая лучшие симуляторы от Cadence / Mentor / Synopsys. Я кратко смотрю на источник CPLCver, но я не могу сказать, использует ли он приоритетное планирование для одного процесса или планирование для нескольких процессов. Назначение НБА должно происходить параллельно или считаться одной операцией. В противном случае вы получите ту же проблему состояния гонки, что и #0. - person Greg; 09.04.2014
comment
@Greg Это не ошибка, а обычный Verilog: произвольный порядок выполнения за нулевое время (Thomas & Moorby's 8.3). См. Также мою запись в блоге. Неважно, сколько топовых симуляторов дадут один и тот же ответ: вы не можете доказать отсутствие недетерминизма с помощью моделирования. Тем не менее, единственный симулятор с другим ответом доказывает его наличие, как и мысленные эксперименты, основанные на основах планирования Verilog. - person Jan Decaluwe; 10.04.2014
comment
@Greg, спасибо за пояснение! Но, интерпретируя спецификацию, я все еще не согласен. Вы перемещаете указатель «эта область выполняет указатель», но в спецификации указано activate all *** events, а затем E = any active event. Значит, события нужно переместить в активную область, иначе E останется пустым? @JanDecaluwe, приятно видеть здесь, и спасибо за подсказку о детской площадке EDA. Конечно, это может быть ошибкой GPLCver, но, вероятно, это не так? Однако моя интуиция согласуется с большинством симуляторов, а мой мозг - нет ;-). Как бы вы ответили на мой первоначальный вопрос? - person Alex; 12.04.2014
comment
Ваш исходный вопрос: как сказал @Greg, событие @ будет запланировано в активной области. Однако вы не можете делать никаких предположений о порядке оценки этого события и других существующих активных событий. Это объясняет, почему ваш пример в этом разделе комментариев недетерминирован. - person Jan Decaluwe; 13.04.2014