关于寄存器对输入信号延迟失败的问题

本人最近在做导师的一个小任务,需要用到FPGA开发。在设计电路中需要对输入的使能信号做一个时钟周期的延迟,但在仿真过程中遇到了一个之前从未遇到过的情况,即寄存器在某些情况下对输入信号延迟失败。

问题描述

代码如下图所示,其中输入的使能信号为data_en, data_en_buff实现一个寄存器,负责对data_en做一个时钟周期的延迟。

下图为本人使用modelsim仿真的波形,当data_en为周期方波信号时,data_en_buff能够对data延迟一个时钟周期。但当data_en只是某一时刻后从低电平跳变至高电平的信号时,data_en_buff未能对data_en_buff延迟一个时钟周期,而是与data_en同时变化。

 最初本人怀疑是不是我的代码写的有问题,于是在编译过后查看了一下RTL视图,如下图所示。data_en_buff确实生成了一个寄存器,其中D信号连接的确实是data_en,由于不方便全部截入图片,该图片中未体现。由此可见我的代码应该没问题。

本人在网上查阅了不少帖子,同时也询问了学长,大概明白了问题所在。

问题原因

此处牵涉到非阻塞赋值的延迟问题,非阻塞赋值在某些情况下会延迟一个时钟周期,某些情况下不会。本人参考了以下文章

(21条消息) Verilog之非阻塞赋值(三)—— 赋值延后一个周期_隔壁老余的博客-CSDN博客_verilog延迟一个周期

以下为具体情况:(以下默认always块中描述时序电路用非阻塞赋值,描述组合逻辑电路用阻塞赋值)

1. always块中的if语句的每个条件分支都仅有一条赋值语句,并且if语句的条件判断式中不含有非阻塞赋值的reg变量(即会生成寄存器的reg变量)时,此时非阻塞赋值会在时钟上升沿时瞬间完成。

2. 当always块中的if语句的条件判断式中含有wire型变量或阻塞赋值的reg型变量,即最终生成的是组合电路的信号,同时该变量与其他非阻塞赋值的reg变量无关时,该非阻塞赋值会在时钟上升沿时瞬间完成;反之则会延迟一个时钟周期。

3.当always块中的if语句的条件分支中含有多条非阻塞赋值语句,且某些语句的RHS(赋值语句的右侧)是别的语句的LHS(赋值语句的左侧)时,会出现延迟一个时钟周期的情况。

本人的代码为上述的情况2。其中条件判断式为外部输入信号,modelsim并不知道该信号是寄存器型的信号还是wire型信号。

当data_en为周期方波信号时,modelsim认为其与其他非阻塞赋值的reg变量有关,赋值会延迟一个时钟周期;当data_en为在某一时刻从低电平跳变至高电平的信号时,modelsim认为其与其他非阻塞赋值的reg变量无关,赋值会在时钟上升沿到来时瞬间完成。

因此本人猜测我遇到的问题其实由verilog语法的导致的功能仿真出错,但不会对实际电路产生影响。因为在RTL视图中可以看到data_en_buff确实生成为一个寄存器了,实际上板之后就不会遇到寄存器延迟失败的问题了。

 解决方案

因为实际电路并没有问题,只是功能仿真时出现错误,所以可以忽略掉该问题。由于在本人的工程中,data_en实际从另一个模块中的非阻塞赋值reg变量输出的,所以进行联合仿真时modelsim就会知道data_en是寄存器型的信号了,于是便会延迟一个时钟周期后赋值。仿真截图如下。

本人后来咨询师兄,师兄给出的解释是,寄存器输出本身有延时,但在前仿时被忽略了。可以在赋值的时候,在赋值语句前加一个时延,例如 #1 data_en_buff <= data_en,这样信号的跳变就和时钟边沿错开了,也更接近真实情况。而进行综合时,这些时延会被自动忽略,并不需要修改代码。一般调用了ip核时可能会遇到这种问题,可以在遇到这种问题时加个时延,没有遇到就可以不加。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值