diff --git a/CFA/demosaic2.v b/CFA/demosaic2.v new file mode 100644 index 0000000..ea97337 --- /dev/null +++ b/CFA/demosaic2.v @@ -0,0 +1,164 @@ +module demosaic2 #( + parameter IM_WIDTH = 512, // 图像宽度 + parameter IM_HEIGHT = 256, // 图像高度 + parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg +)( + // 基本信号 + input clk, + input reset, + + // 数据输入信号 + input data_en, + input [15:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 + output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 + output reg data_line, // 新一行请求数据线,高电平:请求九个数据,直到读取完才拉低 + + // en: 输出数据有效信号,高电平有效 + output reg out_en, + output reg [15:0] out_r, + output reg [15:0] out_g, + output reg [15:0] out_b +); + + // 常量,包括状态机 + localparam IM_SIZE = IM_HEIGHT * IM_WIDTH; + 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 + + // 下一状态更新 + always @(*) begin + 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; + data_line <= 1; + + // 内部寄存器初始化 + pos_x <= 0; + pos_y <= 0; + cnt_data <= 0; + raw_type <= RAW_TYPE; + end + else begin + // 状态机执行 + case (state) + // 读取数据 + READ_DATA: begin + data_que <= 1; + if (cnt_data < 2) + data_line <= 1; + + 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]; + cnt_data <= cnt_data + 1; + end + end + + COLOR_GEN: begin + // 取消数据请求 + data_que <= 0; + data_line <= 0; + + // 生成rgb图像 + case (raw_type) + 0: 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 + + 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 + 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 + endcase + raw_type <= raw_type + 1; + 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; + if (pos_x >= IM_WIDTH - 2) begin + cnt_data <= 0; + pos_x <= 0; + pos_y <= pos_y + 1; + // if (pos_y >= IM_HEIGHT - 2) + // pos_y <= 0; + end + else begin + cnt_data <= 2; + + // 窗口右移 + data_cache[0][0] = data_cache[0][1]; + data_cache[1][0] = data_cache[1][1]; + data_cache[2][0] = data_cache[2][1]; + data_cache[0][1] = data_cache[0][2]; + data_cache[1][1] = data_cache[1][2]; + data_cache[2][1] = data_cache[2][2]; + end + end + endcase + end + end + +endmodule + diff --git a/isp.v b/isp.v index c2424c9..4131330 100644 --- a/isp.v +++ b/isp.v @@ -1,14 +1,40 @@ `timescale 1ns/1ps module isp #( - parameter IN_WIDTH = 1936; - parameter IN_HEIGHT = 1088; - parameter OUT_WIDTH = 1920; - parameter OUT_HEIGHT = 1080; + parameter IN_WIDTH = 1936, + parameter IN_HEIGHT = 1088, + parameter OUT_WIDTH = 1936 - 2, + parameter OUT_HEIGHT = 1088 - 2, + parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg ) ( - input clk; - input reset; + // 基本信号 + input clk, + input reset, + // 数据输入信号 + input data_en, + input [15:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 + output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 + output reg data_line, // 新一行请求数据线,高电平:请求九个数据,直到读取完才拉低 + + // en: 输出数据有效信号,高电平有效 + output reg out_en, + output reg [15:0] out_r, + output reg [15:0] out_g, + output reg [15:0] out_b ); + + demosaic2 #(IN_WIDTH, IN_HEIGHT, RAW_TYPE) CFA ( + .clk(clk), + .reset(reset), + .data_en(data_en), + .data_in(data_in), + .data_que(data_que), + .data_line(data_line), + .out_en(out_en), + .out_r(out_r), + .out_g(out_g), + .out_b(out_b) + ); endmodule \ No newline at end of file