finish GammaCorrection and pass simmulation
This commit is contained in:
parent
897db1e699
commit
24ac284c52
|
@ -2,9 +2,9 @@
|
|||
|
||||
// 三通道图像合成一个RGB图像
|
||||
module ColorBlender #(
|
||||
parameter reg [ 4:0] IN_DEPTH = 12, // 输入图像的色深
|
||||
parameter reg [ 4:0] OUT_DEPTH = 8, // 输出图像的色深
|
||||
parameter reg [ 8:0] BUFF_SIZE = 32
|
||||
parameter reg [4:0] IN_DEPTH = 12, // 输入图像的色深
|
||||
parameter reg [4:0] OUT_DEPTH = 8, // 输出图像的色深
|
||||
parameter reg [8:0] BUFF_SIZE = 32
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
@ -18,13 +18,13 @@ module ColorBlender #(
|
|||
input wire in_ready,
|
||||
input wire in_receive,
|
||||
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_green,
|
||||
input wire [15:0] gain_blue,
|
||||
input wire color_correction
|
||||
input wire enable
|
||||
);
|
||||
localparam reg [2:0] READ_DATA = 0;
|
||||
localparam reg [2:0] CALC_DATA = 1;
|
||||
|
@ -62,7 +62,9 @@ module ColorBlender #(
|
|||
data_cal[1] <= 0;
|
||||
data_cal[2] <= 0;
|
||||
|
||||
out_data <= 0;
|
||||
out_data[0] <= 0;
|
||||
out_data[1] <= 0;
|
||||
out_data[2] <= 0;
|
||||
out_en <= 0;
|
||||
end else begin
|
||||
case (state)
|
||||
|
@ -75,12 +77,11 @@ module ColorBlender #(
|
|||
end
|
||||
|
||||
CALC_DATA: begin
|
||||
if (color_correction) begin
|
||||
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[2] <= (data_cal[2] * {{(BUFF_SIZE - 16){1'b0}}, gain_blue}) >> 16;
|
||||
end
|
||||
else begin
|
||||
if (enable) begin
|
||||
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[2] <= (data_cal[2] * {{(BUFF_SIZE - 16) {1'b0}}, gain_blue}) >> 16;
|
||||
end else begin
|
||||
data_cal[0] <= data_cal[0] >> 8;
|
||||
data_cal[1] <= data_cal[1] >> 8;
|
||||
data_cal[2] <= data_cal[2] >> 8;
|
||||
|
@ -88,17 +89,17 @@ module ColorBlender #(
|
|||
end
|
||||
|
||||
SATI_DATA: begin
|
||||
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[2] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[2];
|
||||
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[2] <= |data_cal[0][BUFF_SIZE-1 : OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[2];
|
||||
end
|
||||
|
||||
SEND_DATA: begin
|
||||
if (in_ready && !in_receive) begin
|
||||
out_en <= 1;
|
||||
out_data <= {
|
||||
data_cal[0][OUT_DEPTH-1:0], data_cal[1][OUT_DEPTH-1:0], data_cal[2][OUT_DEPTH-1:0]
|
||||
};
|
||||
out_data[0] <= data_cal[0][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
|
||||
|
||||
|
|
|
@ -7,16 +7,17 @@ module GammaCorrection #(
|
|||
input wire reset,
|
||||
|
||||
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_receive,
|
||||
|
||||
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_receive,
|
||||
|
||||
input wire [8:0] gamma
|
||||
input wire enable,
|
||||
input wire [9:0] gamma_inverse
|
||||
);
|
||||
reg [2:0] state, nextState;
|
||||
localparam reg [2:0] READ_DATA = 0;
|
||||
|
@ -39,13 +40,48 @@ module GammaCorrection #(
|
|||
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;
|
||||
end
|
||||
else begin
|
||||
out_data[0] <= 0;
|
||||
out_data[1] <= 0;
|
||||
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
|
||||
|
||||
|
|
|
@ -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_green,
|
||||
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_HEIGHT = IN_HEIGHT - 2;
|
||||
|
@ -36,9 +41,13 @@ module isp #(
|
|||
wire blender_en, blender_ready, blender_receive;
|
||||
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 请求数据
|
||||
reg [3 * COLOR_DEPTH - 1:0] crop_data;
|
||||
reg [COLOR_DEPTH - 1:0] crop_data[3];
|
||||
|
||||
// 写入RAM
|
||||
// wire RAM_in_en;
|
||||
|
@ -51,7 +60,7 @@ module isp #(
|
|||
.IM_WIDTH (IN_WIDTH),
|
||||
.IM_HEIGHT(IN_HEIGHT),
|
||||
.RAW_TYPE (RAW_TYPE)
|
||||
) CFA (
|
||||
) inst_demosaic (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.in_en(in_en),
|
||||
|
@ -70,7 +79,7 @@ module isp #(
|
|||
ColorBlender #(
|
||||
.IN_DEPTH (12),
|
||||
.OUT_DEPTH(8)
|
||||
) blender (
|
||||
) inst_blender (
|
||||
.clk (clk),
|
||||
.reset(reset),
|
||||
|
||||
|
@ -79,15 +88,57 @@ module isp #(
|
|||
.out_ready(blender_ready),
|
||||
.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_receive(crop_receive),
|
||||
.out_en(crop_en),
|
||||
.out_data(crop_data),
|
||||
|
||||
.gain_red(gain_red),
|
||||
.gain_green(gain_green),
|
||||
.gain_blue(gain_blue),
|
||||
.color_correction(color_correction)
|
||||
.gamma_table(gamma_table),
|
||||
.enable(gamma_enable)
|
||||
);
|
||||
|
||||
Crop #(
|
||||
|
@ -96,14 +147,14 @@ module isp #(
|
|||
.OUT_WIDTH(OUT_WIDTH),
|
||||
.OUT_HEIGHT(OUT_HEIGHT),
|
||||
.COLOR_DEPTH(COLOR_DEPTH)
|
||||
) crop_process (
|
||||
) inst_crop (
|
||||
.clk (clk),
|
||||
.reset(reset),
|
||||
|
||||
.in_en(crop_en),
|
||||
.out_ready(crop_ready),
|
||||
.out_receive(crop_receive),
|
||||
.in_data(crop_data),
|
||||
.in_data({crop_data[2], crop_data[1], crop_data[0]}),
|
||||
|
||||
.out_en(out_en),
|
||||
.in_ready(in_ready),
|
||||
|
|
|
@ -207,11 +207,15 @@ int sc_main(int argc, char* argv[]) {
|
|||
sc_signal<bool> out_receive;
|
||||
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_green;
|
||||
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;
|
||||
|
||||
// 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_green(gain_green);
|
||||
isp->gain_blue(gain_blue);
|
||||
isp->color_correction(color_correction);
|
||||
isp->blender_enable(blender_enable);
|
||||
|
||||
color_correction.write(true); // enable color correction
|
||||
gain_red.write((uint32_t)(color_gain.red * std::pow(2, 8)));
|
||||
gain_green.write((uint32_t)(color_gain.green * std::pow(2, 8)));
|
||||
gain_blue.write((uint32_t)(color_gain.blue * std::pow(2, 8)));
|
||||
isp->gamma_enable(gamma_enable);
|
||||
// isp->gamma_inverse(gamma_inverse);
|
||||
|
||||
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
|
||||
TB_ISP tb_isp("tb_isp");
|
||||
|
|
Loading…
Reference in New Issue