Is my Verilog code synthesizable/correct?

Viewed 37

I am trying to write a module to "blur" a raster image - take the average of a 3x3 pixel sliding window across the image. The input image is a series of bytes with RGB values of the pixels, row by row, from bottom to top (similar to bitmap). It selects and outputs the average of the 3x3 window on the positive clock edge, and "moves" the window on the negative clock edge. When it is finished it drives the DONE wire to high.

I come from a software background, and want to know if I'm making any obvious errors/pitfalls. As I am trying to learn Verilog without a physical FPGA, I have simply been using icarus-verilog to test my code, and have no idea whether I am writing my test-benches correctly and whether my code is actually synthesizable. So, I was hoping someone could help take a look or give feedback.

I am also unsure of when/why to use blocking (=) versus non-blocking (<=) assignment. I read online that = is for combination logic and <= for sequential logic. But how do I know when I should be using combinational or sequential logic?

Thank you!

module blur
    #(parameter
        WIDTH  = 640,   // Image width
        HEIGHT  = 426,   // Image height
        INPUTBYTES = WIDTH*HEIGHT*3
    )
    (
      input CLK,          // clock     
      input RST,         // Reset (active low)
      input wire [7 : 0] input_memory [0 : INPUTBYTES-1],// memory to store  8-bit data image
      output reg [7 : 0] output_memory [0 : INPUTBYTES-1],// memory to store  8-bit data image
      output wire DONE     // Done flag
    );

    integer row = 0; // row index of the image
    integer col = 0; // col index of the image
    integer counter = 0;

    reg [7:0]  DATA_R = 0;  // 8 bit Red data
    reg [7:0]  DATA_G = 0;  // 8 bit Green data
    reg [7:0]  DATA_B = 0;  // 8 bit Blue data

    assign DONE = (counter > INPUTBYTES-1);

    always@(negedge CLK) begin

        if (col == WIDTH-3) begin
            col <= 0;
            row <= row+1;
        end
        else begin
            col <= col+1;
        end

        counter <= counter+3;
    end


    always@(posedge CLK) begin
        integer i;
        integer j;

        // Sum up all the R, G, B values of the 3x3 square
        for(i=0; i<3; i=i+1) begin
            for(j=0; j<3; j=j+1) begin
                DATA_R = DATA_R + input_memory[3*(WIDTH*(row+i)+(col+j))+0];
                DATA_G = DATA_G + input_memory[3*(WIDTH*(row+i)+(col+j))+1];
                DATA_B = DATA_B + input_memory[3*(WIDTH*(row+i)+(col+j))+2];
            end
        end

        // Output is the averaged RGB values
        output_memory[counter+0] = DATA_R/9;
        output_memory[counter+1] = DATA_G/9;
        output_memory[counter+2] = DATA_B/9;
    end
endmodule
0 Answers
Related