finish reconstruction and pass simulation
This commit is contained in:
		@@ -2,36 +2,37 @@
 | 
			
		||||
 | 
			
		||||
// 三通道图像合成一个RGB图像
 | 
			
		||||
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 [ 4:0] IN_DEPTH   = 12,   // 输入图像的色深
 | 
			
		||||
    parameter reg [ 4:0] OUT_DEPTH  = 8,    // 输出图像的色深
 | 
			
		||||
    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;
 | 
			
		||||
      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: ;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								Crop/Crop.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								Crop/Crop.v
									
									
									
									
									
										Normal file
									
								
							@@ -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,23 +47,21 @@ 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;
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
  // 请求数据
 | 
			
		||||
  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_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
 | 
			
		||||
            out_r <= red;
 | 
			
		||||
            out_b <= blue;
 | 
			
		||||
            out_g <= green;
 | 
			
		||||
          end
 | 
			
		||||
          if (in_ready && !in_receive) begin
 | 
			
		||||
            out_en <= 1;
 | 
			
		||||
            out_r  <= red;
 | 
			
		||||
            out_b  <= blue;
 | 
			
		||||
            out_g  <= green;
 | 
			
		||||
          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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								isp.v
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								isp.v
									
									
									
									
									
								
							@@ -1,58 +1,63 @@
 | 
			
		||||
`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;
 | 
			
		||||
 | 
			
		||||
  // 任意比例缩放图像
 | 
			
		||||
  wire                         crop_en, crop_ready, crop_receive;  // scaler 请求数据
 | 
			
		||||
  reg  [3 * COLOR_DEPTH - 1:0] crop_data;
 | 
			
		||||
  wire crop_en, crop_ready, crop_receive;  // scaler 请求数据
 | 
			
		||||
  reg [3 * COLOR_DEPTH - 1:0] crop_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;
 | 
			
		||||
  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 --------------------"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										183
									
								
								sim/sc_main.cpp
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								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,30 +309,31 @@ 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
 | 
			
		||||
            data[index + 2] = blue; // B
 | 
			
		||||
            data[index + 0] = red;    // R
 | 
			
		||||
            data[index + 1] = green;  // G
 | 
			
		||||
            data[index + 2] = blue;   // B
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user