SV-线程同步与通信-事件-旗语-信箱

本文介绍了Verilog语言中的事件(event)、信号(ref)以及旗语(semaphore)和信箱(mailbox)在并发系统中的应用,包括事件的触发与等待、信号的引用方式、资源访问控制和通信模型,展示了如何利用这些机制进行同步和资源共享。
摘要由CSDN通过智能技术生成

事件event

         用event来声明一个事件,用箭头->来触发,用@来等待事件的发生。

`timescale 1ns/1ps
module tb;
    event e1, e2, e3;

    task automatic wait_event(event e, string name);
        $display("@%t start waiting event %s", $time, name);
        @e;
        $display("@%t finish waiting event %s", $time, name);
    endtask

    initial begin
        fork
            wait_event(e1, "e1");
            wait_event(e2, "e2");
            wait_event(e3, "e3");
        join
    end

    initial begin
        fork
            begin #10ns -> e1; end
            begin #20ns -> e2; end
            begin #30ns -> e3; end
        join
    end
endmodule



module tb2;
    logic e1, e2, e3;

    task automatic wait_event(ref bit e, string name);
        $display("@%t start waiting event %s", $time, name);
        @e;
        $display("@%t finish waiting event %s", $time, name);
    endtask

    initial begin
        fork
            wait_event(e1, "e1");
            wait_event(e2, "e2");
            wait_event(e3, "e3");
        join
    end

    initial begin
        fork
            begin #10ns  e1 = !e1; end
            begin #20ns  e2 = !e2; end
            begin #30ns  e3 = !e3; end
        join
    end
endmodule


       tb2中,ref表方向,logic表数据类型。

      tb2中变量要加ref,而event中没有添加ref。  等待的是信号,用ref。

         @是边沿触发,wait是电平触发。   先等待再触发,用@。

         wait_order按照一定顺序去等待event发生

AB

        event之间可以拷贝,拷的是句柄,都共同指向一个event。   如果要等待event,要先等到event再去触发

旗语semaphore

        旗语就是个容器,用来保护,保护共享的资源。为了保护共享的资源,一开始去分配一个访问这个共享资源的钥匙🔑。   访问共享资源,且不允许读/写来访问memory(非共享)等。——此为需求。用semaphore来实现。

`timescale 1ns/1ns
module tb;
    semaphore mem_acc_key;

    int unsigned mem[int unsigned];

    task automatic write(int unsigned addr, int unsigned data);
        mem_acc_key.get();
        #1ns;
        mem[addr] = data;
        mem_acc_key.put();
    endtask

    task automatic read(int unsigned addr, output int unsigned data);
        mem_acc_key.get();
        #1ns;
        if(mem.exists(addr))
            data = mem[addr];
        else
            data = 'x;
        mem_acc_key.put();
    endtask
    
    initial begin
        int unsigned data = 100;
        mem_acc_key = new(1);
        forever begin
            fork //fork-join是并行执行的
                begin
                    #10ns;
                    write('h10, data + 100);
                    $display("@%t write with data %d", $time, data);               
                end
                begin
                    #10ns;
                    read('h10, data);
                    $display("@%t read with data %d", $time, data);                  
                end
            join
        end
    end
endmodule

        semaphore的目的是先例化一把钥匙,一开始大家都有往里写/读的权限。而memory是单端口memory,只能读/写,不能读写同时。

         旗语等待的方式是队列——先进先出。   先开始等的先拿钥匙🔑。

         try_get是函数,拿不到就不拿了,会立即返回。   0表示拿不到足量的钥匙。

信箱mailbox

         event事件,旗语semaphore,信箱mailbox共同点是赋值时,其变量是句柄

        信箱和旗语例化的时候要用new,事件不需要用new,因为其很小。

        信箱是丢进去数据,然后拿出数据。mailbox信箱就是一个FIFO,mailbox的通信只能把其当作FIFO来使用。

        try-put和try-get是为了不被堵塞,放进去返回1,放不进去返回0。;信箱可以写满。   peek可以拿数据,拍个快照,数据仍停留在信箱mailbox里边,get是拿走了。

         信箱里边的数据,num来调用信箱的数据。num()返回信箱目前的消息数目。;队列,动态数组访问其有几个数,数据内容用.size。信箱是用.num()

 

         mailbox #,#表示只能存放该种数据类型...。

module tb;
    mailbox #(int) mb;

    initial begin
        int data;
        mb = new(8);
        forveer begin
            case($urandom() % 2)
                0: begin
                       data = $urandom_range(0, 10);
                       if(mb.try_put(data))
                          $display("mb put data %0d", data);
                   end
                1: begin
                       if(mb.try_get(data))
                          $display("mb get data %0d", data);
                   end 
            endcase                 
        end
    end
endmodule

AB

         可以指定信箱mailbox存储的数据类型,#来限定存储的类型是什么;   可以不限制信箱的大小,new的时候不传参数即可;;;   信箱写满时,再写,数据不会溢出会等待;   信箱为空时,调用try_get返回0,调用get会一直阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值