Verilog error : A reference to a wire or reg is not allowed in a constant expression

Verilog error : A reference to a wire or reg is not allowed in a constant expression

我是 Verilog 的新手,如果有人能帮我解决这个错误,我将不胜感激:

output  reg [0:image_width][image_height:0]    result
....
integer i, j, imageX, imageY, x, y, kernelX, kernelY;
....

@(negedge ACLK)
for(x = 0; x < image_width; x++) begin 
    for(y = 0; y < image_height; y++)
    begin
    //multiply every value of the filter with corresponding image pixel
        for(kernelX = 0; kernelX < kernel_width; kernelX++) begin            
            for(kernelY = 0; kernelY < kernel_height; kernelY++)
                begin           
                    imageX = (x - kernel_width / 2 + kernelX + image_width) % image_width;
                    imageY = (y - kernel_height / 2 + kernelY + image_height) % image_height;

                    // ignore input samples which are out of bound
                    if( imageY >= 0 && imageY < image_height && imageX >= 0 && imageX < image_width )
                        //ERROR HERE!!!
                        result[x][y] += image[imageX][imageY] * kernel[kernelX][kernelY];   
                    end
                end
        end
    end
end

我得到的错误是:

error: A reference to a wire or reg ('x') is not allowed in a constant expression.
error: Array index expressions must be constant here.
error: A reference to a wire or reg ('imageX') is not allowed in a constant expression.
error: Array index expressions must be constant here.
error: A reference to a wire or reg ('kernelX') is not allowed in a constant expression.
error: Array index expressions must be constant here.

有人能告诉我我做错了什么吗?谢谢!

@(negedge ACLK);
               ^

我很确定分号不属于那里。正如所写,for 循环都在 always 块之外。

此外,您的 image 数组目前每个像素只有一位。这是故意的吗?不管是不是,我都建议你重新考虑这个架构;在单个时钟周期内过滤任何显着尺寸的图像都不会很好地合成。

这一行是问题所在:

result[x][y] += image[imageX][imageY] * kernel[kernelX][kernelY];

只允许对常量表达式进行数组索引。不允许在向量索引中使用变量。请记住,您是在使用 HDL:您是在指示硬件中的物理连接。在索引中有一个变量意味着能够动态地重新连接电路。 This SO question 有一些粗略的解决方法可能对您有用。但是,您真的应该尝试重构您的算法,以避免首先需要使用变量索引。

顺便说一句,您应该使用 non-blocking assignments 而不是您当前拥有的阻塞分配。您的代码位于时钟块中,因此应避免阻塞组合逻辑:

imageX <= (x - kernel_width / 2 + kernelX + image_width) % image_width;
imageY <= (y - kernel_height / 2 + kernelY + image_height) % image_height;

// ignore input samples which are out of bound
if( imageY >= 0 && imageY < image_height && imageX >= 0 && imageX < image_width )
    result[x][y] <= result[x][y] + image[imageX][imageY] * kernel[kernelX][kernelY];