sobel流水线操作Verilog程序
0赞
发表于 7/25/2014 2:13:05 PM
阅读(3069)
sobel算子的verilog实现,采用了流水线操作。
module sobel_computer (
clock ,
reset,
OrigDataEn,
//SobelAluEn,
OrigData,
SobelData
);
input clock ,reset;
input OrigDataEn ;
//input SobelAluEn ;
input [63:0] OrigData ;
output reg [63:0] SobelData ;
reg [63:0] prev_row, curr_row, next_row ;
reg [1:0] data_state ;
reg [7:0]abs_D ;
//*****************OrigDataEn 维持三个周期,将数据保存到三个reg 中****************
always @ (posedge clock or negedge reset )
if(!reset)
begin
data_state <= 2'b00 ;
prev_row <= 64'd0 ;
curr_row <= 64'd0 ;
next_row <= 64'd0 ;
end
else if(OrigDataEn)
begin
case (data_state)
2'b00 :
begin
prev_row <= OrigData ;
data_state <= 2'b01 ;
end
2'b01 :
begin
curr_row <= OrigData ;
data_state <= 2'b10 ;
end
2'b10 :
begin
next_row <= OrigData ;
//data_state <= 2'b01 ;
end
endcase
end
else
begin
data_state <= 2'b00 ;
prev_row <= prev_row << 8 ;
curr_row <= curr_row << 8 ;
next_row <= next_row << 8 ;
end
//----------------------------------------------------------------
//function : 函数名= 内部reg,并返回。不包含 # @ wait,至少一个输入参数
function [9:0] abs (input signed[10:0] data);
abs = data[10]? (~data[9:0]+1): data[9:0];
endfunction
reg signed [10:0] Dx,Dy ; //8'b1111_1111 * 6 = 11'd1530 所以采用11bit的Dx 和Dy
reg [7:0]Orig [-1:1][-1:1];
/*
分段方式:[63:56] [55:48] [47:40] [39:32] [31:24] [23:16] [15:8] [7:0]
sobel Dx -1 0 +1
-2 0 +2
-1 0 +1
Dy +1 +2 +1
0 0 0
-1 -2 -1
*/
//**************************************************************
always @ (posedge clock or negedge reset)
if(!reset)
begin
abs_D <= 8'd0 ;
Dx <= 11'd0 ;
Dy <= 11'd0 ;
SobelData <= 64'd0 ;
end
else if(!OrigDataEn) //if(SobelAluEn )
begin
Dx <= $signed (~{3'b000,Orig[-1][-1]}+1) // * -1
+ $signed(~({3'b00,Orig[0][-1]}<<1)+1) // * -2
+ $signed(~{3'b000,Orig[1][-1]}+1) // * -1
+ $signed({3'b000,Orig[-1][1]}) // * 1
+ $signed({3'b00,Orig[0][1]}<<1) // * 2
+ $signed ({3'b000,Orig[1][1]}) ; // * 1
Dy <= $signed ({3'b000,Orig[-1][-1]}) // * 1
+ $signed ({3'b00,Orig[-1][0]}<<1) // * 2
+ $signed({3'b000,Orig[-1][1]}) // * 1
+ $signed(~{3'b000,Orig[1][-1]}+1) // * -1
+ $signed(~({3'b00,Orig[1][0]}<<1)+1) // * -2
+ $signed(~{3'b000,Orig[1][1]}+1) ; // * -1
abs_D <= (abs(Dx) + abs(Dy))>> 2;
SobelData <= {SobelData[55:0],abs_D};
Orig[-1][-1] <= Orig[-1][0]; Orig[-1][0] <= Orig[-1][1]; Orig[-1][1] <= prev_row[63:56];
Orig[0][-1] <= Orig[0][0]; Orig[0][0] <= Orig[0][1]; Orig[0][1] <= curr_row[63:56];
Orig[1][-1] <= Orig[1][0]; Orig[1][0] <= Orig[1][1]; Orig[1][1] <= next_row[63:56];
end
endmodule
