芯学长 | 掌握芯资讯,引领芯未来

您当前所在位置:首页 > 芯片设计 > 数字IC验证

数字IC验证|SystemVerilog线程

发布时间:2023-10-23来源:芯学长 0

1、线程的使用

1.1程序和模块

  • module (模块)作为SV从Verilog继承过来的概念,自然地保持了它的特点除了作为RTL模型的外壳包装和实现硬件行为, 在更高层的集成层面,模块之间也需要通信和同步。

  • 对于硬件的过程块,它们之间的通信可理解为不同逻辑/时序块之间的通信或者同步,是通过信号的变化来完成的。

  • 从硬件实现的角度来看,Verilog通过always,initial过程语句块和信号数据连接实现进程间通信。

  • 我们可以将不同的module作为独立的程序块,他们之间的同步通过信号的变化(event触发)、等待特定事件(时钟周期)或者时间(固定延时)来完成。

如果按照软件的思维理解硬件仿真,仿真中的各个模块首先是独立运行的线程(thread)。

模块(线程)在仿真一开始便并行执行, 除了每个线程会依照自身内部产生的事件来触发过程语句块之外, 也同时依靠相邻模块间的信号变化来完成模块之间的线程同步。

• 线程即独立运行的程序。

• 线程需要被触发, 可以结束或者不结束。

• 在module中的initial和always,都可以看做独立的线程,它们会在仿真0时刻开始,而选择结束或者不结束。

• 硬件模型中由于都是always语句块 , 所以可以看成是多个独立运行的线程, 而这些线程会一直占用仿真资源, 因为它们并不会结束。

• 软件测试平台中的验证环境都需要由initial语句块去创建, 而在仿真过程中, 验证环境中的对象可以创建和销毁, 因此软件测试端的资源占用是动态的。

软件环境中的initial块对语句有两种分组方式 , 使用begin ... end或fork... join。

begin ... end的语句以顺序的方式执行,而fork...join中的语句则以并发方式执行。

与fork... join类似的并行方式语句还包括fork...join_any,fork...join_none.

• 线程的执行轨迹是呈树状结构的, 即任何的线程都应该有父线程。

• 父线程可以开辟若干个子线程, 父线程可以暂停或者终止子线程。

• 当子线程终止时, 父线程可以继续执行。

• 当父线程终止时, 其所开辟的所有子线程都应当会终止。

2、线程的控制

2.1 fork.... join

image

图片


打印代码:

@0: start fork... join example

@10: sequential after #10

@10: parallel start

@20: parallel after #10

@40: sequential after #30

@50: sequential after #10

@60: parallel after #50

@60: after join

@140: finish after #80

2.2 fork...join_any

image

打印代码:

@0: start fork... join_any example

@10: sequential after #10

@10: parallel start

@10: after join_any

@20: parallel after #10

@40: sequential after #30

@50: sequential after #10

@60: parallel after #50

@90: finish after #80

2.3 fork...join_none

image

打印代码:

@0: start fork... join_none example

@10: sequential after #10

@10: after join_none

@10: parallel start

@20: parallel after #10

@40: sequential after #30

@50: sequential after #10

@60: parallel after #50

@90: finish after #80

2.4 等待所有衍生线程

• 在SV中, 当程序中的initial块全部执行完毕, 仿真器就退出了。

• 如果我们希望等待fork块中的所有线程执行完毕再退出结束initial块, 我们可以使用wait fork语句来等待所有子线程结束。

image

2.5 停止单个线程

在使用了fork.. join_any或者fork... join_none以后,我们可以使用disable来指定需要停止的线程。

image

2.6 停止多个线程

disable fork可以停止从当前线程中衍生出来的所有子线程。

image

图片

2.7 停止被多次调用的任务

如果你给某—个任务或者线程指明标号, 那么当这个线程被调用多次以后 , 如果通过disable去禁止这个线程标号, 所有衍生的同名线程都将被禁止。

image

• 任务wait_for_time_out被调用了三次, 从而衍生了三个线程。

• 线程0在#2延时之后禁止了该任务,而由于三个线程均是“ 同名”线程, 因此这些线程都被禁止了, 最终也都没有完成。

【免责声明】:本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。

文章评价

-   全部 0 条 我要点评

有疑惑?
在线客服帮您
029-81122100

立即咨询 >