我收到了错误
[Synth 8-2576]不允许对非登记结果进行程序性分配[“lpm_mult.v”:29]
我究竟做错了什么?
module lpm_mult (
dataa, datab, // multiplicand,multiplier
sum, // partial sum
clock, // pipeline clock
clken, // clock enable
aclr, // asynch clear
result // product
);
input clock;
input clken;
input aclr;
input [31:0] dataa;
input [31:0] datab;
input [63:0] sum;
output [63:0] result;
always @ (clken or posedge clock) begin
if (1==clken) begin
assign result = dataa * datab;
end
end
endmodule
然后有更多问题给出错误消息。正如其他人已经指出的那样,result
应该定义为output reg [63:0] result;
其他问题不会产生编译错误;它们会产生不正确的行为并且不可合成。随着代码:
always @ (clken or posedge clock) begin if (1==clken) begin assign result = dataa * datab; end end
clken
是异步触发器;它不应该在敏感列表中。assign
语句称为程序连续赋值。一旦分配被触发,它将连续立即更新到dataa
或datab
的任何变化(忽略clken
和clock
的条件)。
注意:IEEE正在考虑贬低程序性连续分配,因此将来很可能会成为非法语法。 IEEE Std 1800-2012 C.4.2程序转让和解除委托声明:
程序性assign
和deassign
语句可能是设计错误的根源,可能会妨碍工具实现。程序性assign
和deassign
语句不提供避免这些问题的另一种方法无法完成的能力。因此,程序性assign
和deassign
语句在弃用列表中。换句话说,IEEE Std 1800的未来版本可能不需要支持这些语句。当前的标准仍然需要工具来支持程序性的assign
和deassign
语句。但是,强烈建议用户迁移其代码以使用其中一种替代的程序或连续分配方法。
定期连续分配(程序块之外的assign
)将仍然是合法的法律语法。
Verilog和SystemVerilog由IEEE与IEEE Std 1800-2009正式合并。<=
)分配。在同步逻辑块中阻塞(=
)赋值是合法的语法,但是它不会重新开始。在同步逻辑块中使用阻塞分配可能导致模拟器中的竞争条件,导致RTL和合成电路之间的行为不匹配。
注意:assign
语句必须使用阻塞分配(非阻塞是非法语法)。您的代码应该看起来符合以下内容以进行编译并在模拟中正确运行:
...
output reg [63:0] result;
always @ (posedge clock) begin
if (clken==1) begin
result <= dataa * datab;
end
end
你在result
区内分配always
,这是不允许的,因为result
是wire
,而不是reg
。
按照以下方式声明result
以使其工作:
output reg [63:0] result;
默认情况下,所有输入和输出信号都是“导线”。无法在程序块中分配导线。
output reg [63:0] result;
这应该可以解决错误。