ISP/rtl/BayerProcess/Demosaic_Pipeline.sv

122 lines
4.6 KiB
Systemverilog
Raw Normal View History

2024-10-22 20:31:51 +08:00
`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
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, green, blue};
2024-10-22 20:31:51 +08:00
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<->21<->3。
// bgb gbg grg rgr 147
// grg rgr bgb gbg 258
endmodule