Verilog 为什么wire变量会导致连续赋值中的非法左侧?

Verilog 为什么wire变量会导致连续赋值中的非法左侧?,verilog,Verilog,我已经阅读了所有类似的帖子,但没有一篇涉及到我的问题,即第41行assigny Y[b]=~Y[b]导致错误“连续赋值中左侧非法” 我没有分配任何注册表,所以我看不出有什么问题。如果我将b替换为一个实际的数字(比如说,3),它可以正常工作。但是我需要b作为变量 // Hamming code 1-bit error correction module HCG(I,e,O); input [4:1] I; // input BCD input [7:1] e; // noise s

我已经阅读了所有类似的帖子,但没有一篇涉及到我的问题,即第41行
assigny Y[b]=~Y[b]导致错误“连续赋值中左侧非法”

我没有分配任何注册表,所以我看不出有什么问题。如果我将
b
替换为一个实际的数字(比如说,3),它可以正常工作。但是我需要
b
作为变量

// Hamming code 1-bit error correction
module HCG(I,e,O);
  input [4:1] I;   // input BCD
  input [7:1] e;   // noise simulation
  wire [7:1] X;    // Hamming code
  wire [7:1] Y;     // Hamming code after addition of noise
  wire [3:1] P;     // Parity at start
  wire [3:1] S;    // Parity at end
  wire b;        // the error bit
  output [4:1] O;  // corrected output


  assign X[1]=I[1]^I[2]^I[4];   // Hamming code generator
  assign X[2]=I[1]^I[3]^I[4];
  assign X[3]=I[1];
  assign X[4]=I[2]^I[3]^I[4];
  assign X[5]=I[2];
  assign X[6]=I[3];
  assign X[7]=I[4];

  assign P[1]=X[1]; // Parity at start
  assign P[2]=X[2];
  assign P[3]=X[4];

  assign Y[1]=e[1]^X[1]; // noise added
  assign Y[2]=e[2]^X[2];
  assign Y[3]=e[3]^X[3];
  assign Y[4]=e[4]^X[4];
  assign Y[5]=e[5]^X[5];
  assign Y[6]=e[6]^X[6];
  assign Y[7]=e[7]^X[7];

  assign S[1]=Y[3]^Y[5]^Y[7]; // Parity at end
  assign S[2]=Y[3]^Y[6]^Y[7];
  assign S[3]=Y[5]^Y[6]^Y[7];

  assign b=(S[1]!=P[1])? b:b+1; // if parity of 2^0 not the same, add 1 to b
  assign b=(S[2]!=P[2])? b:b+2; // if parity of 2^1 not the same, add 2 to b
  assign b=(S[3]!=P[3])? b:b+4; // if parity of 2^2 not the same, add 4 to b

  assign Y[b]=~Y[b]; // correct the incorrect bit
  assign O[1]=Y[3]; // assigning outputs
  assign O[2]=Y[5];
  assign O[3]=Y[6];
  assign O[4]=Y[7];

endmodule

module
endmodule
之间的行同时执行。(似乎您认为它们是按顺序执行的。)因此,您正在驱动这些行中的
Y
的所有位

  assign Y[1]=e[1]^X[1]; // noise added
  assign Y[2]=e[2]^X[2];
  assign Y[3]=e[3]^X[3];
  assign Y[4]=e[4]^X[4];
  assign Y[5]=e[5]^X[5];
  assign Y[6]=e[6]^X[6];
  assign Y[7]=e[7]^X[7];
然后在此行中再次驱动
Y
的一个位:

  assign Y[b]=~Y[b]; // correct the incorrect bit

那么(a)你有短路,(b)哪个位有短路?这取决于
b
。因此,短路的位置取决于其中一根内部导线的状态。您已经描述了一个可以根据输入重新配置自身的电路。Verilog不会让你这么做的。Verilog是一种硬件描述语言。传统数字硬件无法根据其输入的状态自行重新配置。

问题在于您正在执行的连续分配。引用(第10.3节)中关于连续作业的内容:

连续赋值应将值驱动到向量(压缩)和标量的网络或变量上只要右侧的值发生变化,该赋值就会发生。连续赋值提供了一种在不指定门互连的情况下对组合逻辑建模的方法


当您分配Y[b]=~Y[b]
时,分配本身会自动导致右侧再次改变,从而再次触发分配。

Verilog standard列出了连续分配的合法lhs值,如下所示(表10-1):

净或变量(向量或标量)

向量网或压缩变量的常量位选择

向量网或压缩变量的常数部分选择

上述任何左侧的串联或嵌套串联

在您的例子中,
Y[b]
不是一个常量选择,因为
b
不是一个常量。因此,从语法上讲,您的lhs是非法的,您可以从编译器获得此消息


另一方面,这里有一个零延迟循环。有关解释,请参阅其他答案。

b
的宽度仅为1位。它只能是0或1,不能是3。我已经更正了我的代码,我应该在哪里再次发布它?很抱歉,我是这个论坛的新成员。@Joe如果您已经更正了代码,但现在出现了不同的错误,请发布一个新问题。如果你这样做,我建议你提及这一点,以强调你没有问过同样的问题两次。然而。。。你似乎对Verilog的工作原理有一个基本的误解。你解决了吗?首先我把
b
设为一个整数,把它放在
始终
块中,因为如果这三个条件都为真,我希望它的值累加<代码>始终@(即e)开始b=0;//如果(S[1]!=P[1])b=b+1,则将b初始化为零;如果(S[2]!=P[2])b=b+2;如果(S[3]!=P[3])b=b+4;如果(b!=0)开始Y[b]=!(Y[b]);//更正不正确的位结束但是,我仍然得到错误,我认为这是因为我将
Y
这是
导线
放置在
始终
块中。我很难理解如何在if条件下处理reg和连接变量。我想你知道我想要实现什么?也就是说,如果
b不等于零,我希望
Y[b]
变成
!Y[b]
。我已尝试更正我的代码,我应该在哪里再次发布?