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的连接图:

其实也就只有1个比较重要的寄存器,即CEnCFG。该寄存器有两套完全不同的配置。分别对应于同步存储器模式和异步存储器模式。由于FPGA内部RAM工作于同步模式,故我们来看一下同步模式下该寄存器的配置。

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个周期的读延时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | /*----------------------------------------------------------------------------------- * * 初始化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 } |
posted on 2018-10-19 01:43 limanjihe 阅读(21239) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~