EMIF接口與FPGA的互聯(轉)


reference: https://blog.csdn.net/ruby97/article/details/7539151

DSP6455的EMIFA模塊

之前介紹了DSP6455的GPIO和中斷部分。今天,繼續介紹EMIFA模塊。

關於C6000系列的GPIO,請參考:C6000系列DSP的GPIO模塊

關於C6000系列的中斷系統,請參考:C6000系列DSP的中斷系統


 

背景

      使用FPGA系統進行視頻采集,DSP進行視頻處理需要了解以下知識:

  • 1.  DSP-C6000系列的中斷與GPIO系統
  • 2.  DSP-C6000系列的EMIFA模塊
  • 3.  DSP-C6000系列的EDMA模塊
  • 4.  FPGA的乒乓RAM
  • 5.  一種視頻格式(例如VGA,PAL等)
  • 6.  視頻處理算法

 

之前已經介紹了第一部分,今天介紹第二部分。


 

主題

      EMIF是External Memory Interface的簡稱。個人認為它是DSP比較強大的地方之一。通過EMIF接口,使得DSP可以和FPGA很方便地進行大數據量的數據傳輸。

 

      C6455的EMIFA可以訪問多種外部存儲器,比如:SRAM,ROM,FLASH等等。當然,也包括FPGA。本文的重點就是介紹使用EMIFA接口與FPGA建立無縫連接。

 

--------------------------------------------華麗分割------------------------------------------------

 

EMIFA

根據習慣,還是先貼圖,框圖總給人一目了然的感覺。

 

 

這是官方文檔給出的EMIFA模塊的接口示意圖,乍一看,復雜的很。好多引腳而且還有好多復用。沒關系,我們再貼一張,你就會感覺輕松很多了。

 

 

 

 

這一張圖首先是把EMIFA模塊的接口分了類,然和呢,我把在與FPGA通信場合下所需要使用的管腳使用紅色框框標注了出來。是不是少了很多呢。歸納一下標注的管腳,如下:

  • AED[63:0]        64位數據總線
  • AEA[19:0]        20位地址總線(Optional)
  • ACE2              片選信號(低有效)
  • AECLKOUT      時鍾信號
  • ASWE             寫使能(低有效)
  • ASRE               讀使能(低有效)

(注:應用場合是DSP讀FPGA內部RAM中的圖像數據,其他場合續根據情況調整)

由於FPGA的可編程性,使得一切從DSP看來簡單了許多。因為DSP面對的“存儲器”顯得格外智能。甚至連地址線都可以不需要。

下面,我們來一一分析上述的信號。

  • 首先,應該是片選信號CE。這里不得不提到DSP的地址空間。下圖是DSP6455的EMIFA映射情況
 
從圖中可以看出:
  • EMIFA共支持4個外部存儲器,比如可以把CE2分配給FPGA,CE3分配給SRAM,CE4分配給FLASH等。
  • 每個外部存儲器的尋址空間大小是8MB。20根地址線即2的20次方,也就是1MB,此外由於數據總線是64位的,故對應的尋址空間是8MB

 

由於FPGA內部時序邏輯可以產生地址,所以我們可以不使用地址線。這樣,下面的事情就簡單了。只要把CE2管腳和FPGA的某一個通用IO口連上即可。

在讀取FPGA內部RAM數據時告訴EDMA要讀取的數據的基地址是0xA0000000,以及讀取的數據的長度即可。

  • 第二個信號,ECLKOUT,即時鍾信號的。因為FPGA工作是需要時鍾激勵的,沒有時鍾信號怎么產生地址邏輯呢?此外,時鍾頻率不能過高,要考慮到FPGA芯片的能力。OK,因為有了同步時鍾,所以EMIFA模塊的工作模式也就確定了,即同步工作模式。
  • 第三個信號,包括2個,即ASRE,ASWE。更熟悉的叫法是RE,WE。讀使能和寫使能。這個就不贅述了。
  • 第四個信號,數據總線&地址總線。也不贅述了。

經過上面的分析,我們可以簡要的畫出FPGA與DSP的連接圖:

 

 
 
 
在連接的思路清晰之后,我們可以開始配置EMIFA的寄存器了。

其實也就只有1個比較重要的寄存器,即CEnCFG。該寄存器有兩套完全不同的配置。分別對應於同步存儲器模式和異步存儲器模式。由於FPGA內部RAM工作於同步模式,故我們來看一下同步模式下該寄存器的配置。

 
SSEL設置為1時,表示該CE對應同步模式的外部存儲器。
在與FPGA連接時,主要考慮以下四個參數:
 
R_ENABLE 設置SRE/SADS管腳功能
值為 1 管腳功能為SRE,即Read Enable
值為 0 管腳功能為SADS

 

W_LTNCY 寫延時周期
值為 00 0周期延時
值為 01 1周期延時
值為 10 2周期延時
值為 11 3周期延時

 

R_LTNCY 讀延時周期
值為 01 1周期延時
值為 10 2周期延時
值為 11 3周期延時

 

讀延時:當CE和RE同時為低電平后,表示DSP開始讀FPGA的RAM,經過R_LTNCY個ECLKOUT周期后第一個數據出現在數據總線上

 

SBSIZE 數據位寬
值為 00 8位數據總線
值為 01 16位數據總線
值為 10 32位數據總線
值為 11 64位數據總線

 


 

 

EMIFA之CSL

使用CSL配置EMIFA模塊時,主要的步驟如下:

  • l  1. 使能設備EMIFA模塊
  • l  2. 配置CEnCFG寄存器
  • l  3. 初始化EMIFA模塊
  • l  4. 打開EMIFA模塊
  • l  5. 把2中配置的參數設置到打開的EMIFA模塊中

 

完整配置代碼:(把EMIFA的CE2配置為以FPGA作為外部存儲器,64位數據線,2個周期的讀延時)

 

 
/*-----------------------------------------------------------------------------------
 
*
 
* 初始化EMIFA
 
*
 
-----------------------------------------------------------------------------------*/
 
#define EMIFA_MEMTYPE_ASYNC 0
 
#define EMIFA_MEMTYPE_SYNC 1
 
 
 
#define EMIFA_CE2_BASE_ADDR (0xA0000000)//地址空間基地址
 
#define CSL_EMIFA_SYNCCFG_RLTNCY_PARAMETER 2//讀延時2周期
 
#define CSL_EMIFA_SYNCCFG_SBSIZE_PARAMETER 3//64位數據總線
 
#define CSL_EMIFA_SYNCCFG_READEN_PARAMETER	1//SRE
 
 
 
//CEnCFG寄存器參數宏
 
#define CSL_EMIFA_SYNCCFG_PARAMETER {\
 
(Uint8)CSL_EMIFA_SYNCCFG_READBYTEEN_DEFAULT, \
 
(Uint8)CSL_EMIFA_SYNCCFG_CHIPENEXT_DEFAULT, \
 
(Uint8)CSL_EMIFA_SYNCCFG_READEN_PARAMETER, \
 
(Uint8)CSL_EMIFA_SYNCCFG_WLTNCY_DEFAULT, \
 
(Uint8)CSL_EMIFA_SYNCCFG_RLTNCY_PARAMETER, \
 
(Uint8)CSL_EMIFA_SYNCCFG_SBSIZE_PARAMETER \
 
}
 
 
 
void Init_EMIF()
 
{
 
CSL_EmifaObj emifaObj;
 
CSL_Status status;
 
CSL_EmifaHwSetup hwSetup;
 
CSL_EmifaHandle hEmifa;
 
CSL_EmifaMemType syncVal;
 
CSL_EmifaSync syncMem = CSL_EMIFA_SYNCCFG_PARAMETER;
 
 
 
memset(&emifaObj, 0, sizeof(CSL_EmifaObj));
 
memset(&hwSetup, 0, sizeof(CSL_EmifaHwSetup));
 
 
 
//步驟1: 使能設備的EMIFA功能(不用先解鎖外設寄存器)
 
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, ENABLE);
 
 
 
//步驟2:配置CE2CFG寄存器
 
syncVal.ssel = EMIFA_MEMTYPE_SYNC;
 
syncVal.async = NULL;
 
syncVal.sync = &syncMem;
 
 
 
hwSetup.ceCfg[0] = &syncVal;
 
hwSetup.ceCfg[1] = NULL;
 
hwSetup.ceCfg[2] = NULL;
 
hwSetup.ceCfg[3] = NULL;
 
 
 
//步驟3:初始化EMIFA模塊
 
status = CSL_emifaInit(NULL);
 
 
 
#ifdef SHOW_PRINTF
 
if (status != CSL_SOK) {
 
printf("EMIFA: Initialization error.\n");
 
printf("\tReason: CSL_emifaInit [status = 0x%x].\n", status);
 
return;
 
}
 
else {
 
printf("EMIFA: Module Initialized.\n");
 
}
 
#endif
 
 
 
//步驟4:打開EMIFA模塊
 
hEmifa = CSL_emifaOpen(&emifaObj,CSL_EMIFA,NULL,&status);
 
 
 
#ifdef SHOW_PRINTF
 
if ((status != CSL_SOK) || (hEmifa == NULL)) {
 
printf("EMIFA: Error opening the instance. [status = 0x%x, hEmifa \
 
= 0x%x]\n", status, hEmifa);
 
return;
 
}
 
else {
 
printf("EMIFA: Module instance opened.\n");
 
}
 
#endif
 
 
 
//步驟5:把步驟2中配置的參數設置到打開的EMIFA模塊中
 
status = CSL_emifaHwSetup(hEmifa,&hwSetup);
 
#ifdef SHOW_PRINTF
 
if (status != CSL_SOK) {
 
printf("EMIFA: Error in HW Setup.\n");
 
printf("Read write operation fails\n");
 
return;
 
}
 
else {
 
printf("EMIFA: Module Hardware setup is successful.\n");
 
}
 
#endif
 
}

 

 


免責聲明!

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



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