FPGA的Verilog打拍方式无法打拍,测试的仿真结果不打拍的解决方法。

       先附上参考链接:http://t.csdn.cn/krJki

        最近做项目涉及到边缘检测,发现对输入信号打拍时仿真结果无法实现打两拍的功能。这些年多多少少都遇到过类似打拍失效的情况,因为当时项目的原因起初没有太过注意,但现在需要对周期数严格把控,就需要实时的仿真观测到到底是多少拍,由此开始了面向CSDN的学习过程,网上所讲甚少,为了方便后来的小伙伴快速解决,所以根据参考链接和测试有了以下的解决方式。

先提出解决方法:在编写测试激励文件也就是tb文件设计时:

时钟复位用阻塞赋值(=),其他信号用非阻塞赋值(<=)。

        为了更具体的看到效果,做下面的测试。简单的设计的一个.v文件,代码如下:

module Beat(
    input clk,rst,
    input   wire Flag_in,
    output  wire Flag_out
    );
 reg Flag_R0,Flag_R1;
always@(posedge clk)
    if(rst)
       begin
        Flag_R0<=1'b0;
        Flag_R1<=1'b0;
       end 
       else begin
             Flag_R0<=Flag_in;
             Flag_R1<=Flag_R0;   
            end
 assign   Flag_out    =Flag_R1;     
endmodule

        其实现的功能就是将输入的Flag_in信号打两拍然后输出给到Flag_out信号。接下来就是仿真激励文件代码如下:

`timescale 1ns / 1ps
module Beat_tb;
    reg clk,rst;
    reg    Flag_in;
    wire   Flag_out;
Beat b0(
    .clk(clk),
    .rst(rst),
    .Flag_in(Flag_in),
    .Flag_out(Flag_out)
    );    
initial
 begin
    clk =1'b1;
    rst =1'b1;
    #2
    rst =1'b0;
    forever #2 clk =!clk;
 end
 initial
 begin
    Flag_in =1'b0;
    #10
    Flag_in =1'b1;
    #20
    Flag_in =1'b0;
 end  
endmodule

        当我们对所有的输入信号都通过阻塞的方式赋值时,就会产生如下结果

        可以直观的看到,从输入Flag_in到Flag_R0时没有实现打拍效果的,R0到R1是可以打拍。接下来我继续测试了1、所有信号非阻塞赋值和2、时钟复位非阻塞赋值,其他信号阻塞赋值,这两种赋值组合,结果都跟上图一样无法实现打两拍操作

        最后就是正确方法的测试代码:

`timescale 1ns / 1ps
module Beat_tb;
    reg clk,rst;
    reg    Flag_in;
    wire   Flag_out;
Beat b0(
    .clk(clk),
    .rst(rst),
    .Flag_in(Flag_in),
    .Flag_out(Flag_out)
    );    
initial
 begin
    clk =1'b1;
    rst =1'b1;
    #2
    rst =1'b0;
    forever #2 clk =!clk;
 end
// always #2 clk=!clk;
 initial
 begin
    Flag_in <=1'b0;
    #10
    Flag_in <=1'b1;
    #20
    Flag_in <=1'b0;
 end  
endmodule

测试的结果如下图:

        可以看到利用 时钟复位用阻塞赋值(=),其他信号用非阻塞赋值(<=)的方式成功的实现了打拍的操作,输入到R0成功打了一拍。

        深究原因还是仿真中阻塞赋值和非阻塞赋值的使用原因,如果有知道其原理的大佬可以麻烦在评论区指教一下,因为本文只提出了解决方法,也是知其然,不知其所以然。

  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Verilog中,打一指的是将信号通过一次寄存器来延迟一。这样可以确保信号在时钟上升沿到来时已经稳定,并且可以在下一个时钟周期中使用。打一方法是在always块中使用非阻塞赋值语句(<=)将输入信号赋值给一个寄存器变量。例如: ```verilog always @(posedge Clk) begin input_reg <= input; // 其他逻辑操作 end ``` 在上述代码中,input_reg是一个寄存器变量,input是输入信号。在时钟上升沿到来时,input_reg会被赋值为input的当前值。这样,input_reg就保存了上一个时钟周期的输入信号值,可以在下一个时钟周期中使用。 需要注意的是,打一只适用于同一时钟域的信号。如果信号来自异步时钟域,需要进行更复杂的寄存器设计来处理时序问题。 #### 引用[.reference_title] - *1* *2* [FPGA “打一”含义](https://blog.csdn.net/kebu12345678/article/details/80669549)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Verilog HDL | 移位“打拍](https://blog.csdn.net/m0_38053615/article/details/67664797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值