System Verilog线程与通信

本文深入探讨了System Verilog中的并发编程技术,包括事件(event)触发、邮箱(mailbox)通信及信号量(semaphore)同步机制的具体实现与应用案例。

在测试平台的环境里,大多数语句块被模拟成事务处理器,并运行在各自的线程thread(进程process)里。

  • 线程:SV的调度器就像交通警察,总是不停地选择下一个要运行的线程。
  • 线程之间通信:解决环境类知道发生器什么时候完成任务,以便及时终止测试平台中还在运行的线程。线程间通信由标准的Verilog事件、事件控制、wait语句、信箱和旗语。
    Verilog里面执行方式:顺序执行(begin…end)和并发方式(fork…join)
    SV里面新加入两种创建线程方式:fork…join_none和fork…join_any
    开始都是平行发送,同时执行
    在这里插入图片描述
    线程间的通信(event,mailbox,semaphore):
    1.event事件
    testbench.sv
module t;
    tb a=new();
    event   event0;      
    initial begin 
        fork
            a.wait_for_trigger (event0);
            #5 -> event0;
        join
    end               
endmodule

class tb;            
    task wait_for_trigger (event event0);
	$display("[%0t] wait for event0 to be triggered", $time);
        wait (event0.triggered);
	$display("[%0t] event0 has to be triggered", $time);
    endtask
endclass

Makefile文件

TB_FILE_LIST  =  filelist.list

all: clean comp run

COMP = vcs -full64 -sverilog +v2k -debug_all -fsdb

SIMV = ./simv

comp:
	$(COMP) testbench.sv 
run:
	$(SIMV) -l simv.log
clean:
	rm -rf AN.DB DVEfiles csrc *.simv *.simv.daidir ucli.key 64
	rm -rf *.log* *.vpd *.fsdb *.vdb novas* *verdi*
	rm -rf simv*

编译、仿真结果

[0] wait for event0 to be triggered
[5] event0 has to be triggered

2.mailbox
testbench.sv文件

program tb;
    mailbox mbx;
    my_gen gen;
    my_drv drv;

    initial begin
        mbx = new();
        gen = new(mbx);
        drv = new(mbx);

        fork
            #10;
            gen.gen_data();
            drv.drv_data();
        join_none
    end

endprogram

my_gen文件

class my_gen;
    mailbox mbx;
    function new(mailbox mbx);
        this.mbx = mbx;
    endfunction

    task gen_data();
        my_trans put_trans;
        put_trans = new();
        put_trans.randomize();
        put_trans.display();
        $display("[%0t] put trans into mailbox", $time);
        mbx.put(put_trans);
    endtask
endclass

my_drv文件

class my_drv;
    mailbox mbx;
    function new(mailbox mbx);
        this.mbx=mbx;
    endfunction

    task drv_data();
        my_trans get_trans;
        get_trans = new();
        $display("[%0t] get trans into mailbox", $time);
        mbx.get(get_trans);
        get_trans.display();
    endtask
endclass

my_trans文件

class my_trans;
    randc bit [7:0] data;

    function display ();
        $display ("[%0t] Data = 0x%0h", $time, data);
    endfunction
endclass

编译、仿真结果

[0] Data = 0x3f
[0] put trans into mailbox
[0] get trans into mailbox
[0] Data = 0x3f

3.semaphore

module tb;

    semaphore   flag;

    initial begin
	flag = new(1);
	fork
        boy();
	    girl();
	    #25 boy();
        join_none
    end

    task get_task(bit [1:0] id);
	$display("[%0t] try to get for id[%0d]", $time, id);
        flag.get(1);
	$display("[%0t] already get for id[%0d]", $time, id);
    endtask

    task put_task(bit [1:0] id);
	$display("[%0t] try to put for id[%0d]", $time, id);
        flag.put(1);
	$display("[%0t] already put for id[%0d]", $time, id);
    endtask

    task boy();
        get_task(1);
        #20 put_task(1);
    endtask

    task girl();
	#5 get_task(2);
        #10 put_task(2);
    endtask

endmodule

编译,仿真结果

[0] try to get for id[1]
[0] already get for id[1]
[5] try to get for id[2]
[20] try to put for id[1]
[20] already put for id[1]
[20] already get for id[2]
[25] try to get for id[1]
[30] try to put for id[2]
[30] already put for id[2]
[30] already get for id[1]
[50] try to put for id[1]
[50] already put for id[1]
<think>嗯,用户问的是SystemVerilog中的线程是什么。我得先回忆一下SystemVerilog的相关知识。记得SystemVerilogVerilog基础上增加了许多验证功能,线程应该是其中一部分,用于并发执行。 首先,线程在编程中通常指的是独立的执行流程。SystemVerilog作为硬件描述和验证语言,支持并发执行,所以线程应该和并行处理有关。需要区分线程和进程的不同,可能在SystemVerilog里,线程指的是更轻量级的并发单元? 然后,用户可能想知道线程如何创建、控制以及应用场景。比如,使用fork...join、fork...join_any、fork...join_none这些结构来创建线程。需要解释每种结构的区别,比如join会等待所有线程结束,join_any等待任意一个,而join_none不等待直接继续。 还要提到线程间的同步机制,比如事件(event)、旗语(semaphore)、信箱(mailbox)这些。用户可能在实际验证中需要线程之间通信或协调,这些机制就派上用场了。 另外,线程的控制操作,比如wait fork等待所有子线程结束,disable终止指定线程。这部分需要举例说明,让用户明白如何应用。 可能用户是刚开始学习SystemVerilog,或者是做验证需要用到并发处理。需要结合实际例子,比如测试平台中同时驱动多个信号,或者并行检查多个协议。避免使用过于专业的术语,保持解释清晰易懂。 还要注意系统级指令,比如用中文回答,数学公式的正确格式。不过这个问题里可能涉及代码示例,需要用正确的SystemVerilog语法,可能不需要数学公式,但要注意代码块的格式。 总结回答的结构:先定义线程,然后创建方式(fork...join等),同步机制,控制方法,应用场景,最后实例说明。这样用户能逐步理解线程的概念和应用。</think>SystemVerilog中的线程是验证环境中实现并发行为的重要机制。以下是逐步解释: 1. **线程定义** 线程是独立执行的代码单元,在验证环境中用于模拟硬件/软件的并行性。SystemVerilog通过以下方式实现线程: - 动态线程:通过`fork...join`结构创建 - 静态线程:通过`always`/`initial`块创建 2. **线程创建(3种方式)** ```systemverilog // 示例1:fork...join(并行执行,等待所有完成) fork begin : thread1 #10 $display("Thread1完成"); end begin : thread2 #20 $display("Thread2完成"); end join // 在此阻塞,直到两个线程都完成 // 示例2:fork...join_any(任一完成即继续) fork task1(); task2(); join_any // 任一任务完成即继续后续代码 // 示例3:fork...join_none(不阻塞直接继续) fork send_packet(); join_none // 立即继续执行后续代码 ``` 3. **线程同步机制** - **事件(event)**:通过`->`触发和`@`等待 ```systemverilog event data_ready; // 线程A -> data_ready; // 线程B @(data_ready); // 阻塞直到事件触发 ``` - **旗语(semaphore)**:控制资源访问 ```systemverilog semaphore bus_lock = new(1); // 创建1个钥匙 task acquire_bus(); bus_lock.get(1); // 获取钥匙 // 访问共享资源... bus_lock.put(1); // 归还钥匙 endtask ``` - **信箱(mailbox)**:线程通信 ```systemverilog mailbox #(int) mbx = new(); // 生产者线程 mbx.put(123); // 消费者线程 int data; mbx.get(data); ``` 4. **线程控制操作** - `wait fork`:等待所有子线程完成 - `disable`:终止指定线程/代码块 ```systemverilog fork : timeout_block begin #100; $display("超时!"); disable timeout_block; end begin long_task(); end join ``` 5. **典型应用场景** - 验证环境:并行驱动多个接口 - 协议测试:同时模拟主从设备 - 异步事件处理:中断响应 - 覆盖率收集:并行监控多个指标 6. **注意事项** - 避免线程饿死(使用公平调度策略) - 注意资源共享的原子性(使用同步机制) - 推荐使用自动变量存储(auto storage) - 谨慎处理线程终止(避免资源泄漏) 示例:并行数据检查 ```systemverilog initial begin fork begin : check_thread forever begin @(posedge clk); if (data_valid) check_data(); end end begin #1000ns; disable check_thread; // 1us后终止检查 end join end ``` 理解SystemVerilog线程机制可以有效构建复杂的并发验证环境,提高验证效率并准确模拟真实硬件行为。实际使用中需特别注意同步和资源管理问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值