0

我是 verilog HDL 的新手,我的第一个项目是使用一组寄存器实现一个简单的秒表计数器。我正在使用 Altera Quartus。

当我尝试编译下面的代码时,我不断收到每个寄存器的错误。其中一条错误消息如下所示:

错误 (10028): 无法在 test_interface.v(127) 解析网络“sec0[3]”的多个常量驱动程序

任何人都可以帮忙吗?代码在 Modelsim 中模拟得很好。

这是导致问题的代码片段:

always @ (posedge clk)

  if (qsoutput == 1)
      sec0 = sec0 + 1;
  else if (sec0 == 4'b1010) begin
      sec1 = sec1 + 1;
      sec0 = 4'b0000;
  end else if (sec1 == 4'b0110) begin
      min0 = min0 + 1;
      sec1 = 4'b0000;
  end else if (min0 == 4'b1010) begin
      min1 = min1 + 1;
      min0 = 4'b0000;     
  end else if (min1 == 4'b0110) begin
      sec0 = 4'b0000;
      sec1 = 4'b0000;
      min0 = 4'b0000;
      min1 = 4'b0000;
  end
4

1 回答 1

3

根据您在 Dropbox 中的代码,您在多个always块中分配寄存器。这对于所指的 Altera Quartus 错误消息的综合和共同发起者来说是非法的。一个reg类型只能在一个always块中分配。

例如,在您的问题sec0中定义always @(posedge reset_reg)和提供的代码。Dropbox中的代码更糟糕,因为您将计数器逻辑拆分为 4 个单独的 always 块,它们分别分配sec0.

我建议你把所有sec*min*电阻一个时钟同步总是用异步阻塞:

always(@posedge clk or posedge reset_reg)
begin
  if(reset_reg)
  begin
    // ... asynchronous reset code ...
  end
  else
  begin
    // ... synchronous counter code ...
  end
end

本文详细介绍了用于合成的良好 Verilog 编码实践:http: //www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf


您将遇到的其他问题:

  • <=分配寄存器时使用非阻塞 ( )。这在前面提到的Cliff 的论文中进行了讨论。
  • 摆脱初始块。我知道有些 FPGA 合成器允许它,有些则忽略它。使用异步将所有内容放入已知且可预测的值是一种更好的做法。
  • 以 开头的块always @ (clk or start_reg or lap_reg or reset_reg)有一个奇怪的敏感性列表,可能会给你带来问题。如果你想要@(*)组合逻辑或@(posedge clk or posedge reset_reg)同步触发器,你会想要。
  • 很少使用双边触发器。该线路always @ (posedge clk or negedge clk)应用于always @ (posedge clk)同步或always @(*)组合逻辑。
于 2013-08-22T17:54:05.907 回答