【问题标题】:initial block execution order in verilogVerilog中的初始块执行顺序
【发布时间】:2018-09-30 06:38:53
【问题描述】:

我做了一个计数器模块,我似乎无法掌握计数器模块和测试台模块的初始块的执行顺序。

据我所知,我认为在verilog中,总是会先执行初始块。

在这种情况下,我将执行 testbench 模块并假设 initial 块 对于testbench_counter 将首先执行。

接下来,我认为计数器模块C 将被执行,x_in 的值将更新为temp,而无需#1 模块C 中的延迟。

但是没有#1,或者将initial 更改为always@(x_in) 我看到redline

所以问题是

  1. 计数器模块 Cinitial 块是否会在测试台的 initial 块之前首先执行?

  2. 如果我使用always@(x_in),为什么它会起作用?

提前致谢。

计数器代码

`timescale 1ns/1ns
module counter(x_in,clk,y_out);
    input [31:0] x_in;
    input clk;
    output [31:0] y_out;
    reg [31:0] y_out;
    reg [31:0] temp;

    initial begin
        #1 temp=x_in;
    end

    always@(posedge clk) begin
        temp<=temp+1;   
        y_out<=temp;
    end
endmodule

测试台代码

`timescale 1ns/1ns

module testbench_conter();
    wire [31:0]y_out;
    wire [31:0]temp;
    reg [31:0]x_in;
    reg clk;

    counter C(x_in,clk,y_out);

    always begin
        #5 clk=~clk;
    end

    initial begin
        clk=1'b0; 
        x_in=32'd0;
        #0
        #10000
        $stop;
    end
endmodule

【问题讨论】:

    标签: verilog


    【解决方案1】:

    接下来,我以为计数器模块C会被执行……

    您认为的主要缺陷是计数器中的初始语句是在计数器“执行”时执行的。不是这种情况。 所有初始语句在程序开始时运行,并且只运行一次。因此,您的两个初始语句形成了竞争条件。

    通过使用 #1 或 always@(x_in),您可以延迟对 `temp1 的分配,直到定义 x_in 之后。

    更好的办法是向您的计数器添加一个“加载”信号,该信号在激活时获取 x_in 的值。

    您的 y_out 也被另一个时钟周期延迟。

    通常一个可加载的计数器看起来像:

    always@(posedge clk)
    begin
       if (load)
          y_out <= x_in;
       else
          y_out <= y_out + 1;   
    end
    

    【讨论】:

      【解决方案2】:

      回答您的问题 1:initial 块之间绝对没有保证的执行顺序。 Verilog 模拟以任意不可预测的顺序启动它们。同步的唯一方法是#delays 和其他等待和延迟语句。

      Verilog 保证任何过程块(包括初始块和始终块)的执行都会在等待条件下停止,直到它得到满足。

      Verilog 还保证所有初始块开始任何always块之前。

      alway 块敏感度列表中指定的任何信号都扮演“延迟”语句的角色,导致 always 块等待任何信号值发生变化。之后它将继续执行该块。

      所以,回答你的第二个问题,always@(x_in) 将等到信号的值发生变化。

      所以,在你的情况下:

       initial begin    << will start execution at time '0' before any always block
          clk=1'b0;     << change value of clk from 'x' -> '1' 
          x_in=32'd0;   << change value of x_in 'x' -> '0'
          #0            << makes absolutely no sense here. It is a special statement
          #10000        << pauses execution for 10000 time units
          $stop;        << stopps execution
      end
      

      当上述初始块产生时,其他块开始执行。

      initial begin     << starts execution at time 0, befor or after the block above
          #1 temp=x_in; << pauses for 1 time unit, then assigns temp
      end 
      

      上面的赋值发生在第一个初始块等待 #10000 时。

      如果你使用 always 块

      always @(x_in)
         temp = x_in;
      

      当 x_in 更改并且第一个初始块开始等待时,它将执行分配。当信号发生变化时,这个 always 块将在同一周期“0”执行。它与您使用的#1 不同。在您的情况下,更改将发生在周期“1”。

      【讨论】:

      • 文件中初始块执行的顺序如何?还是不能保证?
      • 不,不能保证。所有文件中的所有这些块同时开始执行并并行运行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2023-01-17
      • 2013-11-02
      相关资源
      最近更新 更多