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

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 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)