• Verilog 过程结构(initial, always)


    过程结构语句有 2 种,initial 与 always 语句。它们是行为级建模的 2 种基本语句。

    一个模块中可以包含多个 initial 和 always 语句,但 2 种语句不能嵌套使用

    这些语句在模块间并行执行,与其在模块的前后顺序没有关系

    但是 initial 语句或 always 语句内部可以理解为是顺序执行的(非阻塞赋值除外)

    每个 initial 语句或 always 语句都会产生一个独立的控制流,执行时间都是从 0 时刻开始

    initial语句

    initial 语句从 0 时刻开始执行,只执行一次,多个 initial 块之间是相互独立的

    如果 initial 块内包含多个语句,需要使用关键字 begin 和 end 组成一个块语句。

    如果 initial 块内只要一条语句,关键字 begin 和 end 可使用也可不使用。

    initial 理论上来讲是不可综合的,多用于初始化、信号检测等。

    1. Example1:
    2. `timescale 1ns/1ns
    3. module test ;
    4. reg ai, bi ;
    5. initial begin
    6. ai = 0 ;
    7. #25 ; ai = 1 ;
    8. #35 ; ai = 0 ; //absolute 60ns
    9. #40 ; ai = 1 ; //absolute 100ns
    10. #10 ; ai = 0 ; //absolute 110ns
    11. end
    12. initial begin
    13. bi = 1 ;
    14. #70 ; bi = 0 ; //absolute 70ns
    15. #20 ; bi = 1 ; //absolute 90ns
    16. end
    17. //at proper time stop the simulation
    18. initial begin
    19. forever begin
    20. #100;
    21. //$display("---gyc---%d", $time);
    22. if ($time >= 1000) begin
    23. $finish ;
    24. end
    25. end
    26. end
    27. endmodule

    always 语句

            与 initial 语句相反,always 语句是重复执行的。always 语句块从 0 时刻开始执行其中的行为语句;当执行完最后一条语句后,便再次执行语句块中的第一条语句,如此循环反复。由于循环执行的特点,always 语句多用于仿真时钟的产生,信号行为的检测等。

    下面用 always 产生一个 100MHz 时钟源,并在 1010ns 时停止仿真代码如下。

    1. Example2:
    2. `timescale 1ns/1ns
    3. module test ;
    4. parameter CLK_FREQ = 100 ; //100MHz
    5. parameter CLK_CYCLE = 1e9 / (CLK_FREQ * 1e6) ; //switch to ns
    6. reg clk ;
    7. initial clk = 1'b0 ; //clk is initialized to "0"
    8. always # (CLK_CYCLE/2) clk = ~clk ; //generating a real clock by reversing
    9. always begin
    10. #10;
    11. if ($time >= 1000) begin
    12. $finish ;
    13. end
    14. end
    15. endmodule

    对比Example3和Example4,这两个语句执行的效果是完全一致的。Example3中always在0时刻开始执行,然后进入begin语句后遇到@(posedge clk);执行完后继续执行adder1<=adder1+1;
    执行完毕后,再次返回到@(posedge clk);执行,如此周期反复。Example4中,always在0时刻开始执行,然后进入begin语句后遇到adder1<=adder1+1;执行完毕后再次返回@(posedge clk);语句执行,如此周期反复。

    1. Example3:
    2. always begin
    3. @(posedge clk);
    4. adder1<=adder1+1;
    5. end
    1. Example4:
    2. always @(posedge clk)
    3. begin
    4. adder1<=adder1+1;
    5. end

  • 相关阅读:
    第十六章 协程
    3步接入顺丰快递云打印电子面单接口API
    图解DSPy:Prompt的时代终结者?!
    linux--awk
    一种通过nacos动态配置实现多租户的log4j2日志物理隔离的设计
    创建基于多任务的并发服务器
    字节跳动软件测试岗,前两面过了,第三面HR天坑,结局透心凉...
    灰度、rgb之间的概念
    64 位条件下 C++内置类型大小区别
    第五章 数据库设计和事物
  • 原文地址:https://blog.csdn.net/qq_33300585/article/details/127863682