Verilog实现信号对齐,并且打一拍。以及测试文件中阻塞赋值和非阻塞赋值的区别。

编程入门 行业动态 更新时间:2024-10-08 13:33:34

Verilog实现信号对齐,并且打一拍。以及测试文件中阻塞<a href=https://www.elefans.com/category/jswz/34/1769111.html style=赋值和非阻塞赋值的区别。"/>

Verilog实现信号对齐,并且打一拍。以及测试文件中阻塞赋值和非阻塞赋值的区别。

实现功能:

标题首先我遇到的问题是,所有信号变化与时钟上升沿对齐,所以时钟上升沿时候,这些信号该如何取值?

以第三个时钟上升沿为例,a信号在这一时刻该取1还是取2?
a信号在第三个时钟上升沿前一点时间取值,所以a信号取值为1;同理,b信号取值为3,c信号取值为5,d信号取值为2.
也就是说在时钟上升沿时刻,一般信号采样会采该信号前面一点点时刻所对应的值。

如何打一拍

“打一拍”是指信号延迟一个时钟周期。
我们可以看到,vld_out是vld_in打一拍输出后的结果,那么如何进行打拍呢?
使用D触发器即可实现打一拍。

always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)vld_out<=1'b0;
else vld_out<=vld_in;
end

设计文件代码

该代码上述功能要求:

module four_data_multiply(
clk    ,
rst_n  ,
vld_in ,
a      ,
b      ,
c      ,
d      ,
vld_out,
dout
);//参数定义
parameter      DATA_W =         4;
parameter      DATA_O_W =      16;//输入信号定义
input               clk    ;
input               rst_n  ;
input               vld_in ;
input[DATA_W-1:0]   a      ;
input[DATA_W-1:0]   b      ;
input[DATA_W-1:0]   c      ;
input[DATA_W-1:0]   d      ;
//输出信号定义
output[DATA_O_W-1:0]  dout ;
output              vld_out;
//输出信号reg定义
reg   [DATA_O_W-1:0]  dout   ;
reg                 vld_out; 
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begindout<=1'b0;
end
else begin   dout<=a*b*c*d;      
end
endalways@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)vld_out<=1'b0;
else vld_out<=vld_in;
end
endmodule

测试文件中阻塞赋值和非阻塞赋值区别

在Verilog眼中无论testbench、dut还是assertion都是code。

所以先把code吃进来,然后有一个时间轴参数,仅仅处理set t = 0时刻的code.这个code有阻塞语句、$display、assignment…0时刻还有#0语句、在处理非阻塞的LHS、最后monitor语句。

当我的测试文件是使用非阻塞赋值

`timescale 1ns / 1ps
module testBench();reg        clk   ;reg        rst_n ;reg        vld_in;reg[3:0]   a     ;reg[3:0]   b     ;reg[3:0]   c     ;reg[3:0]   d     ;wire[15:0] dout  ;parameter CYCLE=10   ; parameter RST_TIME=2 ;four_data_multiply test(.clk(clk)   ,.rst_n(rst_n)  ,.vld_in(vld_in) ,.a(a)      ,.b(b)      ,.c(c)      ,.d(d)     ,.vld_out(vld_out),.dout(dout));initial beginclk=1;#1;forever #(CYCLE/2)clk=~clk;endinitial beginrst_n=1;#(1) rst_n=0;#(RST_TIME) rst_n=1;endinteger i;initial begin #(1);for(i=0;i<6;i=i+1)begin #(CYCLE);a<=i;b<=i+1;c<=i+2;d<=i+3;end  endinitial beginvld_in<=0;#(CYCLE*2+1);vld_in<=1;  #(CYCLE*2);vld_in<=0;#(CYCLE*1);vld_in<=1;#(CYCLE*1);vld_in<=0;end
endmodule

然后我的仿真结果如下所示:
可以完成该要求。

当我的测试文件使用阻塞赋值:

`timescale 1ns / 1ps
module testBench();reg        clk   ;reg        rst_n ;reg        vld_in;reg[3:0]   a     ;reg[3:0]   b     ;reg[3:0]   c     ;reg[3:0]   d     ;wire[15:0] dout  ;parameter CYCLE=10   ; parameter RST_TIME=2 ;four_data_multiply test(.clk(clk)   ,.rst_n(rst_n)  ,.vld_in(vld_in) ,.a(a)      ,.b(b)      ,.c(c)      ,.d(d)     ,.vld_out(vld_out),.dout(dout));initial beginclk=1;#1;forever #(CYCLE/2)clk=~clk;endinitial beginrst_n=1;#(1) rst_n=0;#(RST_TIME) rst_n=1;endinteger i;initial begin #(1);for(i=0;i<6;i=i+1)begin #(CYCLE);a=i;b=i+1;c=i+2;d=i+3;end  endinitial beginvld_in=0;#(CYCLE*2+1);vld_in=1;#(CYCLE*2);vld_in=0;#(CYCLE*1);vld_in=1;#(CYCLE*1);vld_in=0;end
endmodule

仿真结果如下:
可以看出,虽然我在设计文件里写了打拍节奏,然而依然没有实现打拍。

原因如下:

在Verilog眼中无论testbench、dut还是assertion都是code。所以先把code吃进来,然后有一个时间轴参数,仅仅处理set t = 0时刻的code.这个code有阻塞语句、$display、assignment…0时刻还有#0语句、在处理非阻塞的LHS、最后monitor语句。
所以当使用阻塞赋值时,在时钟上升沿时,首先执行阻塞赋值,然后信号采样阻塞赋值的结果。
所以当使用非阻塞赋值时,在时钟上升沿时,信号采样非阻塞赋值的前一时刻的结果,等到采样结束,才执行非阻塞赋值的LHS。

更多推荐

Verilog实现信号对齐,并且打一拍。以及测试文件中阻塞赋值和非阻塞赋值的区别。

本文发布于:2024-02-13 15:34:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759373.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:赋值   一拍   信号   区别   文件

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!