以下verilog代码是否存在竞争条件问题



我正在使用一个verilog模块(如下所示(,该模块有两个始终块。因为一个块设置寄存器,另一个块使用寄存器,所以不会有某种竞争条件吗。这会引起什么样的问题?

谢谢,Stephen

module XYZ
(                               
input  wire         CLK,    
input  wire         Reset,    
input  wire         nReset,   
input  wire [15:0]  X,      
input  wire [15:0]  A,    
input  wire         T,  
input  wire         B,  
output reg          M     
);
assign C = X > A;
reg P;  
reg N;
always @(posedge CLK, negedge nReset)
begin
if (~nReset)
begin
P <= 1;
N <= 1;
end else begin
if (Reset)
begin
P <= 1;
N <= 1;
end else begin
P <= T?  1:  ((C & ~M)?  0:  P);
N <= B?  1:  ((M & ~C)?  0:  N);
end
end
end
always @(posedge CLK, negedge nReset)
begin
if (~nReset)
begin
M <= 0;
end else begin
if (Reset)
begin
M <= 0;
end else begin
M <= M?  ~(N & ~C):  (P & C);
end
end
end

端模块

否,不存在竞赛条件。Verilog是一个事件驱动的模拟器。Posedge(除非时钟出现故障或重置(通常在每个模拟刻度执行一次。如果正确使用非阻塞分配(看起来确实如此(,则由边缘触发的每个始终块都将使用输入变量值的旧版本,即在时钟边缘之前存在的值。

下面是一个简化的例子:

always @(posedge clk)
r <= in;
always @(posedge clk)
out <= r;

在这种情况下会发生以下情况:

  1. r将在稍后的模拟时间点被分配in的值,在对始终块进行评估之后(参见nba调度区域(。

  2. 由于r还没有真正改变,所以out将被调度为被分配具有边缘之前的值的r的值。

如果r在边缘之前为0,而in为1,则在模拟结束时,r将变为1,out将变为0。

这模仿了硬件中实际失败的行为。

在您的情况下,它可能看起来是一个循环依赖项。事实上,它没有。出于与上述相同的原因,M值将是来自posedge之前的值,并且不会引起任何竞争。由于Flops的性质-逻辑性质,它们不能被包含在组合循环中。

我完全同意上述答案,我会对上述答案提出更多建议,当我开始学习Verilog时,我也有同样的疑问,参考书中的这些行澄清了我的疑问。我在这里处理声明对于进一步的疑问,你可以在这里发表评论,或者你可以查看

  • 参考。第135页
  • 书名:Verilog HDL:数字设计与综合指南,第二版Samir Palnitkar
  • 示例2中使用的

非阻塞语句消除了竞争条件。在时钟的正边缘,所有右侧的值变量为"read",右侧表达式为评估并存储在临时变量中。写入期间操作,存储在临时变量中的值将被赋值到左侧变量。分离读写操作确保寄存器a和b的值交换正确,无论写入操作的顺序如何执行。不利的一面是,非阻塞分配可能会导致模拟器性能的降低和存储器使用的增加。

//Example 2: Two concurrent always blocks with nonblocking
//statements
always @(posedge clock)
a <= b;
always @(posedge clock)
b <= a;

u可以使用这种类型的编码风格,这不是强制性的,但为了便于调试和加快模拟,u可以尽可能减少开始-结束块的使用

module XYZ
(                               
input  wire         CLK,    
input  wire         Reset,    
input  wire         nReset,   
input  wire [15:0]  X,      
input  wire [15:0]  A,    
input  wire         T,  
input  wire         B,  
output reg          M     
);
reg P,N;
always @(posedge CLK, negedge nReset)
if (~nReset)begin
P <= #10 1;
N <= #10 1;
end else if (Reset) begin
P <= #10 1;
N <= #10 1;
end else begin
P <= #10 T ?  1 :  ((C & ~M) ?  0:  P);
N <= #10 B ?  1 :  ((M & ~C) ?  0:  N);
end
always @(posedge CLK, negedge nReset)
if      (~nReset) M <= #10 0 ;
else if (  Reset) M <= #10 0 ;
else              M <= #10 M ?  ~(N & ~C):  (P & C);
assign C = X > A;
endmodule

相关内容

  • 没有找到相关文章

最新更新