Verilog错误:不是有效的l值
我试图测试线路是否接通,以表明我的alu代码中是否存在错误/溢出。鉴于此代码: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
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风格的编码捕获意外的多个驱动程序问题。竞争条件通常来自于糟糕的编码,我通常会在代码评审中发现这一点。皮棉检查也可以发现这些问题的大部分。在大型设计中,创建中间层很容易出现打字错误,从而导致连接问题。只要你的策略对你有效;每个人都有自己的。