【问题标题】:Verilog error: not a valid l-valueVerilog 错误:不是有效的左值
【发布时间】:2017-11-14 23:29:21
【问题描述】:

我正在尝试测试电线是否打开,以表明我的 alu 代码中是否存在错误/溢出。鉴于此代码:

output reg[3:0]x;                       // line 149
output wire error;
output wire overflow;

always @* begin
    if(error || overflow) begin         
        assign x = 4'b1111;             // line 155
        assign error = ~error;
        assign overflow = ~overflow;
    end else begin
        assign x = opcode;
    end
end

我收到以下错误消息:

uut 是我的测试台中的实例化单元,名为main

【问题讨论】:

  • erroroverflow 声明为reg,因为它们在程序块中用作定位符/左值。

标签: verilog alu


【解决方案1】:

示例中的代码有几个问题。

1) 您尝试使用“程序分配”,这是一个高级 Verilog 主题。换句话说,assign 语句位于 always 块内。这是不可综合的,只能用于reg 类型,并且在非常特殊的情况下存在于verilog 中。不要不要使用它。

您的错误消息来自 erroroverflow 被声明为 wire

2) 您试图在非时钟逻辑中将值的反转版本分配给自身。它不会像您期望的那样运行。根据使用情况,它要么不能切换,要么会导致无限的零延迟循环,或者在您的情况下,它可能只会产生故障。

因此,您的代码可能应该如下所示:

input wire clk; // << you need clock
output reg[3:0]x;                       // line 149
output wire error;
output wire overflow;

reg error_reg, overflow_reg; 

 always @(posedge clk) begin
    if(error || overflow) begin         
        x <= 4'b1111;             // line 155
        error_reg <= ~error;
        overflow_reg <= ~overflow;
    end else begin
        x <= opcode;
    end
 assign error = error_reg;
 assign overflow = overflow_reg;
end

【讨论】:

  • 当您可以使用output reg 时,创建reg 只是为了将其分配给output wire 有什么意义?
  • @Greg 在这种情况下,我不想更改原始端口定义。是的,您可以将它们声明为 reg,但您可能会将与 reg 相关的行为传播到其他模块,并且可能很难调试比赛和多个驱动程序问题。仅在模块端口中坚持使用“网络”始终是一种很好的方法。
  • 它解决了所有问题!感谢您的建议!没有意识到无法在始终块中分配电线
  • @Serge 我的经历不同,而我则相反。使用 Verilog-2005 的 uwire 升级或 SytemVerilog 样式编码可捕获意外的多个驱动程序问题。竞争条件通常来自我通常在代码审查中发现的糟糕的编码。 Lint 检查也可以捕获大部分这些问题。创建中间体很容易出现拼写错误,从而导致连接问题在大型设计中难以捕捉。只要您的策略适合您;各有各的。
【解决方案2】:

您错误地使用了分配。这可以在始终进程之外使用,但不能在进程内部使用。
另外,分配时需要类型线

wire [3:0] x;
assign x = 4'b1111;

在always进程中,去掉assign语句,直接说

reg [3:0] x;  // Note that this is assigned as a reg now
 always @* begin
    if(blah) begin 
       x = 4'b1111;
    end else begin
       x = opcode;
    end
 end

【讨论】:

  • 实际上赋值可以在always块内使用,但只能在寄存器上使用。
  • 正如@Serge 所说,您可以在always 块内使用assign,但不要。这意味着一些奇怪的东西。
猜你喜欢
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 2017-04-26
  • 2016-01-12
  • 2014-04-10
相关资源
最近更新 更多