天天看點

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

1)實驗平台:正點原子達芬奇FPGA開發闆

2) 摘自【正點原子】達芬奇之Microblaze 開發指南

3)購買連結:https://detail.tmall.com/item.htm?id=624335496505

4)全套實驗源碼+手冊+視訊下載下傳位址:http://www.openedv.com/docs/boards/fpga/zdyz_dafenqi.html

5) 正點原子官方B站:https://space.bilibili.com/394620890

6)對正點原子FPGA感興趣的同學可以加群讨論:876744900

第十一章RGB LCD彩條顯示實驗

在《達芬奇之FPGA開發指南》中“RGB_LCD彩條顯示實驗”介紹了如何在LCD液晶顯示屏上顯示彩條,本章我們将使用MicroBlaze軟核處理器在RGB TFT-LCD液晶屏上顯示彩條。本章包括以下幾個部分:

1111.1 簡介

11.2 實驗任務

11.3 硬體設計

11.4 軟體設計

11.5 下載下傳驗證

11.1簡介

本章将通過MicroBlaze處理器實作RGB LCD的彩條顯示,其實作思路是:MicroBlaze處理器産生彩條資料,并通過AXI4接口将資料寫入外部DDR3中。FPGA負責讀取外部DDR3中的彩條資料,然後将資料傳輸給内部LCD屏驅動子產品,以驅動外部RGB LCD屏顯示彩條。MicroBlaze隻進行DDR3的寫操作,而FPGA負責DDR3的讀操作。我們知道,在MicroBlaze的開發中,無論是對DDR3進行寫操作或者讀操作,都是将資料通過AXI4接口傳輸到DDR3控制器,然後DDR3控制器和外部DDR3做資料互動,是以需要我們熟悉掌握AX14的接口協定和時序,才能實作對DDR3的讀寫操作。

AXI4接口總共有三種類型,它們分别是AXI4(AXI4-Full)、AXI4-Lite和AXI4-Stream,不同的接口類型适用于不同的應用場景,下面對這三個接口做簡要說明。

AXI4-Full:最高性能的接口,适合存儲器映射的通信,支援每個位址階段最高256個資料傳輸周期的批量傳輸,最适合于更需要持久、高速性能的IP。

AXI4-Lite:AXI4-Full接口的輕量級版本,用于存儲器映射的單次資料通信會話。這個版本的好處是簡化了的接口占用較少的邏輯部分面積。這個版本不支援批量資料,隻支援每次傳輸單個資料,适合于需要最小硬體消耗的較低性能的IP。

AXI4-Stream:它沒有位址階段,是以不是存儲器映射。為流式資料的傳輸定義了單個通道,支援無數量限制的批量傳輸,最适合于需要持續固定資料流的應用。連接配接隻能是從主機到從機,是以如果需要雙向傳輸的話,兩個外圍裝置都必須是主機/從機相容類型的。

本次實驗需要通過AXI4接口源源不斷地從DDR3中讀出彩條資料,是以資料量較大,由于AXI4-Lite速度稍慢,不适合本實驗;AX14-Stream雖然本身占用資源不多,但是為了和AXI互聯子產品連接配接,需要接AXI DMA或者其它子產品,占的資源反而更多,而達芬奇開發闆資源有限,是以AXI4-Stream接口也不适合;AXI4(AXI4-Full)接口無論在資源占用還是速度方面均能滿足本實驗的需求,故本實驗采用的接口為AXI4。

AXI4協定具有5個獨立的通道,分别為:讀位址通道、讀資料通道、寫位址通道、寫資料通道和寫響應通道,通道之間互相獨立且存在差别。通信是由主機發起的,主機可以對從機進行資料的讀或寫操作。每次讀或寫操作都需要相應的讀位址通道或寫位址通道傳輸一個位址。資料傳輸使用寫資料通道來實作主機到從機的寫資料傳輸,資料傳輸使讀資料通道用來實作從機到主機的讀資料傳輸。下面以AXI4 IP核為例,詳細介紹AXI4協定的各通道和通道接口。

在本實驗中FPGA從外部DDR3中讀取資料,可視為主機,是以在例化、封裝IP時應選擇“Master”作為主機,接口名字以m_為字首(具體步驟會在本章中較長的描述,我們先直接拿來為大家講解相關的通道和接口)。AXI4 IP核未展時開如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.1 未展開時接口

上圖紅标1處為IP核的時鐘和複位信号,紅标2處M_AXI為通道接口,其他為資料驗證信号。下面展開紅标2處,介紹M_AXI接口,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.2 展開時通道和接口

在上圖中,以m_axi_aw_為字首的接口屬于寫位址通道;以m_axi_w_為字首的接口屬于寫資料通道;以m_axi_b_為字首的接口屬于寫響應通道;以m_axi_ar_為字首的接口屬于讀位址通道;以m_axi_r_為字首的接口屬于讀資料通道。

寫位址通道包含的信号及信号含義如下表所示:

表11.1.1 通道信号

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

寫資料通道包含的信号及信号含義如下表所示:

表11.1.2 通道信号

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

寫響應通道包含的信号及信号含義如下表所示:

表11.1.3 通道信号

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

讀位址通道包含的信号及信号含義如下表所示:

表11.1.4 通道信号

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)
韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

表11.1.5 通道信号

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

在進行資料傳輸的過程中,傳輸通道均使用valid/ready信号對傳輸過程的位址、資料、控制信号進行握手。使用雙向握手機制,valid和ready都有效的時候表示握手成功。下面将以位址通道為例介紹幾種常見的握手方式。

valid在ready前有效:主機先給出資料和控制資訊,同時驅動valid為高電平。一旦主機驅動valid為高,位址将保持不變,直到從機驅動ready信号為高。一旦從機驅動ready為高,則握手成功,在時鐘上升沿T3時刻開始進行位址。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.3 valid在ready之前

valid在ready後有效:從機在主機驅動valid前,就驅動了ready信号為高。一旦主機确定valid信号為高,則握手成功,在T3時刻開始傳輸位址。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.4 valid在ready之後

valid和ready同時有效:主機驅動valid和從機驅動ready同時發生,在T2時刻開始傳輸位址。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.5 valid和ready同時有效

AXI4讀通道結構如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.6讀通道結構

由上圖可知,主機首先傳遞位址和控制資訊給從機,之後從機将有效的位址上對應的讀資料批量讀資料發送給主機。在突發讀過程中,讀通道上典型的信号互動過程如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.7 突發讀信号互動

由上圖可知在讀位址通道中:主機在T0時間段内先提供位址m_axi_araddr,同時将m_axi_arvalid拉高;從機在T1時間段内将m_axi_arready拉高,表明從機可以接收位址;m_axi_aradd和m_axi_arready均為高時則握手成功,在T2時鐘上升沿時刻,開始傳輸位址。

在讀資料通道中:主機在T3時間段内将m_axi_rready拉高,表明主機可以接收資料;從機在T5時間段内提供讀資料同時将m_axi_rvalid拉高,表明資料D0有效可以讀出;m_axi_rvalid和m_axi_rready均為高時則握手成功,在T6時鐘上升沿時刻,開始傳輸資料D0。同理在T9、T10時鐘上升沿時刻,分别輸資料D1、D2。在T13時鐘上升沿時刻,從機拉高m_axi_rlast,表明D3是此次突發最後一個需要傳輸的資料。

AXI4寫通道結構如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.8寫通道結構

由上圖可知,主機首先傳遞位址和控制資訊,再發送批量寫資料給從機。從機接收完所有的資料後,從機發送一個寫響應信号給主機。突發寫過程中寫通道上典型的信号互動過程如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.9 突發寫信号互動

由上圖可知在寫位址通道中:主機在T0時間段内先提供位址m_axi_awaddr,同時将m_axi_awvalid拉高;從機在T1時間段内将m_axi_awready拉高,表明從機可以接收位址;m_axi_awaddr和m_axi_awready均為高時則握手成功,在T2時鐘上升沿時刻,開始傳輸位址。

在寫資料通道中:主機在T2時間段内先提供寫資料D0,同時将m_axi_awvalid拉高,表明該資料有效;從機在T3時間段内将m_axi_wready拉高,表明從機可以接收資料;m_axi_awvalid和m_axi_wready均為高時則握手成功,T4時鐘上升沿時刻,開始傳輸資料D0。同理,在T6、T8、T9時鐘上升沿時刻,分别傳輸資料D1、D2、D3;

在寫響應通道中:主機在T2時間段内将m_axi_bready拉高,表示主機可以接收來自從機的寫響應信号;從機接收此次突發最後一個傳輸的寫資料D3時,在T9時間段提供些響應信号OKAY,同時将m_axi_bvalid拉高,表明寫響應信号有效。m_axi_bvalid和m_axi_bready均為高時則握手成功,T10時鐘上升沿時刻,開始傳輸OKAY。注意:寫響應信号必須跟随最後一次突發的寫傳輸資料。

多個具有AXI4協定的裝置或子產品可以通過互聯子產品進行資料的互動。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.1.10 多機互聯

11.2實驗任務

本章的實驗任務是Microblaze處理器向DDR3中寫彩條資料,然後通過自定義的帶AXI接口的IP核将彩條資料從DDR3中讀出來,并顯示在RGB LCD液晶屏上(支援正點原子推出的所有RGB LCD屏)。

11.3硬體設計

根據簡介及實驗任務可知,彩條資料先由MicroBlaze寫入DDR3,之後被讀出并在LCD RGB液晶顯示屏上以彩條的形式呈現出來。由此我們可以畫出本次實驗的系統框圖,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.1系統框圖

在上圖中,LCD_RGB_TOP、AXI4_DDR_READ、AXI4_Lite_COMM都是自定義的IP核。

具體的資料流走向:LCD_RGB_TOP首先識别螢幕ID(LCD_ID),MicroBlaze軟核根據螢幕ID将對應的彩條資料寫入DDR3中,接着AXI4_DDR_READ通過AXI4協定并根據螢幕ID将彩條資料讀出至FIFO緩存,資料最後經過驅動子產品LCD_RGB_TOP後在LCD螢幕上顯示出彩條。

LCD_RGB_TOP子產品是由《達芬奇FPGA開發指南》之“RGB_LCD彩條顯示實驗”的代碼子產品改動後封裝而來,具體的修改會在之後詳細說明。此子產品用于識别外部接入的的RGB888 TFT-LCD螢幕産生螢幕ID,并将螢幕ID傳遞給AXI4_Lite_COMM子產品和AXI4_DDR_READ子產品;另外接收并且驅動被讀出的彩條資料在螢幕上展示彩條。

AXI4_Lite_COMM是自定義的帶有AXI4接口的IP核,用來傳輸外設的參數,在本實驗中傳輸的是螢幕ID。AXI4_Lite_COMM可使用AXI GPIO IP核進行代替,但AXI4_Lite_COMM的優勢在于今後能連接配接更多的外設進行更多的參數傳輸,不用為每一個外設都例化AXI GPIO IP核,是以可以大大減少資源使用量。考慮到達芬奇的資源量以及後續工程的開發,建議使用AXI4_Lite_COMM IP核進行參數傳輸。

AXI4_DDR_READ IP核是先例化一個帶有AXI4接口IP核,然後根據我們的需求修改後再進行封裝而成的IP核。該IP核根據螢幕ID,确定DDR3的幀緩存空間大小,通過AXI4接口讀出顯示資料并傳輸給後級FIFO。注意,因為本實驗隻需要讀取DDR3中的彩條資料,是以在修改時隻啟用讀功能即可,無需啟用寫功能。如果在後續的開發中,比如使用攝像頭采集圖像并将圖像資料寫入DDR3,最後在LCD屏顯示實時圖像,這時此IP核的寫功能也要被啟用。

在硬體環境搭建之前,先進行上述3個IP核的封裝和自定義。

(1)AXI4_DDR_READ IP核的封裝

首先建立axi4_ddr_read檔案夾。打開Vivado軟體,軟體啟動後在“Tasks”一欄選擇“Manage IP”,然後點選“New IP Location…”,将工程定位在axi4_ddr_read下,點選“Finish”。接着在菜單欄中點選“Tools”,然後在下拉清單中選擇“Create and Package New IP”,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.2建立IP核

在彈出的對話框中點選“Next”,選擇“Create a new AXI4 Peripheral”,點選“Next”,IP核命名為axi4_ddr_read,位置自動填充在ip_repo下,點選“Next”。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.3 IP名稱

将接口命名為“M_AXI”,接口類型選擇“Full”(AXI4-Full),模式選擇“Master”(本實驗FPGA通過AXI4協定讀取外部DDR3中的資料,是以選擇Master作為主機),點選“Next”。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.4接口設定

選擇“Edit IP”,點選“Finish”。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.5 Edit IP核

稍等片刻,軟體就會建立一個IP核封裝工程,工程包含兩個具有AXI4協定完整讀寫功能的子產品。工程如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.6 axi4_ddr_read IP核封裝工程

工程的兩個檔案子產品檔案位置如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.7 子產品檔案位置

接下來用Notepad++打開兩個檔案,以便進行修改,依據實驗任務可知主要修改點為:彩條資料是由MicroBlaze産生并寫入DDR3中,不需要通過axi4_ddr_read寫資料,是以代碼可屏蔽寫相關邏輯。axi4_ddr_read根據螢幕ID從DDR3讀取彩條資料後并将彩條資料緩存到FIFO中,是以需要新增FIFO和螢幕ID的接口信号。本實驗不再采用狀态機的方式控制讀功能。

為了代碼的整潔和可讀性,我們對源代碼進行了修改和整理,隻保留了突發讀相關的代碼。下面将解釋說明修改後的AXI4協定實作讀功能的邏輯。打開axi4_ddr_read_v1_0_M_AXI子產品代碼:

  1. 33 // Users to add ports here
  2. 34 input [15:0] lcd_id,
  3. 35 input [11:0] fifo_wr_cnt,
  4. 36 output fifo_wr_en,
  5. 37 output [31:0] fifo_wr_data,

如上所示,子產品端口位置新增FIFO信号有fifo_wr_cnt、fifo_wr_en和fifo_wr_data,新增幕ID信号lcd_id。

  1. 570 //根據LCD ID,計算單幀圖像突發的次數
  2. 571 always @ (posedge M_AXI_ACLK) begin
  3. 572 if(M_AXI_ARESETN == 1'b0) begin
  4. 573 burst_end_counter <= 12'd750;
  5. 574 end
  6. 575 else begin
  7. 576 case (lcd_id)
  8. 577 16'h4342 : burst_end_counter <= 12'd255; //480*272*16/32/256 = 255
  9. 578 16'h4384 : burst_end_counter <= 12'd750; //800*480*16/32/256 = 750
  10. 579 16'h7084 : burst_end_counter <= 12'd750; //800*480*16/32/256 = 750
  11. 580 16'h7016 : burst_end_counter <= 12'd1200; //1024*600*16/32/256 = 1200
  12. 581 16'h1018 : burst_end_counter <= 12'd2000; //1280*800*16/32/256 = 2000
  13. 582 default : burst_end_counter <= 12'd750;
  14. 583 endcase
  15. 584 end
  16. 585 end

本段代碼,實作了由螢幕ID(lcd_id)計算單幀圖像對應的讀突發次數的功能。不同分辨率螢幕的lcd_id不同,對應的突發次數也不同,但計算方法是一樣的,如800*480*16/32/256 = 750。其中,800*480為螢幕分辨率;16為RGB565格式的彩條資料位寬;32為突發傳輸資料的位寬;256為每次突發要傳輸的資料個數;最終得出計算結果分辨率為800*480的螢幕對應的突發次數為750次。

  1. 587 //根據FIFO資料個數,産生開始突發讀信号
  2. 588 always @ (posedge M_AXI_ACLK) begin
  3. 589 if(M_AXI_ARESETN == 1'b0 || reads_done == 1'b1) begin
  4. 590 start_single_burst_read <= 1'b0;
  5. 591 end
  6. 592 else begin
  7. 593 if((~axi_arvalid) && (~burst_read_active) && (~start_single_burst_read)
  8. 594 && (fifo_wr_cnt <= 12'd256)) begin
  9. 595 start_single_burst_read <= 1'b1;
  10. 596 end
  11. 597 else begin
  12. 598 start_single_burst_read <= 1'b0;
  13. 599 end
  14. 600 end
  15. 601 end

本段代碼用于驅動突發讀開始信号tart_single_burst_read,第593至596行代碼表明:在讀位址通道的axi_arvalid為低、未正在進行突發讀資料傳輸、緩存FIFO非滿的時将該信号拉高,此時進行突發讀資料傳輸,往緩存FIFO中寫入資料。由于每次突發讀傳輸的資料個數為256(C_M_AXI_BURST_LEN),是以一次突發讀往緩存FIFO中寫入256個資料。第一次突發讀寫入FIFO的256個資料,被讀出1個後,FIFO非滿,即可允許下一次突發讀,此時假設極端情況,下一次突發讀的資料全部存入FIFO,是以緩存FIFO至少容納的資料個數為256-1+256 = 511。保險起見,在後續設計例化緩存FIFO時,其深度設定為1024或更大。

  1. 613 //讀資料通道axi_rready
  2. 614 always @(posedge M_AXI_ACLK)
  3. 615 begin
  4. 616 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 )
  5. 617 begin
  6. 618 axi_rready <= 1'b0;
  7. 619 end
  8. 622 else if (M_AXI_RVALID)
  9. 623 begin
  10. 624 if (M_AXI_RLAST && axi_rready)
  11. 625 begin
  12. 626 axi_rready <= 1'b0;
  13. 627 end
  14. 628 else
  15. 629 begin
  16. 630 axi_rready <= 1'b1;
  17. 631 end
  18. 632 end
  19. 634 end

本段代碼驅動讀資料通道的主機axi_rready信号,以此表明主機是否可以接收來自從機的讀資料。第622行代碼表示握手信号M_AXI_RVALID在axi_rready之前有效。第624行至627行代碼表明本次突發讀傳輸最後一個資料完成後将axi_rready拉低,主機不再接收資料。第629行至631行代碼表明突發傳輸不是最後一個資料,axi_rready一直拉高。ILA中axi_rready信号波形如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.8 axi_rready信号波形

由上圖可知,在讀資料通道上,主機在從機RVALID拉高後将RREADY拉高,資料開始突發傳輸,之後在突發傳輸最後資料标志RLAST為低的過程中,突發資料一直有效。

  1. 637 //讀位址通道axi_arvalid
  2. 638 always @(posedge M_AXI_ACLK)
  3. 639 begin
  4. 640 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 )
  5. 641 begin
  6. 642 axi_arvalid <= 1'b0;
  7. 643 end
  8. 645 else if (~axi_arvalid && start_single_burst_read)
  9. 646 begin
  10. 647 axi_arvalid <= 1'b1;
  11. 648 end
  12. 649 else if (M_AXI_ARREADY && axi_arvalid)
  13. 650 begin
  14. 651 axi_arvalid <= 1'b0;
  15. 652 end
  16. 653 else
  17. 654 axi_arvalid <= axi_arvalid;
  18. 655 end

本段代碼驅動讀位址通道的主機axi_arvalid信号,表明位址是是否有效。第645行至648行代碼表明未進行位址傳輸時允許進行傳輸。第649行至652行代碼表明位址通道握手信号握手成功後,将axi_arvalid拉低,axi_arvalid持續一個周期的高狀态。在ILA中觀察axi_arvalid波形如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.9 axi_arvalid信号波形

由上圖可知,在讀位址通道上,主機在從機将ERREADY拉高後将AVALID拉高,此時位址有效,位址通道突發傳輸位址0x85016800。

  1. 658 //Next address after ARREADY indicates previous address acceptance
  2. 659 always @(posedge M_AXI_ACLK)
  3. 660 begin
  4. 661 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 )
  5. 662 begin
  6. 663 axi_araddr <= 'b0;
  7. 664 end
  8. 665 else if (M_AXI_ARREADY && axi_arvalid)
  9. 666 begin
  10. 667 axi_araddr <= axi_araddr + burst_size_bytes;
  11. 668 end
  12. 669 else
  13. 670 axi_araddr <= axi_araddr;
  14. 671 end

本段代碼用來計算在位址通道上的下次突發讀資料的位址。burst_size_bytes為每次突發讀256個資料的總位元組數。

674 assign rnext = M_AXI_RVALID && axi_rready;

675 assign fifo_wr_en = rnext;

676 assign fifo_wr_data = {M_AXI_RDATA[15:0],M_AXI_RDATA[31:16]};

本段代碼驅動緩存FIFO的端口信号,功能是将突發讀資料寫入到外部緩存FIFO中。由第674可知,資料通道的M_AXI_RVALID與axi_rready握手成功,此時突發讀資料有效,可以被寫入至外部緩存FIFO。握手信号與突發讀傳輸資料波形如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.10 突發讀資料有效

結合上圖和FIFO的端口信号可知,在讀資料通道上,當從機RREADY和主機RVALD同時為高時,即可将突發資料寫入到緩存FIFO中。

  1. 683 //突發次數計數
  2. 684 always @(posedge M_AXI_ACLK)
  3. 685 begin
  4. 686 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 )
  5. 687 begin
  6. 688 read_burst_counter <= 'b0;
  7. 689 end
  8. 690 else if (M_AXI_ARREADY && axi_arvalid)
  9. 691 begin
  10. 692 if (read_burst_counter <= burst_end_counter - 1'b1)
  11. 693 begin
  12. 694 read_burst_counter <= read_burst_counter + 1'b1;
  13. 695 end
  14. 696 end
  15. 697 else
  16. 698 read_burst_counter <= read_burst_counter;
  17. 699 end

    本段代碼用來統計已經突發的次數read_burst_counter,由第690至第696行代碼可知,突發次數在位址通道握手信号握手成功時進行累加,一個有效位址對應一次突發。

  1. 704 //突發已經傳輸的的資料個數計數
  2. 705 always @(posedge M_AXI_ACLK)
  3. 706 begin
  4. 707 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 || start_single_burst_read)
  5. 708 begin
  6. 709 read_index <= 0;
  7. 710 end
  8. 711 else if (rnext && (read_index != C_M_AXI_BURST_LEN-1))
  9. 712 begin
  10. 713 read_index <= read_index + 1;
  11. 714 end
  12. 715 else
  13. 716 read_index <= read_index;
  14. 717 end

本段代碼用于對一次突發傳輸的資料個數進行統計。由第711行至714行代碼可知,資料通道上握手信号握手成功時read_index進行累加,一次突發傳輸的資料最大個數為256(C_M_AXI_BURST_LEN值)。

  1. 722 //突發傳輸有效
  2. 723 always @(posedge M_AXI_ACLK)
  3. 724 begin
  4. 725 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 || start_single_burst_read)
  5. 726 burst_read_active <= 0;
  6. 728 else if (start_single_burst_read)
  7. 729 burst_read_active <= 1'b1;
  8. 730 else if (M_AXI_RVALID && axi_rready && M_AXI_RLAST)
  9. 731 burst_read_active <= 0;
  10. 732 end

    本段代碼用于驅動burst_read_active信号,表明突發傳輸是否有效。由第728至729行代碼可知,在突發讀開始信号為高時将burst_read_active拉高,表明突發傳輸有效;由第730至731行代碼可知,如果本次突發讀傳輸的最後一個資料傳輸完畢,則将其拉低,表明傳輸無效,突發傳輸停止。

  1. 738 //所有次突發傳輸完成
  2. 739 always @(posedge M_AXI_ACLK)
  3. 740 begin
  4. 741 if (M_AXI_ARESETN == 0)
  5. 742 reads_done <= 1'b0;
  6. 743 else if (M_AXI_RVALID && axi_rready && (read_index == C_M_AXI_BURST_LEN-1) 744 &&(read_burst_counter == burst_end_counter))
  7. 745 reads_done <= 1'b1;
  8. 746 else
  9. 747 reads_done <= 1'b0;
  10. 748 end

本段代碼用于判斷所有突發次數的所有資料是否傳輸完成。第743行至745行代碼可知,read_index == C_M_AXI_BURST_LEN-1用于判斷一次突發所有資料傳輸完成,read_burst_counter == burst_end_counter用于判斷突發的次數達到要求。比如,lcd_id為7084,需要750次突發,從第0次開始突發一直到第750次突發的第256個資料傳輸完成時,拉高reads_done,表明所有資料全部突發完畢。

修改完axi4_ddr_read_v1_0_M_AXI子產品後注意要儲存!在其例化時新增FIFO和螢幕ID的信号,屏蔽不需要的資料驗證信号。頂層子產品axi4_ddr_read_v1_0做對應的接口處理。修改後注意要儲存!axi4_ddr_read_v1_0子產品修改後如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.11 axi4_ddr_read_v1_0接口

至此,經過如上代碼的修改,我們希望該代碼能夠完成隻啟用AXI4協定的讀功能,并且将讀出的資料緩存到了FIFO的功能。但是究竟能不能達到我們的理想,就需要封裝該IP并且進行驗證,那麼接下來我們就進行IP核的封裝。(注意,為避免大家在修改遺漏或錯誤導緻後續封裝的IP核不能正常使用,是以建議使用例程中的代碼檔案封裝IP核或使用例程中封裝好的IP核進行設計),例程中代碼檔案如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.12 例程中封裝IP核代碼檔案

拷貝例程中的代碼檔案替換原來的檔案後,回到之前的工程界面,并重新整理代碼,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.13 重新整理代碼檔案

此時右面的封裝界面還是替換之前的代碼檔案對應的封裝界面,需要關閉重新打開,重新打開後才是最新代碼檔案對應的封裝界面。點選右上角Package IP紅标處,關閉原來的封裝界面,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.14 關閉原來的封裝界面

點選左側菜單IP Catalog下的“Edit Package IP”,重新打開新代碼檔案對應的封裝界面,如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.15 點選Edit Package IP

打開新的封裝界面後,參考第十章IP核封裝過程在Identification中設定資訊、在Compatibility中設定相容性、在File Groups更新檔案組、在Customization Parameters重新整理定制變量。重新整理定制變量如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.16 重新整理變量

緊接着在“Ports and interface”界面可以看到,紅标1處的為通道接口;紅标2處的為時鐘和複位信号接口;紅标3處為我們添加的螢幕ID和FIFO信号接口。如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.17 信号接口

在下圖“Customization GUI”界面,紅标1處為封裝後的的IP核預覽圖;紅标2處為IP核傳遞的參數,這些參數值可在例化IP核時依據具體的需求設定。

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖11.3.18 IP核預覽

最後在“Review and Package”界面點選“Package IP”封裝IP,封裝IP核完成之後,在今後的工程如果需要調用該IP核,可以直接拷貝檔案夾axi4_ddr_read_1.0到工程中,并添加至工程即可。封裝完成後的IP核在如下路徑:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖11.3.19 IP核路徑

(2)LCD_RGB_TOP IP核的封裝

封裝該IP核用到的子產品檔案如下:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.20 子產品檔案

需要說明的是,這些子產品是在《達芬奇之FPGA開發指南》中“RGB_LCD彩條顯示實驗”的子產品代碼檔案基礎上修改而來,每個子產品可參考《達芬奇之FPGA開發指南》中的說明解釋。

由于本實驗在硬體設計是在Block Design中進行的,有些端口就會受到限制,比如雙向接口lcd_rgb(LCD資料)。在Block Design中設計硬體時,雙向接口會被綜合程單向輸出接口,是以我們就需要對lcd_rgb進行修改,由一個雙向端口修改為三個接口:一個方向接口,一個輸入接口和一個輸出接口。修改後如下圖所示:

韋東山 IMX6ULL和正點原子_「正點原子FPGA連載」第十一章RGB LCD彩條顯示(一)

圖 11.3.21 修改後的lcd_rgb接口

上一篇: DOS啟動過程
下一篇: 神船·神舟