首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Verilog中的并发始终块

Verilog中的并发始终块
EN

Stack Overflow用户
提问于 2017-08-08 16:38:50
回答 1查看 973关注 0票数 1

我对一些看起来完全正常的Verilog风格的代码进行了几次讨论,但在我看来相当危险(我是Verilog的新手)。它总是关于并发,总是-块和/或分配。下面是一个示例:

代码语言:javascript
运行
复制
module some(input clk_i);

..
    module ram(
          input   wire                a_clk,
          input   wire                a_wr,
          input   wire    [ADDR-1:0]  a_addr,
          input   wire    [DATA-1:0]  a_din,
          output  reg     [DATA-1:0]  a_dout,
    );

    reg [DATA-1:0] mem [(2**ADDR)-1:0];


    always @(posedge a_clk) begin
          a_dout      <= mem[a_addr];
          if(a_wr) begin
              a_dout      <= a_din;
              mem[a_addr] <= a_din;
          end
    end

    endmodule
..

reg wrmem=1'b0;
reg[ADDR-1:0] memaddr;
reg[DATA-1:0] d_in;


ram mem(.a_clk(clk_i),.a_wr(wrmem),.a_addr(memaddr),.a_din(d_in),.a_dout(memout));

..

always @(posedge clk_i) begin
    wrmem <= 1'b0;
        ...
        if(..) begin
            d_in <= sth.
            memaddr <= some address
            wrmem <= 1b'1;
    end
end

endmodule;  

所以这里我们有两个并发的总是块。第一个(在模块“ram”中)对时钟和'reg a_wr‘的高响应。在第二个步骤中,这个“reg”设置为0,几步后又设置为1。为什么这不会导致模块"ram“的任意行为(因为第一个块不会等到第一个模块完成)?

EN

Stack Overflow用户

回答已采纳

发布于 2017-08-08 19:01:15

这正是在verilog中存在的非阻塞分配的原因。

Verilog调度包括每个增量周期的几个桶。大致上,非阻塞分配是在一个单独的调度桶中执行的,阻塞分配之后。

所以,在你的例子中,你有两件事:

代码语言:javascript
运行
复制
always @(posedge clk) 
    if (wreg)
       ...

代码语言:javascript
运行
复制
always @(posedge clk)
    wreg <= 0;
    ...

在仿真中,第一个块将使用'wreg‘的值,因为它存在于非阻塞桶执行之前,可能是1

第二个块将在非阻塞桶中调度的wreg更新为0,但尚未执行。所以,这里没有冲突。

因此,您可以保证在模拟过程中得到一致的结果。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45573722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档