diff --git a/ColorBlender/ColorBlender.v b/ColorBlender/ColorBlender.v new file mode 100644 index 0000000..974475b --- /dev/null +++ b/ColorBlender/ColorBlender.v @@ -0,0 +1,86 @@ +`timescale 1ns / 1ps + +// 三通道图像合成一个RGB图像 +module ColorBlender #( + parameter reg [ 4:0] IN_DEPTH = 12, // 输入图像的色深 + parameter reg [ 4:0] OUT_DEPTH = 8, // 输出图像的色深 + parameter reg [12:0] GAIN_RED = 120, // 红色增益系数(除以10^小数位数) + parameter reg [12:0] GAIN_GREEN = 50, // 绿色增益系数 + parameter reg [12:0] GAIN_BLUE = 95, // 蓝色增益系数 + parameter reg [ 4:0] GAIN_OFFSET = 7 +) ( + input clk, + input reset, + + input in_en, + input [15:0] data_in[2], // 0:R 1:G 2:B + output out_ready, + output out_receive, + + // 输出相关 + input in_ready, + input in_receive, + output out_en, + output [3 * OUT_DEPTH - 1:0] data_out, + + // 颜色校正 + input wire color_correction +); + localparam READ_DATA = 0; + localparam CALC_DATA = 1; + localparam SEND_DATA = 2; + + reg [2:0] state, nextState; + reg [31:0] data_cal[2]; // 用于保存运算结果,防止溢出 + + always @(posedge clk or posedge reset) begin + if (reset) begin + state <= READ_DATA; + end else begin + state <= nextState; + end + end + + always @(*) begin + case (state) + READ_DATA: nextState = (in_en) ? (color_correction ? CALC_DATA : SEND_DATA) : READ_DATA; + CALC_DATA: nextState = SEND_DATA; + SEND_DATA: nextState = READ_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; + + always @(posedge clk or posedge reset) begin + if (reset) begin + // 初始化 + data_cal[0] <= 0; + data_cal[1] <= 0; + data_cal[2] <= 0; + end else begin + case (state) + READ_DATA: begin + + if (in_en) begin + data_cal[0] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[0]} >> (IN_DEPTH - OUT_DEPTH)); + data_cal[1] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[1]} >> (IN_DEPTH - OUT_DEPTH)); + data_cal[2] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[2]} >> (IN_DEPTH - OUT_DEPTH)); + end + end + + CALC_DATA: begin + end + + SEND_DATA: begin + + end + + default: ; + endcase + end + end + +endmodule diff --git a/Demosaic/demosaic2.v b/Demosaic/demosaic2.v index 05f3a98..2df8e6c 100644 --- a/Demosaic/demosaic2.v +++ b/Demosaic/demosaic2.v @@ -1,186 +1,187 @@ module demosaic2 #( - parameter IM_WIDTH = 512, // 图像宽度 - parameter IM_HEIGHT = 256, // 图像高度 - parameter RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg - parameter DATA_SIZE = 16 -)( + 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 +) ( // 基本信号 input clk, input reset, // 数据输入信号 - input data_en, - input [DATA_SIZE - 1:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 - output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 + input in_en, + input [DATA_SIZE - 1:0] in_data [2], // 数据输入线,0、1、2分别表示第一、二、三行 + output out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 + output out_receive, // en: 输出数据有效信号,高电平有效 - output reg out_en, + input in_ready, + input in_receive, + output 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 ); - // 常量,包括状态机 - // 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; + // 常量,包括状态机 + // localparam IM_SIZE = IM_HEIGHT * IM_WIDTH; + localparam READ_DATA = 0; + localparam COLOR_GEN = 1; + localparam SEND_DATA = 2; + localparam SLIDE_WINDOW = 3; - // 三段状态机实现,窗口滑动,颜色计算 - // 状态切换 - always @(posedge clk or posedge reset) begin - if (reset) - state <= READ_DATA; - else - state <= nextState; - end + // 寄存器 + reg [2:0] state, nextState; + reg [15:0] data_cache[2][2]; // 缓存颜色数据,行列3x3 + reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置 + reg [2:0] cnt_data; // 记录输入数据数量,最大值256 + reg [1:0] raw_type; + reg [15:0] red, blue, green; - // 下一状态更新 - always @(state or cnt_data) 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) state <= READ_DATA; + else state <= nextState; + 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; + // 下一状态更新 + always @(state or cnt_data) 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; + endcase + end - // 内部寄存器初始化 - pos_x <= 0; - pos_y <= 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_en = (in_ready && state == SEND_DATA) ? 1 : 0; + + // 各状态执行的操作 + always @(posedge clk or posedge reset) begin + if (reset) begin + // 外部输出初始化 + out_en <= 0; + out_r <= 0; + out_g <= 0; + out_r <= 0; + + // 内部寄存器初始化 + pos_x <= 0; + pos_y <= 0; + cnt_data <= 0; + raw_type <= RAW_TYPE; + end else begin + // 状态机执行 + case (state) + // 读取数据 + 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]; + + cnt_data <= cnt_data + 1; + end + end + + 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 + 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]; + 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 + 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 + default: ; + endcase + + case (raw_type) + 0: raw_type <= 1; + 1: raw_type <= 0; + 2: raw_type <= 3; + 3: raw_type <= 2; + endcase + end + + SEND_DATA: begin + if (in_ready) begin + out_r <= red; + out_b <= blue; + out_g <= green; + end + end + + SLIDE_WINDOW: begin + // 记录位置寄存器自增,并处理缓存数据 + pos_x <= pos_x + 1; + if (pos_x >= IM_WIDTH - 2 - 1) begin cnt_data <= 0; - raw_type <= RAW_TYPE; + pos_x <= 0; + pos_y <= pos_y + 1; + if (pos_y >= IM_HEIGHT - 2 - 1) begin + pos_y <= 0; + end + // 换行后切换Bayer格式 + if (pos_y % 2 == 1) begin + raw_type <= RAW_TYPE; + end else begin + case (RAW_TYPE) + 0: raw_type <= 2; + 1: raw_type <= 3; + 2: raw_type <= 0; + 3: raw_type <= 1; + default: ; + endcase + end + end else begin + 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]; + end end - else begin - // 状态机执行 - case (state) - // 读取数据 - READ_DATA: begin - // 请求数据 - if (cnt_data <= 2) begin - data_que <= 1; - end - - 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; - data_que <= 0; - end - end - - 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 - 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]; - 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 - 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 - endcase - - case (raw_type) - 0: raw_type <= 1; - 1: raw_type <= 0; - 2: raw_type <= 3; - 3: raw_type <= 2; - endcase - 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 - 1) begin - cnt_data <= 0; - pos_x <= 0; - pos_y <= pos_y + 1; - if (pos_y >= IM_HEIGHT - 2 - 1) begin - pos_y <= 0; - end - // 换行后切换Bayer格式 - if (pos_y % 2 == 1) begin - raw_type <= RAW_TYPE; - end - else begin - case (RAW_TYPE) - 0: raw_type <= 2; - 1: raw_type <= 3; - 2: raw_type <= 0; - 3: raw_type <= 1; - endcase - end - end - else begin - 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]; - end - end - endcase - end - end + default: ; + endcase + end + end endmodule diff --git a/FIFO/SOFTFIFO.v b/FIFO/SOFTFIFO.v deleted file mode 100644 index 9c93736..0000000 --- a/FIFO/SOFTFIFO.v +++ /dev/null @@ -1,894 +0,0 @@ - -`timescale 1ns/1ps -// -// =========================================================================== -// Copyright (c) 2011-2022 Anlogic Inc. All Right Reserved. -// -// TEL: 86-21-61633787 -// WEB: http://www.anlogic.com/ -// =========================================================================== -// $Version : v1.1 -// $Date : 2022/07/08 -// $Description: asynchronous/synchronous FIFO rtl codes , fixed the error of -// gray code -// =========================================================================== -//`pragma protect begin -module SOFTFIFO #(parameter DATA_WIDTH_W = 16, - parameter DATA_WIDTH_R = 16, - parameter ADDR_WIDTH_W = 10, - parameter ADDR_WIDTH_R = 10, - parameter AL_FULL_NUM = 1021, - parameter AL_EMPTY_NUM = 2, - parameter SHOW_AHEAD_EN = 1'b1, - parameter OUTREG_EN = "OUTREG") ( - //SHOWAHEAD mode enable - //OUTREG, NOREG - //independent clock mode,fixed as asynchronous reset - input rst, //asynchronous port,active hight - input clkw, //write clock - input clkr, //read clock - input we, //write enable,active hight - input [(DATA_WIDTH_W - 1):0] di, //write data - input re, //read enable,active hight - output [(DATA_WIDTH_R - 1):0] dout, //read data - output reg valid, //read data valid flag - output reg full_flag, //fifo full flag - output empty_flag, //fifo empty flag - output reg afull, //fifo almost full flag - output aempty, //fifo almost empty flag - output [(ADDR_WIDTH_W - 1):0] wrusedw, //stored data number in fifo - output [(ADDR_WIDTH_R - 1):0] rdusedw //available data number for read - ) ; - //-------------------------------------------------------------------------------------------- - //-------------internal parameter and signals definition below--------------- - //-------------------------------------------------------------------------------------------- - //-------------parameter definition - localparam FULL_NUM = ({ADDR_WIDTH_W{1'b1}} - 1) ; - //-------------signals definition - reg asy_w_rst0 ; - reg asy_w_rst1 ; - reg asy_r_rst0 ; - reg asy_r_rst1 ; - wire rd_rst ; - wire wr_rst ; - wire [(ADDR_WIDTH_R - 1):0] rd_to_wr_addr ; // read address synchronized to write clock domain - wire [(ADDR_WIDTH_W - 1):0] wr_to_rd_addr ; // write address synchronized to read clock domain - reg [(ADDR_WIDTH_W - 1):0] wr_addr ; // current write address - reg [(ADDR_WIDTH_R - 1):0] rd_addr ; // current write address - wire wr_en_s ; - wire rd_en_s ; - reg [(ADDR_WIDTH_W - 1):0] shift_rdaddr ; - reg [(ADDR_WIDTH_R - 1):0] shift_wraddr ; - wire [(ADDR_WIDTH_W - 1):0] wr_addr_diff ; // the difference between read and write address(synchronized to write clock domain) - wire [(ADDR_WIDTH_R - 1):0] rd_addr_diff ; // the difference between read and write address(synchronized to read clock domain) - reg empty_flag_r1 ; - reg empty_flag_r2 ; - reg re_r1 ; - reg re_r2 ; - //-------------------------------------------------------------------------------------------- - //--------------------fuctional codes below--------------------------------- - //-------------------------------------------------------------------------------------------- - // ============================================= - // reset control logic below; - // ============================================= - //Asynchronous reset synchronous release on the write side - always - @(posedge clkw or - posedge rst) - begin - if (rst) - begin - asy_w_rst0 <= 1'b1 ; - asy_w_rst1 <= 1'b1 ; - end - else - begin - asy_w_rst0 <= 1'b0 ; - asy_w_rst1 <= asy_w_rst0 ; - end - end - //Asynchronous reset synchronous release on the read side - always - @(posedge clkr or - posedge rst) - begin - if (rst) - begin - asy_r_rst0 <= 1'b1 ; - asy_r_rst1 <= 1'b1 ; - end - else - begin - asy_r_rst0 <= 1'b0 ; - asy_r_rst1 <= asy_r_rst0 ; - end - end - assign rd_rst = asy_r_rst1 ; - assign wr_rst = asy_w_rst1 ; - // ============================================= - // address generate logic below; - // ============================================= - // write and read ram enable - assign wr_en_s = ((!full_flag) & we) ; - assign rd_en_s = ((!empty_flag) & re) ; - // generate write fifo address - always - @(posedge clkw or - posedge wr_rst) - begin - if ((wr_rst == 1'b1)) - wr_addr <= 'b0 ; - else - if (wr_en_s) - wr_addr <= (wr_addr + 1) ; - end - // generate rd fifo address - always - @(posedge clkr or - posedge rd_rst) - begin - if ((rd_rst == 1'b1)) - rd_addr <= 'b0 ; - else - if (rd_en_s) - rd_addr <= (rd_addr + 1) ; - end - always - @(*) - begin - if ((ADDR_WIDTH_R >= ADDR_WIDTH_W)) - begin - shift_rdaddr = (rd_to_wr_addr >> (ADDR_WIDTH_R - ADDR_WIDTH_W)) ; - shift_wraddr = (wr_to_rd_addr << (ADDR_WIDTH_R - ADDR_WIDTH_W)) ; - end - else - begin - shift_rdaddr = (rd_to_wr_addr << (ADDR_WIDTH_W - ADDR_WIDTH_R)) ; - shift_wraddr = (wr_to_rd_addr >> (ADDR_WIDTH_W - ADDR_WIDTH_R)) ; - end - end - // two's complement format - assign wr_addr_diff = (wr_addr - shift_rdaddr) ; // the count of data writen to fifo - assign rd_addr_diff = (shift_wraddr - rd_addr) ; // the count of data available for read - // ============================================= - // generate all output flag and count below; - // ============================================= - // generate fifo full_flag indicator - always - @(posedge clkw or - posedge wr_rst) - begin - if ((wr_rst == 1'b1)) - full_flag <= 1'b0 ; - else - if ((wr_addr_diff >= FULL_NUM)) - full_flag <= 1'b1 ; - else - full_flag <= 1'b0 ; - end - // generate fifo afull indicator - always - @(posedge clkw or - posedge wr_rst) - begin - if ((wr_rst == 1'b1)) - afull <= 1'b0 ; - else - if ((wr_addr_diff >= AL_FULL_NUM)) - afull <= 1'b1 ; - else - afull <= 1'b0 ; - end - // generate fifo empty_flag indicator - /* verilator lint_off WIDTHEXPAND */ - assign empty_flag = ((rd_addr_diff == 5'b0) ? 1'b1 : 1'b0) ; - // generate fifo aempty indicator - assign aempty = ((rd_addr_diff <= AL_EMPTY_NUM) ? 1'b1 : 1'b0) ; - // the count of data writen to fifo - assign wrusedw = wr_addr_diff ; - // the count of data available for read - assign rdusedw = rd_addr_diff ; - // delay empty_flag for 2cycle - always - @(posedge clkr or - posedge rd_rst) - begin - if ((rd_rst == 1'b1)) - begin - empty_flag_r1 <= 1'b1 ; - empty_flag_r2 <= 1'b1 ; - end - else - begin - empty_flag_r1 <= empty_flag ; - empty_flag_r2 <= empty_flag_r1 ; - end - end - // delay rd_en_s for 2cycle - always - @(posedge clkr or - posedge rd_rst) - begin - if ((rd_rst == 1'b1)) - begin - re_r1 <= 1'b0 ; - re_r2 <= 1'b0 ; - end - else - begin - re_r1 <= rd_en_s ; - re_r2 <= re_r1 ; - end - end - // generate data output valid flag - always - @(*) - begin - if ((SHOW_AHEAD_EN && (OUTREG_EN == "NOREG"))) - valid = (!empty_flag) ; - else - if (((!SHOW_AHEAD_EN) && (OUTREG_EN == "OUTREG"))) - valid = (re_r2 & (!empty_flag_r2)) ; - else - valid = (re_r1 & (!empty_flag_r1)) ; - end - // ============================================= - // instance logic below; - // ============================================= - // fifo read address synchronous to write clock domain using gray code - fifo_cross_domain_addr_process_al_SOFTFIFO #(.ADDR_WIDTH(ADDR_WIDTH_R)) rd_to_wr_cross_inst (.primary_asreset_i(rd_rst), - .secondary_asreset_i(wr_rst), - .primary_clk_i(clkr), - .secondary_clk_i(clkw), - .primary_addr_i(rd_addr), - .secondary_addr_o(rd_to_wr_addr)) ; - // fifo write address synchronous to read clock domain using gray code - fifo_cross_domain_addr_process_al_SOFTFIFO #(.ADDR_WIDTH(ADDR_WIDTH_W)) wr_to_rd_cross_inst (.primary_asreset_i(wr_rst), - .secondary_asreset_i(rd_rst), - .primary_clk_i(clkw), - .secondary_clk_i(clkr), - .primary_addr_i(wr_addr), - .secondary_addr_o(wr_to_rd_addr)) ; - ram_infer_SOFTFIFO #( - .DATAWIDTH_A(DATA_WIDTH_W), - .ADDRWIDTH_A(ADDR_WIDTH_W), - .DATAWIDTH_B(DATA_WIDTH_R), - .ADDRWIDTH_B(ADDR_WIDTH_R), - .MODE("SDP"), - .REGMODE_B(OUTREG_EN) - /* verilator lint_off PINMISSING */ - ) ram_inst ( - .clka(clkw), - .rsta(wr_rst), - .cea(1'b1), - .wea(wr_en_s), - .ocea(1'b0), - .dia(di), - .addra(wr_addr), - .clkb(clkr), - .rstb(rd_rst), - .ceb((SHOW_AHEAD_EN | rd_en_s)), - .web(1'b0), - .oceb(1'b1), - /* verilator lint_off WIDTHEXPAND */ - .addrb((rd_addr + (SHOW_AHEAD_EN & rd_en_s))), - .dob(dout) - ); -endmodule - - - -`timescale 1ns/1ps -// =========================================================================== -// $Version : v1.0 -// $Date : 2022/04/26 -// $Description: fifo write and read address crocess domain process -// =========================================================================== -/* verilator lint_off DECLFILENAME */ -module fifo_cross_domain_addr_process_al_SOFTFIFO #(parameter ADDR_WIDTH = 9) ( - input primary_asreset_i, - input secondary_asreset_i, - input primary_clk_i, - input secondary_clk_i, - input [(ADDR_WIDTH - 1):0] primary_addr_i, - output reg [(ADDR_WIDTH - 1):0] secondary_addr_o) ; - //-------------------------------------------------------------------------------------------- - //-------------internal parameter and signals definition below--------------- - //-------------------------------------------------------------------------------------------- - //-------------localparam definition - //-------------signals definition - wire [(ADDR_WIDTH - 1):0] primary_addr_gray ; - reg [(ADDR_WIDTH - 1):0] primary_addr_gray_reg ; /* fehdl keep="true" */ - reg [(ADDR_WIDTH - 1):0] sync_r1 ; /* fehdl keep="true" */ - reg [(ADDR_WIDTH - 1):0] primary_addr_gray_sync ; - //-------------------------------------------------------------------------------------------- - //--------------------fuctional codes below--------------------------------- - //-------------------------------------------------------------------------------------------- - function [(ADDR_WIDTH - 1):0] gray2bin ; - input [(ADDR_WIDTH - 1):0] gray ; - integer j ; - begin - gray2bin[(ADDR_WIDTH - 1)] = gray[(ADDR_WIDTH - 1)] ; - for (j = (ADDR_WIDTH - 1) ; (j > 0) ; j = (j - 1)) - gray2bin[(j - 1)] = (gray2bin[j] ^ gray[(j - 1)]) ; - end - endfunction - function [(ADDR_WIDTH - 1):0] bin2gray ; - input [(ADDR_WIDTH - 1):0] bin ; - integer j ; - begin - bin2gray[(ADDR_WIDTH - 1)] = bin[(ADDR_WIDTH - 1)] ; - for (j = (ADDR_WIDTH - 1) ; (j > 0) ; j = (j - 1)) - bin2gray[(j - 1)] = (bin[j] ^ bin[(j - 1)]) ; - end - endfunction - // convert primary address to grey code - assign primary_addr_gray = bin2gray(primary_addr_i) ; - // register the primary Address Pointer gray code - always - @(posedge primary_clk_i or - posedge primary_asreset_i) - begin - if ((primary_asreset_i == 1'b1)) - primary_addr_gray_reg <= 0 ; - else - primary_addr_gray_reg <= primary_addr_gray ; - end - //-------------------------------------------------------------------- - // secondary clock Domain - //-------------------------------------------------------------------- - // synchronize primary address grey code onto the secondary clock - always - @(posedge secondary_clk_i or - posedge secondary_asreset_i) - begin - if ((secondary_asreset_i == 1'b1)) - begin - sync_r1 <= 0 ; - primary_addr_gray_sync <= 0 ; - end - else - begin - sync_r1 <= primary_addr_gray_reg ; - primary_addr_gray_sync <= sync_r1 ; - end - end - // convert the synchronized primary address grey code back to binary - always - @(posedge secondary_clk_i or - posedge secondary_asreset_i) - begin - if ((secondary_asreset_i == 1'b1)) - secondary_addr_o <= 0 ; - else - secondary_addr_o <= gray2bin(primary_addr_gray_sync) ; - end -endmodule - - - -`timescale 1ns/1ps -// =========================================================================== -// $Version : v1.0 -// $Date : 2022/04/26 -// $Description: DRAM/ERAM infer logic -// =========================================================================== -module ram_infer_SOFTFIFO (clka, - rsta, - cea, - ocea, - wea, - dia, - addra, - doa, - clkb, - rstb, - ceb, - oceb, - web, - dib, - addrb, - dob) ; - //parameter - parameter MODE = "SDP" ; //SP, SDP, DP - parameter BYTE_SIZE = 8 ; //8, 9, 10 - /* verilator lint_off UNUSEDPARAM */ - parameter INIT_FILE = "" ; //memory initialization file which can be $readmemh, generated by software from .mif - /* verilator lint_off UNUSEDPARAM */ - parameter INIT_VALUE = 0 ; - parameter USE_BYTE_WEA = 0 ; //0,1, use Byte Writes or not - parameter DATAWIDTH_A = 32 ; //A WIDTH - parameter WEA_WIDTH = ((USE_BYTE_WEA == 0) ? 1 : (DATAWIDTH_A / BYTE_SIZE)) ; //wea port width - parameter REGMODE_A = "NOREG" ; //OUTREG, NOREG - parameter RESETMODE_A = "ASYNC" ; //SYNC, ASYNC, ARSR - parameter INITVAL_A = {DATAWIDTH_A{1'b0}} ; //A initial value or reset value - parameter WRITEMODE_A = "NORMAL" ; //NORMAL, WRITETHROUGH, READBEFOREWRITE - parameter ADDRWIDTH_A = 5 ; //A ADDR WIDTH - parameter DATADEPTH_A = (2 ** ADDRWIDTH_A) ; //A DEPTH - parameter SSROVERCE_A = "ENABLE" ; //ENABLE, DISABLE - parameter USE_BYTE_WEB = USE_BYTE_WEA ; //0,1, use Byte Writes or not - parameter DATAWIDTH_B = DATAWIDTH_A ; //B WIDTH - parameter WEB_WIDTH = ((USE_BYTE_WEB == 0) ? 1 : (DATAWIDTH_B / BYTE_SIZE)) ; //web port width - parameter REGMODE_B = "NOREG" ; //OUTREG, NOREG - parameter RESETMODE_B = "ASYNC" ; //SYNC, ASYNC, ARSR - parameter INITVAL_B = {DATAWIDTH_B{1'b0}} ; //B initial value or reset value - parameter WRITEMODE_B = "NORMAL" ; //NORMAL, WRITETHROUGH, READBEFOREWRITE - parameter ADDRWIDTH_B = ADDRWIDTH_A ; //B ADDR WIDTH - parameter DATADEPTH_B = (2 ** ADDRWIDTH_B) ; //A DEPTH - parameter SSROVERCE_B = "ENABLE" ; //ENABLE, DISABLEi - //input - input clka, - rsta, - cea, - ocea ; - input [(WEA_WIDTH - 1):0] wea ; - input [(DATAWIDTH_A - 1):0] dia ; - input [(ADDRWIDTH_A - 1):0] addra ; - input clkb, - rstb, - ceb, - oceb ; - input [(WEB_WIDTH - 1):0] web ; - input [(DATAWIDTH_B - 1):0] dib ; - input [(ADDRWIDTH_B - 1):0] addrb ; - //output - output [(DATAWIDTH_A - 1):0] doa ; - output [(DATAWIDTH_B - 1):0] dob ; - // check parameters - //integer fp; - localparam MIN_WIDTH = ((DATAWIDTH_A > DATAWIDTH_B) ? DATAWIDTH_B : DATAWIDTH_A) ; - localparam MAX_DEPTH = ((DATADEPTH_A > DATADEPTH_B) ? DATADEPTH_A : DATADEPTH_B) ; - localparam WIDTHRATIO_A = (DATAWIDTH_A / MIN_WIDTH) ; - localparam WIDTHRATIO_B = (DATAWIDTH_B / MIN_WIDTH) ; - reg [(MIN_WIDTH - 1):0] memory [(MAX_DEPTH - 1):0] ; /* fehdl force_ram=1, ram_style="bram" */ - reg [(DATAWIDTH_A - 1):0] doa_tmp = INITVAL_A ; - reg [(DATAWIDTH_B - 1):0] dob_tmp = INITVAL_B ; - reg [(DATAWIDTH_A - 1):0] doa_tmp2 = INITVAL_A ; - reg [(DATAWIDTH_B - 1):0] dob_tmp2 = INITVAL_B ; - /* verilator lint_off UNUSEDSIGNAL */ - integer i ; - //Initial value - // if (INIT_FILE != "") begin - // initial $readmemb(INIT_FILE, memory); - // end else begin - // initial begin - // for(i=0; i> (IN_DEPTH - OUT_DEPTH) ) * GAIN_RED / (10 ** DECIMAL); - data_cal[1] <= ( {16'b0, data_in[1] } >> (IN_DEPTH - OUT_DEPTH) ) * GAIN_GREEN / (10 ** DECIMAL); - data_cal[2] <= ( {16'b0, data_in[2] } >> (IN_DEPTH - OUT_DEPTH) ) * GAIN_BLUE / (10 ** DECIMAL); - end - else begin - data_cal[0] <= ( {16'b0, data_in[0] } >> (IN_DEPTH - OUT_DEPTH) ); - data_cal[1] <= ( {16'b0, data_in[1] } >> (IN_DEPTH - OUT_DEPTH) ); - data_cal[2] <= ( {16'b0, data_in[2] } >> (IN_DEPTH - OUT_DEPTH) ); - end - - end - end - - SEND_DATA: begin - fifo_en <= 1; - fifo_in <= {data_cal[0][OUT_DEPTH - 1:0], data_cal[1][OUT_DEPTH - 1:0], data_cal[2][OUT_DEPTH - 1:0]}; - end - endcase - end - end - - // 存在数据请求且FIFO不为空时,才发送数据 - assign fifo_que = (out_que && !fifo_empty) ? 1 : 0; - - SOFTFIFO #( - .DATA_WIDTH_W(3 * OUT_DEPTH), - .DATA_WIDTH_R(3 * OUT_DEPTH) - ) RGB_FIFO ( - .rst(reset), //asynchronous port,active hight - .clkw(clk), //write clock - .clkr(clk), //read clock - .we(fifo_en), //write enable,active hight - .di(fifo_in), //write data - .re(fifo_que), //read enable,active hight - .dout(data_out), //read data - .valid(out_en), //read data valid flag - /* verilator lint_off PINCONNECTEMPTY */ - .full_flag(), //fifo full flag - .empty_flag(fifo_empty), //fifo empty flag - /* verilator lint_off PINCONNECTEMPTY */ - .afull(), //fifo almost full flag - /* verilator lint_off PINCONNECTEMPTY */ - .aempty(), //fifo almost empty flag - /* verilator lint_off PINCONNECTEMPTY */ - .wrusedw(), //stored data number in fifo - /* verilator lint_off PINCONNECTEMPTY */ - .rdusedw() //available data number for read - ); - -endmodule diff --git a/isp.v b/isp.v index aef7f03..a163526 100644 --- a/isp.v +++ b/isp.v @@ -1,12 +1,12 @@ -`timescale 1ns/1ps +`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 = 1920, + parameter OUT_HEIGHT = 1080, parameter COLOR_DEPTH = 8, - parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg + parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg ) ( // 基本信号 input wire clk, @@ -14,7 +14,7 @@ module isp #( // 数据输入信号 input wire data_en, - input reg [15:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 + input reg [15:0] data_in[2:0], // 数据输入线,0、1、2分别表示第一、二、三行 output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 output wire out_clk, @@ -23,90 +23,89 @@ module isp #( input wire color_correction ); - localparam BAYER_WIDTH = IN_WIDTH - 2; - localparam BAYER_HEIGHT = IN_HEIGHT - 2; - // 三通道合成RGB图像 - wire rgb_en; - wire [15:0] im_red, im_green, im_blue; + localparam BAYER_WIDTH = IN_WIDTH - 2; + localparam BAYER_HEIGHT = IN_HEIGHT - 2; + // 三通道合成RGB图像 + wire rgb_en; + wire [15:0] im_red, im_green, im_blue; - // 任意比例缩放图像 - reg scale_in_en; - wire scale_in_que; // scaler 请求数据 - reg [3 * COLOR_DEPTH - 1:0] scale_in_data; + // 任意比例缩放图像 + reg scale_in_en; + wire scale_in_que; // scaler 请求数据 + reg [3 * COLOR_DEPTH - 1:0] scale_in_data; - // 写入RAM - // wire RAM_in_en; - // wire RAM_in_que; // RAM 请求数据 - // wire [3 * COLOR_DEPTH - 1:0] RAM_in_data; + // 写入RAM + // wire RAM_in_en; + // wire RAM_in_que; // RAM 请求数据 + // wire [3 * COLOR_DEPTH - 1:0] RAM_in_data; - always @(clk) - out_clk <= clk; + always @(clk) out_clk <= clk; - demosaic2 #( - .IM_WIDTH(IN_WIDTH), - .IM_HEIGHT(IN_HEIGHT), - .RAW_TYPE(RAW_TYPE) - ) CFA ( - .clk(clk), - .reset(reset), - .data_en(data_en), - .data_in(data_in), - .data_que(data_que), - .out_en(rgb_en), - .out_r(im_red), - .out_g(im_green), - .out_b(im_blue) - ); + demosaic2 #( + .IM_WIDTH (IN_WIDTH), + .IM_HEIGHT(IN_HEIGHT), + .RAW_TYPE (RAW_TYPE) + ) CFA ( + .clk(clk), + .reset(reset), + .data_en(data_en), + .data_in(data_in), + .data_que(data_que), + .out_en(rgb_en), + .out_r(im_red), + .out_g(im_green), + .out_b(im_blue) + ); - chanels_to_RGB #( - .IN_DEPTH(12), - .OUT_DEPTH(8), + ColorBlender #( + .IN_DEPTH (12), + .OUT_DEPTH(8), - .GAIN_RED(120), - .GAIN_GREEN(50), - .GAIN_BLUE(95), - .DECIMAL(2) - ) merge_toRGB( - .clk(clk), - .reset(reset), - .in_en(rgb_en), - .data_in({im_blue, im_green, im_red}), + .GAIN_RED(120), + .GAIN_GREEN(50), + .GAIN_BLUE(95), + .DECIMAL(2) + ) blender ( + .clk(clk), + .reset(reset), + .in_en(rgb_en), + .data_in({im_blue, im_green, im_red}), - .out_que(scale_in_que), - .out_en(scale_in_en), - .data_out(scale_in_data), - .color_correction(color_correction) - ); + .out_que(scale_in_que), + .out_en(scale_in_en), + .data_out(scale_in_data), + .color_correction(color_correction) + ); - crop #( - .IN_WIDTH(BAYER_WIDTH), - .IN_HEIGHT(BAYER_HEIGHT), - .OUT_WIDTH(OUT_WIDTH), - .OUT_HEIGHT(OUT_HEIGHT), - .COLOR_DEPTH(COLOR_DEPTH) - ) crop_process ( - .clk(clk), - .reset(reset), + crop #( + .IN_WIDTH(BAYER_WIDTH), + .IN_HEIGHT(BAYER_HEIGHT), + .OUT_WIDTH(OUT_WIDTH), + .OUT_HEIGHT(OUT_HEIGHT), + .COLOR_DEPTH(COLOR_DEPTH) + ) crop_process ( + .clk (clk), + .reset(reset), - .in_en(scale_in_en), - .in_que(scale_in_que), - .data_in(scale_in_data), + .in_en (scale_in_en), + .in_que (scale_in_que), + .data_in(scale_in_data), - .out_en(out_en), - .data_out(data_out) - ); + .out_en (out_en), + .data_out(data_out) + ); - // RGB_to_RAM write_to_RAM ( - // .clk(clk), - // .reset(reset), + // RGB_to_RAM write_to_RAM ( + // .clk(clk), + // .reset(reset), - // .in_en(RAM_in_en), - // .in_que(RAM_in_que), - // .data_in(RAM_in_data), + // .in_en(RAM_in_en), + // .in_que(RAM_in_que), + // .data_in(RAM_in_data), + + // .write_que(out_que), + // .write_en(out_en), + // .data_write(data_out) + // ); - // .write_que(out_que), - // .write_en(out_en), - // .data_write(data_out) - // ); - endmodule diff --git a/sim/sc_main.cpp b/sim/sc_main.cpp index 009d728..d647af1 100644 --- a/sim/sc_main.cpp +++ b/sim/sc_main.cpp @@ -205,7 +205,7 @@ int sc_main(int argc, char* argv[]) { isp->data_out(data_out); isp->color_correction(color_correction); - color_correction.write(true); // enable color correction + color_correction.write(false); // enable color correction // Construct testbench module TB_ISP tb_isp("tb_isp"); diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..e69de29