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