直方图均衡化Verilog实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
// 2012年4月26日10:56:37
// 修改说明 : ①将86-94行的数据赋值方式均改为阻塞赋值
// ②将161直方图重新映射时应该乘255,原来为(x/N)*256 → (x/N)*255,详细操作见修改后的代码
// ③将38行 im_index <= im_index + 1; 去掉,修改过后对结果没有影响
// histeq_syn.v
`timescale 10 ns/ 10ns
module histeq_syn(reset_n, im_input, clk, out_en, im_output);
parameter n = 18, row = ( 1 << n ) - 1, m_step = n - 8;//row = 2^18 - 1 = 262143 for 512*512 gray image;
parameter col = 2 << ( n/2 + 3);
input [7:0] im_input;
input clk;
input reset_n;
output out_en;
output [7:0] im_output;
reg [n+1:0] hist_count[255:0];
reg [n+1:0] hist_acc[255:0];
reg [n+1:0] output_buffer;
reg hist_count_en, hist_acc_en, hist_map_en;
reg [n+1:0] hist_count_index, hist_map_index;
reg [8:0] hist_acc_index;
reg [7:0] im_buffer[(row+col):0];
reg [7:0] im_output;
reg out_en;
reg [63:0] syn;
reg syn_en;
reg [7:0] syn_buffer[7:0];
reg syn_clk;
reg [9:0] syn_index;
reg [4:0] syn_index_1;
reg syn_clk_en;
// for loop initialize the reg varialbe hist_count and hist_ac
integer im_index;
always @ ( posedge clk or negedge reset_n )
begin
if ( reset_n == 0 )
for ( im_index=0 ; im_index < 9'd256 ; im_index = im_index + 1)
begin
hist_count[im_index] <= 0;
hist_acc[im_index] <= 0;
im_index <= im_index + 1;
end
end
//generate syn_clk
always @ (posedge clk or negedge reset_n)
begin
if( reset_n == 0 )
begin
syn_index <= 10'b0;
syn_clk <= 1;
syn_clk_en <= 0;
end
else
if ( syn_clk_en == 0)
begin
if ( syn_index <= 7)
begin
syn_clk <= 0;
syn_index = syn_index + 1;
end
else
begin
syn_clk <= 1;
syn_index = syn_index + 1;
if( syn_index == (10'd512 + 4'd8 ) )
syn_index <= 10'b0;
end
end
end
//judge syn signal enable or disalbe from initial 64bits data of each row
always @ (posedge clk or negedge reset_n)
begin
if( reset_n == 0 )
begin
syn_en <= 0;
syn_index_1 <= 0;
syn <= 64'b0;
end
else
begin
if( syn_clk == 1'b0 )
begin
syn_buffer[syn_index_1] = im_input;
syn_index_1 = syn_index_1 + 1'b1;
if( syn_index_1 == 8 )
begin
syn = { syn_buffer[0],syn_buffer[1],syn_buffer[2],syn_buffer[3],syn_buffer[4],syn_buffer[5],syn_buffer[6],syn_buffer[7]};
syn_index_1 = 0;
case ( syn )
64'hC53A_A53C_C53A_5002 : syn_en = 1'b1;
64'hC53A_A53C_C53A_5003 : syn_en = 1'b1;
64'hC53A_A53C_C53A_5004 : syn_en = 1'b1;
endcase
end
end
end
end
/
/syn clock signal enable to activate hist count enable signal
always @ ( posedge syn_clk or negedge reset_n)
begin
if( reset_n == 1 )
if( syn_en == 1 )
begin
hist_count_en <= 1;
end
end
always @ ( negedge syn_clk or negedge reset_n)
begin
if( reset_n == 1 )
begin
hist_count_en <= 0;
syn_en <=0;
end
end
//statistic, accumulate, remap process of histogram equalization
always @ (posedge clk or negedge reset_n)
begin
if( reset_n == 0 )
begin
hist_count_index <= 0;
hist_map_index <= 0;
hist_acc_index <= 1;
hist_acc_en <= 0;
hist_count_en <= 0;
hist_map_en <= 0;
out_en <= 0;
end
else
if ( hist_count_en == 1 )
begin
im_buffer[hist_count_index] = im_input;//image data buffer
hist_count[im_input] <= hist_count[im_input] + 1;
hist_count_index = hist_count_index + 1;
if ( hist_count_index == row+1 )
begin
hist_count_en <= 0;
hist_acc_en <= 1'b1;
hist_count_index <= 0;
hist_acc[0] <= hist_count[0];//initialize hist_acc[0]
end
end
else
if ( hist_acc_en == 1 )
begin
hist_acc[hist_acc_index] <= hist_acc[hist_acc_index-1'b1] + hist_count[hist_acc_index];
hist_acc_index <= hist_acc_index + 1'b1;
if ( hist_acc_index == 256 )
begin
hist_acc_index <= 0;
hist_acc_en <= 0;
hist_map_en <= 1;
end
end
else
if ( hist_map_en == 1 )
begin
output_buffer = (( ( hist_acc[im_buffer[hist_map_index]] ) >> m_step )-( ( hist_acc[im_buffer[hist_map_index]] ) >> n ));// pixel remap
im_output <= output_buffer[7:0];
hist_map_index <= hist_map_index + 1;
out_en = 1;
if ( hist_map_index == (row+1) )
begin
hist_map_index <= 1'b0;
hist_map_en <= 0;
out_en <= 0;
end
end
end
endmodule
// histeq_syn_tb.v --- 无修改
`timescale 10 ns/ 10ns
module histeq_syn_tb;
parameter n = 18, row = ( 1 << n ) - 1;//row = 2^18 - 1 = 262143;
parameter col = (1 << ( n/2 + 3 ));
reg clk;
wire [7:0] im_output;
wire out_en ;
wire im_output_en;//illegal output or inout port connection
//reg syn;
reg [7:0] im_input;
reg [7:0] data_mem[(row+col):0];
reg [n+1:0] i;
reg reset_n;
initial
begin
reset_n = 1;
#6 reset_n = 0;
#6 reset_n = 1;
end
initial
begin
clk = 1'b0;
i = 1'b0;
end
initial
begin
$readmemh("D://lena_syn.txt",data_mem);
end
always #1 clk <= ~clk;
always @ ( posedge clk or negedge reset_n )
begin
if(reset_n == 1'b0)
begin
//im_input <= data_m
em[0];
i <= 0;
end
else
if ( i < (row+col+1) )
begin
im_input = data_mem[i];
i = i + 1;
end
else
im_input <= 8'b0;
end
integer w_file;
initial w_file=$fopen("D://lena_syn_1.txt");
always @ (posedge clk)
begin
if ( out_en == 1 )
begin
$fdisplay(w_file,"%x",im_output);
end
//else
//$fclose("D://lena1.txt");
end
histeq_syn port_map(.reset_n(reset_n),
.im_input(im_input),
.clk(clk),
.out_en,
.im_output(im_output)
);
endmodule