空格回车life 2017-05-21 15:47 采纳率: 0%
浏览 5991
已结题

Verilog中非阻塞赋值会使数据延时一个clock的疑惑?

 `timescale 1ns/1ps
module freq ();
reg             clk_250     =   1'b0        ;
reg             rst         =   1'b1        ;               
reg [6  :   0]  cnt         =   7'd0        ;
reg             valid       =   1'b0        ;
reg [2  :   0]  valid_cnt   =   3'd0        ;

parameter PERIOD_250 = 4 ;


//产生250MHZ时钟
initial
begin
    clk_250 = 0;
    forever #(PERIOD_250/2) clk_250 = ~clk_250; 
end

initial
begin
    #8  rst =   1'b0    ;
end

always  @   (   posedge clk_250 )
begin
    if( rst ==  1)
        cnt <=  8'b0000_0000    ;
    else
        begin
            if( cnt ==  8'd100  )
                cnt <=  8'd1    ;
            else
                cnt <=  cnt +   8'b1;
        end
end


always  @   (   posedge clk_250 )
begin
    if( rst ==  1'b1    )
        valid_cnt   <=  3'd0                ;
    else
        begin
            if( valid_cnt   ==  3'd6)
                valid_cnt   <=  3'd1;
            else
                valid_cnt   <=  valid_cnt   +   3'd1;
        end     
end


always  @   (   posedge clk_250 )
begin
    if( rst ==  1)
        valid   <=  1'b0    ;
    else
        begin
            if( valid_cnt   ==  1)
                valid   <=  1'd1;
            else
                valid   <=  1'd0;
        end
end
endmodule

上面代码想实现的是1到100的数据进行循环。并且有一个valid信号标志有效位,每6个数据有一个valid信号。下面是我用modelsim仿真得到的仿真图。图片说明
自己认为的仿真图应该是下面这样。图片说明
非阻塞赋值的结果要在下一个clock的上升沿才能得出。也就是需要延迟一个clock。仿真图里面感觉就有点自相矛盾。在生成cnt信号和valid-cnt 信号时直接在当前的clock就产生数据。然而产生valid信号时却是在下一个时钟产生的。
自己接触verilog时间不常工作需要,所以必须要把这个点弄会。总结上面的问题,其实就一个,非阻塞赋值会使得到的数据延时一个clock吗?如果是如何解释cnt和valid-cnt信号的生成。如果不延时一个clock那么valid信号为什么在下一clock才得出结果。希望能够得到专业的回答!!!毕竟我写了这么多又做了这么多的工作。

  • 写回答

6条回答

  • weixin_45857394 2020-06-16 15:16
    关注

    这个我觉得应该从时间片的概念上解答
    图片说明

    verilog的timeslot划分5个域:
    Active region : 执行process语句,阻塞赋值,连续赋值,及非阻塞赋值的右侧求值事件,阻塞赋值和连续赋值会触发在该时刻的新事件。$display是在该region执行。
    Inactive region : 执行 #0的阻塞赋值;
    NBA region : 更新非阻塞赋值的LHS(左侧值);
    Monitor region : 执行$monitor 和 $strobe等,不会触发任何其他事件的read-only region
    process: 进程是Verilog中的独立执行单元,包括:原语(Primitives), 模块(Moules), initial过程块, always过程块, 连续赋值语句(assign), 异步任务(task)。在仿真时,所有的进程都是仿真器按Verilog的语义来顺序执行的,效果是各个进程并行执行的效果,在未执行完当前所有的进程时,仿真时间不会向前推进。
    你这个例子就是先在active region执行了porcess 这个时候非阻塞运算的cnt值( 处在右侧求值阶段) ,cnt实际值=6,执行判断语句(cnt == 1)当然就不成立,active region执行然后才会跳转到NBA region ,更新非阻塞赋值的左侧值 即cnt在此刻才变成1

    评论

报告相同问题?

悬赏问题

  • ¥15 计算二重积分∫∫e^(x+y)dxdy,其中0≤x≤1,0≤y≤1,试分别用复合辛普森公式(取n=4)以及高斯求积公式(取n=4)计算积分 给出matlab程序
  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的