finish reconstruction and pass simulation
This commit is contained in:
parent
85910958f9
commit
c527835ff6
|
@ -4,34 +4,35 @@
|
|||
module ColorBlender #(
|
||||
parameter reg [ 4:0] IN_DEPTH = 12, // 输入图像的色深
|
||||
parameter reg [ 4:0] OUT_DEPTH = 8, // 输出图像的色深
|
||||
parameter reg [16:0] GAIN_RED = 120, // 红色增益系数
|
||||
parameter reg [16:0] GAIN_GREEN = 50, // 绿色增益系数
|
||||
parameter reg [16:0] GAIN_BLUE = 95, // 蓝色增益系数
|
||||
parameter reg [ 4:0] GAIN_OFFSET = 7
|
||||
parameter reg [ 8:0] BUFF_SIZE = 32
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
input in_en,
|
||||
input [15:0] data_in[2], // 0:R 1:G 2:B
|
||||
output out_ready,
|
||||
output out_receive,
|
||||
input wire in_en,
|
||||
input wire [15:0] in_data[3], // 0:R 1:G 2:B
|
||||
output wire out_ready,
|
||||
output wire out_receive,
|
||||
|
||||
// 输出相关
|
||||
input in_ready,
|
||||
input in_receive,
|
||||
output out_en,
|
||||
output [3 * OUT_DEPTH - 1:0] out_data,
|
||||
input wire in_ready,
|
||||
input wire in_receive,
|
||||
output reg out_en,
|
||||
output reg [3 * OUT_DEPTH - 1:0] out_data,
|
||||
|
||||
// 颜色校正
|
||||
input wire [15:0] gain_red,
|
||||
input wire [15:0] gain_green,
|
||||
input wire [15:0] gain_blue,
|
||||
input wire color_correction
|
||||
);
|
||||
localparam READ_DATA = 0;
|
||||
localparam CALC_DATA = 1;
|
||||
localparam SEND_DATA = 2;
|
||||
localparam reg [2:0] READ_DATA = 0;
|
||||
localparam reg [2:0] CALC_DATA = 1;
|
||||
localparam reg [2:0] SATI_DATA = 2;
|
||||
localparam reg [2:0] SEND_DATA = 3;
|
||||
|
||||
reg [2:0] state, nextState;
|
||||
reg [31:0] data_cal[2]; // 用于保存运算结果,防止溢出
|
||||
reg [BUFF_SIZE - 1:0] data_cal[3]; // 用于保存运算结果,防止溢出
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset) begin
|
||||
|
@ -44,15 +45,15 @@ module ColorBlender #(
|
|||
always @(*) begin
|
||||
case (state)
|
||||
READ_DATA: nextState = (in_en) ? (color_correction ? CALC_DATA : SEND_DATA) : READ_DATA;
|
||||
CALC_DATA: nextState = SEND_DATA;
|
||||
CALC_DATA: nextState = SATI_DATA;
|
||||
SATI_DATA: nextState = SEND_DATA;
|
||||
SEND_DATA: nextState = (in_receive) ? READ_DATA : SEND_DATA;
|
||||
default: nextState = READ_DATA;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign out_ready = (state == READ_DATA) ? 1 : 0;
|
||||
assign out_receive = in_en ? 1 : 0;
|
||||
assign out_en = (in_ready && state == SEND_DATA) ? 1 : 0;
|
||||
assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0;
|
||||
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset) begin
|
||||
|
@ -60,28 +61,38 @@ module ColorBlender #(
|
|||
data_cal[0] <= 0;
|
||||
data_cal[1] <= 0;
|
||||
data_cal[2] <= 0;
|
||||
|
||||
out_data <= 0;
|
||||
out_en <= 0;
|
||||
end else begin
|
||||
case (state)
|
||||
READ_DATA: begin
|
||||
if (in_en) begin
|
||||
data_cal[0] <= ({16'b0, data_in[0]} << 8;
|
||||
data_cal[1] <= ({16'b0, data_in[1]} << 8;
|
||||
data_cal[2] <= ({16'b0, data_in[2]} << 8;
|
||||
data_cal[0] <= ({{(BUFF_SIZE - 16){1'b0}}, in_data[0]}) << (8 - (IN_DEPTH - OUT_DEPTH));
|
||||
data_cal[1] <= ({{(BUFF_SIZE - 16){1'b0}}, in_data[1]}) << (8 - (IN_DEPTH - OUT_DEPTH));
|
||||
data_cal[2] <= ({{(BUFF_SIZE - 16){1'b0}}, in_data[2]}) << (8 - (IN_DEPTH - OUT_DEPTH));
|
||||
end
|
||||
end
|
||||
|
||||
CALC_DATA: begin
|
||||
data_cal[0] <= data_cal[0] * (GAIN_RED << 8)
|
||||
data_cal[1] <= data_cal[1] * (GAIN_GREEN << 8)
|
||||
data_cal[2] <= data_cal[2] * (GAIN_BLUE << 8)
|
||||
data_cal[0] <= (data_cal[0] * {{(BUFF_SIZE - 16){1'b0}}, gain_red}) >> 16;
|
||||
data_cal[1] <= (data_cal[1] * {{(BUFF_SIZE - 16){1'b0}}, gain_green}) >> 16;
|
||||
data_cal[2] <= (data_cal[2] * {{(BUFF_SIZE - 16){1'b0}}, gain_blue}) >> 16;
|
||||
end
|
||||
|
||||
SATI_DATA: begin
|
||||
data_cal[0] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[0];
|
||||
data_cal[1] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[1];
|
||||
data_cal[2] <= |data_cal[0][BUFF_SIZE -1 :OUT_DEPTH] ? {BUFF_SIZE{1'b1}} : data_cal[2];
|
||||
end
|
||||
|
||||
SEND_DATA: begin
|
||||
if (in_ready) begin
|
||||
out_data[0] <= data_cal[0] >> (8 + IN_DEPTH - OUT_DEPTH)
|
||||
out_data[1] <= data_cal[1] >> (8 + IN_DEPTH - OUT_DEPTH)
|
||||
out_data[2] <= data_cal[2] >> (8 + IN_DEPTH - OUT_DEPTH)
|
||||
end
|
||||
if (in_ready && !in_receive) begin
|
||||
out_en <= 1;
|
||||
out_data <= {
|
||||
data_cal[0][OUT_DEPTH-1:0], data_cal[1][OUT_DEPTH-1:0], data_cal[2][OUT_DEPTH-1:0]
|
||||
};
|
||||
end else out_en <= 0;
|
||||
end
|
||||
|
||||
default: ;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
module Crop #(
|
||||
parameter reg [15:0] IN_WIDTH = 1934,
|
||||
parameter reg [15:0] IN_HEIGHT = 1086,
|
||||
parameter reg [15:0] OFFSET_X = 8,
|
||||
parameter reg [15:0] OFFSET_Y = 4,
|
||||
parameter reg [15:0] OUT_WIDTH = 640,
|
||||
parameter reg [15:0] OUT_HEIGHT = 480,
|
||||
parameter reg [4:0] COLOR_DEPTH = 8
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
input wire in_en,
|
||||
output wire out_ready,
|
||||
output wire out_receive,
|
||||
input wire [3 * COLOR_DEPTH - 1:0] in_data,
|
||||
|
||||
input wire in_ready,
|
||||
input wire in_receive,
|
||||
output reg out_en,
|
||||
output reg [3 * COLOR_DEPTH - 1:0] out_data
|
||||
);
|
||||
reg [1:0] state, nextState;
|
||||
localparam reg [1:0] READ_DATA = 0;
|
||||
localparam reg [1:0] HANDLE_DATA = 1;
|
||||
localparam reg [1:0] SEND_DATA = 2;
|
||||
|
||||
reg [15:0] cnt_x, cnt_y;
|
||||
reg [3 * COLOR_DEPTH - 1:0] data;
|
||||
wire is_valid;
|
||||
|
||||
// 状态切换
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset) state <= READ_DATA;
|
||||
else state <= nextState;
|
||||
end
|
||||
|
||||
// 下一状态更新
|
||||
always @(*) begin
|
||||
case (state)
|
||||
READ_DATA: nextState = in_en ? HANDLE_DATA : READ_DATA;
|
||||
HANDLE_DATA: nextState = SEND_DATA;
|
||||
SEND_DATA: nextState = (is_valid && !in_receive) ? SEND_DATA : READ_DATA;
|
||||
default: nextState = READ_DATA;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0;
|
||||
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||
assign is_valid = ((OFFSET_Y <= cnt_y && cnt_y <= (OFFSET_Y + OUT_HEIGHT - 1)) &&
|
||||
(OFFSET_X <= cnt_x && cnt_x <= (OFFSET_X + OUT_WIDTH))) ? 1 : 0;
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset) begin
|
||||
cnt_x <= 0;
|
||||
cnt_y <= 0;
|
||||
data <= 0;
|
||||
|
||||
out_en <= 0;
|
||||
out_data <= 0;
|
||||
end else begin
|
||||
case (state)
|
||||
READ_DATA: begin
|
||||
if (in_en) begin
|
||||
data <= in_data;
|
||||
end
|
||||
end
|
||||
|
||||
HANDLE_DATA: begin
|
||||
if (cnt_x >= IN_WIDTH - 1) begin
|
||||
cnt_x <= 0;
|
||||
cnt_y <= cnt_y + 1;
|
||||
end else begin
|
||||
cnt_x <= cnt_x + 1;
|
||||
end
|
||||
|
||||
if (cnt_y >= IN_HEIGHT - 1) begin
|
||||
cnt_y <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SEND_DATA: begin
|
||||
if (in_ready && !in_receive && is_valid) begin
|
||||
out_en <= 1;
|
||||
out_data <= data;
|
||||
end else out_en <= 0;
|
||||
end
|
||||
|
||||
default: ;
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
91
Crop/crop.v
91
Crop/crop.v
|
@ -1,91 +0,0 @@
|
|||
module crop #(
|
||||
parameter IN_WIDTH = 1934,
|
||||
parameter IN_HEIGHT = 1086,
|
||||
parameter OFFSET_X = 8,
|
||||
parameter OFFSET_Y = 4,
|
||||
parameter OUT_WIDTH = 640,
|
||||
parameter OUT_HEIGHT = 480,
|
||||
parameter COLOR_DEPTH = 8
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input in_en,
|
||||
output reg in_que,
|
||||
input [3 * COLOR_DEPTH - 1:0] data_in,
|
||||
|
||||
output reg out_en,
|
||||
output reg [3 * COLOR_DEPTH - 1:0] data_out
|
||||
);
|
||||
localparam READ_DATA = 0;
|
||||
localparam HANDLE_DATA = 1;
|
||||
localparam SEND_DATA = 2;
|
||||
|
||||
reg [1:0] state, nextState;
|
||||
reg [31:0] cnt_x, cnt_y;
|
||||
reg [3 * COLOR_DEPTH - 1:0] data;
|
||||
|
||||
// 状态切换
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset)
|
||||
state <= READ_DATA;
|
||||
else
|
||||
state <= nextState;
|
||||
end
|
||||
|
||||
// 下一状态更新
|
||||
always @(*) begin
|
||||
case (state)
|
||||
READ_DATA: nextState = (in_que && in_en) ? HANDLE_DATA : READ_DATA;
|
||||
HANDLE_DATA: nextState = SEND_DATA;
|
||||
SEND_DATA: nextState = READ_DATA;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset) begin
|
||||
cnt_x <= 0;
|
||||
cnt_y <= 0;
|
||||
data <= 0;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
READ_DATA: begin
|
||||
in_que <= 1;
|
||||
|
||||
if (in_en) begin
|
||||
data <= data_in;
|
||||
in_que <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
HANDLE_DATA: begin
|
||||
if (OFFSET_Y <= cnt_y && cnt_y <= (OFFSET_Y + OUT_HEIGHT - 1)) begin
|
||||
if (OFFSET_X <= cnt_x && cnt_x <= (OFFSET_X + OUT_WIDTH)) begin
|
||||
out_en <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
if (cnt_x >= IN_WIDTH - 1) begin
|
||||
cnt_x <= 0;
|
||||
cnt_y <= cnt_y + 1;
|
||||
end
|
||||
else begin
|
||||
cnt_x <= cnt_x + 1;
|
||||
end
|
||||
|
||||
if (cnt_y >= IN_HEIGHT - 1) begin
|
||||
cnt_y <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SEND_DATA: begin
|
||||
data_out <= data;
|
||||
out_en <= 0;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,23 +1,23 @@
|
|||
module demosaic2 #(
|
||||
parameter reg [16:0] IM_WIDTH = 512, // 图像宽度
|
||||
parameter reg [16:0] IM_HEIGHT = 256, // 图像高度
|
||||
parameter reg [1:0] RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg
|
||||
parameter reg [5:0] DATA_SIZE = 16
|
||||
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
|
||||
) (
|
||||
// 基本信号
|
||||
input clk,
|
||||
input reset,
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// 数据输入信号
|
||||
input in_en,
|
||||
input [DATA_SIZE - 1:0] in_data [2], // 数据输入线,0、1、2分别表示第一、二、三行
|
||||
output out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
|
||||
output out_receive,
|
||||
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 in_ready,
|
||||
input in_receive,
|
||||
output out_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
|
||||
|
@ -26,15 +26,15 @@ module demosaic2 #(
|
|||
|
||||
// 常量,包括状态机
|
||||
// localparam IM_SIZE = IM_HEIGHT * IM_WIDTH;
|
||||
localparam READ_DATA = 0;
|
||||
localparam COLOR_GEN = 1;
|
||||
localparam SEND_DATA = 2;
|
||||
localparam SLIDE_WINDOW = 3;
|
||||
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[2][2]; // 缓存颜色数据,行列3x3
|
||||
reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置
|
||||
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;
|
||||
|
@ -47,14 +47,14 @@ module demosaic2 #(
|
|||
end
|
||||
|
||||
// 下一状态更新
|
||||
always @(state or cnt_data) begin
|
||||
always @(*) begin
|
||||
case (state)
|
||||
// 记录够3x3个数据后,进行rgb转换
|
||||
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 = 0;
|
||||
default: nextState = READ_DATA;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -62,8 +62,6 @@ module demosaic2 #(
|
|||
assign out_ready = (cnt_data <= 2 && !in_en && state == READ_DATA) ? 1 : 0;
|
||||
// 收到数据
|
||||
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||
// 发送数据有效位
|
||||
assign out_en = (in_ready && state == SEND_DATA) ? 1 : 0;
|
||||
|
||||
// 各状态执行的操作
|
||||
always @(posedge clk or posedge reset) begin
|
||||
|
@ -85,9 +83,9 @@ module demosaic2 #(
|
|||
// 读取数据
|
||||
READ_DATA: begin
|
||||
if (in_en) begin
|
||||
data_cache[cnt_data][0] <= in_data[0];
|
||||
data_cache[cnt_data][1] <= in_data[1];
|
||||
data_cache[cnt_data][2] <= in_data[2];
|
||||
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
|
||||
|
@ -96,33 +94,33 @@ module demosaic2 #(
|
|||
COLOR_GEN: begin
|
||||
// 生成rgb图像
|
||||
// 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
|
||||
// 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)
|
||||
0: 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];
|
||||
blue <= (data_cache[1] + data_cache[7]) / 2;
|
||||
red <= (data_cache[3] + data_cache[5]) / 2;
|
||||
green <= data_cache[4];
|
||||
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];
|
||||
green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) / 4;
|
||||
red <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) / 4;
|
||||
blue <= data_cache[4];
|
||||
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];
|
||||
green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) / 4;
|
||||
blue <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) / 4;
|
||||
red <= data_cache[4];
|
||||
end
|
||||
|
||||
|
||||
3: 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];
|
||||
red <= (data_cache[1] + data_cache[7]) / 2;
|
||||
blue <= (data_cache[3] + data_cache[5]) / 2;
|
||||
green <= data_cache[4];
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
|
@ -136,11 +134,12 @@ module demosaic2 #(
|
|||
end
|
||||
|
||||
SEND_DATA: begin
|
||||
if (in_ready) begin
|
||||
if (in_ready && !in_receive) begin
|
||||
out_en <= 1;
|
||||
out_r <= red;
|
||||
out_b <= blue;
|
||||
out_g <= green;
|
||||
end
|
||||
end else out_en <= 0;
|
||||
end
|
||||
|
||||
SLIDE_WINDOW: begin
|
||||
|
@ -169,12 +168,12 @@ module demosaic2 #(
|
|||
cnt_data <= 2;
|
||||
|
||||
// 窗口右移
|
||||
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];
|
||||
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
|
||||
|
80
isp.v
80
isp.v
|
@ -1,30 +1,37 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module isp #(
|
||||
parameter IN_WIDTH = 1936,
|
||||
parameter IN_HEIGHT = 1088,
|
||||
parameter OUT_WIDTH = 1920,
|
||||
parameter OUT_HEIGHT = 1080,
|
||||
parameter COLOR_DEPTH = 8,
|
||||
parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg
|
||||
parameter reg [15:0] IN_WIDTH = 1936,
|
||||
parameter reg [15:0] IN_HEIGHT = 1088,
|
||||
parameter reg [15:0] OUT_WIDTH = 1920,
|
||||
parameter reg [15:0] OUT_HEIGHT = 1080,
|
||||
parameter reg [ 4:0] COLOR_DEPTH = 8,
|
||||
parameter reg [ 1:0] RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg
|
||||
) (
|
||||
// 基本信号
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// 数据输入信号
|
||||
input wire data_en,
|
||||
input reg [15:0] data_in[2:0], // 数据输入线,0、1、2分别表示第一、二、三行
|
||||
output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
|
||||
input wire in_en,
|
||||
input wire [15:0] in_data[3], // 数据输入线,0、1、2分别表示第一、二、三行
|
||||
output wire out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
|
||||
output wire out_receive,
|
||||
|
||||
output wire out_clk,
|
||||
output wire out_en,
|
||||
output reg [3 * COLOR_DEPTH - 1:0] data_out,
|
||||
output wire [3 * COLOR_DEPTH - 1:0] out_data,
|
||||
input wire in_ready,
|
||||
input wire in_receive,
|
||||
|
||||
// 是否启动颜色矫正
|
||||
input wire [15:0] gain_red,
|
||||
input wire [15:0] gain_green,
|
||||
input wire [15:0] gain_blue,
|
||||
input wire color_correction
|
||||
);
|
||||
localparam BAYER_WIDTH = IN_WIDTH - 2;
|
||||
localparam BAYER_HEIGHT = IN_HEIGHT - 2;
|
||||
localparam reg [15:0] BAYER_WIDTH = IN_WIDTH - 2;
|
||||
localparam reg [15:0] BAYER_HEIGHT = IN_HEIGHT - 2;
|
||||
// 三通道合成RGB图像
|
||||
wire blender_en, blender_ready, blender_receive;
|
||||
wire [15:0] blender_r, blender_g, blender_b;
|
||||
|
@ -38,21 +45,19 @@ module isp #(
|
|||
// wire RAM_in_que; // RAM 请求数据
|
||||
// wire [3 * COLOR_DEPTH - 1:0] RAM_in_data;
|
||||
|
||||
always @(clk) out_clk <= clk;
|
||||
assign out_clk = clk;
|
||||
|
||||
demosaic2 #(
|
||||
Demosaic2 #(
|
||||
.IM_WIDTH (IN_WIDTH),
|
||||
.IM_HEIGHT(IN_HEIGHT),
|
||||
.RAW_TYPE (RAW_TYPE)
|
||||
) CFA (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.in_en(data_en),
|
||||
.in_data(data_in),
|
||||
.out_ready(data_que),
|
||||
.out_en(blender_en),
|
||||
.out_receive(),
|
||||
.in_en(in_en),
|
||||
.in_data(in_data),
|
||||
.out_ready(out_ready),
|
||||
.out_receive(out_receive),
|
||||
|
||||
.out_en(blender_en),
|
||||
.in_ready(blender_ready),
|
||||
|
@ -64,13 +69,9 @@ module isp #(
|
|||
|
||||
ColorBlender #(
|
||||
.IN_DEPTH (12),
|
||||
.OUT_DEPTH(8),
|
||||
|
||||
.GAIN_RED(120),
|
||||
.GAIN_GREEN(50),
|
||||
.GAIN_BLUE(95),
|
||||
.OUT_DEPTH(8)
|
||||
) blender (
|
||||
.clk(clk),
|
||||
.clk (clk),
|
||||
.reset(reset),
|
||||
|
||||
.in_en(blender_en),
|
||||
|
@ -79,14 +80,17 @@ module isp #(
|
|||
.out_receive(blender_receive),
|
||||
|
||||
.in_ready(crop_ready),
|
||||
.in_receive(crop_receive)
|
||||
.in_receive(crop_receive),
|
||||
.out_en(crop_en),
|
||||
.data_out(crop_data),
|
||||
.out_data(crop_data),
|
||||
|
||||
.gain_red(gain_red),
|
||||
.gain_green(gain_green),
|
||||
.gain_blue(gain_blue),
|
||||
.color_correction(color_correction)
|
||||
);
|
||||
|
||||
crop #(
|
||||
Crop #(
|
||||
.IN_WIDTH(BAYER_WIDTH),
|
||||
.IN_HEIGHT(BAYER_HEIGHT),
|
||||
.OUT_WIDTH(OUT_WIDTH),
|
||||
|
@ -96,15 +100,15 @@ module isp #(
|
|||
.clk (clk),
|
||||
.reset(reset),
|
||||
|
||||
.in_en (crop_en),
|
||||
.out_ready (crop_ready),
|
||||
.out_receive(crop_receive)
|
||||
.in_en(crop_en),
|
||||
.out_ready(crop_ready),
|
||||
.out_receive(crop_receive),
|
||||
.in_data(crop_data),
|
||||
|
||||
.out_en (out_en),
|
||||
.in_ready(),
|
||||
.in_receive(),
|
||||
.out_data(data_out)
|
||||
.out_en(out_en),
|
||||
.in_ready(in_ready),
|
||||
.in_receive(in_receive),
|
||||
.out_data(out_data)
|
||||
);
|
||||
|
||||
// RGB_to_RAM write_to_RAM (
|
||||
|
@ -113,11 +117,11 @@ module isp #(
|
|||
|
||||
// .in_en(RAM_in_en),
|
||||
// .in_que(RAM_in_que),
|
||||
// .data_in(RAM_in_data),
|
||||
// .in_data(RAM_in_data),
|
||||
|
||||
// .write_que(out_que),
|
||||
// .write_en(out_en),
|
||||
// .data_write(data_out)
|
||||
// .data_write(out_data)
|
||||
// );
|
||||
|
||||
endmodule
|
||||
|
|
33
sim/Makefile
33
sim/Makefile
|
@ -37,7 +37,7 @@ VERILATOR_FLAGS += -sc --exe
|
|||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
# VERILATOR_FLAGS += -x-assign fast
|
||||
VERILATOR_FLAGS += -x-assign fast
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
|
@ -45,7 +45,7 @@ VERILATOR_FLAGS += --trace
|
|||
# Check SystemVerilog assertions
|
||||
VERILATOR_FLAGS += --assert
|
||||
# Enable multithreading
|
||||
# VERILATOR_FLAGS += --threads 4
|
||||
VERILATOR_FLAGS += --threads 14
|
||||
# Generate coverage analysis
|
||||
# VERILATOR_FLAGS += --coverage
|
||||
# Run Verilator in debug mode
|
||||
|
@ -56,7 +56,7 @@ VERILATOR_FLAGS += --assert
|
|||
TOP_MODULE = isp
|
||||
VERILATOR_FLAGS += -top $(TOP_MODULE)
|
||||
# Input files for Verilator
|
||||
VERILATOR_INPUT = ../isp.v *.cpp ../Demosaic/demosaic2.v ../Crop/*.v ../FIFO/*.v ../Merge/*.v ../RAM/*.v
|
||||
VERILATOR_INPUT = ../isp.v *.cpp ../Demosaic/Demosaic2.v ../Crop/*.v ../ColorBlender/*.v ../RAM/*.v
|
||||
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
|
||||
|
@ -64,15 +64,16 @@ SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
|
|||
######################################################################
|
||||
|
||||
ifneq ($(SYSTEMC_EXISTS),)
|
||||
default: run
|
||||
default: build run
|
||||
else
|
||||
default: nosc
|
||||
endif
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- Verilator tracing example"
|
||||
lint:
|
||||
@echo "-- Verilator lint check ----"
|
||||
$(VERILATOR) -sc --lint-only $(VERILATOR_INPUT)
|
||||
|
||||
build:
|
||||
@echo
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT)
|
||||
|
@ -86,17 +87,21 @@ run:
|
|||
# 3. Or, call a submakefile where we can override the rules ourselves:
|
||||
$(MAKE) -j -C obj_dir -f V$(TOP_MODULE).mk
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- RUN ---------------------"
|
||||
# @rm -rf logs
|
||||
# @mkdir -p logs
|
||||
# obj_dir/V$(TOP_MODULE) +trace
|
||||
obj_dir/V$(TOP_MODULE)
|
||||
|
||||
# @echo
|
||||
# @echo "-- COVERAGE ----------------"
|
||||
# @rm -rf logs/annotated
|
||||
# $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
# @echo
|
||||
# @echo "-- COVERAGE ----------------"
|
||||
# @rm -rf logs/annotated
|
||||
# $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
@echo "-- FINISH ------------------"
|
||||
|
||||
trace:
|
||||
@rm -rf logs
|
||||
@mkdir -p logs
|
||||
obj_dir/V$(TOP_MODULE) +trace
|
||||
|
||||
@echo
|
||||
@echo "-- DONE --------------------"
|
||||
|
|
175
sim/sc_main.cpp
175
sim/sc_main.cpp
|
@ -5,51 +5,61 @@
|
|||
#include <systemc>
|
||||
|
||||
// Include common routines
|
||||
#include <sys/stat.h> // mkdir
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_sc.h>
|
||||
|
||||
#include <sys/stat.h> // mkdir
|
||||
|
||||
// Include model header, generated from Verilating "isp.v"
|
||||
#include "Visp.h"
|
||||
|
||||
// Handle file
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
// math
|
||||
#include <cmath>
|
||||
|
||||
#include "bmp.hpp"
|
||||
|
||||
#define IN_WIDTH 1936
|
||||
#define IN_HEIGHT 1088
|
||||
static const uint16_t IN_WIDTH = 1936;
|
||||
static const uint16_t IN_HEIGHT = 1088;
|
||||
#define IN_SIZE (IN_WIDTH * IN_HEIGHT)
|
||||
#define OUT_WIDTH 1920
|
||||
#define OUT_HEIGHT 1080
|
||||
static const uint16_t OUT_WIDTH = 1920;
|
||||
static const uint16_t OUT_HEIGHT = 1080;
|
||||
#define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT)
|
||||
|
||||
// const float red_gain = 1.2f; // Adjust these values as necessary
|
||||
// const float green_gain = 0.5f;
|
||||
// const float blue_gain = 0.95f;
|
||||
struct color_gain
|
||||
{
|
||||
double red;
|
||||
double green;
|
||||
double blue;
|
||||
}color_gain {1.0, 0.5, 1.1};
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
|
||||
SC_MODULE (TB_ISP) {
|
||||
SC_MODULE(TB_ISP) {
|
||||
sc_in_clk clk;
|
||||
sc_in<bool> reset;
|
||||
|
||||
sc_in<bool> data_que;
|
||||
sc_out<bool> data_en;
|
||||
sc_out<uint32_t> data_out[3];
|
||||
sc_in<bool> in_ready;
|
||||
sc_in<bool> in_receive;
|
||||
sc_out<bool> out_en;
|
||||
sc_out<uint32_t> out_data[3];
|
||||
|
||||
sc_in<bool> im_clk;
|
||||
sc_in<bool> im_en;
|
||||
sc_out<bool> out_ready;
|
||||
sc_out<bool> out_receceive;
|
||||
sc_in<uint32_t> im_data;
|
||||
|
||||
sc_out<bool> is_done;
|
||||
unique_ptr<uint16_t[]> image = make_unique<uint16_t[]>(IN_SIZE);
|
||||
unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(OUT_SIZE);
|
||||
|
||||
SC_CTOR (TB_ISP) {
|
||||
SC_CTOR(TB_ISP) {
|
||||
SC_CTHREAD(send_Data, clk.pos());
|
||||
reset_signal_is(reset, true);
|
||||
|
||||
|
@ -58,56 +68,63 @@ SC_MODULE (TB_ISP) {
|
|||
|
||||
void send_Data(void) {
|
||||
uint16_t pos_x = 0, pos_y = 0;
|
||||
while (true)
|
||||
{
|
||||
if (data_que.read() && pos_y < IN_HEIGHT - 2) {
|
||||
data_en.write(1);
|
||||
while (true) {
|
||||
if (in_ready.read() && pos_y < IN_HEIGHT - 2) {
|
||||
out_en.write(1);
|
||||
|
||||
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 0 ) * IN_WIDTH + pos_x]);
|
||||
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 1 ) * IN_WIDTH + pos_x]);
|
||||
printf("x=%4d, y=%4d, data=0x%04x\n", pos_x, pos_y, image[( pos_y + 2 ) * IN_WIDTH + pos_x]);
|
||||
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y,
|
||||
image[(pos_y + 0) * IN_WIDTH + pos_x]);
|
||||
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y,
|
||||
image[(pos_y + 1) * IN_WIDTH + pos_x]);
|
||||
printf("x=%4d, y=%4d, data=0x%04x\n", pos_x, pos_y,
|
||||
image[(pos_y + 2) * IN_WIDTH + pos_x]);
|
||||
|
||||
data_out[0].write(image[( pos_y + 0 ) * IN_WIDTH + pos_x]);
|
||||
data_out[1].write(image[( pos_y + 1 ) * IN_WIDTH + pos_x]);
|
||||
data_out[2].write(image[( pos_y + 2 ) * IN_WIDTH + pos_x]);
|
||||
out_data[0].write(image[(pos_y + 0) * IN_WIDTH + pos_x]);
|
||||
out_data[1].write(image[(pos_y + 1) * IN_WIDTH + pos_x]);
|
||||
out_data[2].write(image[(pos_y + 2) * IN_WIDTH + pos_x]);
|
||||
|
||||
wait(1);
|
||||
data_en.write(0);
|
||||
// wait(1);
|
||||
// out_en.write(0);
|
||||
|
||||
if (++pos_x >= IN_WIDTH) {
|
||||
pos_x = 0;
|
||||
pos_y++;
|
||||
}
|
||||
} else {
|
||||
data_en.write(0);
|
||||
out_en.write(0);
|
||||
}
|
||||
|
||||
wait();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void read_Data(void) {
|
||||
is_done.write(0);
|
||||
uint16_t pos_x = 0, pos_y = 0;
|
||||
uint32_t last_data = 0;
|
||||
uint16_t cnt = 0;
|
||||
while (true)
|
||||
{
|
||||
uint32_t cnt = 0;
|
||||
while (true) {
|
||||
if (im_en.read()) {
|
||||
out_ready.write(false);
|
||||
out_receceive.write(true);
|
||||
|
||||
out[pos_y * OUT_WIDTH + pos_x] = im_data.read();
|
||||
|
||||
if (pos_x++ >= OUT_WIDTH) {
|
||||
pos_x = 0;
|
||||
pos_y++;
|
||||
}
|
||||
} else {
|
||||
out_ready.write(true);
|
||||
out_receceive.write(false);
|
||||
}
|
||||
|
||||
// when data didn't change some time, it end
|
||||
if (last_data == im_data.read()) {
|
||||
cnt++;
|
||||
if (cnt >= 10000) {
|
||||
if (cnt >= 100000L) {
|
||||
is_done.write(1);
|
||||
printf("x=%d, y=%d\n",pos_x, pos_y);
|
||||
printf("x=%d, y=%d\n", pos_x, pos_y);
|
||||
}
|
||||
} else {
|
||||
cnt = 0;
|
||||
|
@ -142,13 +159,15 @@ int sc_main(int argc, char* argv[]) {
|
|||
uint32_t i = 0;
|
||||
for (int y = 0; y < IN_HEIGHT; y++) {
|
||||
for (int x = 0; x < IN_WIDTH; x++) {
|
||||
image[y * IN_WIDTH + x] = (uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8);
|
||||
image[y * IN_WIDTH + x] =
|
||||
(uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
cout << "Finish Reading data" << endl;
|
||||
|
||||
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||
// This is a more complicated example, please also see the simpler
|
||||
// examples/make_hello_c.
|
||||
|
||||
// Create logs/ directory in case we have traces to put under it
|
||||
Verilated::mkdir("logs");
|
||||
|
@ -161,7 +180,8 @@ int sc_main(int argc, char* argv[]) {
|
|||
// May be overridden by commandArgs argument parsing
|
||||
Verilated::randReset(2);
|
||||
|
||||
// Before any evaluation, need to know to calculate those signals only used for tracing
|
||||
// Before any evaluation, need to know to calculate those signals only used
|
||||
// for tracing
|
||||
Verilated::traceEverOn(true);
|
||||
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
|
@ -176,49 +196,68 @@ int sc_main(int argc, char* argv[]) {
|
|||
// Define interconnect
|
||||
sc_signal<bool> reset;
|
||||
|
||||
sc_signal<bool> data_en;
|
||||
sc_signal<bool> data_que;
|
||||
sc_signal<uint32_t> data_in[3];
|
||||
sc_signal<bool> in_en;
|
||||
sc_signal<bool> in_ready;
|
||||
sc_signal<bool> in_receive;
|
||||
sc_signal<uint32_t> in_data[3];
|
||||
|
||||
sc_signal<bool> out_clk;
|
||||
sc_signal<bool> out_en;
|
||||
sc_signal<uint32_t> data_out;
|
||||
sc_signal<bool> out_ready;
|
||||
sc_signal<bool> out_receive;
|
||||
sc_signal<uint32_t> out_data;
|
||||
|
||||
sc_signal<bool> color_correction;
|
||||
sc_signal<uint32_t> gain_red;
|
||||
sc_signal<uint32_t> gain_green;
|
||||
sc_signal<uint32_t> gain_blue;
|
||||
|
||||
sc_signal<bool> flag_done;
|
||||
|
||||
|
||||
// Construct the Verilated model, from inside Visp.h
|
||||
// Using unique_ptr is similar to "Visp* isp = new Visp" then deleting at end
|
||||
// Using unique_ptr is similar to "Visp* isp = new Visp" then deleting at
|
||||
// end
|
||||
const std::unique_ptr<Visp> isp{new Visp{"isp"}};
|
||||
// Attach Visp's signals to this upper model
|
||||
isp->clk(clk);
|
||||
isp->reset(reset);
|
||||
isp->data_en(data_en);
|
||||
isp->data_que(data_que);
|
||||
isp->data_in[0](data_in[0]);
|
||||
isp->data_in[1](data_in[1]);
|
||||
isp->data_in[2](data_in[2]);
|
||||
isp->in_en(in_en);
|
||||
isp->in_ready(in_ready);
|
||||
isp->in_receive(in_receive);
|
||||
isp->in_data[0](in_data[0]);
|
||||
isp->in_data[1](in_data[1]);
|
||||
isp->in_data[2](in_data[2]);
|
||||
isp->out_clk(out_clk);
|
||||
isp->out_en(out_en);
|
||||
isp->data_out(data_out);
|
||||
isp->out_ready(out_ready);
|
||||
isp->out_receive(out_receive);
|
||||
isp->out_data(out_data);
|
||||
|
||||
isp->gain_red(gain_red);
|
||||
isp->gain_green(gain_green);
|
||||
isp->gain_blue(gain_blue);
|
||||
isp->color_correction(color_correction);
|
||||
|
||||
color_correction.write(false); // enable color correction
|
||||
color_correction.write(true); // enable color correction
|
||||
gain_red.write((uint32_t)(color_gain.red * std::pow(2, 8)));
|
||||
gain_green.write((uint32_t)(color_gain.green * std::pow(2, 8)));
|
||||
gain_blue.write((uint32_t)(color_gain.blue * std::pow(2, 8)));
|
||||
|
||||
// Construct testbench module
|
||||
TB_ISP tb_isp("tb_isp");
|
||||
tb_isp.clk(clk);
|
||||
tb_isp.reset(reset);
|
||||
tb_isp.data_que(data_que);
|
||||
tb_isp.data_en(data_en);
|
||||
tb_isp.data_out[0](data_in[0]);
|
||||
tb_isp.data_out[1](data_in[1]);
|
||||
tb_isp.data_out[2](data_in[2]);
|
||||
tb_isp.in_ready(out_ready);
|
||||
tb_isp.in_receive(out_receive);
|
||||
tb_isp.out_en(in_en);
|
||||
tb_isp.out_ready(in_ready);
|
||||
tb_isp.out_receceive(in_receive);
|
||||
tb_isp.out_data[0](in_data[0]);
|
||||
tb_isp.out_data[1](in_data[1]);
|
||||
tb_isp.out_data[2](in_data[2]);
|
||||
tb_isp.im_clk(out_clk);
|
||||
tb_isp.im_en(out_en);
|
||||
tb_isp.im_data(data_out);
|
||||
tb_isp.im_data(out_data);
|
||||
tb_isp.is_done(flag_done);
|
||||
tb_isp.image = move(image);
|
||||
|
||||
|
@ -251,8 +290,7 @@ int sc_main(int argc, char* argv[]) {
|
|||
reset.write(0); // Deassert reset
|
||||
}
|
||||
|
||||
if (flag_done.read())
|
||||
break;
|
||||
if (flag_done.read()) break;
|
||||
|
||||
// Simulate 1ns
|
||||
sc_start(1, SC_NS);
|
||||
|
@ -271,26 +309,27 @@ int sc_main(int argc, char* argv[]) {
|
|||
cout << "Ready to save raw RGB image" << endl;
|
||||
// for (int y = 0; y < OUT_HEIGHT; y++)
|
||||
// for(int x = 0; x < OUT_WIDTH; x++)
|
||||
// out_image.write((const char *)&tb_isp.out[y * OUT_WIDTH + x], sizeof(tb_isp.out[0]));
|
||||
// out_image.write((const char *)&tb_isp.out[y * OUT_WIDTH + x],
|
||||
// sizeof(tb_isp.out[0]));
|
||||
// out_image.close();
|
||||
|
||||
|
||||
|
||||
// save to image
|
||||
uint8_t* data = new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
|
||||
uint8_t* data =
|
||||
new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
|
||||
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
uint8_t red = ( tb_isp.out[y * OUT_WIDTH + x] & 0x00ff0000 ) >> 16;
|
||||
uint8_t green = ( tb_isp.out[y * OUT_WIDTH + x] & 0x0000ff00 ) >> 8;
|
||||
uint8_t blue = ( tb_isp.out[y * OUT_WIDTH + x] & 0x000000ff );
|
||||
uint8_t red = (tb_isp.out[y * OUT_WIDTH + x] & 0x00ff0000) >> 16;
|
||||
uint8_t green = (tb_isp.out[y * OUT_WIDTH + x] & 0x0000ff00) >> 8;
|
||||
uint8_t blue = (tb_isp.out[y * OUT_WIDTH + x] & 0x000000ff);
|
||||
|
||||
out_image.write((const char *)&red, sizeof(red));
|
||||
out_image.write((const char *)&green, sizeof(green));
|
||||
out_image.write((const char *)&blue, sizeof(blue));
|
||||
out_image.write((const char*)&red, sizeof(red));
|
||||
out_image.write((const char*)&green, sizeof(green));
|
||||
out_image.write((const char*)&blue, sizeof(blue));
|
||||
|
||||
printf("x=%4d, y=%4d, red=0x%02x, green=0x%02x, blue=0x%02x\n", x, y, red, green, blue);
|
||||
printf("x=%4d, y=%4d, red=0x%02x, green=0x%02x, blue=0x%02x\n", x,
|
||||
y, red, green, blue);
|
||||
|
||||
data[index + 0] = red; // R
|
||||
data[index + 1] = green; // G
|
||||
|
|
Loading…
Reference in New Issue