/* 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