ISP/rtl/BayerProcess/Demosaic2.sv

230 lines
6.1 KiB
Systemverilog
Raw Permalink Normal View History

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