136 lines
3.5 KiB
Systemverilog
Executable File
136 lines
3.5 KiB
Systemverilog
Executable File
`timescale 1ns / 1ps
|
|
|
|
// 三通道图像合成一个RGB图像
|
|
module WhiteBalance #(
|
|
parameter reg [4:0] IN_DEPTH = 12, // 输入图像的色深
|
|
parameter reg [4:0] OUT_DEPTH = 8, // 输出图像的色深
|
|
parameter reg [8:0] BUFF_SIZE = 32,
|
|
parameter reg [31:0] RAM_BEGIN_ADDR = 0,
|
|
parameter reg [31:0] IM_SIZE = 1920 * 1080
|
|
) (
|
|
input wire clk,
|
|
input wire reset,
|
|
|
|
input wire in_en,
|
|
input wire [15:0] in_data[3], // 0:R 1:G 2:B
|
|
output wire out_ready,
|
|
output wire out_receive,
|
|
|
|
// 输出相关
|
|
input wire in_ready,
|
|
input wire in_receive,
|
|
output wire out_en,
|
|
output wire [OUT_DEPTH - 1:0] out_data[3],
|
|
|
|
input wire enable,
|
|
input wire [8:0] flame_rate,
|
|
input wire [31:0] white_gain[3]
|
|
);
|
|
|
|
wire ram_read_en, ram_write_en, ram_read_ready, ram_write_ready;
|
|
wire [31:0] ram_read_data, ram_read_addr, ram_write_data, ram_write_addr;
|
|
|
|
reg [8:0] cnt_flame;
|
|
reg [31:0] cnt_in_pic, cnt_out_pic, cnt_pixels;
|
|
reg [31:0] red_total, green_total, blue_total;
|
|
reg [31:0] r_white_gain[3];
|
|
|
|
wire is_finish_cal;
|
|
always @(*) begin
|
|
if (cnt_in_pic >= IM_SIZE) is_finish_cal = 1;
|
|
else if (cnt_out_pic >= IM_SIZE) is_finish_cal = 0;
|
|
else is_finish_cal = is_finish_cal;
|
|
end
|
|
|
|
assign ram_read_addr = cnt_out_pic;
|
|
assign ram_write_addr = cnt_in_pic;
|
|
assign cnt_pixels = (is_finish_cal)
|
|
? IM_SIZE - cnt_out_pic + cnt_in_pic
|
|
: cnt_in_pic - cnt_out_pic;
|
|
|
|
assign out_ready = (!in_en && !reset && cnt_pixels < IM_SIZE) ? 1 : 0;
|
|
assign out_receive = (in_en && !reset && cnt_in_pic < IM_SIZE) ? 1 : 0;
|
|
|
|
DiffWidthSyncFIFO #(
|
|
.DATA_WIDTH (8),
|
|
.DATA_DEPTH (12),
|
|
.READ_DEPTH (4),
|
|
.WRITE_DEPTH(3)
|
|
) in_fifo (
|
|
.clk(clk),
|
|
.reset(reset),
|
|
.read_ready(ram_write_ready),
|
|
.read_en(ram_write_en),
|
|
.read_data(ram_write_data),
|
|
.write_ready(in_ready),
|
|
.write_en(in_en),
|
|
.write_data(in_data)
|
|
);
|
|
|
|
DiffWidthSyncFIFO #(
|
|
.DATA_WIDTH (8),
|
|
.DATA_DEPTH (12),
|
|
.READ_DEPTH (3),
|
|
.WRITE_DEPTH(4)
|
|
) out_fifo (
|
|
.clk(clk),
|
|
.reset(reset),
|
|
.read_ready(out_ready),
|
|
.read_en(out_en),
|
|
.read_data(out_data),
|
|
.write_ready(ram_read_ready),
|
|
.write_en(ram_read_en),
|
|
.write_data(ram_read_data)
|
|
);
|
|
|
|
SDRAM inst_RAM (
|
|
.clk(clk),
|
|
.read_en(ram_read_en),
|
|
.read_addr(ram_read_addr),
|
|
.read_data(ram_read_data),
|
|
.read_ready(ram_read_ready),
|
|
.write_en(ram_write_en),
|
|
.write_addr(ram_write_addr),
|
|
.write_data(ram_write_data),
|
|
.write_ready(ram_write_ready)
|
|
);
|
|
|
|
// calculate white gain
|
|
always @(posedge clk) begin
|
|
if (reset) begin
|
|
red_total <= 0;
|
|
green_total <= 0;
|
|
blue_total <= 0;
|
|
cnt_flame <= 0;
|
|
cnt_in_pic <= 0;
|
|
r_white_gain[0] <= white_gain[0];
|
|
r_white_gain[1] <= white_gain[1];
|
|
r_white_gain[2] <= white_gain[2];
|
|
end else begin
|
|
if (in_en && cnt_pixels < IM_SIZE) begin
|
|
red_total <= red_total + in_data[0];
|
|
green_total <= green_total + in_data[1];
|
|
blue_total <= blue_total + in_data[2];
|
|
if (cnt_in_pic < IM_SIZE) cnt_in_pic <= cnt_in_pic + 1;
|
|
else cnt_in_pic <= 0;
|
|
end else begin
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
// calculate out data
|
|
always @(posedge clk) begin
|
|
if (reset) begin
|
|
cnt_out_pic <= 0;
|
|
end else begin
|
|
if (out_ready && is_finish_cal) begin
|
|
out_en <= 1;
|
|
end else begin
|
|
out_en <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|