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