错误 "procedural assignment to a non-register result is not permitted"

Error "procedural assignment to a non-register result is not permitted"

我遇到错误

[Synth 8-2576] procedural assignment to a non-register result is not permitted ["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

您正在 always 块内分配给 result,这是不允许的,因为 resultwire,而不是 reg

如下声明 result 以使其工作:

output reg [63:0] result;

默认所有输入和输出信号都是'wires'。不能在程序块中分配电线。

output reg [63:0] result;

这应该可以修复错误。

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

其他问题不会产生编译错误;他们正在产生不正确的行为并且是不可综合的。使用代码:

always @ (clken or posedge clock) begin
    if (1==clken) begin
        assign result = dataa * datab;
    end
end
  • clken为异步触发;它不应该在敏感列表中。
  • always 块中的 assign 语句称为过程连续赋值。一旦赋值被触发,它将在 dataadatab 的任何变化上持续并立即更新(忽略 clkenclock 的条件)。

    • 注意:IEEE 正在考虑贬低程序连续赋值,因此将来它可能会成为非法语法。 IEEE Std 1800-2012 C.4.2 程序赋值和取消赋值语句:

      The procedural assign and deassign statements can be a source of design errors and can be an impediment to tool implementation. The procedural assign and deassign statements do not provide a capability that cannot be done by another method that avoids these problems. Therefore, the procedural assign and deassign statements are on a deprecation list. In other words, a future revision of IEEE Std 1800 might not require support for these statements. This current standard still requires tools to support the procedural assign and deassign statements. However, users are strongly encouraged to migrate their code to use one of the alternate methods of procedural or continuous assignments.

      常规连续赋值(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