• 生成3x3矩阵(1):FIFO法


      在对图像进行处理时经常用到矩阵操作,本篇博客介绍一下用两个FIFO生成 3x3 矩阵的方法,并对其进行验证。

      要求:模拟一张分辨率为 10x5 的图片,图片的数据为 1~50,对其生成 3x3 矩阵,以便后面的图像处理。

       testbench:数据的使能和数据对齐,每隔 10 个数据就空闲小段时间,每隔 50 个数据又空闲一段时间,模仿图像帧的样子,如下所示:

     

    一、计数器行列规划

      数据是 1-50,分为 10 列 5 行,而数据本身是没有行列概念的,因此要用两个计数器对数据行列规划。

      第一个计数器为 col_cnt,计10下。第二个计数器为 row_cnt,计5下。这样数据就人为的划分成了10x5,如下图所示:

    二、调用两个FIFO形成3行数据

      1、生成一个同步 FIFO IP核,深度只要是超过 2 行的数据个数就行,例如这里一行数据个数是10个,FIFO的深度就选为32。模式选为 normal(standard)模式,其他信号都不勾选。

      2、设计3x3模块,调用两次 FIFO IP 核,两个FIFO写数据相同,都是本模块进来的数据 din,两个FIFO的各种信号按后缀 1 和 2 来区分。两个FIFO的读写信号示意图如下所示:

    这样设置的话,从第 3 行 din 来开始,q_1、q_2 和新进来的数据din就能形成 3 行平行数据,代码书写如下:

    assign wr_en_1 = (cnt_row < 4) ? din_vld : 1'b0; //不写最后1行
    assign rd_en_1 = (cnt_row > 0) ? din_vld : 1'b0; //从第1行开始读
    assign wr_en_2 = (cnt_row < 3) ? din_vld : 1'b0; //不写最后2行
    assign rd_en_2 = (cnt_row > 1) ? din_vld : 1'b0; //从第2行开始读

      3、这样操作后生成的仿真波形如下所示:

      由波形看到 din_r(din打了一拍)和 q_1、q_2 信号在第三行数据时变成了平行的三行数据。 din 信号需要打一拍是因为此次使用的FIFO模式为normal(standard)模式,给出其读使能后过 1clk 后才出数据 q,因此 din 打了一拍后就能和 q_1、q_2 对齐了。如果 FIFO 使用的是 show-ahead(first word fall through)模式则不需要对 din 信号进行打拍就能对齐。

      从波形中还可以得出一些信息:

      (1)来前两行数据时,din_r 和 q_1、q_2 形成的三行数据不完整,从第3行数据时才完整。

      (2)din_r、q_1、q_2的顺序和我们的数据排列相比是倒的,符合人的正常思维的顺序是:q_2、q_1、din_r。

      (3)形成3行数据后,由于FIFO选用的是 normal(standard)模式,din数据打了一拍,所以整个过程消耗了 1clk。

    三、打 3 拍形成 3x3 矩阵

      获得了上述的波形后,我们采用打拍即可完成矩阵的生成,上面说了数据是倒的,因此选择矩阵数据时把编号给正过来。

    //矩阵数据选取,1clk
    //---------------------------------------------------
    assign row_1 = q_2;
    assign row_2 = q_1;
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            row_3 <= 'd0;
        else
            row_3 <= din;
    end

      这里 row_3 就是原本的 din_r,命名将顺序正过来,后面打拍也就更能理解了。

    //打拍形成矩阵,矩阵顺序归正,1clk
    //---------------------------------------------------
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            {matrix_11, matrix_12, matrix_13} <= {8'd0, 8'd0, 8'd0};
            {matrix_21, matrix_22, matrix_23} <= {8'd0, 8'd0, 8'd0};
            {matrix_31, matrix_32, matrix_33} <= {8'd0, 8'd0, 8'd0};
        end
        else begin
            {matrix_11, matrix_12, matrix_13} <= {matrix_12, matrix_13, row_1};
            {matrix_21, matrix_22, matrix_23} <= {matrix_22, matrix_23, row_2};
            {matrix_31, matrix_32, matrix_33} <= {matrix_32, matrix_33, row_3};
        end
    end

      最后形成的矩阵波形如下所示:

      由波形见得,最后生成的矩阵是成功的,该矩阵的观看顺序是从上到下,一列一列的看,例如第一个矩阵是:{000,000,001},第二个矩阵是:{000,000,012}。此外由于矩阵是打拍形成的,也耗费了 1clk 。至此,我们的 3x3 矩阵就生成了,总共耗费 2clk,即两个时钟周期。

    四、问题引出

      如果只是做到这样,其实已经能做图像处理了,但是细细品味这些波形会发现很多小问题。我们会产生一些疑问:

      (1)换行时的数据很怪,如第 4 行数据的第一个矩阵是{10,10,11,20,20,21,30,30,31},这是什么鬼?

      (2)换帧时的数据更怪,虽然第一帧图片前面的矩阵很多都是0,但第二帧图片前面的矩阵很多都是上一帧图片遗留的数据,怎么办?

      (3)这个矩阵进行图像处理的实际效果怎么样?

      (4)show-ahead(first word fall through)模式的话又会是什么情况?

      (5)对于上面的问题,有改进的办法吗?

       这篇博客已经有些长度了,对这些问题我们下篇博客继续分析!

    参考资料:

        [1]V3学院FPGA教程

  • 相关阅读:
    python之集合(set)
    python之字典
    python之列表
    随笔
    JS实现颜色值格式转换 rgb和十六进制的转换
    20211025一周的计划
    密码肯定没错,但是你死活登录不了,登录页面检查密码格式不对,无法执行登录的一种解决方法
    安卓mbn文件丢失,无法搜索移动信号,工程模式mbn乱改,不用QPST烧录怎样恢复?超简单!
    安装Linux Deploy和Termux之后,再安装ftp服务软件都是多余的!
    “500 oops socket” Debian 9 running via Linux Deploy上成功部署vsftpd的解决方案(201901原创)【成功完美简单极致】
  • 原文地址:https://www.cnblogs.com/xianyufpga/p/12401085.html
Copyright © 2020-2023  润新知