AnnaR
AnnaR

Reputation: 361

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

I'm new to Verilog and I would really appreciate it if someone could help me out with this error:

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

The error I get is:

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.

Could somebody tell me what I'm doing wrong? Thank you!

Upvotes: 0

Views: 6171

Answers (2)

skrrgwasme
skrrgwasme

Reputation: 9633

This line is the problem:

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

Indexing into arrays is only allowed for constant expressions. You are not allowed to use variables in vector indexes. Remember that you're working with an HDL: you're dictating physical connections in hardware. Having a variable in the index implies the ability to dynamically rewire the circuit. This SO question has some rough workarounds that may work for you. However, you should really try to refactor your algorithm to avoid the need to use the variable indexing in the first place.

By the way, you should be using non-blocking assignments instead of the blocking assignments you currently have. Your code is in a clocked block, so blocking combinational logic should be avoided:

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];   

Upvotes: 2

user149341
user149341

Reputation:

@(negedge ACLK);
               ^

I'm pretty sure that semicolon doesn't belong there. As written, the for loops are all outside the always block.

Additionally, your image array currently only has one bit per pixel. Is this intentional? Whether it is or not, I would recommend that you reconsider this architecture; filtering an image of any significant size in a single clock cycle is not going to synthesize very well.

Upvotes: 0

Related Questions