ZYNQ学习:Verilog语言心得(三)

前言

在使用always语句的时候会用到敏感信号列表,这种列表可以很清晰地表示该always块在什么时候被触发。然而当敏感列表有多个条件的时候,如果条件同时满足,always肯定会触发,但是具体会触发哪一个呢,触发两次还是一次呢?这需要通过一些实验来证明。

测试

编写RTL代码,输入是系统时钟和复位,输出是一个LED灯,模块中还包含了一个计数器,用来测试always块被进入了几次。

module sensitive_test(
    input      sys_clk   ,
    input      sys_rst_n ,
    
    output reg led       
    );
    
    reg [3:0] count = 4'b0;
    
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(sys_clk)
            led <= 1'b1;
        else if(!sys_rst_n)
            led <= 1'b0;
        else
            led <= 1'bz;
        end

    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)
            count <= count + 4'b10;
        else if(sys_clk)
            count <= count + 4'b1; 
        else
            count <= 4'bz;
        end
    
    endmodule

对应的tb代码如下:

`timescale 1ns/1ns
module tb_sensitive_test();

    parameter CLK_PERIOD = 20;

    reg  sys_clk;
    reg  sys_rst_n;

    wire led;

    initial begin
        sys_clk   <= 1'b0;
        sys_rst_n <= 1'b0;
        #(CLK_PERIOD/2)
        sys_rst_n <= 1'b1;
        #(CLK_PERIOD*4)
        sys_rst_n <= 1'b0;
        end
    always #(CLK_PERIOD/2)
        sys_clk <= !sys_clk;

    sensitive_test u_sensitive_test(
        .sys_clk   (sys_clk  ),
        .sys_rst_n (sys_rst_n),
          
        .led       (led      )
        );

    endmodule

经过仿真的波形图如图所示:

下面来仔细分析一下:

1.在0ns处,计数器直接从初始值0变成了2,这说明在tb文件中给sys_rst_n赋值为0也相当于一个下降沿,成功触发了两个always块

2.而后每次时钟上升沿都会触发两个always块,所以灯一直亮,计数器一直加1

3.关键的90ns处,时钟处于上升沿,rst处于下降沿,同时满足了触发always块的条件,所以进入了always块,这里需要注意,没有先后顺序,同时满足就进入,并不是满足了哪一个所以进了,就是都满足所以进来了,无需纠结到底是谁触发的这个always。

问题1:90ns处,这里led并没有清零,这是为什么呢?

答:因为我们的代码是这样写的:

    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(sys_clk)        //先判断时钟信号,这是一种不妙的写法
            led <= 1'b1;
        else if(!sys_rst_n)
            led <= 1'b0;
        else
            led <= 1'bz;
        end

所以,逻辑是这样的:因为“两个信号同时触发了” ==> 进入了always块 ==> 进入后第一行要求判断clk的电平  ==> 因为输入信号取变化后的值  ==> 所以clk为高  ==> 执行led变高电平  ==> 退出

(对输入信号为什么取变化后的值不理解,可以看上一篇文章)

问题2:90ns处,计数器直接加了2,这说明什么呢?

计数器直接加二,说明进入always块后执行了如下计数器代码:

    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)
            count <= count + 4'b10;
        else if(sys_clk)
            count <= count + 4'b1; 
        else
            count <= 4'bz;
        end

判断rst为低,所以直接执行count+2的代码,然后退出结束。

这说明:两个敏感电平同时变化,只会进入always块一次,否则这里就会加4了

总结

1.对于多个敏感信号触发的always模块,如果条件同时满足,将只会执行一次块内代码。

2.不论如何进入的always模块,都会严格按照always模块内部逻辑按顺序进行执行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值