ISP/rtl/isp.sv

207 lines
5.3 KiB
Systemverilog
Raw Normal View History

2024-10-03 15:13:24 +08:00
`timescale 1ns/1ps
module isp #(
parameter reg [15:0] IN_WIDTH = 1936,
parameter reg [15:0] IN_HEIGHT = 1088,
parameter reg [15:0] OUT_WIDTH = 1920,
parameter reg [15:0] OUT_HEIGHT = 1080,
parameter reg [ 4:0] COLOR_DEPTH = 8, // Can't Change!!!
parameter reg [ 1:0] RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg
) (
// 基本信号
input wire clk,
input wire reset,
// 数据输入信号
input wire in_en,
input wire [15:0] in_data[3], // 数据输入线0、1、2分别表示第一、二、三行
output wire out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
output wire out_receive,
// output wire out_clk,
output wire out_en,
output wire [3 * COLOR_DEPTH - 1:0] out_data,
input wire in_ready,
// input wire in_receive,
// 颜色校正,低八位为小数位,高八位为整数位
input wire [15:0] gain_red,
input wire [15:0] gain_green,
input wire [15:0] gain_blue,
input wire blender_enable, // 是否启用颜色校正
// Gamma矫正低八位为小数位
// input wire [7:0] gamma_inverse,
input wire [7:0] gamma_table[256],
input wire gamma_enable,
// 白平衡
input wire [15:0] white_gain[3],
input wire [8:0] flame_rate,
input wire white_enable,
// 饱和度校正
input wire signed [31:0] saturation_inc,
input wire saturation_enable // -256~256
);
localparam reg [15:0] BAYER_WIDTH = IN_WIDTH - 2;
localparam reg [15:0] BAYER_HEIGHT = IN_HEIGHT - 2;
wire [COLOR_DEPTH - 1:0] w_out_data[3];
assign out_data = {w_out_data[2], w_out_data[1], w_out_data[0]};
// 颜色校正,并改变色深
wire blender_en, blender_ready, blender_receive;
wire [15:0] blender_r, blender_g, blender_b;
// 裁切图像
wire crop_en, crop_ready, crop_receive; // scaler 请求数据
reg [COLOR_DEPTH - 1:0] crop_data[3];
// Gamma矫正
wire gamma_en, gamma_ready, gamma_receive;
wire [COLOR_DEPTH - 1 : 0] gamma_data[3];
// 白平衡
wire white_en, white_ready, white_receive;
wire [COLOR_DEPTH - 1 : 0] white_data[3];
// 饱和度校正
wire saturation_en, saturation_ready, saturation_receive;
wire [COLOR_DEPTH - 1 : 0] saturation_data[3];
// reg in_receive;
// always @(posedge clk) in_receive <= in_en;
wire in_receive;
assign in_receive = out_en;
// assign out_clk = clk;
Demosaic2 #(
.IM_WIDTH (IN_WIDTH),
.IM_HEIGHT(IN_HEIGHT),
.RAW_TYPE (RAW_TYPE)
) inst_demosaic (
.clk(clk),
.reset(reset),
.in_en(in_en),
.in_data(in_data),
.out_ready(out_ready),
.out_receive(out_receive),
.out_en(blender_en),
.in_ready(blender_ready),
.in_receive(blender_receive),
.out_r(blender_r),
.out_g(blender_g),
.out_b(blender_b)
);
ColorBlender #(
.IN_DEPTH (12),
.OUT_DEPTH(COLOR_DEPTH)
) inst_blender (
.clk (clk),
.reset(reset),
.in_en(blender_en),
.in_data({blender_b, blender_g, blender_r}),
.out_ready(blender_ready),
.out_receive(blender_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),
.enable(blender_enable)
);
Crop #(
.IN_WIDTH(BAYER_WIDTH),
.IN_HEIGHT(BAYER_HEIGHT),
.OUT_WIDTH(OUT_WIDTH),
.OUT_HEIGHT(OUT_HEIGHT),
.COLOR_DEPTH(COLOR_DEPTH)
) inst_crop (
.clk (clk),
.reset(reset),
.in_en(crop_en),
.out_ready(crop_ready),
.out_receive(crop_receive),
.in_data({crop_data[2], crop_data[1], crop_data[0]}),
.out_en(white_en),
.in_ready(white_ready),
.in_receive(white_receive),
.out_data({white_data[2], white_data[1], white_data[0]})
);
GreyWorld #(
.COLOR_DEPTH(COLOR_DEPTH),
.IM_SIZE({16'b0, OUT_WIDTH} * {16'b0, OUT_HEIGHT})
) inst_whitebalance (
.clk (clk),
.reset(reset),
.in_en(white_en),
.in_data(white_data),
.out_ready(white_ready),
.out_receive(white_receive),
.in_ready(gamma_ready),
.in_receive(gamma_receive),
.out_en(gamma_en),
.out_data(gamma_data),
.enable(white_enable),
.flame_rate(flame_rate),
.white_gain(white_gain)
);
// 查找表型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(saturation_ready),
.in_receive(saturation_receive),
.out_en(saturation_en),
.out_data(saturation_data),
.gamma_table(gamma_table),
.enable(gamma_enable)
);
SaturationCorrection #(
.COLOR_DEPTH(COLOR_DEPTH)
) inst_saturation (
.clk (clk),
.reset(reset),
.in_en(saturation_en),
.out_ready(saturation_ready),
.out_receive(saturation_receive),
.in_data(saturation_data),
.in_ready(in_ready),
.in_receive(in_receive),
.out_en(out_en),
.out_data(w_out_data),
.saturation_inc(saturation_inc),
.enable(saturation_enable)
);
endmodule