Timmy 1 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба Столкнулся со странной особенностью Верилога в 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. Попробовал почитать на эту тему стандарт, ясных разъяснений не нашёл. По-моему, это какая-то дичь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба Приветствую! 23 minutes ago, Timmy said: ... Несмотря на то, что по завершении каждого always процесса, и t1 и t2 сохраняют своё прежнее значение, симулятор считает промежуточное присваивание другого значения достаточным основанием для update event. ... Кто вам сказал такое? Вы применяете blocking присвоение (=) а значит значение переменной меняется сразу же! A не в конце блока always как при использовании nonblocking (<=). Удачи! Rob Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hdl_student 0 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба А Вы хотите реализовать какую-то логику или исследовать поведение симулятора? Если первое, то не очень понятно, какого результата Вы хотите добиться. Похоже на попытку описать асинхронный мультивибратор. ( : Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба 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-ем попахивает :-). К счастью, на практике ситуация крайне редкая, я вот первый раз столкнулся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба А давайте еще обсудим проблему о том, что получится если одновременно подать активный уровень и на R и на S входы в RS-триггере и при этом так же будем клясть верилог... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба Приветствую! Да уж - последовательность обработки событий в симуляторе та еще интересная задачка. Сделал вот такой простой тест `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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться