finish GammaCorrection and pass simmulation
This commit is contained in:
parent
897db1e699
commit
24ac284c52
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
// 三通道图像合成一个RGB图像
|
// 三通道图像合成一个RGB图像
|
||||||
module ColorBlender #(
|
module ColorBlender #(
|
||||||
parameter reg [ 4:0] IN_DEPTH = 12, // 输入图像的色深
|
parameter reg [4:0] IN_DEPTH = 12, // 输入图像的色深
|
||||||
parameter reg [ 4:0] OUT_DEPTH = 8, // 输出图像的色深
|
parameter reg [4:0] OUT_DEPTH = 8, // 输出图像的色深
|
||||||
parameter reg [ 8:0] BUFF_SIZE = 32
|
parameter reg [8:0] BUFF_SIZE = 32
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
|
@ -18,13 +18,13 @@ module ColorBlender #(
|
||||||
input wire in_ready,
|
input wire in_ready,
|
||||||
input wire in_receive,
|
input wire in_receive,
|
||||||
output reg out_en,
|
output reg out_en,
|
||||||
output reg [3 * OUT_DEPTH - 1:0] out_data,
|
output reg [OUT_DEPTH - 1:0] out_data[3],
|
||||||
|
|
||||||
// 颜色校正
|
// 颜色校正
|
||||||
input wire [15:0] gain_red,
|
input wire [15:0] gain_red,
|
||||||
input wire [15:0] gain_green,
|
input wire [15:0] gain_green,
|
||||||
input wire [15:0] gain_blue,
|
input wire [15:0] gain_blue,
|
||||||
input wire color_correction
|
input wire enable
|
||||||
);
|
);
|
||||||
localparam reg [2:0] READ_DATA = 0;
|
localparam reg [2:0] READ_DATA = 0;
|
||||||
localparam reg [2:0] CALC_DATA = 1;
|
localparam reg [2:0] CALC_DATA = 1;
|
||||||
|
@ -62,7 +62,9 @@ module ColorBlender #(
|
||||||
data_cal[1] <= 0;
|
data_cal[1] <= 0;
|
||||||
data_cal[2] <= 0;
|
data_cal[2] <= 0;
|
||||||
|
|
||||||
out_data <= 0;
|
out_data[0] <= 0;
|
||||||
|
out_data[1] <= 0;
|
||||||
|
out_data[2] <= 0;
|
||||||
out_en <= 0;
|
out_en <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
case (state)
|
case (state)
|
||||||
|
@ -75,12 +77,11 @@ module ColorBlender #(
|
||||||
end
|
end
|
||||||
|
|
||||||
CALC_DATA: begin
|
CALC_DATA: begin
|
||||||
if (color_correction) begin
|
if (enable) begin
|
||||||
data_cal[0] <= (data_cal[0] * {{(BUFF_SIZE - 16){1'b0}}, gain_red}) >> 16;
|
data_cal[0] <= (data_cal[0] * {{(BUFF_SIZE - 16) {1'b0}}, gain_red}) >> 16;
|
||||||
data_cal[1] <= (data_cal[1] * {{(BUFF_SIZE - 16){1'b0}}, gain_green}) >> 16;
|
data_cal[1] <= (data_cal[1] * {{(BUFF_SIZE - 16) {1'b0}}, gain_green}) >> 16;
|
||||||
data_cal[2] <= (data_cal[2] * {{(BUFF_SIZE - 16){1'b0}}, gain_blue}) >> 16;
|
data_cal[2] <= (data_cal[2] * {{(BUFF_SIZE - 16) {1'b0}}, gain_blue}) >> 16;
|
||||||
end
|
end else begin
|
||||||
else begin
|
|
||||||
data_cal[0] <= data_cal[0] >> 8;
|
data_cal[0] <= data_cal[0] >> 8;
|
||||||
data_cal[1] <= data_cal[1] >> 8;
|
data_cal[1] <= data_cal[1] >> 8;
|
||||||
data_cal[2] <= data_cal[2] >> 8;
|
data_cal[2] <= data_cal[2] >> 8;
|
||||||
|
@ -88,17 +89,17 @@ module ColorBlender #(
|
||||||
end
|
end
|
||||||
|
|
||||||
SATI_DATA: begin
|
SATI_DATA: begin
|
||||||
data_cal[0] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[0];
|
data_cal[0] <= |data_cal[0][BUFF_SIZE-1 : OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[0];
|
||||||
data_cal[1] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[1];
|
data_cal[1] <= |data_cal[0][BUFF_SIZE-1 : OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[1];
|
||||||
data_cal[2] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[2];
|
data_cal[2] <= |data_cal[0][BUFF_SIZE-1 : OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[2];
|
||||||
end
|
end
|
||||||
|
|
||||||
SEND_DATA: begin
|
SEND_DATA: begin
|
||||||
if (in_ready && !in_receive) begin
|
if (in_ready && !in_receive) begin
|
||||||
out_en <= 1;
|
out_en <= 1;
|
||||||
out_data <= {
|
out_data[0] <= data_cal[0][OUT_DEPTH-1:0];
|
||||||
data_cal[0][OUT_DEPTH-1:0], data_cal[1][OUT_DEPTH-1:0], data_cal[2][OUT_DEPTH-1:0]
|
out_data[1] <= data_cal[1][OUT_DEPTH-1:0];
|
||||||
};
|
out_data[2] <= data_cal[2][OUT_DEPTH-1:0];
|
||||||
end else out_en <= 0;
|
end else out_en <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,17 @@ module GammaCorrection #(
|
||||||
input wire reset,
|
input wire reset,
|
||||||
|
|
||||||
input wire in_en,
|
input wire in_en,
|
||||||
input wire [COLOR_DEPTH - 1 : 0] in_data [3],
|
input wire [COLOR_DEPTH - 1 : 0] in_data[3],
|
||||||
output wire out_ready,
|
output wire out_ready,
|
||||||
output wire out_receive,
|
output wire out_receive,
|
||||||
|
|
||||||
output reg out_en,
|
output reg out_en,
|
||||||
output reg [COLOR_DEPTH - 1 : 0] out_data [3],
|
output reg [COLOR_DEPTH - 1 : 0] out_data[3],
|
||||||
input wire in_ready,
|
input wire in_ready,
|
||||||
input wire in_receive,
|
input wire in_receive,
|
||||||
|
|
||||||
input wire [8:0] gamma
|
input wire enable,
|
||||||
|
input wire [9:0] gamma_inverse
|
||||||
);
|
);
|
||||||
reg [2:0] state, nextState;
|
reg [2:0] state, nextState;
|
||||||
localparam reg [2:0] READ_DATA = 0;
|
localparam reg [2:0] READ_DATA = 0;
|
||||||
|
@ -39,13 +40,48 @@ module GammaCorrection #(
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
|
||||||
always @(posedge clk or posedge reset) begin
|
always @(posedge clk or posedge reset) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
out_en <= 0;
|
out_en <= 0;
|
||||||
out_data <= 0;
|
out_data[0] <= 0;
|
||||||
end
|
out_data[1] <= 0;
|
||||||
else begin
|
out_data[2] <= 0;
|
||||||
|
|
||||||
|
data_cal[0] <= 0;
|
||||||
|
data_cal[1] <= 0;
|
||||||
|
data_cal[2] <= 0;
|
||||||
|
end else begin
|
||||||
|
case (state)
|
||||||
|
READ_DATA: begin
|
||||||
|
if (in_en) begin
|
||||||
|
data_cal[0] <= {8'b0, in_data[0]};
|
||||||
|
data_cal[1] <= {8'b0, in_data[1]};
|
||||||
|
data_cal[2] <= {8'b0, in_data[2]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CALC_DATA: begin
|
||||||
|
if (enable) begin
|
||||||
|
data_cal[0] <= data_cal[0] ** gamma_inverse;
|
||||||
|
data_cal[1] <= data_cal[1] ** gamma_inverse;
|
||||||
|
data_cal[2] <= data_cal[2] ** gamma_inverse;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SEND_DATA: begin
|
||||||
|
if (in_ready) begin
|
||||||
|
out_en <= 1;
|
||||||
|
out_data[0] <= data_cal[0][COLOR_DEPTH-1 : 0];
|
||||||
|
out_data[1] <= data_cal[1][COLOR_DEPTH-1 : 0];
|
||||||
|
out_data[2] <= data_cal[2][COLOR_DEPTH-1 : 0];
|
||||||
|
end else out_en <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module GammaCorrection2 #(
|
||||||
|
parameter reg [4:0] COLOR_DEPTH = 8
|
||||||
|
) (
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
|
||||||
|
input wire in_en,
|
||||||
|
input wire [COLOR_DEPTH - 1 : 0] in_data[3],
|
||||||
|
output wire out_ready,
|
||||||
|
output wire out_receive,
|
||||||
|
|
||||||
|
output reg out_en,
|
||||||
|
output reg [COLOR_DEPTH - 1 : 0] out_data[3],
|
||||||
|
input wire in_ready,
|
||||||
|
input wire in_receive,
|
||||||
|
|
||||||
|
input wire [7:0] gamma_table[256],
|
||||||
|
input wire enable
|
||||||
|
);
|
||||||
|
reg [2:0] state, nextState;
|
||||||
|
localparam reg [2:0] READ_DATA = 0;
|
||||||
|
localparam reg [2:0] SEND_DATA = 2;
|
||||||
|
|
||||||
|
reg [7:0] data_cache[3];
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) state <= READ_DATA;
|
||||||
|
else state <= nextState;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
case (state)
|
||||||
|
READ_DATA: nextState = in_en ? SEND_DATA : READ_DATA;
|
||||||
|
SEND_DATA: nextState = in_receive ? READ_DATA : SEND_DATA;
|
||||||
|
default: nextState = READ_DATA;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_en <= 0;
|
||||||
|
out_data[0] <= 0;
|
||||||
|
out_data[1] <= 0;
|
||||||
|
out_data[2] <= 0;
|
||||||
|
|
||||||
|
data_cache[0] <= 0;
|
||||||
|
data_cache[1] <= 0;
|
||||||
|
data_cache[2] <= 0;
|
||||||
|
end else begin
|
||||||
|
case (state)
|
||||||
|
READ_DATA: begin
|
||||||
|
if (in_en) begin
|
||||||
|
data_cache[0] <= in_data[0];
|
||||||
|
data_cache[1] <= in_data[1];
|
||||||
|
data_cache[2] <= in_data[2];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SEND_DATA: begin
|
||||||
|
if (in_ready) begin
|
||||||
|
out_en <= 1;
|
||||||
|
if (enable) begin
|
||||||
|
out_data[0] <= gamma_table[data_cache[0]];
|
||||||
|
out_data[1] <= gamma_table[data_cache[1]];
|
||||||
|
out_data[2] <= gamma_table[data_cache[2]];
|
||||||
|
end else begin
|
||||||
|
out_data[0] <= data_cache[0];
|
||||||
|
out_data[1] <= data_cache[1];
|
||||||
|
out_data[2] <= data_cache[2];
|
||||||
|
end
|
||||||
|
end else out_en <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
71
isp.v
71
isp.v
|
@ -28,7 +28,12 @@ module isp #(
|
||||||
input wire [15:0] gain_red,
|
input wire [15:0] gain_red,
|
||||||
input wire [15:0] gain_green,
|
input wire [15:0] gain_green,
|
||||||
input wire [15:0] gain_blue,
|
input wire [15:0] gain_blue,
|
||||||
input wire color_correction // 是否启用颜色校正
|
input wire blender_enable, // 是否启用颜色校正
|
||||||
|
|
||||||
|
// Gamma矫正,低八位为小数位
|
||||||
|
// input wire [7:0] gamma_inverse,
|
||||||
|
input wire [7:0] gamma_table [256],
|
||||||
|
input wire gamma_enable
|
||||||
);
|
);
|
||||||
localparam reg [15:0] BAYER_WIDTH = IN_WIDTH - 2;
|
localparam reg [15:0] BAYER_WIDTH = IN_WIDTH - 2;
|
||||||
localparam reg [15:0] BAYER_HEIGHT = IN_HEIGHT - 2;
|
localparam reg [15:0] BAYER_HEIGHT = IN_HEIGHT - 2;
|
||||||
|
@ -36,9 +41,13 @@ module isp #(
|
||||||
wire blender_en, blender_ready, blender_receive;
|
wire blender_en, blender_ready, blender_receive;
|
||||||
wire [15:0] blender_r, blender_g, blender_b;
|
wire [15:0] blender_r, blender_g, blender_b;
|
||||||
|
|
||||||
|
// Gamma矫正
|
||||||
|
wire gamma_en, gamma_ready, gamma_receive;
|
||||||
|
wire [COLOR_DEPTH - 1 : 0] gamma_data[3];
|
||||||
|
|
||||||
// 任意比例缩放图像
|
// 任意比例缩放图像
|
||||||
wire crop_en, crop_ready, crop_receive; // scaler 请求数据
|
wire crop_en, crop_ready, crop_receive; // scaler 请求数据
|
||||||
reg [3 * COLOR_DEPTH - 1:0] crop_data;
|
reg [COLOR_DEPTH - 1:0] crop_data[3];
|
||||||
|
|
||||||
// 写入RAM
|
// 写入RAM
|
||||||
// wire RAM_in_en;
|
// wire RAM_in_en;
|
||||||
|
@ -51,7 +60,7 @@ module isp #(
|
||||||
.IM_WIDTH (IN_WIDTH),
|
.IM_WIDTH (IN_WIDTH),
|
||||||
.IM_HEIGHT(IN_HEIGHT),
|
.IM_HEIGHT(IN_HEIGHT),
|
||||||
.RAW_TYPE (RAW_TYPE)
|
.RAW_TYPE (RAW_TYPE)
|
||||||
) CFA (
|
) inst_demosaic (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.in_en(in_en),
|
.in_en(in_en),
|
||||||
|
@ -70,7 +79,7 @@ module isp #(
|
||||||
ColorBlender #(
|
ColorBlender #(
|
||||||
.IN_DEPTH (12),
|
.IN_DEPTH (12),
|
||||||
.OUT_DEPTH(8)
|
.OUT_DEPTH(8)
|
||||||
) blender (
|
) inst_blender (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
|
||||||
|
@ -79,15 +88,57 @@ module isp #(
|
||||||
.out_ready(blender_ready),
|
.out_ready(blender_ready),
|
||||||
.out_receive(blender_receive),
|
.out_receive(blender_receive),
|
||||||
|
|
||||||
|
.in_ready(gamma_ready),
|
||||||
|
.in_receive(gamma_receive),
|
||||||
|
.out_en(gamma_en),
|
||||||
|
.out_data(gamma_data),
|
||||||
|
|
||||||
|
.gain_red(gain_red),
|
||||||
|
.gain_green(gain_green),
|
||||||
|
.gain_blue(gain_blue),
|
||||||
|
.enable(blender_enable)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算型Gamma校正
|
||||||
|
// GammaCorrection #(
|
||||||
|
// .COLOR_DEPTH(COLOR_DEPTH)
|
||||||
|
// ) inst_gamma (
|
||||||
|
// .clk (clk),
|
||||||
|
// .reset(reset),
|
||||||
|
|
||||||
|
// .in_en(gamma_en),
|
||||||
|
// .in_data(gamma_data),
|
||||||
|
// .out_ready(gamma_ready),
|
||||||
|
// .out_receive(gamma_receive),
|
||||||
|
|
||||||
|
// .in_ready(crop_ready),
|
||||||
|
// .in_receive(crop_receive),
|
||||||
|
// .out_en(crop_en),
|
||||||
|
// .out_data(crop_data),
|
||||||
|
|
||||||
|
// .gamma_inverse(gamma_inverse),
|
||||||
|
// .enable(gamma_enable)
|
||||||
|
// );
|
||||||
|
|
||||||
|
// 查找表型Gamma校正
|
||||||
|
GammaCorrection2 #(
|
||||||
|
.COLOR_DEPTH(COLOR_DEPTH)
|
||||||
|
) inst_gamma (
|
||||||
|
.clk (clk),
|
||||||
|
.reset(reset),
|
||||||
|
|
||||||
|
.in_en(gamma_en),
|
||||||
|
.in_data(gamma_data),
|
||||||
|
.out_ready(gamma_ready),
|
||||||
|
.out_receive(gamma_receive),
|
||||||
|
|
||||||
.in_ready(crop_ready),
|
.in_ready(crop_ready),
|
||||||
.in_receive(crop_receive),
|
.in_receive(crop_receive),
|
||||||
.out_en(crop_en),
|
.out_en(crop_en),
|
||||||
.out_data(crop_data),
|
.out_data(crop_data),
|
||||||
|
|
||||||
.gain_red(gain_red),
|
.gamma_table(gamma_table),
|
||||||
.gain_green(gain_green),
|
.enable(gamma_enable)
|
||||||
.gain_blue(gain_blue),
|
|
||||||
.color_correction(color_correction)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Crop #(
|
Crop #(
|
||||||
|
@ -96,14 +147,14 @@ module isp #(
|
||||||
.OUT_WIDTH(OUT_WIDTH),
|
.OUT_WIDTH(OUT_WIDTH),
|
||||||
.OUT_HEIGHT(OUT_HEIGHT),
|
.OUT_HEIGHT(OUT_HEIGHT),
|
||||||
.COLOR_DEPTH(COLOR_DEPTH)
|
.COLOR_DEPTH(COLOR_DEPTH)
|
||||||
) crop_process (
|
) inst_crop (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
|
||||||
.in_en(crop_en),
|
.in_en(crop_en),
|
||||||
.out_ready(crop_ready),
|
.out_ready(crop_ready),
|
||||||
.out_receive(crop_receive),
|
.out_receive(crop_receive),
|
||||||
.in_data(crop_data),
|
.in_data({crop_data[2], crop_data[1], crop_data[0]}),
|
||||||
|
|
||||||
.out_en(out_en),
|
.out_en(out_en),
|
||||||
.in_ready(in_ready),
|
.in_ready(in_ready),
|
||||||
|
|
|
@ -207,11 +207,15 @@ int sc_main(int argc, char* argv[]) {
|
||||||
sc_signal<bool> out_receive;
|
sc_signal<bool> out_receive;
|
||||||
sc_signal<uint32_t> out_data;
|
sc_signal<uint32_t> out_data;
|
||||||
|
|
||||||
sc_signal<bool> color_correction;
|
sc_signal<bool> blender_enable;
|
||||||
sc_signal<uint32_t> gain_red;
|
sc_signal<uint32_t> gain_red;
|
||||||
sc_signal<uint32_t> gain_green;
|
sc_signal<uint32_t> gain_green;
|
||||||
sc_signal<uint32_t> gain_blue;
|
sc_signal<uint32_t> gain_blue;
|
||||||
|
|
||||||
|
sc_signal<bool> gamma_enable;
|
||||||
|
sc_signal<uint32_t> gamma_inverse;
|
||||||
|
sc_signal<uint32_t> gamma_table[256];
|
||||||
|
|
||||||
sc_signal<bool> flag_done;
|
sc_signal<bool> flag_done;
|
||||||
|
|
||||||
// Construct the Verilated model, from inside Visp.h
|
// Construct the Verilated model, from inside Visp.h
|
||||||
|
@ -236,12 +240,22 @@ int sc_main(int argc, char* argv[]) {
|
||||||
isp->gain_red(gain_red);
|
isp->gain_red(gain_red);
|
||||||
isp->gain_green(gain_green);
|
isp->gain_green(gain_green);
|
||||||
isp->gain_blue(gain_blue);
|
isp->gain_blue(gain_blue);
|
||||||
isp->color_correction(color_correction);
|
isp->blender_enable(blender_enable);
|
||||||
|
|
||||||
color_correction.write(true); // enable color correction
|
isp->gamma_enable(gamma_enable);
|
||||||
gain_red.write((uint32_t)(color_gain.red * std::pow(2, 8)));
|
// isp->gamma_inverse(gamma_inverse);
|
||||||
gain_green.write((uint32_t)(color_gain.green * std::pow(2, 8)));
|
|
||||||
gain_blue.write((uint32_t)(color_gain.blue * std::pow(2, 8)));
|
blender_enable = true; // enable color correction
|
||||||
|
gain_red = (uint32_t)(color_gain.red * std::pow(2, 8));
|
||||||
|
gain_green = (uint32_t)(color_gain.green * std::pow(2, 8));
|
||||||
|
gain_blue = (uint32_t)(color_gain.blue * std::pow(2, 8));
|
||||||
|
|
||||||
|
gamma_enable = true;
|
||||||
|
gamma_inverse = (uint32_t)((1.0 / gamma_value) * std::pow(2, 8));
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
isp->gamma_table[i](gamma_table[i]);
|
||||||
|
gamma_table[i] = (uint32_t)(255 * pow(i / 255.0, 1.0 / gamma_value));
|
||||||
|
}
|
||||||
|
|
||||||
// Construct testbench module
|
// Construct testbench module
|
||||||
TB_ISP tb_isp("tb_isp");
|
TB_ISP tb_isp("tb_isp");
|
||||||
|
|
Loading…
Reference in New Issue