赞
踩
先附上参考链接: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成功打了一拍。
深究原因还是仿真中阻塞赋值和非阻塞赋值的使用原因,如果有知道其原理的大佬可以麻烦在评论区指教一下,因为本文只提出了解决方法,也是知其然,不知其所以然。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。