Verilog错误:不是有效的l值

Verilog错误:不是有效的l值,verilog,alu,Verilog,Alu,我试图测试线路是否接通,以表明我的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

我试图测试线路是否接通,以表明我的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

错误地使用赋值。可以在always进程外部使用,但不能在always进程内部使用。
此外,指定还需要导线类型

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进程外部使用,但不能在always进程内部使用。
此外,指定还需要导线类型

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

示例中的代码有几个问题

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

由于
error
overflow
被声明为
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

输入线时钟;// 示例中的代码有几个问题

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

由于
error
overflow
被声明为
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

输入线时钟;//实际上,assign可以在always块内使用,但只能在寄存器上使用。正如@Serge所说,您可以在always块内使用
assign
,但不能。这意味着一些奇怪的事情。实际上,赋值可以在always块内使用,但只能在寄存器上使用。正如@Serge所说,您可以在always块内使用
assign
,但不能。这意味着一些奇怪的事情。将
error
overflow
声明为
reg
,因为它们在程序块中用作定位器/左值。将
error
overflow
声明为
reg
因为它们在程序块中用作定位器/左值。创建
reg
当您可以使用
output reg
?@Greg时,仅将其分配给
输出线
。@Greg在这种情况下,我不想更改原始端口定义。是的,您可以将它们声明为regs,但是您可能会将与reg相关的行为传播到其他模块,并且可能会遇到调试竞争和多个驱动程序问题的困难。只在模块端口中使用“网络”始终是一种很好的方法。它解决了所有问题!谢谢你的建议!没有意识到导线不能始终分配blocks@Serge我的经历不同,而我的经历正好相反。使用Verilog-2005的
uwire
升级或系统Verilog风格的编码捕获意外的多个驱动程序问题。竞争条件通常来自于糟糕的编码,我通常会在代码评审中发现这一点。皮棉检查也可以发现这些问题的大部分。在大型设计中,创建中间层很容易出现打字错误,从而导致连接问题。只要你的策略对你有效;当您可以使用
output reg
时,创建
reg
仅将其分配给
输出线
有什么意义?@Greg在这种情况下,我不想更改原始端口定义。是的,您可以将它们声明为regs,但是您可能会将与reg相关的行为传播到其他模块,并且可能会遇到调试竞争和多个驱动程序问题的困难。只在模块端口中使用“网络”始终是一种很好的方法。它解决了所有问题!谢谢你的建议!没有意识到导线不能始终分配blocks@Serge我的经历不同,而我的经历正好相反。使用Verilog-2005的
uwire
升级或系统Verilog风格的编码捕获意外的多个驱动程序问题。竞争条件通常来自于糟糕的编码,我通常会在代码评审中发现这一点。皮棉检查也可以发现这些问题的大部分。在大型设计中,创建中间层很容易出现打字错误,从而导致连接问题。只要你的策略对你有效;每个人都有自己的。