sobel算子的verilog实现,采用了流水线操作
1 module sobel_computer ( 2 clock , 3 reset, 4 OrigDataEn, 5 //SobelAluEn, 6 OrigData, 7 SobelData 8 ); 9 input clock ,reset; 10 input OrigDataEn ; 11 //input SobelAluEn ; 12 input [63:0] OrigData ; 13 output reg [63:0] SobelData ; 14 15 16 reg [63:0] prev_row, curr_row, next_row ; 17 reg [1:0] data_state ; 18 reg [7:0]abs_D ; 19 //*****************OrigDataEn 维持三个周期,将数据保存到三个reg 中**************** 20 always @ (posedge clock or negedge reset ) 21 if(!reset) 22 begin 23 data_state <= 2'b00 ; 24 prev_row <= 64'd0 ; 25 curr_row <= 64'd0 ; 26 next_row <= 64'd0 ; 27 end 28 else if(OrigDataEn) 29 begin 30 case (data_state) 31 2'b00 : 32 begin 33 prev_row <= OrigData ; 34 data_state <= 2'b01 ; 35 end 36 2'b01 : 37 begin 38 curr_row <= OrigData ; 39 data_state <= 2'b10 ; 40 end 41 2'b10 : 42 begin 43 next_row <= OrigData ; 44 //data_state <= 2'b01 ; 45 end 46 endcase 47 end 48 else 49 begin 50 data_state <= 2'b00 ; 51 prev_row <= prev_row << 8 ; 52 curr_row <= curr_row << 8 ; 53 next_row <= next_row << 8 ; 54 end 55 //---------------------------------------------------------------- 56 //function : 函数名= 内部reg,并返回。不包含 # @ wait,至少一个输入参数 57 function [9:0] abs (input signed[10:0] data); 58 abs = data[10]? (~data[9:0]+1): data[9:0]; 59 endfunction 60 61 reg signed [10:0] Dx,Dy ; //8'b1111_1111 * 6 = 11'd1530 所以采用11bit的Dx 和Dy 62 reg [7:0]Orig [-1:1][-1:1]; 63 64 /* 65 分段方式:[63:56] [55:48] [47:40] [39:32] [31:24] [23:16] [15:8] [7:0] 66 sobel Dx -1 0 +1 67 -2 0 +2 68 -1 0 +1 69 70 Dy +1 +2 +1 71 0 0 0 72 -1 -2 -1 73 */ 74 //************************************************************** 75 always @ (posedge clock or negedge reset) 76 if(!reset) 77 begin 78 abs_D <= 8'd0 ; 79 Dx <= 11'd0 ; 80 Dy <= 11'd0 ; 81 SobelData <= 64'd0 ; 82 end 83 else if(!OrigDataEn) //if(SobelAluEn ) 84 begin 85 Dx <= $signed (~{3'b000,Orig[-1][-1]}+1) // * -1 86 + $signed(~({3'b00,Orig[0][-1]}<<1)+1) // * -2 87 + $signed(~{3'b000,Orig[1][-1]}+1) // * -1 88 89 + $signed({3'b000,Orig[-1][1]}) // * 1 90 + $signed({3'b00,Orig[0][1]}<<1) // * 2 91 + $signed ({3'b000,Orig[1][1]}) ; // * 1 92 93 Dy <= $signed ({3'b000,Orig[-1][-1]}) // * 1 94 + $signed ({3'b00,Orig[-1][0]}<<1) // * 2 95 + $signed({3'b000,Orig[-1][1]}) // * 1 96 97 + $signed(~{3'b000,Orig[1][-1]}+1) // * -1 98 + $signed(~({3'b00,Orig[1][0]}<<1)+1) // * -2 99 + $signed(~{3'b000,Orig[1][1]}+1) ; // * -1 100 101 abs_D <= (abs(Dx) + abs(Dy))>> 2; 102 SobelData <= {SobelData[55:0],abs_D}; 103 104 Orig[-1][-1] <= Orig[-1][0]; Orig[-1][0] <= Orig[-1][1]; Orig[-1][1] <= prev_row[63:56]; 105 Orig[0][-1] <= Orig[0][0]; Orig[0][0] <= Orig[0][1]; Orig[0][1] <= curr_row[63:56]; 106 Orig[1][-1] <= Orig[1][0]; Orig[1][0] <= Orig[1][1]; Orig[1][1] <= next_row[63:56]; 107 end 108 109 endmodule