finish GammaCorrection and pass simmulation

This commit is contained in:
SikongJueluo 2024-06-29 17:05:57 +08:00
parent 897db1e699
commit 24ac284c52
No known key found for this signature in database
GPG Key ID: D2D3D29A993716EA
5 changed files with 228 additions and 41 deletions

View File

@ -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

View File

@ -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

85
Color/GammaCorrection2.v Normal file
View File

@ -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
View File

@ -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),

View File

@ -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");