错误“不允许对非注册结果进行程序性分配”

问题描述 投票:3回答:3

我收到了错误

[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
verilog vivado
3个回答
5
投票

然后有更多问题给出错误消息。正如其他人已经指出的那样,result应该定义为output reg [63:0] result;

其他问题不会产生编译错误;它们会产生不正确的行为并且不可合成。随着代码:

always @ (clken or posedge clock) begin
    if (1==clken) begin
        assign result = dataa * datab;
    end
end
  • clken是异步触发器;它不应该在敏感列表中。
  • 始终块内的assign语句称为程序连续赋值。一旦分配被触发,它将连续立即更新到dataadatab的任何变化(忽略clkenclock的条件)。 注意:IEEE正在考虑贬低程序性连续分配,因此将来很可能会成为非法语法。 IEEE Std 1800-2012 C.4.2程序转让和解除委托声明: 程序性assigndeassign语句可能是设计错误的根源,可能会妨碍工具实现。程序性assigndeassign语句不提供避免这些问题的另一种方法无法完成的能力。因此,程序性assigndeassign语句在弃用列表中。换句话说,IEEE Std 1800的未来版本可能不需要支持这些语句。当前的标准仍然需要工具来支持程序性的assigndeassign语句。但是,强烈建议用户迁移其代码以使用其中一种替代的程序或连续分配方法。 定期连续分配(程序块之外的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

3
投票

你在result区内分配always,这是不允许的,因为resultwire,而不是reg

按照以下方式声明result以使其工作:

output reg [63:0] result;

3
投票

默认情况下,所有输入和输出信号都是“导线”。无法在程序块中分配导线。

output reg [63:0] result;

这应该可以解决错误。

© www.soinside.com 2019 - 2024. All rights reserved.