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

Я попытался запустить блок Always, присвоив значение и установив значение обратно на 0, пытаясь запустить последовательный блок всегда, но безрезультатно, ниже приведен псевдокод


always_comb begin
 ...some code...
pulse_trigger = 1;
load_var= driver_var // assigning some values
pulse_trigger = 0;
 ...some code...
end

always @(pulse_trigger)begin
 ...some code part 2...
end

Я ожидаю, назначив 1 для pulse_trigger, чтобы активировать блок «Always @ (pulse_trigger)», но в моем моделировании VCS это не так.

Возможно, это связано с тем, что импульсному триггеру назначается 1 и не назначается 1 в одном и том же комбинированном блоке, что занимает 0 времени моделирования, поэтому может показаться, что Pulse_trigger не изменил значения. Или этот метод должен был вызвать «always @ (pulse_trigger)» и выполнить «... некоторый код, часть 2 ..», потому что я смотрю на неправильные значения?

0
TheSprintingEngineer 29 Май 2019 в 18:20

2 ответа

Лучший ответ

В симуляции verilog только один блок всегда может быть оценен за один раз. Таким образом, до тех пор, пока ваш always_comb не закончится, ни один другой блок всегда не может быть оценен. Следовательно, pulse_trigger изменение не будет обнаружено симуляцией (потому что все изменения происходят внутри одного всегда блока.

Вы можете сделать что-то подобное, добавив задержки (при условии, что это не синтезируемый код):

always @* begin
  pulse_trigger = 1;
  load_var= driver_var // assigning some values
  #1 // << this will stop execution of the block for 1 time unit and allow others.
  pulse_trigger = 0;
end

Тем не менее, приведенный выше код не можно синтезировать, но он может быть частью тестового стенда. Кроме того, это не разрешено в always_comb.

3
Serge 29 Май 2019 в 15:51

Результат неопределенный. Стандарт SystemVerilog написан так, что симуляторы могут свободно переключаться между независимыми процессами в любой точке. Но большинство из них ждут события или контроля времени, чтобы приостановить процесс, прежде чем переходить к другому.

Если вы хотите гарантировать триггер, используйте неблокирующее назначение во втором назначении pulse_trigger или используйте именованное событие.

always @* begin
  pulse_trigger = 1;
  load_var= driver_var // assigning some values
  pulse_trigger <= 0; // adds a delta cycle or <= #1 delay without blocking the process
end

Еще лучше заменить второй блок always @ на объявление функции, а затем вызвать функцию, а не вызывать событие.

1
dave_59 30 Май 2019 в 15:59