Иерархическая ссылка SystemVerilog в неблокирующем назначении

#verilog #system-verilog #questasim

Вопрос:

Я наблюдаю странное поведение на своем тестовом стенде, где неблокирующее задание действует как непрерывное задание вместо вывода RHS с задержкой на один цикл.

Мой тестовый стенд привязывает модуль «cov» к DUT в cpu.cache через bind cache cov cov_top , и внутри модуля «cov» у меня есть это неблокирующее назначение:

 module cov
  import cachePkg::*;
(
  input logic clk,
  input logic rst
);
  clocking cclk @(posedge clk iff !rst); endclocking

  logic [1:0] LinkState_d1, LinkState_d2;
  always @(cclk) begin
    LinkState_d1 <= cache.cntrl.LinkState;
    LinkState_d2 <= LinkState_d1;
  end
endmodule
 

И cache.cntrl.LinkState в DUT является результатом неблокирующего назначения, поэтому я ожидал бы, что LinkState_d1 просто последует за LinkState из DUT, просто задержанного на один цикл. Однако в средстве просмотра формы волны я вижу, что LinkState_d1 точно соответствует состоянию связи, как если бы это было непрерывное назначение, вот тактовая диаграмма того, что я вижу в форме волны:

              __    __    __
clk       __|  |__|  |__|  |__
                   ________
LinkState    _____|
                   ________
LinkState_d1 _____|
                         __
LinkState_d2 ___________|
 

Есть ли что-то другое, что происходит, когда мы используем иерархическую ссылку в RHS непрерывного назначения? Или это просто ошибка симулятора? Я использую questasim 2019.4

Комментарии:

1. Да, это тот же clk, который находится в экземпляре cache.cntrl

2. Ваш отредактированный вопрос показывает, что это не те же самые часы,

Ответ №1:

Ваш отредактированный вопрос сильно отличается от оригинала. Проблема в том, что вы используете разные часы. Это не имеет ничего общего с иерархическими ссылками или с тем, что вы используете оператор NBA в модуле cov .

Событие блока синхронизации cclk будет запланировано в наблюдаемой области, которая, предположительно, cache.cntrl.LinkState будет обновлена с новым значением.

Не следует смешивать блоки синхронизации с сигналами, поступающими извне блока синхронизации. Либо прекратите использовать блок синхронизации, либо переместите все внутри него.

 logic [1:0] LinkState_d1, LinkState_d2;

clocking cclk @(posedge clk iff !rst); 
  input LinkState = cache.cntrl.LinkState;
  inout LinkState_d1l
  output LinkState_d2;
endclocking

  always @(cclk) begin
    cclk.LinkState_d1 <= cclk.LinkState;
    cclk.LinkState_d2 <= cclk.LinkState_d1;
  end
endmodule
 

Ответ №2:

Каким-то образом использование блока синхронизации влияет на время выборки NBA, изменение always @(cclk) на always @(clk) устраняет проблему.