Jump to content

    
Sign in to follow this  
Timmy

verilog: что должно считаться update event-ом?

Recommended Posts

Столкнулся со странной особенностью Верилога в Active-HDL 9.1. Если симулировать следующий код, то он зациклится:

reg t1=1'b0,t2=1'b0;
always @(t1) begin
  t2 = 1'b1;
  if(!t1)begin
    t2 = 1'b0;
  end
end  
always @(t2) begin
  t1 = 1'b1;
  if(!t2)begin
    t1 = 1'b0;
  end
end

Несмотря на то, что по завершении каждого always процесса, и t1 и t2 сохраняют своё прежнее значение, симулятор считает промежуточное присваивание другого значения достаточным основанием для update event. Попробовал почитать на эту тему стандарт, ясных разъяснений не нашёл. По-моему, это какая-то дичь.

Share this post


Link to post
Share on other sites

Приветствую!

23 minutes ago, Timmy said:

...

Несмотря на то, что по завершении каждого always процесса, и t1 и t2 сохраняют своё прежнее значение, симулятор считает промежуточное присваивание другого значения достаточным основанием для update event. 

...

Кто вам сказал такое?  Вы применяете blocking присвоение (=) а значит значение переменной меняется сразу же!  A не в конце блока always как при использовании nonblocking (<=).

Удачи! Rob

Share this post


Link to post
Share on other sites

А Вы хотите реализовать какую-то логику или исследовать поведение симулятора?

 

Если первое, то не очень понятно, какого результата Вы хотите добиться. Похоже на попытку описать асинхронный мультивибратор. ( :

Share this post


Link to post
Share on other sites
3 hours ago, RobFPGA said:

Приветствую!

Кто вам сказал такое?  Вы применяете blocking присвоение (=) а значит значение переменной меняется сразу же!  A не в конце блока always как при использовании nonblocking (<=).

Удачи! Rob

Открою страшную тайну: при использовании <= будет та же самая проблема. Вот ещё код попроще:

reg t=1'b0;
always begin
  @(t);
  t <= 1'b1;
  t <= 1'b0;
end

То есть update flag регистру всегда устанавливается немедленно, если присваивается значение, отличное от текущего. А когда неблокирующим присваиваиванием присваивается значение, равное текущему видимому, update flag уже не сбрасывается :-). И это может внезапно привести к проблемам. Для решения пришлось завести локальный промежуточный регистр и присваивать его "глобальному" регистру в конце always блока.

Я удивлён, что регистры Верилога вообще имеют update flag, это как-то VHDL-ем попахивает :-).

К счастью, на практике ситуация крайне редкая, я вот первый раз столкнулся.

Share this post


Link to post
Share on other sites

А давайте еще обсудим проблему о том, что получится если одновременно подать активный уровень и на R и на S входы в RS-триггере и при этом так же будем клясть верилог...

Share this post


Link to post
Share on other sites

Приветствую!

 

Да уж - последовательность обработки событий в симуляторе та еще интересная задачка.

Сделал вот такой простой тест

`timescale 1ns/1ps

module event_test;
initial $timeformat(-9, 0, " ns", 10);

logic t1,t2;

always @(t1) begin
  $display("[%t]: T1.0: t1:%b, t2:%b",$time(), t1, t2);
end

always @(t2) begin
  $display("[%t]: T2.0: t1:%b, t2:%b",$time(), t1, t2);
end

always @(t1) begin
  $display("[%t]: T1.1: t1:%b, t2:%b",$time(), t1, t2);
  t2 = 1'b0;
  $display("[%t]: T1.2: t1:%b, t2:%b",$time(), t1, t2);
  // #0;
  t2 = 1'b1;
  $display("[%t]: T1.3: t1:%b, t2:%b",$time(), t1, t2);
  // #0;
  t2 = 1'bz;
  $display("[%t]: T1.4: t1:%b, t2:%b",$time(), t1, t2);
end

initial begin
  $display("[%t]: T0.0: t1:%b, t2:%b",$time(), t1, t2);
  #1;
  t1=0;
end

endmodule

 Если запустить как есть то получим  ожидаемый вывод (Questasim v10.6c)

# [      0 ns]: T0.0: t1:x, t2:x
# [      1 ns]: T1.0: t1:0, t2:x
# [      1 ns]: T1.1: t1:0, t2:x
# [      1 ns]: T1.2: t1:0, t2:0
# [      1 ns]: T1.3: t1:0, t2:1
# [      1 ns]: T1.4: t1:0, t2:z
# [      1 ns]: T2.0: t1:0, t2:z

 

event list: ("@time_ps  +#delta_cycle)  

@0      +0
/event_test/t1 1'hx
/event_test/t2 1'hx
@1000 +0
/event_test/t1 1'h0
@1000 +1
/event_test/t2 1'hz 

 

То есть последовательные присвоение одной переменной в блоке always происходит в одном delta_cycle (вроде так и пишут в доках). А вот обработка события изменения этой переменной происходит по окончанию delta_cycle. Что подтверждает вывод сима варианта с убранными комментариями возле #0; (искусственно добавляем delta_cycle).

 

# [      0 ns]: T0.0: t1:x, t2:x
# [      1 ns]: T1.0: t1:0, t2:x
# [      1 ns]: T1.1: t1:0, t2:x
# [      1 ns]: T1.2: t1:0, t2:0
# [      1 ns]: T2.0: t1:0, t2:0
# [      1 ns]: T1.3: t1:0, t2:1
# [      1 ns]: T2.0: t1:0, t2:1
# [      1 ns]: T1.4: t1:0, t2:z
# [      1 ns]: T2.0: t1:0, t2:z

 

event list:

@0      +0
/event_test/t1 1'hx
/event_test/t2 1'hx
@1000 +0
/event_test/t1 1'h0
@1000 +1
/event_test/t2 1'h0
@1000 +2
/event_test/t2 1'h1
@1000 +3
/event_test/t2 1'hz

 

Удачи! Rob.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this