生成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教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM