0
\$\begingroup\$

Im trying to implement 2d convolution (8 bits each cell int he convolution so in systemV it's 3d) in system verilog,and I have trouble inserting data into the "result" array, and i dont understand what im doing wrong, this is my code:

module conv2d (
                input clk,
                input logic [7:0] img[3:0][3:0],
                input logic [7:0] kernel[2:0][2:0],
                output logic [7:0] result [4:0][4:0]
                );//#(parameter img_size=16,kernel_size=4)()
int i,j;


always_ff @(posedge clk) begin
    for(i=0;i<5;i++) begin
        for(j=0;j<5;j++) begin
            for(int k=0;k<3;k++) begin
                for(int l=0;l<3;l++) begin
                    if ((i-k > -1)&&(j-l>-1)&&(i-k < 3)&&(j-l < 3))begin
                        result[i][j] <= result[i][j] + kernel[i-k][j-l]*img[k][l];
                    end
                end
            end
        end
    end
end 

endmodule

my testbench:

module test; 
logic clk;
logic [7:0] img[3:0][3:0] ;
logic [7:0] kernel[2:0][2:0];
logic [7:0] result[4:0][4:0];
initial begin
    for(int i=0;i<5;i++) begin
        for(int j=0;j<5;j++) begin
            result[i][j]=8'b0;
        end
    end
clk=1'b0;
img[0][0]=8'd1;
img[0][1]=8'd0;
img[0][2]=8'd2;
img[0][3]=8'd0;
img[1][0]=8'd1;
img[1][1]=8'd2;
img[1][2]=8'd3;
img[1][3]=8'd1;
img[2][0]=8'd0;
img[2][1]=8'd0;
img[2][2]=8'd1;
img[2][3]=8'd0;
img[3][0]=8'd1;
img[3][1]=8'd0;
img[3][2]=8'd3;
img[3][3]=8'd1;
kernel[0][0]=8'd1;
kernel[0][1]=8'd0;
kernel[0][2]=8'd0;
kernel[1][0]=8'd0;
kernel[1][1]=8'd1;
kernel[1][2]=8'd0;
kernel[2][0]=8'd1;
kernel[2][1]=8'd1;
kernel[2][2]=8'd0;
end
//#100;
//$stop;
always #5 clk = ~clk; 
conv2d con4test (
                    .clk(clk),
                    .img(img),
                    .kernel(kernel),
                    .result(result)
                    );
endmodule

this is my first time my first time working with system verilog and 3d arrays, couldnt find any helpful info online, dont be harsh with me.

Thanks!

EDIT: fixed the test bench problem. And my problem is that the result array is not updating meaning it's still 0 enter image description here

EDIT: working!

I did few changed in the code, but the one who did the work (I think) was changing always_ff with always I will tell the truth i have no idea why.. and I'll be super interested if some one knows.

Thanks again.

\$\endgroup\$
  • \$\begingroup\$ How you trouble looks like? Wrong result? Error message during compilation/simulation? What I immediately see is that you initialize result in your testbench with 1'b0, while vector width is 8. While it may not be a problem, it is not correct. \$\endgroup\$ – Anonymous Jan 27 '18 at 8:49
  • \$\begingroup\$ And my problem is that the result array is not updating meaning it's still 0 this may take place in several circumstances: either the condition (i-k > -1)&&(j-l>-1)&&(i-k < 3)&&(j-l < 3) is false when result must be non-zero, or when it is true, the result is zero. Make the exercise manually on paper to ensure your algorithm is correct, and your result is really wrong. \$\endgroup\$ – Anonymous Jan 27 '18 at 9:14
  • \$\begingroup\$ I checked again, looked in simulation by inserting breakpoint, and i can see it passes the condition. \$\endgroup\$ – albert1905 Jan 27 '18 at 11:26
  • \$\begingroup\$ But what is the result of multiplication and addition? Did you check by hand that it should not be 0? Are arithmetic operations performed properly, and all the vectors are properly defined before the operation? \$\endgroup\$ – Anonymous Jan 27 '18 at 11:28
0
\$\begingroup\$

After some time of debugging and simulation I can say that you must move result initialization into the conv2d module:

module conv2d (
    input clk,
    input logic [7:0] img[3:0][3:0],
    input logic [7:0] kernel[2:0][2:0],
    output logic [7:0] result [4:0][4:0]
    );//#(parameter img_size=16,kernel_size=4)()

int i,j;

initial begin
    for(int i=0;i<5;i++) begin
        for(int j=0;j<5;j++) begin
            result[i][j]=8'b0;
        end
    end
end

always_ff @(posedge clk) begin
    for(i=0;i<5;i++) begin
        for(j=0;j<5;j++) begin
            for(int k=0;k<3;k++) begin
                for(int l=0;l<3;l++) begin
                    if ((i-k > -1)&&(j-l>-1)&&(i-k < 3)&&(j-l < 3))begin
                        result[i][j] <= result[i][j] + kernel[i-k][j-l]*img[k][l];
                    end
                end
            end
        end
    end
end

I actually wonder how you were able simulating your original code because my ModelSim just gives the error written by continuous and procedural assignments on the result (as you try initializing it in test and then modify in conv2d).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.