1.程序、模块
(1)module (模块)作为SV从Verilog继承过来的概念,自然地保持了它的特点,除了作为RTL模型的外壳包装和实现硬件行为,在更高层的集成层面,模块之间也需要通信和同步。
(2)对于硬件的过程块,它们之间的通信可理解为不同逻辑/时序块之间的通信或者同步,是通过信号的变化来完成的。
(3)从硬件实现的角度来看, Verilog通过always, initial过程语句块和信号数据连接实现进程间通信。
(4)我们可以将不同的module作为独立的程序块,他们之间的同步通过信号的变化(event触发)、等待特定事件(时钟周期)或者时间(固定延时)来完成。
(5)如果按照软件的思维理解硬件仿真,仿真中的各个模块首先是独立运行的线程(thread) 。模块(线程)在仿真一开始便并行执行,除了每个线程会依照自身内部产生的事件来触发过程语句块之外,也同时依靠相邻模块间的信号变化来完成模块之间的线程同步。
(6)例题
-
always可以构造组合电路;
2.线程
3.fork并行线程语句块
(1)fork-join、fork-join_any、fork-join_none
(2)fork-join:
所有并行的子线程都结束,fork-join才退出执行fork-join外的语句。
(3)fork-join_any:
最短的子线程结束就执行fork-join_any外的语句,但是fork里的其他线程仍可能会执行,主要看fork外的语句。
(4)fork-join_none:
则是join语句块一开始就可以直接执行fork外的语句,不会等待内部的线程完成就去执行fork外部的语句。但是内部的语句仍可能会执行。
(5)如果没有finish after的语句,则运行到end,就结束了initial,所以就结束了线程。
4.线程的控制
(1)等待所有衍生线程:wait fork
(2)停止单个线程:disable
只执行了(1)线程,disable了(2)线程。
(3)停止多个线程:disable fork
注意disable fork停止了线程1-4,线程1也是停了的。只留下线程0。
(4)停止被多次调用的任务
if语句只管了第一个fork-join_none,第一个fork-join_none在满足id等于0的时候进入。