ISP/rtl/BayerProcess/DPC.sv

299 lines
13 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`timescale 1ns / 1ps
module DPC #(
parameter reg [15:0] TOTAL_WIDTH = 512 + 3, // 总图像宽度
parameter reg [15:0] TOTAL_HEIGHT = 256 + 3, // 总图像高度
parameter reg [ 1:0] RAW_TYPE = 3, // (0,0)位置算起RAW_TYPE的值
parameter reg [ 4:0] DATA_WIDTH = 16 // 输入/输出数据位宽
) (
input wire clk,
input wire reset,
input wire [DATA_WIDTH - 1:0] in_data [5*5],
output reg [DATA_WIDTH - 1:0] out_data,
input wire in_valid,
output wire out_valid,
input wire in_ready,
output wire out_ready
);
localparam WINDOW_LENGTH = 5;
localparam DATA_NUM = WINDOW_LENGTH * WINDOW_LENGTH;
localparam EXPAND_BITS = 5;
localparam PIPILINE = 9;
reg [PIPILINE-1:0] pipeline_valid;
wire pipeline_running;
assign pipeline_running = in_ready | ~pipeline_valid[PIPILINE-1];
//out_ready :只要本模块可以接收数据就一直拉高
assign out_ready = pipeline_running;
//out_valid :只要本模块可以发出数据就一直拉高
assign out_valid = pipeline_valid[PIPILINE-1];
reg [DATA_WIDTH-1:0] data_cache[DATA_NUM]; // 缓存颜色数据行列nxn
reg [DATA_WIDTH-1:0] data_cache0[DATA_NUM]; // 缓存颜色数据行列nxn
reg [DATA_WIDTH-1:0] channel_cache[9]; // 缓存颜色通道数据channel_cache[4]就是中心像素点
reg [DATA_WIDTH-1:0]
channel_cache0,
channel_cache1,
channel_cache2,
channel_cache3,
channel_cache4; // 缓存中心像素点的颜色数据
reg signed [DATA_WIDTH-1+EXPAND_BITS:0]
grad_h_cache[3], grad_v_cache[3], grad_45_cache[3], grad_135_cache[3];
reg [DATA_WIDTH-1+EXPAND_BITS:0]
grad_h_cache0[3], grad_v_cache0[3], grad_45_cache0[3], grad_135_cache0[3];
reg [DATA_WIDTH-1+EXPAND_BITS:0]
grad_h_cache1[3], grad_v_cache1[3], grad_45_cache1[3], grad_135_cache1[3];
reg [DATA_WIDTH-1+EXPAND_BITS:0]
grad_h_cache2[3], grad_v_cache2[3], grad_45_cache2[3], grad_135_cache2[3];
reg [DATA_WIDTH-1+EXPAND_BITS:0] grad_median_cache[4];
reg [1:0] flag_which_dict;
reg [DATA_WIDTH-1:0]
channel_cache_correct[4],
channel_cache_correct0[4],
channel_cache_correct1[4],
channel_cache_correct2[4];
reg [DATA_WIDTH-1:0] channel_cache_correct_final;
reg flag_if_need_corection;
reg [15:0] pos_x;
reg pos_y_bit;
reg [1:0] raw_type;
integer i;
always @(posedge clk) begin
if (reset) begin
for (i = 0; i < DATA_NUM; i = i + 1) data_cache[i] <= 0;
for (i = 0; i < DATA_NUM; i = i + 1) data_cache0[i] <= 0;
for (i = 0; i < 9; i = i + 1) channel_cache[i] <= 0;
channel_cache0 <= 0;
channel_cache1 <= 0;
channel_cache2 <= 0;
channel_cache3 <= 0;
channel_cache4 <= 0;
channel_cache_correct_final <= 0;
for (i = 0; i < 3; i = i + 1) grad_h_cache[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_h_cache1[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_h_cache2[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_v_cache[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_v_cache1[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_v_cache2[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_45_cache[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_45_cache1[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_45_cache2[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_135_cache[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_135_cache1[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_135_cache2[i] <= 0;
for (i = 0; i < 3; i = i + 1) grad_median_cache[i] <= 0;
flag_which_dict <= 0;
flag_if_need_corection <= 0;
for (i = 0; i < 4; i = i + 1) channel_cache_correct[i] <= 0;
for (i = 0; i < 4; i = i + 1) channel_cache_correct1[i] <= 0;
for (i = 0; i < 4; i = i + 1) channel_cache_correct0[i] <= 0;
for (i = 0; i < 4; i = i + 1) channel_cache_correct2[i] <= 0;
pipeline_valid <= 0;
out_data <= 0;
pos_x <= ~0;
pos_y_bit <= ~0;
raw_type <= RAW_TYPE;
end else if (pipeline_running) begin
pipeline_valid <= {pipeline_valid[PIPILINE-2:0], in_valid};
if (in_valid) begin
for (i = 0; i < DATA_NUM; i = i + 1) data_cache0[i] <= in_data[i];
pos_x <= (pos_x >= TOTAL_WIDTH - 1) ? (0) : (pos_x + 1);
pos_y_bit <= (pos_x >= TOTAL_WIDTH - 1) ? (~pos_y_bit) : (pos_y_bit);
end
if (pipeline_valid[0]) begin
for (i = 0; i < DATA_NUM; i = i + 1) data_cache[i] <= data_cache0[i];
case (RAW_TYPE)
2'b00: raw_type <= {pos_y_bit, pos_x[0]};
2'b01: raw_type <= {pos_y_bit, ~pos_x[0]};
2'b10: raw_type <= {~pos_y_bit, pos_x[0]};
2'b11: raw_type <= {~pos_y_bit, ~pos_x[0]};
endcase
end
if (pipeline_valid[1]) begin
case (raw_type)
1, 2: begin
channel_cache[0] <= data_cache[00];
channel_cache[1] <= data_cache[10];
channel_cache[2] <= data_cache[20];
channel_cache[3] <= data_cache[02];
channel_cache[4] <= data_cache[12];
channel_cache[5] <= data_cache[22];
channel_cache[6] <= data_cache[04];
channel_cache[7] <= data_cache[14];
channel_cache[8] <= data_cache[24];
end
0, 3: begin
channel_cache[0] <= data_cache[02];
channel_cache[1] <= data_cache[06];
channel_cache[2] <= data_cache[10];
channel_cache[3] <= data_cache[08];
channel_cache[4] <= data_cache[12];
channel_cache[5] <= data_cache[16];
channel_cache[6] <= data_cache[14];
channel_cache[7] <= data_cache[18];
channel_cache[8] <= data_cache[22];
end
endcase
end
if (pipeline_valid[2]) begin //计算梯度,同时开始校正后数据的部分计算
channel_cache0 <= channel_cache[4];
grad_h_cache[0] <= channel_cache[0] + channel_cache[2] - 2 * channel_cache[1];
grad_h_cache[1] <= channel_cache[3] + channel_cache[5] - 2 * channel_cache[4];
grad_h_cache[2] <= channel_cache[6] + channel_cache[8] - 2 * channel_cache[7];
grad_v_cache[0] <= channel_cache[0] + channel_cache[6] - 2 * channel_cache[3];
grad_v_cache[1] <= channel_cache[1] + channel_cache[7] - 2 * channel_cache[4];
grad_v_cache[2] <= channel_cache[2] + channel_cache[8] - 2 * channel_cache[5];
grad_45_cache[0] <= 2 * (channel_cache[1] - channel_cache[3]);
grad_45_cache[1] <= channel_cache[6] + channel_cache[2] - 2 * channel_cache[4];
grad_45_cache[2] <= 2 * (channel_cache[7] - channel_cache[5]);
grad_135_cache[0] <= 2 * (channel_cache[1] - channel_cache[5]);
grad_135_cache[1] <= channel_cache[0] + channel_cache[8] - 2 * channel_cache[4];
grad_135_cache[2] <= 2 * (channel_cache[3] - channel_cache[7]);
channel_cache_correct[0] <= channel_cache[3] / 2 + channel_cache[5] / 2;
channel_cache_correct[1] <= channel_cache[1] / 2 + channel_cache[7] / 2;
channel_cache_correct[2] <= channel_cache[2] / 2 + channel_cache[6] / 2;
channel_cache_correct[3] <= channel_cache[0] / 2 + channel_cache[8] / 2;
end
if(pipeline_valid[3]) begin //计算绝对值,同时完成校正后数据的计算,注意grad_h_cache等是singed可能为负数
channel_cache1 <= channel_cache0;
grad_h_cache0 [0] <= grad_h_cache [0][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_h_cache [0] + 1) : (grad_h_cache [0]);
grad_h_cache0 [1] <= grad_h_cache [1][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_h_cache [1] + 1) : (grad_h_cache [1]);
grad_h_cache0 [2] <= grad_h_cache [2][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_h_cache [2] + 1) : (grad_h_cache [2]);
grad_v_cache0 [0] <= grad_v_cache [0][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_v_cache [0] + 1) : (grad_v_cache [0]);
grad_v_cache0 [1] <= grad_v_cache [1][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_v_cache [1] + 1) : (grad_v_cache [1]);
grad_v_cache0 [2] <= grad_v_cache [2][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_v_cache [2] + 1) : (grad_v_cache [2]);
grad_45_cache0 [0] <= grad_45_cache [0][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_45_cache [0] + 1) : (grad_45_cache [0]);
grad_45_cache0 [1] <= grad_45_cache [1][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_45_cache [1] + 1) : (grad_45_cache [1]);
grad_45_cache0 [2] <= grad_45_cache [2][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_45_cache [2] + 1) : (grad_45_cache [2]);
grad_135_cache0[0] <= grad_135_cache[0][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_135_cache[0] + 1) : (grad_135_cache[0]);
grad_135_cache0[1] <= grad_135_cache[1][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_135_cache[1] + 1) : (grad_135_cache[1]);
grad_135_cache0[2] <= grad_135_cache[2][DATA_WIDTH-1+EXPAND_BITS] ? (~grad_135_cache[2] + 1) : (grad_135_cache[2]);
channel_cache_correct0[0] <= channel_cache_correct[0] + grad_h_cache[0]/4 + grad_h_cache[2]/4;
channel_cache_correct0[1] <= channel_cache_correct[1] + grad_v_cache[0]/4 + grad_v_cache[2]/4;
channel_cache_correct0[2] <= channel_cache_correct[2] + grad_45_cache[0]/4 + grad_45_cache[2]/4;
channel_cache_correct0[3] <= channel_cache_correct[3] + grad_135_cache[0]/4 + grad_135_cache[2]/4;
end
if (pipeline_valid[4]) begin //计算中位数
channel_cache2 <= channel_cache1;
for (i = 0; i < 4; i = i + 1) channel_cache_correct1[i] <= channel_cache_correct0[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_h_cache1[i] <= grad_h_cache0[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_v_cache1[i] <= grad_v_cache0[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_45_cache1[i] <= grad_45_cache0[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_135_cache1[i] <= grad_135_cache0[i];
grad_median_cache[0] <= MEDIAN(grad_h_cache0);
grad_median_cache[1] <= MEDIAN(grad_v_cache0);
grad_median_cache[2] <= MEDIAN(grad_45_cache0);
grad_median_cache[3] <= MEDIAN(grad_135_cache0);
end
if (pipeline_valid[5]) begin //计算最小值,判断最小梯度方向
channel_cache3 <= channel_cache2;
for (i = 0; i < 4; i = i + 1) channel_cache_correct2[i] <= channel_cache_correct1[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_h_cache2[i] <= grad_h_cache1[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_v_cache2[i] <= grad_v_cache1[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_45_cache2[i] <= grad_45_cache1[i];
for (i = 0; i < 3 + EXPAND_BITS; i = i + 1) grad_135_cache2[i] <= grad_135_cache1[i];
flag_which_dict <= MIN(grad_median_cache);
end
if (pipeline_valid[6]) begin //在最小梯度方向上判断中心点是否是坏点
channel_cache4 <= channel_cache3;
channel_cache_correct_final <= channel_cache_correct2[flag_which_dict];
case (flag_which_dict)
2'b00:
flag_if_need_corection <= grad_h_cache2[1] > 4 * (grad_h_cache2[0] + grad_h_cache2[2]);
2'b01:
flag_if_need_corection <= grad_v_cache2[1] > 4 * (grad_v_cache2[0] + grad_v_cache2[2]);
2'b10:
flag_if_need_corection <= grad_45_cache2[1] > 3 * (grad_45_cache2[0] + grad_45_cache2[2]);
2'b11:
flag_if_need_corection <= grad_135_cache2[1] > 3*(grad_135_cache2[0] + grad_135_cache2[2]);
endcase
end
if(pipeline_valid[7]) begin //如果是坏点,输出计算后的值;如果不是坏点,输出原值
out_data <= (flag_if_need_corection) ? (channel_cache_correct_final) : (channel_cache4);
end
end
end
function [DATA_WIDTH-1+EXPAND_BITS:0] MEDIAN;
input [DATA_WIDTH-1+EXPAND_BITS:0] inx[3];
begin
if ((inx[0] >= inx[1] && inx[1] >= inx[2]) || (inx[2] >= inx[1] && inx[1] >= inx[0]))
MEDIAN = inx[1];
else if ((inx[1] >= inx[0]) || (inx[0] >= inx[1])) MEDIAN = inx[0];
else MEDIAN = inx[2];
end
endfunction
function [1:0] MIN;
input [DATA_WIDTH-1+EXPAND_BITS:0] inx[4];
begin
if (inx[0] >= inx[1] && inx[0] >= inx[2] && inx[0] >= inx[3]) MIN = 2'b00;
else if (inx[1] >= inx[0] && inx[1] >= inx[2] && inx[1] >= inx[3]) MIN = 2'b01;
else if (inx[2] >= inx[0] && inx[2] >= inx[1] && inx[2] >= inx[3]) MIN = 2'b10;
else MIN = 2'b11;
end
endfunction
/*
00 05 10 15 20
01 06 11 16 21 0 1 2
02 07 12 17 22 -> 3 4 5
03 08 13 18 23 6 7 8
04 09 14 19 24
rawtype==0: center is GREEN
g r g r g / / g / /
b g b g b / g / g /
g r g r g -> g / G / g
b g b g b / g / g /
g r g r g / / g / /
rawtype==1: center is RED
r g r g r r / r / r
g b g b g / / / / /
r g r g r -> r / R / r
g b g b g / / / / /
r g r g r r / r / r
rawtype==2: center is BLUE
b g b g b b / b / b
g r g r g / / / / /
b g b g b -> b / B / b
g r g r g / / / / /
b g b g b b / b / b
rawtype==3: center is GREEN
g b g b g / / g / /
r g r g r / g / g /
g b g b g -> g / G / g
r g r g r / g / g /
r g r g r / / g / /
*/
endmodule