ISP/Demosaic/demosaic2.v

188 lines
5.7 KiB
Verilog
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.

module demosaic2 #(
parameter reg [16:0] IM_WIDTH = 512, // 图像宽度
parameter reg [16:0] IM_HEIGHT = 256, // 图像高度
parameter reg [1:0] RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg
parameter reg [5:0] DATA_SIZE = 16
) (
// 基本信号
input clk,
input reset,
// 数据输入信号
input in_en,
input [DATA_SIZE - 1:0] in_data [2], // 数据输入线0、1、2分别表示第一、二、三行
output out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
output out_receive,
// en: 输出数据有效信号,高电平有效
input in_ready,
input in_receive,
output out_en,
output reg [DATA_SIZE - 1:0] out_r,
output reg [DATA_SIZE - 1:0] out_g,
output reg [DATA_SIZE - 1:0] out_b
);
// 常量,包括状态机
// localparam IM_SIZE = IM_HEIGHT * IM_WIDTH;
localparam READ_DATA = 0;
localparam COLOR_GEN = 1;
localparam SEND_DATA = 2;
localparam SLIDE_WINDOW = 3;
// 寄存器
reg [2:0] state, nextState;
reg [15:0] data_cache[2][2]; // 缓存颜色数据行列3x3
reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置
reg [2:0] cnt_data; // 记录输入数据数量最大值256
reg [1:0] raw_type;
reg [15:0] red, blue, green;
// 三段状态机实现,窗口滑动,颜色计算
// 状态切换
always @(posedge clk or posedge reset) begin
if (reset) state <= READ_DATA;
else state <= nextState;
end
// 下一状态更新
always @(state or cnt_data) begin
case (state)
// 记录够3x3个数据后进行rgb转换
READ_DATA: nextState = (cnt_data >= 3) ? COLOR_GEN : READ_DATA;
COLOR_GEN: nextState = SEND_DATA;
SEND_DATA: nextState = (in_receive) ? SLIDE_WINDOW : SEND_DATA;
SLIDE_WINDOW: nextState = READ_DATA;
default: nextState = 0;
endcase
end
// 请求数据
assign out_ready = (cnt_data <= 2 && !in_en && state == READ_DATA) ? 1 : 0;
// 收到数据
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
// 发送数据有效位
assign out_en = (in_ready && state == SEND_DATA) ? 1 : 0;
// 各状态执行的操作
always @(posedge clk or posedge reset) begin
if (reset) begin
// 外部输出初始化
out_en <= 0;
out_r <= 0;
out_g <= 0;
out_r <= 0;
// 内部寄存器初始化
pos_x <= 0;
pos_y <= 0;
cnt_data <= 0;
raw_type <= RAW_TYPE;
end else begin
// 状态机执行
case (state)
// 读取数据
READ_DATA: begin
if (in_en) begin
data_cache[cnt_data][0] <= in_data[0];
data_cache[cnt_data][1] <= in_data[1];
data_cache[cnt_data][2] <= in_data[2];
cnt_data <= cnt_data + 1;
end
end
COLOR_GEN: begin
// 生成rgb图像
// data case 0 case 1 case 2 case 3
// 0 1 2 G R G R G R B G B G B G
// 3 4 5 B G B G B G G R G R G R
// 6 7 8 G R G R G R B G B G B G
case (raw_type)
0: begin // Missing B, R on G
blue <= (data_cache[0][1] + data_cache[2][1]) / 2;
red <= (data_cache[1][0] + data_cache[1][2]) / 2;
green <= data_cache[1][1];
end
1: begin // Missing G, R on B
green <= (data_cache[0][1] + data_cache[1][0] + data_cache[1][2] + data_cache[2][1]) / 4;
red <= (data_cache[0][0] + data_cache[0][2] + data_cache[2][0] + data_cache[2][2]) / 4;
blue <= data_cache[1][1];
end
2: begin // Missing G, B on R
green <= (data_cache[0][1] + data_cache[1][0] + data_cache[1][2] + data_cache[2][1]) / 4;
blue <= (data_cache[0][0] + data_cache[0][2] + data_cache[2][0] + data_cache[2][2]) / 4;
red <= data_cache[1][1];
end
3: begin // Missing B, R on G
red <= (data_cache[0][1] + data_cache[2][1]) / 2;
blue <= (data_cache[1][0] + data_cache[1][2]) / 2;
green <= data_cache[1][1];
end
default: ;
endcase
case (raw_type)
0: raw_type <= 1;
1: raw_type <= 0;
2: raw_type <= 3;
3: raw_type <= 2;
endcase
end
SEND_DATA: begin
if (in_ready) begin
out_r <= red;
out_b <= blue;
out_g <= green;
end
end
SLIDE_WINDOW: begin
// 记录位置寄存器自增,并处理缓存数据
pos_x <= pos_x + 1;
if (pos_x >= IM_WIDTH - 2 - 1) begin
cnt_data <= 0;
pos_x <= 0;
pos_y <= pos_y + 1;
if (pos_y >= IM_HEIGHT - 2 - 1) begin
pos_y <= 0;
end
// 换行后切换Bayer格式
if (pos_y % 2 == 1) begin
raw_type <= RAW_TYPE;
end else begin
case (RAW_TYPE)
0: raw_type <= 2;
1: raw_type <= 3;
2: raw_type <= 0;
3: raw_type <= 1;
default: ;
endcase
end
end else begin
cnt_data <= 2;
// 窗口右移
data_cache[0][0] <= data_cache[1][0];
data_cache[0][1] <= data_cache[1][1];
data_cache[0][2] <= data_cache[1][2];
data_cache[1][0] <= data_cache[2][0];
data_cache[1][1] <= data_cache[2][1];
data_cache[1][2] <= data_cache[2][2];
end
end
default: ;
endcase
end
end
endmodule