【问题标题】:"Not a valid l-value" Error in VerilogVerilog 中的“不是有效的左值”错误
【发布时间】:2018-07-05 23:12:55
【问题描述】:

我是 Verilog 的新手(在较小程度上是编程),我正在尝试创建一个程序来找到一组数字的绝对值,然后计算运行平均值。运行平均值为 5 个点宽,并且跨越一个大约 40 个数字宽的数据集。

我遇到了运行平均值问题(第 14-17 行设计,24-28 测试台)并且收到错误“o2/out is not a valid l-value in tb.avg”。并且“o2/out 在这里被声明为电线”。我应该如何解决这个问题?

这是我的设计:

module absolute_value(i1,o1);
  input signed [11:0] i1;
  output signed [11:0] o1;

  assign o1 = i1[11] ? -i1 : i1;
endmodule 

module moving_average(k1,k2,k3,k3,k4,o2,out);
  input k1, k2, k3, k4, k5;
  output [11:0] o2;
  output [11:0] out;
  integer t;

  always begin
    assign o2 = (k1 + k2 + k3 + k4 + k5) / 5;
    assign out = o2;
  end
endmodule

这是我的测试台:

module tb;
  reg signed [11:0] i1;
  wire signed [11:0] o1;

  reg k1;
  reg k2;
  reg k3;
  reg k4;
  reg k5;
  wire [11:0] o2;
  wire [11:0] out;

  absolute_value abs(i1,o1);  
  moving_average avg(k1,k2,k3,k4,k5,o2,out);

  integer t;

  initial begin
    for (t = -10; t < 30; t = t + 1) begin
      #1
      i1 <= t;
      $display("i1 = %d, o1 = %d", i1, o1);

      assign k5 = k4 ? k4 : o1;
      assign k4 = k3 ? k3 : o1;
      assign k3 = k2 ? k2 : o1;
      assign k2 = k1 ? k1 : o1;
      assign k1 = o1;

      $display("out = %d", out);

      $moniter($time, "i1 = %d, o1 = %d, o2 = %d, out = %d k1 = %d, k2 = %d, k3 = %d, k4 = %d, k5 = %d", i1, o1, o2, out, k1, k2, k3, k4, k5);
    end
  end
endmodule

我敢打赌,我的程序中也存在其他错误,因此非常感谢任何帮助。

【问题讨论】:

  • 如前所述,wire 类型不是l-value。这意味着您不能分配给它。您尝试分配给它。
  • 但即使是注册,仍然存在“o2/out 不是有效的左值”和“o2/out 在此处声明为电线”的错误。
  • 您不应在 always 块内使用 assignassign 已经意味着对正确表达式的持续评估。测试台中的分配也可能有问题。
  • 感谢@HansLehnert,但这仍然不能解决我的问题。我将 o2 和 out 更改为 wire 并删除了 assign 语句,但仍然收到“无效的左值”和“此处声明为电汇”错误。我的代码的其他哪些部分可能会产生这些错误?
  • 这也是错误的,你不能在always 块中分配wire,因为电线没有状态。选项是:(1)将分配移到always块之外(2)将您的输出声明为reg并在always块内使用简单的阻塞分配(即out = o2;

标签: verilog


【解决方案1】:

如 cmets 中所述:

删除always 并保留output [11:0] out

改为:

reg [11:0] o2;
reg [11:0] out;
always @( * )
begin
  o2 = (k1 + k2 + k3 + k4 + k5) / 5;
  out = o2;
end

第二个错误: 您的端口使用 k1、k2、k3、k3、k4 并且缺少 k5。

第三:请不要使用上世纪的港口风格。我建议您切换到新格式:

module moving_average(
  input k1, k2, k3, k4, k5,
  output signed [11:0] o2,out
);

或者对于第二种情况:output signed reg [11:0] o2,out

第四:是$monitor,不是$moniter

【讨论】:

  • 谢谢,但正如我在 cmets 中所说,我仍然在测试台中收到错误。有什么建议吗?
  • 在我进行必要的更改后,它为我编译。我没有运行或检查模拟,因为那里有很多没有意义的东西。例如添加 5 位 K1..K5 以将它们放入 11 位结果中。输出相同的输出 o2, out, 除以 5 可能会导致综合问题,因为并非所有工具都支持它。 (他们将支持除以 4)
  • 感谢@Oldfart!我正在尝试通过代码和调试,但正如我所说,我对此很陌生。您介意说明哪些其他事情没有意义吗?我正在浏览您现在所说的示例,但如果有任何其他帮助,我们将不胜感激。
猜你喜欢
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多