Edge Detection in FPGA using Sobel Operator
Edge Detection in FPGA using Sobel Operator

Sobel Edge Detection Verilog Code

The following is the full verilog code for the project.

/* The complete verilog code that interfaces parallel port and calls sobel core modules.
 * Free to download modify and use
 * 
 */
module imageedge(bus,data_strobe, mode_strobe, bus_rw,clk, reset);

inout [7:0] bus;		// 'bus' is a bi-directional bus 
reg [7:0] bus_out;	// 8 bit internal register for storing output values 
wire [7:0] bus_in;	// this is used to get input data when 'bus' is acting as input. 

input data_strobe;	// The Data Strobe signal on pin 14 of the parallel port. 
input mode_strobe;	// The Mode Strobe signal on pin 17 (address strobe) 
				// is used to indicate the setting of the mode in fpga, Modes yet to be decided (TODO) 

input bus_rw;		// Indicates the direction of data on the data_bus. Pin1 READ=1 WRITE = 0 
input reset;		// No other special meanings. Negative edge resets, default high. 
input clk;			// CLOCK! 

reg [7:0] row3 [33:0];	// 34 byte RAM 
reg [7:0] row2 [33:0];	// 34 byte RAM 
reg [7:0] row1 [33:0];	// 34 byte RAM 

reg [5:0] WAddr;		// 6 bits to move upto 34th location 
reg [5:0] RAddr;		// 6 bits to read 32 sobel outputs and future developments 
reg write_en,read_en;	// internal registers for correct read/write operations. 
reg [5:0] index;		// used as variable in shifting operation 

assign bus = (bus_rw)? bus_out : 8'dz;	// this code enables the duplexing of 'bus' 
assign bus_in = (!bus_rw) ? bus : 8'dz;	// -do- 

// codes till 'always' is for instantiating 32 sobels 

wire [7:0] out1;					
sobel s1(row1[0],row1[1],row1[2],
 row2[0],row2[2],
 row3[0],row3[1],row3[2],out1);
wire [7:0] out2;
sobel s2(row1[1],row1[2],row1[3],
 row2[1],row2[3],
 row3[1],row3[2],row3[3],out2);
wire [7:0] out3;
sobel s3(row1[2],row1[3],row1[4],
 row2[2],row2[4],
 row3[2],row3[3],row3[4],out3);
wire [7:0] out4;
sobel s4(row1[3],row1[4],row1[5],
 row2[3],row2[5],
 row3[3],row3[4],row3[5],out4);
wire [7:0] out5;
sobel s5(row1[4],row1[5],row1[6],
 row2[4],row2[6],
 row3[4],row3[5],row3[6],out5);
wire [7:0] out6;
sobel s6(row1[5],row1[6],row1[7],
 row2[5],row2[7],
 row3[5],row3[6],row3[7],out6);
wire [7:0] out7;
sobel s7(row1[6],row1[7],row1[8],
 row2[6],row2[8],
 row3[6],row3[7],row3[8],out7);
wire [7:0] out8;
sobel s8(row1[7],row1[8],row1[9],
 row2[7],row2[9],
 row3[7],row3[8],row3[9],out8);
wire [7:0] out9;
sobel s9(row1[8],row1[9],row1[10],
 row2[8],row2[10],
 row3[8],row3[9],row3[10],out9);
wire [7:0] out10;
sobel s10(row1[9],row1[10],row1[11],
 row2[9],row2[11],
 row3[9],row3[10],row3[11],out10);
wire [7:0] out11;
sobel s11(row1[10],row1[11],row1[12],
 row2[10],row2[12],
 row3[10],row3[11],row3[12],out11);
wire [7:0] out12;
sobel s12(row1[11],row1[12],row1[13],
 row2[11],row2[13],
 row3[11],row3[12],row3[13],out12);
wire [7:0] out13;
sobel s13(row1[12],row1[13],row1[14],
 row2[12],row2[14],
 row3[12],row3[13],row3[14],out13);
wire [7:0] out14;
sobel s14(row1[13],row1[14],row1[15],
 row2[13],row2[15],
 row3[13],row3[14],row3[15],out14);
wire [7:0] out15;
sobel s15(row1[14],row1[15],row1[16],
 row2[14],row2[16],
 row3[14],row3[15],row3[16],out15);
wire [7:0] out16;
sobel s16(row1[15],row1[16],row1[17],
 row2[15],row2[17],
 row3[15],row3[16],row3[17],out16);
wire [7:0] out17;
sobel s17(row1[16],row1[17],row1[18],
 row2[16],row2[18],
 row3[16],row3[17],row3[18],out17);
wire [7:0] out18;
sobel s18(row1[17],row1[18],row1[19],
 row2[17],row2[19],
 row3[17],row3[18],row3[19],out18);
wire [7:0] out19;
sobel s19(row1[18],row1[19],row1[20],
 row2[18],row2[20],
 row3[18],row3[19],row3[20],out19);
wire [7:0] out20;
sobel s20(row1[19],row1[20],row1[21],
 row2[19],row2[21],
 row3[19],row3[20],row3[21],out20);
wire [7:0] out21;
sobel s21(row1[20],row1[21],row1[22],
 row2[20],row2[22],
 row3[20],row3[21],row3[22],out21);
wire [7:0] out22;
sobel s22(row1[21],row1[22],row1[23],
 row2[21],row2[23],
 row3[21],row3[22],row3[23],out22);
wire [7:0] out23;
sobel s23(row1[22],row1[23],row1[24],
 row2[22],row2[24],
 row3[22],row3[23],row3[24],out23);
wire [7:0] out24;
sobel s24(row1[23],row1[24],row1[25],
 row2[23],row2[25],
 row3[23],row3[24],row3[25],out24);
wire [7:0] out25;
sobel s25(row1[24],row1[25],row1[26],
 row2[24],row2[26],
 row3[24],row3[25],row3[26],out25);
wire [7:0] out26;
sobel s26(row1[25],row1[26],row1[27],
 row2[25],row2[27],
 row3[25],row3[26],row3[27],out26);
wire [7:0] out27;
sobel s27(row1[26],row1[27],row1[28],
 row2[26],row2[28],
 row3[26],row3[27],row3[28],out27);
wire [7:0] out28;
sobel s28(row1[27],row1[28],row1[29],
 row2[27],row2[29],
 row3[27],row3[28],row3[29],out28);
wire [7:0] out29;
sobel s29(row1[28],row1[29],row1[30],
 row2[28],row2[30],
 row3[28],row3[29],row3[30],out29);
wire [7:0] out30;
sobel s30(row1[29],row1[30],row1[31],
 row2[29],row2[31],
 row3[29],row3[30],row3[31],out30);
wire [7:0] out31;
sobel s31(row1[30],row1[31],row1[32],
 row2[30],row2[32],
 row3[30],row3[31],row3[32],out31);
wire [7:0] out32;
sobel s32(row1[31],row1[32],row1[33],
 row2[31],row2[33],
 row3[31],row3[32],row3[33],out32);

always @(posedge clk,negedge reset)
begin
	if(!reset)						
	begin
		WAddr <= 6'b0;			// this sets Write Address to initial position 
		RAddr <= 6'b0;			// this sets read address to initial location 
		read_en <= 1'b0;				// this enables reading from FPGA	 
		write_en <= 1'b0;				// this enables writing to FPGA 			 
		for(index=0;index<34;index=index+1)		// to avoid the don't care values. 
		row1[index] <= 8'b0;
		for(index=0;index<34;index=index+1)		// -do- 
		row2[index] <= 8'b0;
		bus_out <= 8'hff;			// to set bus_out reg value to FF 
	end

	else if(!data_strobe & !bus_rw & !write_en)	// condition for writing data to FPGA 
	begin
		row3[WAddr] <= bus_in;		// writes the data at bus_in to RAM location pointed by WAddr 
		WAddr <= WAddr + 1;		// setting write pointer to next location 
		write_en <= 1'b1;			// this ensures correct write operation 
	end

	else if(!data_strobe & bus_rw & !read_en)	// condition for reading from FPGA  
	begin
		case (RAddr+1)			// initially RAddr is 0. code is written from 1. 
			1: bus_out <= out1;	// this block will implement a 32:1 8 bit Vectored MUX 
			2: bus_out <= out2;
			3: bus_out <= out3;
			4: bus_out <= out4;
			5: bus_out <= out5;
			6: bus_out <= out6;
			7: bus_out <= out7;
			8: bus_out <= out8;
			9: bus_out <= out9;
			10: bus_out <= out10;
			11: bus_out <= out11;
			12: bus_out <= out12;
			13: bus_out <= out13;
			14: bus_out <= out14;
			15: bus_out <= out15;
			16: bus_out <= out16;
			17: bus_out <= out17;
			18: bus_out <= out18;
			19: bus_out <= out19;
			20: bus_out <= out20;
			21: bus_out <= out21;
			22: bus_out <= out22;
			23: bus_out <= out23;
			24: bus_out <= out24;
			25: bus_out <= out25;
			26: bus_out <= out26;
			27: bus_out <= out27;
			28: bus_out <= out28;
			29: bus_out <= out29;
			30: bus_out <= out30;
			31: bus_out <= out31;
			32: bus_out <= out32;
			default:	bus_out <= 8'b0;			
		endcase
		RAddr <= RAddr + 1;	// incrementing to next RAddr location. 
		read_en <= 1'b1;		// to ensure correct read operation 
	end

	else if(!mode_strobe & !bus_rw & !write_en)	// condition for indicating FPGA the end of one row 
	begin
		if(bus_in == 8'b0110_0110)	// '66' is code indicating end of row 
		begin
			for(index=0;index < 34;index = index + 1)	// this loop will implement row shift operation 
			begin
				row1[index] <= row2[index];
				row2[index] <= row3[index];
			end
			WAddr <= 6'b0;	
			RAddr <= 6'b0;
			write_en <= 1'b1;		// to ensure shifting is done only once.		 
		end
		bus_out <= 8'b0;
	end

	else if(data_strobe & mode_strobe)
	begin
		write_en <= 1'b0;
		read_en <= 1'b0;			
	end
	else
	begin
		RAddr <= RAddr;
		WAddr <= WAddr;
		bus_out <= bus_out;
	end
end



endmodule
Download | Licensed under GPL Public License | In short free code

Tags: Verilog , Sobel ,
Tag Cloud 74LS33 74LS641 Architecture BMP BMP Linux Canny Circuit DB25 Device Utilization Digital Image Processing Edge Detection FPGA Fedora GCC Image Manipulation Imtools JPEG Laplacian Linux Memory Modules Octal Transciever OpenGL PC Interface PNG Parallel Port Prewitt RAM Roberts Sobel Spartan 3 System Ubuntu VLSI Verilog XC3S400 Xilinx libjpeg libpng