我是verilog HDL的新手,我的第一个项目是使用一组寄存器实现一个简单的秒表计数器。我正在使用Altera Quartus。
当我尝试编译下面的代码时,我的每个寄存器都会出现错误。其中一条错误消息如下所示:
错误(10028):无法解析test_interface.v(127)中net“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
答案 0 :(得分:3)
基于your code in Dropbox,您将在多个always
块中分配寄存器。这对于Altera Quartus错误消息的综合和共同发起者来说是非法的。只应在一个reg
块中分配always
类型。
例如,sec0
中定义的always @(posedge reset_reg)
和您问题中提供的代码。 code in Dropbox更糟糕,因为您将计数器逻辑拆分为4个单独的始终块,分配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's paper中讨论过。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 @(*)
用于组合逻辑。