Verilog:无法理解由此产生的模拟(延迟,阻塞/非阻塞)

时间:2015-07-07 12:42:06

标签: delay verilog

我正在学习Verilog语言(我已经使用过VHDL)并且我不理解以下代码的模拟:

module exam2011;
integer a,b,c,d;
always
begin
c = #1 a; 
#2 b=a;
d = a;
end

initial
begin

     a = 0; b = 0; c = 0; d = 0;
     #1 a=1;
     #2 a=2;
     #2 a=3;
     #2 a=4;
     #2 a=5;
end
initial $monitor($time, “a=%d, b=%d, c=%d, d=%d”,a,b,c,d);
endmodule

结果:

#                    0a=          0, b=          0, c=          0, d=          0
#                    1a=          1, b=          0, c=          x, d=          0
#                    3a=          2, b=          1, c=          x, d=          1
#                    4a=          2, b=          1, c=          1, d=          1
#                    5a=          3, b=          1, c=          1, d=          1
#                    6a=          3, b=          3, c=          1, d=          3
#                    7a=          4, b=          3, c=          3, d=          3
#                    9a=          5, b=          5, c=          3, d=          5
#                   10a=          5, b=          5, c=          5, d=          5

首先,我不知道我是否以良好的方式思考:当我们同时更改“a”的值以及“b”和“d”(即“a”)的值时,这些变化是如何进行的? 另外,我真的不明白如何在赋值“=”之后解释延迟命令#。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

输出始终取决于模拟器。 '总是'和'初始'语句并行执行。即使它看起来与我们平行,它也会在同一时间戳中由模拟器按顺序执行。

在完成当前时间戳中的所有事件后,模拟器将递增时间戳。在您的代码中,它看起来总是'声明在初始'之前执行。声明。让我试着清楚地解释一下。

resources :test do
   get 'associated_links', on: :member
end

此陈述相当于

c = #1 a;

因为'总是'语句输入1st到模拟器队列,它采样' a'这是' x'并在第0次将其存储在临时变量中。然后它进入初始'声明并指定0到' a'' b'' c'并且' d'。在#1时间单位后,' a'的采样值这是' x'分配给' c'始终'言。

temp = a; //sample the value of 'a'
#1;       // Wait for 1 unit of time
c = temp; //assign the sampled value to 'c'

此陈述相当于

#2 b = a;

3个单位之后,因为'总是' block位于模拟器队列的顶部,值为' a'仍将是' 1'并将其分配给' c。在此之后'初始'声明被执行并且' 2'的值被分配到' a'。其余的输出,表现方式相同。希望这会有所帮助。

答案 1 :(得分:0)

As I said earlier, Output depends on the simulator. I think for the time stamp #9, 'initial' block went 1st to the simulator queue. So it updated the 'a' to 5. In the same time stamp 'always' block is executed after 'initial' block. So 'c' and 'd' are assigned with updated value of 'a' which is '5'.

Since the time stamp is still #9, this value of 'a' which is '5' is sampled and gets stored in temporary variable. This is later assigned to 'c' at time stamp #10. Hope this make sense.

So this is not a good way of coding. This results in ambiguous results. In order to illustrate this ambiguous result, I can given an example. Consider following codes.

always@(posedge clk)
begin
cnt = cnt+1;
end

always@(posedge clk)
begin
A = cnt;
end

If the initial value of 'cnt' is 40, what is the value of 'A' in next clock cycle. See, now the output depends on the simulator. It depends on which 'always' block goes 1st to the simulator queue. If the 1st 'always' block is executed 1st, 'A' value is '41' else it is '40'. This can be removed by using non-blocking statements "<=".

always@(posedge clk)
begin
cnt <= cnt+1;
end

always@(posedge clk)
begin
A <= cnt;
end

Now 'A' will be 40 irrespective of simulator. Hope this helps.