事件控制中的时钟不明确

问题描述 投票:0回答:4

我在xilinx vivado中写了这样的verilog代码:

module a(input clk, input clk1, output reg [4:0] acc)
initial
begin
acc = 5'd0;
end
always @ (posedge clk or posedge clk1)
begin
acc <= acc+1;
end
endmodule  

并且在运行综合时出现错误(事件控制中的模糊时钟),vivado 指出错误位于“always @ (ownedge clk or pedge clk1)”行中。仅发生一处错误。 我想知道为什么会出现这个错误以及如何在不更改代码功能的情况下解决它。正如你所看到的,我想在 clk 或 clk1 从 0 变为 1 时做一些事情。

verilog xilinx vivado
4个回答
2
投票

了解您的clk和clk1是通过按钮输入的,您需要为您的

clk
clk1
提供更好的名称。对于这个答案的其余部分,我将它们称为
btn1
btn2
。您还需要配置一个足够快的时钟来捕获这些按钮按下的情况。

按钮输入通常需要去抖或进行最小边缘检测,这样每次按给定按钮时只需递增一次。

//Button 1 meta stability
logic [2:0] meta_edge_det_btn1;
always @(posedge clk) begin
   meta_edge_det_btn1 <= {meta_edge_det_btn1[1:0], btn1} ;
end

//button 1 Positive edge detection
logic btn1_rise;
always @* begin
   btn1_rise = meta_edge_det_btn1[1] & ~meta_edge_det_btn1[2];
end

logic [2:0] meta_edge_det_btn2;
always @(posedge clk) begin
   meta_edge_det_btn2 <= {meta_edge_det_btn2[1:0], btn2} ;
end

logic btn2_rise;
always @* begin
   btn2_rise = meta_edge_det_btn2[1] & ~meta_edge_det_btn2[2];
end

//Increment if either of the buttons has been pressed
always @ (posedge clk) begin
  if (btn1_rise  | btn2_rise ) begin
    acc <= acc+1;
  end
end

1
投票

您正在使用 verilog 描述硬件。如上所述,一个触发器不能由两个单独的时钟驱动。您将必须使用 2 个独立的always 块,一个对 clk 敏感,另一个对 clk1 敏感。

例如

always @ (posedge clk)
begin 
// your verilog statements here, driven by clk
end

always @ (posedge clk1)
begin 
// your verilog statements here, driven by clk1
end

希望这有帮助。


-1
投票
module a (
      input clk, 
      input clk1, 
       output reg [4:0] acc = 5
         );
always @ (posedge clk or posedge clk1)
begin
     if(clk | clk1)
        acc <= acc+1;
     else
        acc <= acc;
end
endmodule 

这应该有效。如果我们将信号作为always块的时钟,它会产生不明确的时钟错误。我们再次需要在块中使用 if else 来指定它。


-1
投票

有一种情况,两个“时钟”可以与同一个 FF 一起使用。 这称为异步重置(或预设)。 通过创建优先级来解决“歧义”。

always @ (posedge clk or posedge reset) begin
    if (reset)
        count <= 0;
    else
        count <= count + 1;
    end
end

对于更细致的情况,请考虑闹钟的情况,其中有一个按钮可以加速设置闹钟的计数。 我不会解决亚稳态问题和反弹问题,但下面的示例应该说明这个概念。

always @ (posedge clk or posedge btn) begin
    if (button)
        count <= count + 1;
    else
        count <= count + 1;
    end
end

虽然它看起来多余,但它应该在第一种情况下从加法器生成异步负载,在第二种情况下生成正常的 FF 操作。 这两个代码片段的关键点在于,当敏感度列表中有两个边沿触发的“时钟”时,内部代码必须在 if .. else 子句中包含其中之一,以明确指定优先级。 被赋予优先级的一个会成为异步预设或重置,只要它被置位,就会阻止另一个产生任何影响。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.