ISP图像处理之Demosaic算法(RTL篇)

博客围绕ISP图像处理展开,先介绍DUT接收数据情况及仿真参数意义,如行消隐和场消隐。接着阐述RTL实现,包括端口介绍、使用三条memory存三行数据、延迟情况及代码实现,同时指出代码未考虑资源利用、存储外接memory等缺陷。

一、背景介绍

1.1 DUT接收的数据情况介绍:

      driver 在1个cycle向DUT送入v2xH4个pixels,其顺序如下图1所示,这个顺序很重要哦

5eda74bde87d4fe29636ecda40512d84.png

图1:DUT输入数据的顺序

1.2 仿真参数实际意义:

c61adca056a0426fa7e774c36690ed6b.png

(1) 垂直同步时间pvsync:指的是垂直同步的脉冲时间,即image sensor所输出的所有影像数据组成一个frame;
(2) 垂直同步前肩V_frontporch: 指的是当前有效帧结束到下个垂直同步到来的时间间隔。
(3) 垂直同步后肩V_backporch:指的是垂直同步结束到下个有效帧数据到来的时间间隔。
(4) 水平同步时间phsync:指的是水平同步的脉冲时间,即告诉接收端 有效时段内sensor所有的信号输出属同一行;phsync的频率为:像素时钟/(1+H_backporch+768/4+H_frontporch)
(5) 水平同步前肩H_frontporch:指的是当前行结束到下个水平同步到来的时间间隔。
(6) 水平同步后肩H_backporch:指的是水平同步结束到下一行 数据到来的时间间隔.
图像的基本区域划分

行消隐和场消隐的概念来源于老的电视(CRT)视频制式NTSC和PAL,NTSC每秒刷新60次,PAL每秒刷新50次。电子枪从左到右画出像素,每次扫描一条线,画下一条之前要先回到左边并做好画下一条扫描线的准备,这之间有一段时间叫做水平消隐(HBlank)

画完全部扫描线后,又回到屏幕左上交准备画下一帧,这一段时间就是垂直消隐(VBlank)

对于CMOS Sensor来说,也有VBlank和HBlank的概念,Rolling Sensor在曝光时候 一次曝光一行,一般CMOS只有一行ADC用于转换电信号,转换好的数字信号逐像素顺序数据,每一行输出结束和下一行输出开始的间隔我们称为行消隐(HBlank),这一帧结束到下一帧开始这段时间称为场消隐(VBlank).如图2所示

d162a61c549b4d6caabb5160888474af.png

图2 CMOS sensor读出情况

每行耗费的cycle数,这帧图片一共有多少行通过如下参数说明:

6da16ecccab34950b3d8c0ec2d113e8c.png

pix_xx变量的意义。

2fc53dd8e2964132a8c1c3c607389c0a.png

二、RTL实现

我写的verilog实现demosaic并不好哈,如没有考虑到资源的优先利用,也没有考虑到把数据存储到外接memory中,毕竟我的目的是用UVM验证RTL代码,搭建的UVM框架才是我的意图

2.1 端口介绍

【1】输入端口包括:

1 cycle内DUT接收2行4列共8个像素,i_data_0 ---- i_data_7

每帧图像开始的标志:i_pvsync   p是per,v是vertical direction    ;

图像每行开始的标志:i_phsync   p是per,h是horizontal direction;

每行使能信号:i_data_en,其为高,DUT的输入为pixel值、否则输入为0;

【2】输出端口包括

1 cycle内DUT输出2行4列共8个像素、且RGB三通道,

       o_data_R_0 ---- o_data_R_7,o_data_G_0 ---- o_data_G_7,o_data_B_0 ---- o_data_B_7

每帧图像开始处理的标志:o_pvsync,   p是per,v是vertical direction    ;

图像每行开始处理的标志:o_phsync,   p是per,h是horizontal direction;

每行输出的使能信号:o_data_en,其为高,DUT的输出为内部算法计算的值、否则输出为0;

其中,i_phsync, o_phsync与i_pvsync o_pvsync,  i_data_en, o_data_en的延迟时间相等。

2.2 使用的memory个数

         会用到三条memory,每条的深度为 图像的宽度,bit位宽为1个字节(默认输入像素值是1字节),即存三行数据。

        代码中实现memory也非常简单,就是定义一个数组,这代码中的缺陷之一,如果您有很好的解决办法,可以给出对应解决方案。

2.3 延迟情况:

         延迟1行(图像宽度/channel_h+HBLANK+H_pulse)+2cycle;

        代码中使用移位寄存器实现,这会相当浪费资源,也是代码中的缺陷之一。如果您有很好的解决办法,可以给出对应解决方案。另外,书籍《基于FPGA的数字图像处理原理及应用》4.2.1节设计给出了其中一种解决方法

2.4 代码实现:

/*
 * ISP - 反马赛克(Demosaic)处理 
   image sensor处理后的 bayer类型图像转为  -> R, Gr, Gb, B 图像
 */

module isp_demosaic #(
	parameter BITS          = 8, //支持8/16/24/32
	parameter H_frontporch  = 50,
	parameter H_PULSE       = 1,
	parameter H_backporch   = 50,
	parameter HEIGHT        = 512,
	parameter V_frontporch  = 10,
	parameter V_PULSE       = 1,
	parameter V_backporch   = 10,
	parameter WIDTH         = 768,
    parameter h_chan        = 4,
    parameter v_chan        = 2,
    parameter BAYER         = "rggb"
)(
    input                   xclk      ,
    input                   rst_n     ,
    input                   i_data_en ,
    input                   i_phsync  ,
    input                   i_pvsync  ,
    input   [BITS-1:0]      i_data_0  ,
    input   [BITS-1:0]      i_data_1  ,
    input   [BITS-1:0]      i_data_2  ,
    input   [BITS-1:0]      i_data_3  ,
    input   [BITS-1:0]      i_data_4  ,
    input   [BITS-1:0]      i_data_5  ,
    input   [BITS-1:0]      i_data_6  ,
    input   [BITS-1:0]      i_data_7  ,

    output                  o_data_en ,
    output                  o_phsync  ,
    output                  o_pvsync  ,

    output   [BITS-1:0]     o_data_r_0  , o_data_g_0 ,  o_data_b_0 ,
    output   [BITS-1:0]     o_data_r_1  , o_data_g_1 ,  o_data_b_1 ,
    output   [BITS-1:0]     o_data_r_2  , o_data_g_2 ,  o_data_b_2 ,
    output   [BITS-1:0]     o_data_r_3  , o_data_g_3 ,  o_data_b_3 ,
    output   [BITS-1:0]     o_data_r_4  , o_data_g_4 ,  o_data_b_4 ,
    output   [BITS-1:0]     o_data_r_5  , o_data_g_5 ,  o_data_b_5 ,
    output   [BITS-1:0]     o_data_r_6  , o_data_g_6 ,  o_data_b_6 ,
    output   [BITS-1:0]     o_data_r_7  , o_data_g_7 ,  o_data_b_7 ,

    output                  done       );


    localparam H_transfercycle = WIDTH  / h_chan;
    localparam V_transferline  = HEIGHT / v_chan;
	localparam H_totalcycle    = H_frontporch + H_PULSE + H_transfercycle + H_backporch ;
	localparam V_totalline     = V_frontporch + V_PULSE + V_transferline  + V_backporch ;

    localparam integer H_bit   = clogb2(HEIGHT-1);
    localparam integer V_bit   = clogb2(WIDTH -1);
    localparam integer num3    = clogb2(H_totalcycle -1);


    // 延迟1行linedelay + DLY_CLK 个cycles
    // 这种延迟方式太太太浪费资源了,需要使用新的方式来实现
    localparam DLY_CLK = H_totalcycle + 2;
    
    reg        [H_totalcycle-1:0] data_en_tmp_dly;
    reg        [DLY_CLK     -1:0]     data_en_dly;
    reg        [DLY_CLK     -1:0]      pvsync_dly;
    reg        [DLY_CLK     -1:0]      phsync_dly;
    
    always @ (posedge xclk or negedge rst_n) begin
        if (!rst_n) begin
            data_en_tmp_dly <= 0;
            data_en_dly     <= 0;
            pvsync_dly       <= 0;
            phsync_dly       <= 0;
        end else begin
            data_en_tmp_dly <= {data_en_tmp_dly[H_totalcycle-2:0], i_data_en};
            data_en_dly     <= {data_en_dly    [DLY_CLK     -2:0], i_data_en};
            pvsync_dly      <= { pvsync_dly    [DLY_CLK     -2:0], i_pvsync };
            phsync_dly      <= { phsync_dly    [DLY_CLK     -2:0], i_phsync };
        end
    end

    // 处理 o_data_en,存在 "1"行 的line_delay , 且要延迟i_data_en 1个cycle
    assign o_data_en   = data_en_dly[DLY_CLK-1];
    assign o_pvsync    =  pvsync_dly[DLY_CLK-1];
    assign o_phsync    =  phsync_dly[DLY_CLK-1];
    
    wire   data_en_tmp = data_en_tmp_dly[H_totalcycle-1];


    // 处理列数: col_cnt;  
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值