先附上参考链接: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成功打了一拍。文章来源:https://www.toymoban.com/news/detail-528711.html
深究原因还是仿真中阻塞赋值和非阻塞赋值的使用原因,如果有知道其原理的大佬可以麻烦在评论区指教一下,因为本文只提出了解决方法,也是知其然,不知其所以然。文章来源地址https://www.toymoban.com/news/detail-528711.html
到了这里,关于FPGA的Verilog打拍方式无法打拍,测试的仿真结果不打拍的解决方法。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!