System verilog 如何将信息从内部序列/属性传递到外部世界

System verilog 如何将信息从内部序列/属性传递到外部世界,system-verilog,System Verilog,我有一个属性正在等待两个不同的序列发生,如下所示(这里已经简化了序列和属性): 一些信号1,一些信号2,其他信号1,其他信号2都是RTL信号 我的问题: 当属性abc被传递或覆盖时,我想知道序列中采样的相应其他信号1和其他信号2。如何访问这些信号值 我正在考虑分层访问序列局部变量,例如seq1.a或seq2.b。但这是不允许的,因为他们是当地人 将这些变量声明为形式参数也没有帮助,因为形式参数不能在LHS中赋值 我打算将这些信号用于其他目的,即: cover property (abc) beg

我有一个
属性
正在等待两个不同的
序列
发生,如下所示(这里已经简化了
序列
属性
):

一些信号1
一些信号2
其他信号1
其他信号2
都是RTL信号

我的问题: 当
属性abc
被传递或覆盖时,我想知道序列中采样的相应
其他信号1
其他信号2
。如何访问这些信号值

我正在考虑分层访问
序列
局部变量,例如
seq1.a
seq2.b
。但这是不允许的,因为他们是当地人

将这些变量声明为形式参数也没有帮助,因为形式参数不能在LHS中赋值

我打算将这些信号用于其他目的,即:

cover property (abc) begin
  // grab seq1.a and seq2.b, and do some other tasks
end

您可以在
(,)
中逗号右侧执行以下三项操作之一:

  • 赋值(局部变量)
  • 增加或减少
  • 调用任务、任务方法、无效函数、无效函数方法或系统任务
(参见第16.11节,在序列匹配时调用子程序)

任务调用是实现这一点的关键。您可以在从序列中调用的任务中为任务范围外的变量赋值:

  sequence seq1;
    @(posedge clk) (some_signal1 == 1, assign_a(other_signal1)); 
  endsequence

  sequence seq2;
    @(posedge clk) (some_signal2 == 1, assign_b(other_signal2)); 
  endsequence

  property abc;
    seq1 ##[1:$] seq2;
  endproperty

  cover property (abc) 
    $display("a= %d, b= %d", a , b);

  task assign_a(input int i);
    a = i;
  endtask

  task assign_b(input int i);
    b = i;
  endtask

您可以在
(,)
中逗号右侧执行以下三项操作之一:

  • 赋值(局部变量)
  • 增加或减少
  • 调用任务、任务方法、无效函数、无效函数方法或系统任务
(参见第16.11节,在序列匹配时调用子程序)

任务调用是实现这一点的关键。您可以在从序列中调用的任务中为任务范围外的变量赋值:

  sequence seq1;
    @(posedge clk) (some_signal1 == 1, assign_a(other_signal1)); 
  endsequence

  sequence seq2;
    @(posedge clk) (some_signal2 == 1, assign_b(other_signal2)); 
  endsequence

  property abc;
    seq1 ##[1:$] seq2;
  endproperty

  cover property (abc) 
    $display("a= %d, b= %d", a , b);

  task assign_a(input int i);
    a = i;
  endtask

  task assign_b(input int i);
    b = i;
  endtask

由于属性是自动的,通过使用简单的任务分配,
a
将在前一个线程尚未完成时,每当另一个
seq1
触发时被覆盖。从这个意义上说,我们应该保留
a
的多个记录(
a
必须是自动的)。我不认为这样简单的本地分配可以工作(因为当新线程出现时,它将被覆盖)。@AldoT我不确定我是否理解。你的原始代码不会有同样的问题吗(如果它是合法的);您的原始代码分配给
a
b
,我的代码也是如此。该任务不消耗时间,也没有局部变量,因此我不理解为什么自动/静态区分很重要。在您的示例中,
other_signal 1
other_signal 2
是常量,因此您不会看到任何问题。如果这些信号在时间上发生变化怎么办?这里有一个反例来澄清我的问题。@AldoTThanks举个例子,我现在明白你的意思了。难道你最初的(非工作的)想法不存在同样的问题吗?如果要“获取”局部变量
a
b
的值,则需要以某种方式存储它们,以解释可能存在多个线程的事实。所以,为了解决这个问题,您可以设计一个类来管理它吗?它将有一个从
assign\uuu
任务中调用的方法,该方法将新值添加到某种动态数据结构中,然后代码的其余部分可以在需要时访问该结构?我的原始代码只是为了表达我的意图。它不起作用。我认为有一些内在的方法可以实现这一点。如果没有,那么我需要像你提到的那样设计一个类。由于属性是自动的,通过使用简单的任务分配,
a
将在前一个线程尚未完成时,每当另一个
seq1
触发时被覆盖。从这个意义上说,我们应该保留
a
的多个记录(
a
必须是自动的)。我不认为这样简单的本地分配可以工作(因为当新线程出现时,它将被覆盖)。@AldoT我不确定我是否理解。你的原始代码不会有同样的问题吗(如果它是合法的);您的原始代码分配给
a
b
,我的代码也是如此。该任务不消耗时间,也没有局部变量,因此我不理解为什么自动/静态区分很重要。在您的示例中,
other_signal 1
other_signal 2
是常量,因此您不会看到任何问题。如果这些信号在时间上发生变化怎么办?这里有一个反例来澄清我的问题。@AldoTThanks举个例子,我现在明白你的意思了。难道你最初的(非工作的)想法不存在同样的问题吗?如果要“获取”局部变量
a
b
的值,则需要以某种方式存储它们,以解释可能存在多个线程的事实。所以,为了解决这个问题,您可以设计一个类来管理它吗?它将有一个从
assign\uuu
任务中调用的方法,该方法将新值添加到某种动态数据结构中,然后代码的其余部分可以在需要时访问该结构?我的原始代码只是为了表达我的意图。它不起作用。我认为有一些内在的方法可以实现这一点。如果没有,那么我将需要像你提到的那样设计一个类。我认为,断言/属性/序列是为了验证设计,而不是为了分配数据。对于赋值,您应该使用过程块。我认为,断言/属性/序列是为了验证设计,而不是为了分配数据。对于赋值,应使用程序块。