7

我收到错误

[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
4

3 回答 3

9

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

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

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

    • 注意: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
于 2015-07-17T16:46:40.360 回答
4

result在一个always块内分配,这是不允许的,因为result是 a wire,而不是 a reg

声明result如下以使其工作:

output reg [63:0] result;
于 2015-07-17T10:50:41.150 回答
3

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

output reg [63:0] result;

这应该可以修复错误。

于 2015-07-17T14:48:39.347 回答