ISP/Demosaic/demosaic2.v

182 lines
6.5 KiB
Coq
Raw Normal View History

2024-05-10 20:13:58 +08:00
module demosaic2 #(
parameter IM_WIDTH = 512, // 图像宽度
parameter IM_HEIGHT = 256, // 图像高度
2024-05-13 11:29:03 +08:00
parameter RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg
parameter DATA_SIZE = 16
2024-05-10 20:13:58 +08:00
)(
// 基本信号
input clk,
input reset,
// 数据输入信号
input data_en,
2024-05-11 21:53:35 +08:00
input [DATA_SIZE - 1:0] data_in [2:0], // 数据输入线012分别表示第一三行
2024-05-10 20:13:58 +08:00
output reg data_que, // 数据请求线高电平请求三个数据直到读取完才拉低
// en: 输出数据有效信号高电平有效
output reg out_en,
2024-05-11 21:53:35 +08:00
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-05-10 20:13:58 +08:00
);
// 常量包括状态机
2024-05-10 21:41:47 +08:00
// localparam IM_SIZE = IM_HEIGHT * IM_WIDTH;
2024-05-10 20:13:58 +08:00
localparam READ_DATA = 0;
localparam COLOR_GEN = 1;
localparam WRITE_DATA = 2;
localparam SLIDE_WINDOW = 3;
// 寄存器
reg [2:0] state, nextState;
reg [15:0] data_cache [2:0][2:0]; // 缓存颜色数据行列3x3
reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置
reg [1: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
// 下一状态更新
2024-05-14 21:00:19 +08:00
always @(state or cnt_data) begin
2024-05-10 20:13:58 +08:00
case (state)
// 记录够3x3个数据后进行rgb转换
READ_DATA: nextState = (cnt_data >= 3) ? COLOR_GEN : READ_DATA;
COLOR_GEN: nextState = WRITE_DATA;
WRITE_DATA: nextState = SLIDE_WINDOW;
SLIDE_WINDOW: nextState = READ_DATA;
endcase
end
// 各状态执行的操作
always @(posedge clk or posedge reset) begin
if (reset) begin
// 外部输出初始化
out_en <= 0;
out_r <= 0;
out_g <= 0;
out_r <= 0;
data_que <= 0;
// 内部寄存器初始化
pos_x <= 0;
pos_y <= 0;
cnt_data <= 0;
raw_type <= RAW_TYPE;
end
else begin
// 状态机执行
case (state)
// 读取数据
READ_DATA: begin
2024-05-14 21:00:19 +08:00
// 请求数据
if (cnt_data <= 2) begin
data_que <= 1;
end
2024-05-10 20:13:58 +08:00
if (data_en) begin
data_cache[cnt_data][0] <= data_in[0];
data_cache[cnt_data][1] <= data_in[1];
data_cache[cnt_data][2] <= data_in[2];
2024-05-14 21:00:19 +08:00
2024-05-10 20:13:58 +08:00
cnt_data <= cnt_data + 1;
2024-05-14 21:00:19 +08:00
data_que <= 0;
2024-05-10 20:13:58 +08:00
end
end
COLOR_GEN: begin
// 生成rgb图像
2024-05-14 21:00:19 +08:00
// 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
2024-05-10 20:13:58 +08:00
case (raw_type)
0: begin // Missing B, R on G
2024-05-14 21:00:19 +08:00
blue <= (data_cache[0][1] + data_cache[2][1]) / 2;
red <= (data_cache[1][0] + data_cache[1][2]) / 2;
2024-05-10 20:13:58 +08:00
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
2024-05-14 21:00:19 +08:00
red <= (data_cache[0][1] + data_cache[2][1]) / 2;
blue <= (data_cache[1][0] + data_cache[1][2]) / 2;
2024-05-10 20:13:58 +08:00
green <= data_cache[1][1];
end
endcase
2024-05-14 21:00:19 +08:00
case (raw_type)
0: raw_type <= 1;
1: raw_type <= 0;
2: raw_type <= 3;
3: raw_type <= 2;
endcase
2024-05-10 20:13:58 +08:00
end
WRITE_DATA: begin
out_en <= 1;
out_r <= red;
out_b <= blue;
out_g <= green;
end
SLIDE_WINDOW: begin
// 恢复相关寄存器变量
out_en <= 0;
// 记录位置寄存器自增并处理缓存数据
pos_x <= pos_x + 1;
2024-05-14 21:00:19 +08:00
if (pos_x >= IM_WIDTH - 2 - 1) begin
2024-05-10 20:13:58 +08:00
cnt_data <= 0;
pos_x <= 0;
pos_y <= pos_y + 1;
2024-05-17 16:47:28 +08:00
if (pos_y >= IM_HEIGHT - 2 - 1) begin
2024-05-10 21:41:47 +08:00
pos_y <= 0;
2024-05-17 16:47:28 +08:00
end
2024-05-18 18:56:32 +08:00
// 换行后切换Bayer格式
case (RAW_TYPE)
0: raw_type <= 2;
1: raw_type <= 3;
2: raw_type <= 0;
3: raw_type <= 1;
endcase
2024-05-10 20:13:58 +08:00
end
else begin
cnt_data <= 2;
// 窗口右移
2024-05-14 21:00:19 +08:00
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];
2024-05-10 20:13:58 +08:00
end
end
endcase
end
end
endmodule