【问题标题】:HDLCompilers:246 - "numop.v" line 28 Reference to vector reg 'numopout' is not a legal net lvalueHDLCompilers:246 - “numop.v”第 28 行对向量 reg 'numopout' 的引用不是合法的净左值
【发布时间】:2015-05-28 09:16:05
【问题描述】:

在这个模块中,我正在验证按钮并将值分配给另一个变量并将其发送到另一个模块,该模块返回 numopout 输出的值。 但它说它不是合法的净左值,我不知道这是什么意思。

module numop(
input btn1,
input btn2,
input [3:0] numopin,
output reg [3:0] numopout
);
 reg [1:0] aux;
 loco locovox(aux,numopin,numopout);
always @ (posedge btn1,posedge btn2)
begin
    if((btn1 == 1)&&(btn2 == 0))
        aux = 2'b11;
    else if((btn1 == 0)&&(btn2 == 1))
        aux = 2'b10;
    else if((btn2 == 0)&&(btn1 == 0))
        aux = 2'b01;
    else if((btn2 == 1)&&(btn1 == 1))
        aux = 2'b00;
    else
        aux = 2'b00;
end

结束模块

【问题讨论】:

  • numopout 应定义为 wire,而不是 reg

标签: verilog


【解决方案1】:

| 是按位或运算。敏感度列表使用or(并且自 Verilog-2001 起也支持,)。因此:

always @ (btn1 | btn2 | numopin[0] | numopin[1] | numopin[2] | numopin[3])

应该是:

always @ (btn1 or btn2 or numopin[0] or numopin[1] or numopin[2] or numopin[3])

或(如果 IEEE Std 1364-2001 或更新版本)

always @ (btn1, btn2, numopin[0], numopin[1], numopin[2], numopin[3])

并且可以简化为:

  • always @(btn1 or btn2 or numopin)(IEEE 标准 1364-1995 和更新版本)
  • always @(btn1, btn2, numopin)(IEEE 标准 1364-2001 和更新版本)
  • always @*(IEEE 标准 1364-2001 和更新版本)推荐

@*(或@ (*))是一个自动敏感列表;在 IEEE 标准 1364-2001 中添加。组合块中引用且未分配的任何信号都被视为输入。 @* 是使用 always 块描述组合逻辑的重新开始等待(除非您严格遵循 IEEE Std 1364-1995)。


灵敏度列表中的posedgenegedge 用于可综合触发器或不可综合行为建模。如果您有两个(或更多)边缘,则智能(高级)合成器将假定程序代码中使用的灵敏度列表中的任何信号都是异步的。一个简单的将第一个信号视为同步的,而将其他信号视为异步的。

设计指南: 仅将 posedgenegedge 用于同步触发器逻辑。

一种解决方案(改动很小)是:

always @ (btn1 or btn2)
begin
    if((btn1 == 1'b1)&&(btn2 == 1'b0))
        aux = 2'b11;
    else if((btn1 == 1'b0)&&(btn2 == 1'b1))
        aux = 2'b10;
    else if((btn2 == 1'b0)&&(btn1 == 1'b0))
        aux = 2'b01;
    else // this 'else' handles '(btn2 == 1'b1)&&(btn1 == 1'b1)' for you
        aux = 2'b00;
end

但您可以将代码(相同的综合输出)简化为:

always @* begin
  case({btn2,btn1})
    2'b00 : aux = 2'b01;
    2'b01 : aux = 2'b11;
    2'b10 : aux = 2'b10;
    default : aux = 2'b00;
  endcase
end

仅供参考:比较 btn1 == 1btn2 == 0 也是一种不好的做法。这是因为10 被认为是32 位值,你应该得到综合警告。最好是明确的:btn1 == 1'b1btn2 == 1'b0

【讨论】:

  • 它可以编译,但它说我必须配置时钟,我不希望它是时钟,我只想按下一个按钮,该信号进入我的模块。
  • 听起来您在推断设计中的锁存器并试图在没有锁存器的 FPGA 上运行。闩锁是由缺少分配引起的。例如if(btn1) ... else if(btn2) ... 缺少else。如果btn1btn2 都较低,则没有定义numopout 应该是什么值;假定保持先前(锁存器)。不完整的案例陈述也会发生同样的情况。
  • 我为 if 和 case 添加了缺失的赋值,但它一直告诉我 btn1 是一个时钟信号。我添加了一个 if(btn1 == 1) else if(btn1 == 0) else if(btn2 == 1) else if(btn2 == 0) 和 else。
  • 您不需要额外的else if,只需一个else。请使用您的实际代码更新您的问题。
  • 已更新。我更改了我的代码并尝试使用另一个逻辑,但现在它给了我另一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2022-11-30
  • 2016-06-22
  • 2015-12-18
  • 2016-12-16
  • 2010-11-27
相关资源
最近更新 更多