关于Verilog和SV中task及其内部变量是static还是automatic
问题1:那这个是不是就意味着以下代码是错误的呢?
- task dis;
- input A, B;
- output reg C;
- C = A + B;
- endtask
- always @ (*)
- dis(A1, B1, C1);
- always @ (*)
- dis(A2, B2, C2);
然后在verilog2001,对task的定义增添了automatic,意味着,每一次调用task都会单独开辟一段存储空间,当然调用完之后就会自动释放该task。
问题2:以下的代码自己综合过,可以通过编译,VCS和NC都是可以的。那么按照2001中的解释,是不是以为着以下代码中task dis的定义就是automatic的呢?因为两个always肯定是并行调用task嘛。如果说是static的task定义,那么调用static的task的时候,不是只有一份copy吗?
- module task_test(A,B,C);
- input A, B;
- output reg C;
- regD, E, F;
- task dis;
- input A, B;
- output reg C;
- C = A + B;
- endtask
- always @ (*) //should be included in procedure
- begin
- dis(A,B,C);
- end
- always @ (*)
- begin
- dis(D, E, F);
- end
- endmodule
在SV中,又新添加了定义。即,可以在automatic的task中定义static的变量,也可以在static的task中定义automatic的变量。前者用于变量共享,后者用于堆栈存储变量。
问题3:默认的task到底是static还是automatic(verilog和SV两者)?
问题4:默认的static task中变量是不是是static而非automatic,而默认的automatic task中变量是不是automatic而非static?
问题5:task中的变量作用域(scope)是在task内吗?即是局部变量,对于class中的其他task是么有影响的吗?
关于问题5,我自己的解答是,如若task定义的时候代码写作如下,那么A中的变量可以在task中直接使用,task中不用定义变量。
- class A;
- ...
- endclass
- task A::B;
- ...
- endtask
但是如果代码如下,则会报编译错误,说task B中没有定义变量,必须把变量定义上,即A中的变量定义没有传入B中,但是即便在B中定义了变量,task依然不能通过extern在class中定义,所报的错误为:too many actual arguments。虽然我目前还不知道这个错误的原因,也望各位解释。
- class A;
- ...extern task B;
- endclass
- task B;
- ...
- endtask
顶起讨论
问题3答案:
Systemverilog中,module和program块中,缺省使用静态存储;如果想使用自动存储,需加入automatic关键词。
问题1: compile 不會fail, 只要不是同一時間 call task dis, simulation result 就不會超出你的 expect, 但若同一個時間點 call task, 會有 unexpected result.
问题2: code 要在 task 後加 automatic, 也就是 "task automatic dis" 才是 automatic, 不然就是 static, compile 不會去判斷是否由兩個地方 call, 來決定是 static 或 automatic
问题3: task 後没寫 automatic 就是 static
问题4: task 中宣告的 variable, default 是非 static 的, 但不要和 automatic 搞混, automatic 是 task 才用到的, 可以把它想成, 每 call 一次宣告為 automatic 的 task, 就又產生一新的此 task, task 內的 variable 又是新的, 只為此 call 所用.
问题5: 是的. task中的变量作用域(scope)只在task内.
代码如下, compile 應不會 error
class A;
extern task B;
endclass
task A::B;
....
endtask
很優秀
第5个问题应该把它理解为面向对象的问题,而不单单是sv的问题。
class A;
extern task B;
endclass
task A::B;
....
endtask
意思是 taskB 是classA 的一个方法成员 ,只不过采用外部定义的方式。classA中定义的var是它的属性当然可以在A的任何一个方法成员中使用。方法B中的变量是局部变量。
class A;
...extern task B;
endclass
task B;
...
endtask
这种写法 是有问题的,当然可以这样把B 写为类A的友元方法然后调用,但A和B的关系仅仅是同级关系而非从属关系。