为什么使用`begin/end`允许我在SystemVerilog任务的中间声明变量?

huangapple go评论64阅读模式
英文:

Why does begin/end allow me to declare a variable partway through a SystemVerilog task?

问题

我试图在`uvm_test`派生类的`run_phase()`任务中执行一个序列。我在任务开始时提出异议;在顺序器上声明、创建和执行序列;放弃异议。

task run_phase(uvm_phase phase);

phase.raise_objections(this);

uvm_sequence seq;
seq = uvm_sequence::type_id::create("seq");
seq.start(m_env.m_sequencer);

phase.drop_objections(this);

endtask: run_phase


这给我带来了错误

`expecting an '=' or '<=' sign in an assignment`

指的是语句 `uvm_sequence seq`。

我现在知道,我不能在任务中间声明变量,除非我在声明时给它赋值。然而,如果我使用`begin/end`语句,我可以在提出异议后声明序列,如下

task run_phase(uvm_phase phase);

phase.raise_objections(this);

begin
uvm_sequence seq;
seq = uvm_sequence::type_id::create("seq");
seq.start(m_env.m_sequencer);
end

phase.drop_objections(this);

endtask: run_phase


这段代码编译正常。`begin/end`块有什么特殊之处,可以让我在任务中间声明变量呢?
英文:

I am trying to execute a sequence within the run_phase() task of a uvm_test derived class. I raise an objection at the start of the task; declare, create, and execute a sequence on a sequencer; drop the objection.

task run_phase(uvm_phase phase);
  
  phase.raise_objections(this);
  
  uvm_sequence seq;
  seq = uvm_sequence::type_id::create(&quot;seq&quot;);
  seq.start(m_env.m_sequencer);
  
  phase.drop_objections(this);

endtask: run_phase

This gives me the error

expecting an &#39;=&#39; or &#39;&lt;=&#39; sign in an assignment

referring to the statement uvm_sequence seq.

I know now that I can't declare a variable midway through a task unless I assign a value when I declare it. However, if I use begin/end statements, I can declare the sequence after I raise the objection, as such

task run_phase(uvm_phase phase);
  
  phase.raise_objections(this);
  
  begin
    uvm_sequence seq;
    seq = uvm_sequence::type_id::create(&quot;seq&quot;);
    seq.start(m_env.m_sequencer);
  end
  
  phase.drop_objections(this);

endtask: run_phase

This code compiles fine. What is it about the begin/end block that allows me to declare a variable mid-task?

答案1

得分: 2

IEEE Std 1800-2017,第9.3.1节Sequential blocks展示了begin/end块的语法:

begin [ : block_identifier ] { block_item_declaration } { statement_or_null }
end [ : block_identifier ]

begin关键字之后,您可以添加一个可选的块名称,后面是变量的声明,如果有的话。这些变量是局限于begin块内部的。

这意味着您可以在task体内在其他过程语句之后声明变量,比如调用raise_objections


如果您不想在这里使用begin/end,您可以在raise_objections调用之前放置seq声明:

task run_phase(uvm_phase phase);
  
  uvm_sequence seq;

  phase.raise_objections(this);
  
  seq = uvm_sequence::type_id::create("seq");
  seq.start(m_env.m_sequencer);
  
  phase.drop_objections(this);

endtask: run_phase
英文:

IEEE Std 1800-2017, section 9.3.1 Sequential blocks shows the syntax for a begin/end block as:

begin [ : block_identifier ] { block_item_declaration } { statement_or_null }
end [ : block_identifier ]

After the begin keyword, you can add an optional block name followed by declarations of variables, if any. These variables are local to the begin block.

This means that you can declare variables inside the task body after other procedural statements, like the call to raise_objections.


If you don't want to use begin/end there, you could place the seq declaration before the raise_objections call:

task run_phase(uvm_phase phase);
  
  uvm_sequence seq;

  phase.raise_objections(this);
  
  seq = uvm_sequence::type_id::create(&quot;seq&quot;);
  seq.start(m_env.m_sequencer);
  
  phase.drop_objections(this);

endtask: run_phase

huangapple
  • 本文由 发表于 2023年3月9日 22:23:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定