SystemVerilog基础:disable fork语句 相关阅读SystemVerilog基础https://blog.csdn.net/weixin_45791458/category_12517449.html?spm1001.2014.3001.5482https://blog.csdn.net/weixin_45791458/category_12517449.html?spm1001.2014.3001.5482一、进程的概念在学习disable fork语句之前首先的了解SystemVerilog中的进程概念进程是一系列可以独立执行的一个或多个表达式。SystemVerilog中每个initial语句、always语句包括always、always_comb、always_latch和always_ff、final语句和连续赋值语句都定义了一个独立的静态进程它们的存在由静态层次结构决定并从仿真开始时开始并且它们无法在运行时创建。除此之外SystemVerilog还有动态进程这些进程可以在运行时创建、停止、重新启动和销毁。二、子进程的概念上一小节中定义了进程的概念并说明了创建进程的语句有哪些但是这些进程是独立且不可嵌套的也就是说所有的initial语句、always语句、final语句和连续赋值语句在一个模块中都是并列的顶层进程。fork语句包括fork-join、fork-join_any、fork-join_none可以动态创建子进程其中每条并行的语句都是独立的子进程当执行到fork语句时子进程创建。关于这三种fork语句的区别请参考下面的博客。SystemVerilog基础并行块fork-join、join_any、join_none上https://chenzhang.blog.csdn.net/article/details/134694526https://chenzhang.blog.csdn.net/article/details/134694526三、测试在学习了进程和子进程的概念后下面通过几个例子来巩固知识。问题1例1中存在几个顶层进程// 例1 module example1; // 信号声明 reg clk, reset; reg [7:0] data_in, data_out; reg [3:0] address; wire [7:0] result; // 连续赋值语句 assign result data_in data_out; // initial 语句 initial begin $display(Simulation started); clk 0; reset 1; data_in 8h00; data_out 8h00; address 4b0000; #10 reset 0; end // always 语句 always begin #5 clk ~clk; // 产生时钟信号 end // always_comb 语句 always_comb begin if (reset) begin data_out 8h00; end else begin data_out data_in 1; end end // always_latch 语句 always_latch begin if (reset) begin address 4b0000; end else begin address address 1; end end // always_ff 语句 always_ff (posedge clk or posedge reset) begin if (reset) begin data_in 8h00; end else begin data_in data_in 1; end end // final 语句 final begin $display(Simulation finished); end // function 定义 function [7:0] add_two_numbers; input [7:0] a, b; begin add_two_numbers a b; end endfunction // task 定义 task print_address; input [3:0] addr; begin $display(Current address: %b, addr); end endtask // 调用function和task initial begin #20; $display(Sum: %h, add_two_numbers(8h10, 8h20)); // 调用function print_address(4b1010); // 调用task end endmodule答案1存在八个顶层进程需要注意的是task和function并不属于顶层进程的一种。问题2例2中存在几个子进程// 例2 module example2; // 信号声明 reg clk, reset; reg [7:0] data_in, data_out; // initial 语句 initial begin // begin-end语句 $display(Simulation started); fork // fork-join 语句 data_in 8hAA; begin // begin-end语句 #10 data_in 8hBB; #10 data_in 8hCC; end join data_out data_in 1; $display(Data out: %h, data_out); end endmodule答案2存在两个子进程分别是fork-join语句中的data_in 8hAA;语句和begin-end语句。其中begin-end语句作为子进程又由两条阻塞赋值语句组成。顶层进程initial中只有一条begin-end语句而其中又有四条语句两条$display语句、一条阻塞赋值语句和一条fork-join语句。四、disable fork语句disable fork语句终止该语句所在进程创建的所有活跃的子进程其语法如下所示disable fork;disable fork语句不仅终止该语句所在进程创建的所有活跃的子进程还终止子进程的子进程。换句话说如果任何子进程有自己的子进程禁用fork语句也将终止它们这类似disable语句。下面是来自SystemVerilog标准的例子。task get_first( output int adr ); fork wait_device( 1, adr ); wait_device( 7, adr ); wait_device( 13, adr ); join_any disable fork; endtask在任务get_first中fork-join_any语句创建了三个子进程每个子进程等待特定设备(1、7、13)就绪并返回其地址。当三个子进程中有任意一个完成时继续执行父进程中的disable fork语句并终止剩下的两个子进程。下面的例3进一步说明了调用task并不创建子进程。// 例3 module example3; // 信号声明 reg clk, reset; reg [7:0] data_in, data_out; task disable_task; begin disable fork; end endtask task fork_task; begin fork $display(Task start); #10 $display(Task stop); // 该语句永远不会执行 join_none end endtask // initial 语句 initial begin fork_task; #5 disable_task; end endmodule在例3中只有在执行fork-join_none语句时创建了两个子进程而其他语句都属于顶层进程initial因此任务disable_task中的disable fork语句终止了另一个任务中的#10 $display(Task stop);语句因为该语句在执行disable fork语句时是顶层进程的活跃子进程子进程$display(Task start);语句此时已经结束了。问题3假设将例3中的initial语句中的begin-end语句换成fork-join语句如例4所示此时还能与之前有同样的效果吗​// 例4 module example4; // 信号声明 reg clk, reset; reg [7:0] data_in, data_out; task disable_task; begin disable fork; end endtask task fork_task; begin fork $display(Task start); #10 $display(Task stop); // 该语句会执行 join_none end endtask // initial 语句 initial fork fork_task; #5 disable_task; join endmodule答案4不行因为此时disable fork语句所在的进程已经不是任务fork_task中语句的父进程了事实上disable fork语句所在的进程只有一条disable-fork语句。五、写在最后当disable fork语句终止进程执行时会有一些其他的副作用本文将不对此进行详述具体可参考下面的博客除其中第三点外。Verilog基础disable语句https://blog.csdn.net/weixin_45791458/article/details/131543670?ops_request_misc%257B%2522request%255Fid%2522%253A%25220317350431fbd1bf31f233a546d22a2e%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id0317350431fbd1bf31f233a546d22a2ebiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-131543670-null-null.nonecaseutm_termdisablespm1018.2226.3001.4450https://blog.csdn.net/weixin_45791458/article/details/131543670?ops_request_misc%257B%2522request%255Fid%2522%253A%25220317350431fbd1bf31f233a546d22a2e%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id0317350431fbd1bf31f233a546d22a2ebiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-131543670-null-null.nonecaseutm_termdisablespm1018.2226.3001.4450