手把手教你搞定DSP C6747与FPGA的EMIF通信:从寄存器配置到地址映射实战
手把手教你搞定DSP C6747与FPGA的EMIF通信:从寄存器配置到地址映射实战
在嵌入式系统开发中,DSP与FPGA的协同设计已经成为高性能信号处理、通信系统等领域的标配方案。而EMIF(External Memory Interface)作为两者之间的桥梁,其稳定可靠的通信是实现系统功能的关键。本文将从一个实际工程案例出发,带你深入理解TI C6747 DSP与Xilinx 7系列FPGA通过EMIF接口通信的全过程。
1. EMIF接口基础与硬件连接
EMIF是DSP与外部存储器或外设通信的重要接口,C6747 DSP提供了EMIFA和EMIFB两个独立的EMIF接口。在我们的案例中,使用的是16位数据总线宽度的EMIFA接口。
1.1 硬件连接要点
开发板上DSP与FPGA的EMIF连接通常包括以下信号线:
- 数据总线:EMIFA_D[15:0] - 16位双向数据总线
- 地址总线:EMIFA_A[12:0] - 13位地址总线
- 片选信号:EMIFA_CS[2:5] - 4个异步存储器片选信号
- 控制信号:
- EMIFA_WE - 写使能(低电平有效)
- EMIFA_OE - 读使能(低电平有效)
- EMIFA_BA[1:0] - 字节地址信号
提示:在PCB设计阶段,需要特别注意EMIF信号线的等长匹配,特别是高速应用场景下,信号完整性对通信稳定性至关重要。
1.2 片选信号与地址空间
C6747 DSP的EMIFA接口提供了4个片选信号(CS2-CS5),每个片选对应不同的地址空间:
| 片选信号 | 地址范围 | 空间大小 |
|---|---|---|
| CS2 | 0x4000 0000 | 32MB |
| CS3 | 0x4200 0000 | 32MB |
| CS4 | 0x6400 0000 | 32MB |
| CS5 | 0x6600 0000 | 32MB |
在我们的案例中,使用的是CS4片选信号,对应的基地址为0x64000000。
2. EMIF寄存器配置详解
正确配置EMIF相关寄存器是确保通信正常的第一步。C6747 DSP的EMIFA接口主要有三类配置寄存器需要关注。
2.1 AWCCR寄存器配置
AWCCR(Asynchronous Wait Cycle Configuration Register)用于配置异步访问的等待周期:
AEMIF_AWCCR = 0xFF; // 二进制:1111_1111这个配置值表示:
- 读/写建立时间:15个EMIF时钟周期
- 读/写选通时间:15个EMIF时钟周期
- 读/写保持时间:15个EMIF时钟周期
2.2 CEnCFG寄存器配置
CEnCFG(Asynchronous n Configuration Register)用于配置特定片选的时序参数和数据总线宽度。对于CS4(对应AEMIF_A3CR寄存器),我们使用以下配置:
AEMIF_A3CR = 0x9844C2D; // 二进制:0000_1001_1000_0100_1100_0010_1101这个配置值的各个字段含义如下:
| 字段 | 值 | 含义 |
|---|---|---|
| W_SETUP | 0x09 | 写建立时间 = 10个周期 |
| W_STROBE | 0x84 | 写选通时间 = 133个周期 |
| W_HOLD | 0xC2 | 写保持时间 = 3个周期 |
| R_SETUP | 0x0D | 读建立时间 = 14个周期 |
| R_STROBE | 0x84 | 读选通时间 = 133个周期 |
| R_HOLD | 0xC2 | 读保持时间 = 3个周期 |
| TA | 0x01 | 开启Turnaround周期 |
| ASIZE | 0x01 | 16位数据总线宽度 |
2.3 NANDFCR寄存器
NANDFCR(NAND Flash Control Register)主要用于NAND Flash控制,在普通异步存储器接口应用中通常不需要修改。
3. 地址映射原理与实践
理解DSP逻辑地址与FPGA物理地址之间的映射关系是调试EMIF通信的关键环节。
3.1 逻辑地址与物理地址
- 逻辑地址:DSP程序中访问的地址,如0x64000140
- 物理地址:实际出现在EMIF地址总线上的信号组合
对于16位数据总线宽度,物理地址的计算公式为:
cpu_addr[13:0] = {emif_a[12:0], emif_ba[1]};3.2 地址转换实例分析
以逻辑地址0x64000140为例,其偏移量为0x140:
- 将0x140转换为二进制:0000 0001 0100 0000
- 去掉最后两位(字节地址):0000 0001 0100 00
- 第6位由0变为1:000 0001 1100 00
- 最终物理地址:emif_a[12:0] = 0000001110000
这个转换关系可以通过以下代码片段验证:
#define TEST_ADDR (*((volatile unsigned short*)(0x64000140)))3.3 常见地址映射问题
在实际调试中,地址映射常会遇到以下问题:
- 地址对齐错误:16位总线宽度下,地址必须是2字节对齐的
- 字节序问题:DSP和FPGA对数据的字节序理解可能不一致
- 地址转换错误:物理地址计算与预期不符
注意:不同厂商的FPGA开发工具对地址线的处理方式可能不同,需要仔细核对原理图和约束文件。
4. 双向通信实现与调试技巧
实现DSP与FPGA之间的可靠双向通信是EMIF接口应用的最终目标。
4.1 FPGA向DSP发送数据
FPGA端代码示例:
always @(posedge clk) begin case(emif_a[12:0]) // FPGA->DSP 11'b0000001110000: cpu_dr <= 411; // 对应DSP地址0x64000140 11'b0000001110001: cpu_dr <= 211; // 对应DSP地址0x64000144 endcase end assign emif_d[15:0] = (~emif_oe) ? cpu_dr : {16{1'bZ}};DSP端读取代码:
while(1) { short rdval1 = (*((volatile unsigned short*)(0x64000140))); short rdval2 = (*((volatile unsigned short*)(0x64000144))); printf("rdval1 = %d \r\n", rdval1); printf("rdval2 = %d \r\n", rdval2); }4.2 DSP向FPGA发送数据
DSP端写入代码:
#define WRITE_TEST1 (*((volatile unsigned short*)(0x64000148))) #define WRITE_TEST2 (*((volatile unsigned short*)(0x6400014c))) WRITE_TEST1 = 0x5555; WRITE_TEST2 = 0x6666;FPGA端接收代码:
reg [15:0] write_test1, write_test2; always @(posedge clk) begin case(emif_a[12:0]) // DSP->FPGA 11'b0000001110010: write_test1 <= emif_d[15:0]; // 对应DSP地址0x64000148 11'b0000001110011: write_test2 <= emif_d[15:0]; // 对应DSP地址0x6400014c endcase end4.3 调试技巧与常见问题
信号完整性检查:
- 使用示波器检查EMIF时钟和数据线信号质量
- 确认信号幅度、上升/下降时间符合要求
时序分析:
- 验证建立/保持时间是否满足器件要求
- 必要时调整AWCCR和CEnCFG寄存器中的时序参数
调试工具:
- 使用CCS的Memory Browser查看DSP端数据
- 利用FPGA的SignalTap或ChipScope观察FPGA端信号
常见错误:
- 数据线接反或错位
- 片选信号未正确使能
- 时序参数设置不合理
5. 性能优化与高级应用
在基本通信功能实现后,我们可以进一步优化EMIF接口的性能和可靠性。
5.1 时序优化策略
通过调整EMIF寄存器参数,可以在速度和稳定性之间取得平衡:
- 减少等待周期:在信号质量允许的情况下,适当减少AWCCR中的等待周期
- 优化建立/保持时间:根据实际测量结果调整CEnCFG中的时序参数
- 使用EDMA:利用DSP的EDMA控制器实现高效数据传输
5.2 大数据量传输方案
对于需要传输大量数据的应用,可以考虑以下方案:
- 双缓冲机制:在FPGA端实现双缓冲,避免数据丢失
- 块传输模式:配置EMIF支持突发传输,提高传输效率
- 数据打包:将多个数据打包成32位或更大宽度传输
5.3 错误检测与处理
为提高系统可靠性,可以增加以下错误检测机制:
- CRC校验:对传输的数据添加CRC校验字段
- 超时检测:设置通信超时机制,防止死锁
- 状态反馈:FPGA向DSP反馈数据接收状态
在实际项目中,EMIF接口的调试往往需要反复验证和优化。记得保存每个阶段的配置和测试结果,这不仅能帮助定位问题,也能为后续项目积累宝贵经验。
