• SystemVerilog 控制流语句


    • unique-if/unique0-if

    • 对于unique-if ,如果condition没有一个匹配且没有加else语句,则会报告一个错误;如果超过1个condition匹配,也会报告错误;
      unique0-if与unique-if的不同之处在于,如果没有一个condition匹配也不会报错

      1. module tb;
      2. int x = 4;
      3. initial begin
      4. // This if else if construct is declared to be "unique"
      5. // Error is not reported here because there is a "else"
      6. // clause in the end which will be triggered when none of
      7. // the conditions match
      8. unique if (x == 3)
      9. $display ("x is %0d", x);
      10. else if (x == 5)
      11. $display ("x is %0d", x);
      12. else
      13. $display ("x is neither 3 nor 5");
      14. // When none of the conditions become true and there
      15. // is no "else" clause, then an error is reported
      16. unique if (x == 3)
      17. $display ("x is %0d", x);
      18. else if (x == 5)
      19. $display ("x is %0d", x);
      20. end
      21. endmodule

    • priority-if

    • 果condition没有一个匹配且没有加else语句,则会报告一个错误;如果有多个condition匹配,排在前面的优先级最高,且执行完最高的优先级后退出选择
       
      1. module tb;
      2. int x = 4;
      3. initial begin
      4. // Exits if-else block once the first match is found
      5. priority if (x == 4)
      6. $display ("x is %0d", x);
      7. else if (x != 5)
      8. $display ("x is %0d", x);
      9. end
      10. endmodule
    • unique,unique0 case

    • 对于unique case ,如果case没有一个匹配,则会报告一个错误;如果超过1个condition匹配,也会报告错误,同时执行第一个匹配到的case;
      unique0-case与unique-case的不同之处在于,如果没有一个case匹配也不会报错
      1. module tb;
      2. bit [1:0] abc;
      3. initial begin
      4. abc = 1;
      5. // None of the case items match the value in "abc"
      6. // A violation is reported here
      7. unique case (abc)
      8. 0 : $display ("Found to be 0");
      9. 2 : $display ("Found to be 2");
      10. //使用unique case此时多加default
      11. endcase
      12. end
      13. endmodule
    • priority case

    • 至少有一个条件选项的值与条件表达式匹配。如果有多个条件选项的值与条件表达式匹配,必须执行第一个匹配分支
    1. bit [2:0] a;
    2. priority case(a) //4,5,6,7会引起一个运行时警告
    3. 3'b00?: $display("0 or 1");
    4. 3'b0??: $display("2 or 3");
    5. endcase

    forever

    在SV中,always块不能存在于类和其他过程块中,所以用forever代替。格式如下:

    1. always begin
    2. // Multiple statements
    3. end
    1. class Monitor;
    2. virtual task run();
    3. forever begin
    4. @(posedge vif.clk);
    5. if (vif.write & vif.sel)
    6. // Capture write data
    7. if (!vif.write & vif.sel)
    8. // Capture read data
    9. end
    10. endtask
    11. endclass
    12. module tb;
    13. Monitor mon;
    14. // Start the monitor task and allow it to continue as
    15. // long as there is activity on the bus
    16. initial begin
    17. fork
    18. mon.run();
    19. join_none
    20. end
    21. endmodule

            为了防止循环体在delta时间内产生无限循环,导致仿真挂起,forever循环体内部必须带有时序控制或者disable语句

    break

    类C语言的break声明立即结束循环操作。循环不会重新执行,除非执行流程重新到达循环的起点

    1. 1 // find first bit set within a range of bits
    2. 2 always_comb begin
    3. 3 first_bit = 0;
    4. 4 for (int i=0; i<=63; i=i+1) begin
    5. 5 if (i < start_range) continue;
    6. 6 if (i > end_range) break; // exit loop
    7. 7 if ( data[i] ) begin
    8. 8 first_bit = i;
    9. 9 break; // exit loop
    10. 10 end
    11. 11 end // end of the loop
    12. 12 ... // process data based on first bit set
    13. 13 end

    continue

            类C语言的continue声明跳转到循环的末尾并执行循环的控制。使用continue声明时,不需要对代码添加命名的begin…end块,而这在使用disable声明时是必要的。

    1. 1 logic [15:0] array [0:255];
    2. 2 always_comb begin
    3. 3 for (int i = 0; i <= 255; i++) begin : loop
    4. 4 if (array[i] == 0)
    5. 5 continue; // skip empty elements
    6. 6 transform_function(array[i]);
    7. 7 end // end of loop
    8. 8 end

    return

            system verilog增加了类C语言的return声明,用于从一个非void函数中返回数值或者从一个void函数或任务返回。return声明可以在任务或函数执行流程的任意一点执行。当return声明执行后,任务或者函数立即退出而不需要执行到任务或者函数的末尾

    1. 1 task add_up_to_max (input [ 5:0] max,
    2. 2 output [63:0] result);
    3. 3 result = 1;
    4. 4 if (max == 0) return; // exit task
    5. 5 for (int i=1; i<=63; i=i+1) begin
    6. 6 result = result + result;
    7. 7 if (i == max) return; // exit task
    8. 8 end
    9. 9 endtask

    disable

            disable :用于在多进程的场景下终止一个或多个进程
            disable语句可以用在task或者块中去终止指定的task或块,包括终止disable语句所在的块或者task。disable也可以用在function中去终止task或者块,但不能用于终止function。当在function中用dsiable语句终止了一个task或者块,而这个task或者块刚好又是这个function的caller, 这种情况的结果是未知的。

    1. task proc_a;
    2. begin
    3. ...
    4. ...
    5. if (a == 0)
    6. disable proc_a; // return if true
    7. ...
    8. ...
    9. end
    10. endtask

    event

            event是一个静态对象句柄,用于在两个或多个同时活动的进程之间进行同步。 一个进程将触发事件,另一个进程将等待事件。

    【1】可以赋值或与其他事件变量进行比较
    【2】可以赋值为空
    【3】当赋值给另一个事件时,两个变量都指向同一个同步对象
    【4】可以传递给队列,函数和任务

    如何触发并等待事件?

    【1】可以使用->或->>运算符触发命名事件
    【2】进程可以使用@运算符或.triggered等待事件

    1. module tb;
    2. //创建一个事件变量,进程可用于触发和等待
    3. event event_a;
    4. // 线程1:使用“->”运算符触发事件
    5. initial begin
    6. #20 ->event_a;
    7. $display ("[%0t] Thread1: triggered event_a", $time);
    8. end
    9. // 线程2:使用“ @”运算符等待事件
    10. initial begin
    11. $display ("[%0t] Thread2: waiting for trigger ", $time);
    12. @(event_a);
    13. $display ("[%0t] Thread2: received event_a trigger ", $time);
    14. end
    15. // 线程3:使用“ .triggered”等待事件
    16. initial begin
    17. $display ("[%0t] Thread3: waiting for trigger ", $time);
    18. wait(event_a.triggered);
    19. $display ("[%0t] Thread3: received event_a trigger", $time);
    20. end
    21. endmodule

  • 相关阅读:
    vue 学习 -- day36(分析工程结构)
    【商鼎云更新】你想要的相册备份功能,已经安排上了​
    请问哪家淘宝/天猫店 您家的是真的 STM32F103C8T6系统板?
    基于ASP.NET大学生校园招聘网站的设计与开发
    STM32CubeMX教程9 USART/UART 异步通信
    目标检测算法——YOLOv5/YOLOv7改进之结合Swin Transformer V2
    JAVA中的内存泄漏和需要手动关闭的资源
    (十九)ATP应用测试平台——springboot集成RocketMQ案例实战
    安全计算环境(设备和技术注解)
    ES6:const声明
  • 原文地址:https://blog.csdn.net/qq_33300585/article/details/133206169