侧边栏壁纸
    • 累计撰写 302 篇文章
    • 累计收到 527 条评论
    Verilog教程语句块
    我的学记|刘航宇的博客

    Verilog教程语句块

    刘航宇
    2022-08-09 / 0 评论 / 171 阅读 / 正在检测是否收录...

    Verilog 语句块提供了将两条或更多条语句组成语法结构上相当于一条一句的机制。主要包括两种类型:顺序块和并行块。

    顺序块

    顺序块用关键字 begin 和 end 来表示。
    顺序块中的语句是一条条执行的。当然,非阻塞赋值除外。
    顺序块中每条语句的时延总是与其前面语句执行的时间相关。
    在本节之前的仿真中,initial 块中的阻塞赋值,都是顺序块的实例。
    并行块
    并行块有关键字 fork 和 join 来表示。
    并行块中的语句是并行执行的,即便是阻塞形式的赋值。
    并行块中每条语句的时延都是与块语句开始执行的时间相关。
    顺序块与并行块的区别显而易见,下面用仿真说明。

    仿真代码如下:

    `timescale 1ns/1ns
     
    module test ;
        reg [3:0]   ai_sequen, bi_sequen ;
        reg [3:0]   ai_paral,  bi_paral ;
        reg [3:0]   ai_nonblk, bi_nonblk ;
     
     //============================================================//
        //(1)Sequence block
        initial begin
            #5 ai_sequen         = 4'd5 ;    //at 5ns
            #5 bi_sequen         = 4'd8 ;    //at 10ns
        end
        //(2)fork block
        initial fork
            #5 ai_paral          = 4'd5 ;    //at 5ns
            #5 bi_paral          = 4'd8 ;    //at 5ns
        join
        //(3)non-block block
        initial fork
            #5 ai_nonblk         <= 4'd5 ;    //at 5ns
            #5 bi_nonblk         <= 4'd8 ;    //at 5ns
        join
     
    endmodule

    仿真结果如下:

    如图所示,顺序块顺序执行,第 10ns 时,信号 bi_sequen 才赋值为 8。
    而并行块,ai_paral 与 bi_paral 的赋值是同时执行的,所以均在 5ns 时被赋值。
    而非阻塞赋值,也能达到和并行块同等的赋值效果。
    Test

    嵌套块

    顺序块和并行块还可以嵌套使用。
    仿真代码如下:

    `timescale      1ns/1ns
     
    module test ;
     
        reg [3:0]   ai_sequen2, bi_sequen2 ;
        reg [3:0]   ai_paral2,  bi_paral2 ;
        initial begin
            ai_sequen2         = 4'd5 ;    //at 0ns
            fork
                #10 ai_paral2          = 4'd5 ;    //at 10ns
                #15 bi_paral2          = 4'd8 ;    //at 15ns
            join
            #20 bi_sequen2      = 4'd8 ;    //at 35ns
        end
     
    endmodule

    仿真结果如下:

    并行块语句块内是并行执行,所以信号 ai_paral2 和信号 bi_paral2 分别在 10ns, 15ns 时被赋值。而并行块中最长的执行时间为 15ns,所以顺序块中的信号 bi_sequen2 在 35ns 时被赋值。
    Test

    命名块

    我们可以给块语句结构命名。
    命名的块中可以声明局部变量,通过层次名引用的方法对变量进行访问。
    仿真代码如下:

    `timescale 1ns/1ns
     
    module test;
     
        initial begin: runoob   //命名模块名字为runoob,分号不能少
            integer    i ;       //此变量可以通过test.runoob.i 被其他模块使用
            i = 0 ;
            forever begin
                #10 i = i + 10 ;      
            end
        end
     
        reg stop_flag ;
        initial stop_flag = 1'b0 ;
        always begin : detect_stop
            if ( test.runoob.i == 100) begin //i累加10次,即100ns时停止仿真
                $display("Now you can stop the simulation!!!");
                stop_flag = 1'b1 ;
            end
            #10 ;
        end
     
    endmodule

    仿真结果如下:

    Test
    命名的块也可以被禁用,用关键字 disable 来表示。
    disable 可以终止命名块的执行,可以用来从循环中退出、处理错误等。
    与 C 语言中 break 类似,但是 break 只能退出当前所在循环,而 disable 可以禁用设计中任何一个命名的块。
    仿真代码如下:

    `timescale 1ns/1ns
     
    module test;
     
        initial begin: runoob_d //命名模块名字为runoob_d
            integer    i_d ;
            i_d = 0 ;
            while(i_d<=100) begin: runoob_d2
                # 10 ;
                if (i_d >= 50) begin       //累加5次停止累加
                    disable runoob_d3.clk_gen ;//stop 外部block: clk_gen
                    disable runoob_d2 ;       //stop 当前block: runoob_d2
                end
                i_d = i_d + 10 ;
            end
        end
     
        reg clk ;
        initial begin: runoob_d3
            while (1) begin: clk_gen  //时钟产生模块
                clk=1 ;      #10 ;
                clk=0 ;      #10 ;
            end
        end
     
    endmodule

    仿真结果如下:

    由图可知,信号 i_d 累加到 50 以后,便不再累加,以后 clk 时钟也不再产生。
    可见,disable 退出了当前的 while 块。
    Test
    需要说明的是,disable 在 always 或 forever 块中使用时只能退出当前回合,下一次语句还是会在 always 或 forever 中执行。因为 always 块和 forever 块是一直执行的,此时的 disable 有点类似 C 语言中的 continue 功能。

    1
    Verilog 实现并行 FIR 滤波器设计
    « 上一篇 2022-08-13
    真心谈谈西北大学843、849专业课与数学复习建议-电子科学、信息通信、新一代电子信息
    下一篇 » 2022-07-30

    评论 (0)

    取消