`timescale 1ns / 1ps module Demosaic_Pipeline #( parameter WINDOW_LENGTH = 3, 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 [WINDOW_LENGTH*WINDOW_LENGTH], // 数据输入线.第一列数据在[0],[1],[2]中 output reg [DATA_WIDTH - 1:0] out_data[3], // 数据输出线,3、2、1分别表示r、g、b input wire in_valid, output wire out_valid, input wire in_ready, output wire out_ready, output reg out_hsync, // 行同步,一行第一个像素点输出的同时高电平 output reg out_fsync // 帧同步,一帧第一个像素点输出的同时高电平 ); localparam DATA_NUM = WINDOW_LENGTH * WINDOW_LENGTH; localparam PIPILINE = 4; 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 [31:0] pos_x, pos_y, temp_pos_x1, temp_pos_y1, temp_pos_x2, temp_pos_y2; reg [DATA_WIDTH-1:0] red, blue, green; 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; pipeline_valid <= 0; {red, green, blue} <= 0; {out_data[2], out_data[1], out_data[0]} <= 0; {out_hsync, out_fsync} <= 0; pos_x <= ~0; pos_y <= ~0; temp_pos_x1 <= ~0; temp_pos_y1 <= ~0; temp_pos_x2 <= ~0; temp_pos_y2 <= ~0; raw_type <= RAW_TYPE; end else if (pipeline_running) begin // First level pipeline for reading data 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 <= (pos_x >= TOTAL_WIDTH - 1)?((pos_y >= TOTAL_HEIGHT - 1)?(0):(pos_y + 1)):(pos_y); end if (pipeline_valid[0]) begin for (i = 0; i < DATA_NUM; i = i + 1) data_cache[i] <= data_cache0[i]; temp_pos_x1 <= pos_x; temp_pos_y1 <= pos_y; case (RAW_TYPE) 2'b00: raw_type <= {pos_y[0], pos_x[0]}; 2'b01: raw_type <= {pos_y[0], ~pos_x[0]}; 2'b10: raw_type <= {~pos_y[0], pos_x[0]}; 2'b11: raw_type <= {~pos_y[0], ~pos_x[0]}; endcase end if (pipeline_valid[1]) begin temp_pos_x2 <= temp_pos_x1; temp_pos_y2 <= temp_pos_y1; case (raw_type) 0: begin // Missing B, R on G blue <= (data_cache[1] >> 1) + (data_cache[7] >> 1); red <= (data_cache[3] >> 1) + (data_cache[5] >> 1); green <= data_cache[4]; end 1: begin // Missing G, R on B green <= (data_cache[1] >> 2) + (data_cache[3] >> 2) + (data_cache[5] >> 2) + (data_cache[7] >> 2); red <= (data_cache[0] >> 2) + (data_cache[2] >> 2) + (data_cache[6] >> 2) + (data_cache[8] >> 2); blue <= data_cache[4]; end 2: begin // Missing G, B on R green <= (data_cache[1] >> 2) + (data_cache[3] >> 2) + (data_cache[5] >> 2) + (data_cache[7] >> 2); blue <= (data_cache[0] >> 2) + (data_cache[2] >> 2) + (data_cache[6] >> 2) + (data_cache[8] >> 2); red <= data_cache[4]; end 3: begin // Missing B, R on G red <= (data_cache[1] >> 1) + (data_cache[7] >> 1); blue <= (data_cache[3] >> 1) + (data_cache[5] >> 1); green <= data_cache[4]; end endcase end if (pipeline_valid[2]) begin {out_data[2], out_data[1], out_data[0]} <= {red, blue, green}; out_hsync <= (temp_pos_x2 == 0); out_fsync <= ((temp_pos_x2 == 0) && (temp_pos_y2 == 0)); end end end // 0:grg 1:rgr 2:bgb 3:gbg 036 窗口右移,0<->1 2<->3; 窗口下移,0<->2,1<->3。 // bgb gbg grg rgr 147 // grg rgr bgb gbg 258 endmodule