简介:围绕创龙Kintex-7与TMS320C6678的异构开发资料,面向FPGA工程师和DSP嵌入式开发者,适用于高速数据采集、信号处理及通信接口调试等场景。压缩包共971个文件、458MB,核心内容涵盖原理图与PCB设计文件(schdoc/pcbdoc)、FPGA约束与配置(xdc/bit/bin)、C语言源码及头文件、PDF应用笔记,以及TCL/Python等辅助脚本,覆盖从工程搭建到MIG、DMA、Aurora等常用IP核调试的完整链路。已有2054人学习下载。资料按功能模块组织,便于查阅;其中bin/out/elf等镜像文件可直接用于板卡验证,ccxml/gel文件可辅助CCS环境调试,bat脚本可快速启动开发环境与工程创建,适合希望快速上手K7+DSP平台或深入理解异构通信机制的开发者参考。
1. 创龙Kintex7+TM320C6678资料包:FPGA+DSP异构板卡,先看懂再动手
做高速信号处理的工程师,手里拿到一块创龙K7+C6678的开发板,第一反应往往是先翻资料包。这套板子把Xilinx Kintex-7 FPGA和TI TMS320C6678八核DSP做了异构,FPGA负责前端采集和接口扩展,DSP跑算法和协议栈,正好覆盖雷达、通信、图像处理这类需要高吞吐和低延迟的场景。资料包能不能用、例程能不能直接跑,直接决定你从开箱到跑通第一个链路要花三天还是三周。这篇笔记就用创龙这套资料的完整拆解过程,把硬件选型、开发环境、数据通路和几个典型的翻车点都过一遍,最后给一个能快速验证板卡全链路自检的方法。适合刚拿到板卡准备入手的嵌入式工程师,也适合在选型阶段看这套异构方案能不能抗住项目需求的人。
2. 硬件架构与开发环境:先弄清K7和C6678的分工再动手
2.1 异构架构里的分工:FPGA管前端,DSP管算法
拿到资料包先别急着点开例程,先把这两种芯片的分工画在脑子里。Kintex-7属于Xilinx 28nm工艺的中高端FPGA,资料包里常见的型号是XC7K325T或XC7K410T,逻辑资源够塞一个千兆以太网MAC加一组ADC接口再加一个SRIO端点核。它擅长的是并行数据搬移和低延迟接口,比如ADC采样、LVDS/GTX高速串行收发、自定义协议帧解析,这些都是FPGA的看家本领。
TM320C6678严格说是TMS320C6678,TI KeyStone架构八核C66x定点/浮点DSP,每个核心主频能到1.25GHz,单核带32KB L1P、32KB L1D和1MB L2,整颗芯片共享4MB MSMC内存。它强的在复杂算法,像脉压、FFT、波束形成、矩阵运算,C66x内核有SIMD指令和硬件复数乘法单元,算这些东西比FPGA用逻辑搭要舒服得多。
资料包里最值钱的其实是那张接口互联框图:FPGA和DSP之间通常走SRIO x4、PCIe x2、EMIF16和I2C/UART几条路。SRIO跑数据面,PCIe跑控制面,EMIF16跑慢速配置状态,这样分工的目的是不抢总线。
开发这套板子的基本流程是:先用Vivado把FPGA工程跑起来,用CCS把DSP程序编译成.out,再用一个统一的加载方案让两边的镜像协同工作。资料包里如果只有裸机例程,没有Linux或SYS/BIOS系统,那说明厂商默认你要直接操作寄存器,这对熟悉TI平台的工程师反而是好事。
2.2 开发工具链版本搭配:Vivado、CCS与SDK的选型
创龙这套资料在工具版本上有个明显的对应关系,因为K7是Xilinx 28nm器件,官方支持到Vivado 2017.4之后的新版本,但由于TI C6678的CCS老工程是基于CCS 5.5或6.0建的,版本配不好会直接导致编译报错。
我一般会这样搭环境,资料包里只要带了例程源码,这套组合基本能通吃:
bash
安装Vivado(选2017.4到2019.1之间的版本,都支持Kintex-7)
安装时勾选Kintex-7器件支持,避免后续综合报找不到器件
sudo ./xsetup
安装CCS(建议装CCS 6.1或6.2,兼容C6678的SDK,资料包例程大多基于此版本)
安装路径不要有中文和空格
sudo ./ccs_setup_6.1.0.bin
逻辑说明:先装Vivado再装CCS,这一步主要为了占用稳定的环境变量顺序。CCS对路径空格敏感,工程里的绝对路径是在工程文件里写死的,如果路径中间有空格,编译会直接报找不到文件。装完后要检查环境变量里有没有残留的其他版本工具链,常见的问题就是机器上还有旧的ISE或老的CCS 3.x,导致makefile调用到了错误的编译器。
参数说明:Vivado版本选2017.4到2019.1,原因是Xilinx对28nm器件的时序引擎在这个阶段最成熟,太新版本对K7的时序约束反而会出现一些行为变化。CCS版本选6.1而非5.5,是因为6.x自带编译器对C6678的cgtools支持更完整,而且调试器驱动对XDS100V2/XDS200V3的兼容性更好。如果资料包里有RTOS例程,建议再加装SYS/BIOS 6.37。
装好两个工具后,我习惯先打开资料包里的一个最小工程验证环境。资料包里应该有类似“LED”或“HelloWorld”这种DSP裸机工程,先编译这个,能过就说明CCS和编译器版本没有问题。FPGA侧则打开Vivado工程的.tcl或.xpr文件,重新跑一次综合和实现,这个过程首次大概需要十几分钟,能顺利跑完就说明FPGA工程和工具版本匹配。
3. 资料包目录与启动流程:找到例程、烧写镜像不迷路
3.1 数据结构与目录结构
创龙的资料包在文件组织上有个特点:文档、原理图、例程、工具分得比较开,但如果你打开一个子目录发现里面还套着压缩包,不要奇怪,这是厂商习惯性的打包方式。我拿到手先按下面这个顺序展开目录:
bash
先解压到路径没有中文的目录下
unzip Tronlong_TL-K7C6678.zip -d ~/tronlong_k7c6678
查看一级目录
cd ~/tronlong_k7c6678 && ls -la
重点看这四个目录:Hardware、Demo、Doc、Tools
逻辑说明:Hardware目录放的是原理图PDF和PCB源文件(通常是Altium格式),Doc目录放的是硬件手册、寄存器手册、启动配置说明,Demo目录才是整个包里最有价值的部分,里面按功能划分,比如SRIO、PCIe、UART、EMIF、DDR3测试等子目录。Tools目录放的是烧写工具和flash烧写器。
参数说明:展开Demo目录时注意看例程命名规律,比如Demo/SRIO_loopback这种名字说明是SRIO回环测试,Demo/DSP_LED说明是DSP点灯。每个例程目录下通常会有dsp和fpga两个子目录,dsp里面是CCS工程,fpga里面是Vivado工程,这两个必须成对使用,不能混搭版本。
看原理图的时候我习惯先看两处:一是电源树,看K7和C6678的核心电压是不是独立供电;二是启动配置引脚,DSP的启动模式拨码开关接在哪个GPIO上。创龙这类板子通常会做4位拨码开关来选DSP启动方式,常见的有SPI启动、No Boot和EMIF启动。资料包Doc目录里的“硬件使用手册”会有一页专门讲拨码开关和启动模式对应关系,这个表要拍照存手机里,后面烧写经常要翻。
3.2 启动配置与镜像烧写流程
C6678上电后怎么知道自己从哪读取程序,完全取决于启动配置引脚。最常见的两种配置是No Boot和SPI启动:No Boot模式下DSP停留在等待仿真器连接的状态,适合调试;SPI启动从板载SPI Flash读镜像,适合脱机运行。FPGA的配置则主要走SPI Flash或JTAG,看板子上有没有配QSPI Flash。
先把DSP设成No Boot模式调试,烧写流程包括:
bash
启动CCS,创建Target Configuration,选择C6678和仿真器型号
目标配置里加载GEL文件,路径通常在Demo/Common目录下
连接目标板后加载.out文件
执行:File -> Load Program,选择编译出来的.out镜像
**逻辑说明:** No Boot模式下DSP没有从Flash加载任何代码,所有核心都停在复位向量处等待调试器操作。GEL文件负责初始化锁相环和DDR3控制器,CCS在连接目标板后会自动调用GEL里的OnTargetConnect函数来初始化时钟和内存,这一步不做的话,DDR3直接不可用。 **参数说明:** 要确认GEL文件里锁相环倍频倍数和板子实际晶振频率匹配。C6678核心时钟是1GHz还是1.25GHz,取决于PLLM和PLLD寄存器配置,GEL文件写错倍频会导致DSP核心电压和频率不匹配,表现是连上仿真器能读到寄存器,但一跑程序就崩。 FPGA侧的烧写,因为K7通常没有内置Flash,需要通过外部SPI Flash或JTAG链。常用方式: bash # 打开Vivado,点击Open Hardware Manager # 连接板卡后,右键FPGA器件 -> Add Configuration Memory Device # 选择板载SPI Flash型号(常见N25Q128或W25Q128) # Program完成后断电重上电,FPGA配置从SPI Flash加载 **逻辑说明:** Vivado在硬件管理器里可以直接把比特流烧进SPI Flash,不需要额外的烧写器。烧写过程中选择存储器件型号要和板卡实际焊接的Flash对应,选错容量或厂商会导致写入后上电无法读取。烧写完成后,拨码开关要切换成SPI启动模式,否则FPGA还是会从JTAG链上等配置,现象就是上了电什么都干不了。 ## 4. 数据通路实战:从FPGA到DSP的SRIO高速链路搭建 ### 4.1 为什么选SRIO:四条路里它的吞吐和实时性最平衡 K7和C6678之间能走的高速接口有SRIO、PCIe、HyperLink和EMIF,资料包里最常见的官方例程是SRIO。SRIO在C6678上是RapidIO 2.1协议,支持x1/x2/x4 lane配置,单lane速率可以选1.25Gbps、2.5Gbps、3.125Gbps和5Gbps。x4模式5Gbps lane速率,理论吞吐能做到2.5GB/s左右,这对雷达中频采集后的数据传输基本够用。 PCIe同样能做数据面,但它要考虑RC和EP的角色分配,FPGA侧做Endpoint通常还需要加载XDMA IP核,驱动和中断响应也比SRIO复杂。EMIF16是并口,32位数据总线,跑异步访问,吞吐天花板大概在100MB/s级别,只适合做寄存器配置和状态交互。 所以做高速连续数据流,SRIO是这套板卡的首选。它有专门的Doorbell中断机制,FPGA可以往DSP发中断通知“数据已经放到缓冲区了”,DSP侧收到Doorbell后直接从MSMC或DDR3里取数据,不需要轮询,实时性比PCIe的MSI中断要直接。 ### 4.2 SRIO链路参数与初始化流程 用SRIO前要做五件事:配置lane速率、配置设备ID、配置Base路由表、配置缓冲区、注册Doorbell中断处理函数。创龙例程里通常会在主程序初始化阶段把这些做掉,里面对应的参数项如下: **SRIO链路关键参数表格** | 参数项 | 推荐值 | 说明 | | --- | --- | --- | | Lane速率 | 3.125Gbps | x4模式,兼顾稳定性和吞吐 | | 参考时钟 | 125MHz | 板上SRIO SerDes参考时钟,勿改动 | | 设备ID | FPGA=0x50,DSP=0x51 | 路由表里决定数据的去向 | | 传输模式 | Direct IO | 读/写内存映射,最简单 | | 维护类型 | Doorbell | DSP接收FPGA数据完成通知 | | 缓冲区地址 | 共享MSMC下的0x0C000000 | 两端都能访问,延迟最低 | 初始化代码里,核心配置一般长这样: c /* SRIO初始化核心配置节选 */ /* 配置lane速率 3.125Gbps, x4模式 */ Srio_InitConfig cfg = {0}; cfg.srioLinkSpeed = Srio_LinkSpeed_3_125G; /* lane速率 */ cfg.laneCount = Srio_LaneCount_4; /* 4条lane */ cfg.deviceId = 0x51; /* DSP的设备ID */ /* 打开SRIO模块并初始化 */ Srio_init(&cfg); /* 设置Base路由表:把ID为0x50的数据路由到端口0 */ CSL_SRIO_SetBaseRoutingTable(0x50, 0);逻辑说明:SRIO的物理层是SerDes,初始化顺序直接决定链路能否建立。先配lane速率再配设备ID,因为设备ID在链路训练之后才用于数据包路由。Srio_init会完成SerDes的RX均衡和TX摆幅配置,这一步如果参考时钟或lane速率配错,链路状态寄存器会显示没有收到链路训练序列。
参数说明:3.125Gbps是权衡过功耗和信号完整性的选择,5Gbps模式下PCB走线对阻抗匹配要求更严,长走线可能出现误码。缓冲区地址放在MSMC而不是DDR3,是因为MSMC是所有核心共享的片上内存,访问延迟比DDR3低一个数量级;数据量大了再考虑DDR3,用EDMA搬移。
4.3 跑通官方回环例程:验证物理链路
资料包里SRIO例程通常分两种:一种是DSP内部回环,FPGA不参与,纯验证DSP的SRIO模块;另一种是FPGA和DSP互发数据。先从DSP内部回环开始,因为把FPGA排除在外,更容易隔离问题。
操作步骤:先用CCS加载DSP例程,然后打开Vivado加载配套FPGA工程,两个工具同时连着板卡。DSP程序里的回环模式是通过宏定义切换的,比如定义LOOPBACK_INTERNAL就是内部回环,LOOPBACK_EXTERNAL就走FPGA。
跑通内部回环后,再切外部回环。FPGA工程里会有一个SRIO端点,收到DSP发来的包原样发回。用逻辑分析仪或直接在DSP代码里看收到数据是否正确即可。如果外部回环收不到数据,按下面顺序排查:先看FPGA侧SRIO链路状态寄存器是不是进入OK状态,再看FPGA的Clock Region是否提供GTX参考时钟,最后查路由表条目是否配置正确。
5. 避坑指南:创龙资料包里最常见的四个翻车点
5.1 烧写镜像后DSP启动失败
现象:按照文档步骤把.out转成.bin烧进SPI Flash,断电重新上电后,DSP核心不运行,程序卡在0x00800000地址附近,或者用示波器看不到核心IO翻转。
原因:这是最常见的烧写格式问题。CCS编译输出的是COFF或ELF格式的.out文件,不能直接烧Flash。需要先通过hex工具转换成带Boot Table格式的二进制镜像。创龙的文档对这一步骤有时写得不详细,很多人直接在CCS里用Load Program烧到DDR3,断电后自然什么都没有。
解决:使用TI提供的hex6x工具,配合C6678_bootTable.cmd命令文件,把.out转成boot table格式的.bin,再用创龙Tools目录下的SPI Flash烧写工具写入。烧写时注意起始地址要对应启动模式中SPI的映射地址,通常从0x0开始。
bash
在CCS命令行或DOS窗口执行
hex6x -boot -bootorg spi C6678_bootTable.cmd 你的工程.out
生成的文件就是可以烧写进SPI Flash的镜像
### 5.2 DDR3校验不通过或跑一段时间后报ECC错误 **现象:** 加载GEL文件后连着仿真器,运行DDR3测试例程,报数据比对失败,或者跑大数组运算时程序随机崩溃。 **原因:** C6678的DDR3控制器需要严格的时序训练。GEL文件里虽然初始化了PLL,但DDR3的PHY Delay训练如果没做或是在温度变化后没重训,读写时序窗口偏移就会导致偶发错误。另一个常见原因是DDR3的供电电压纹波超标,板上如果用LDO供电,大电流下纹波会直接影响DDR3参考电压。 **解决:** 先看GEL文件里有没有`DDR3_PHY_DLL_Init`和`DDR3_EMIF_Update`这类训练函数,确认在连接目标板后确实执行了。如果确定执行了还不稳,就用示波器量DDR3供电,空白引脚纹波不能超过30mV。创龙板卡上通常有专门的DDR3测试例程,跑三小时以上能过才算稳定。 ### 5.3 例程里FPGA工程编译不过,综合报错指向xdc文件 **现象:** 打开Vivado工程重新跑综合,报错在XDC约束文件,比如`ERROR: [Vivado 12-507]`,提示找不到某个端口或管脚。 **原因:** XDC约束文件里的管脚名称和顶层模块端口名不匹配。创龙有时会在不同版本硬件上微调管脚分配,但Vivado工程里更新的约束文件没同步;另外XDC里如果用了`get_ports`引用了一个改过名的信号,也会报这个错。 **解决:** 对照资料包Hardware目录里最新版的原理图,把顶层模块里所有端口列出来,逐一和XDC里的`set_property PACKAGE_PIN`核对。尤其是FPGA到DSP的SRIO差分对引脚,K7上过GTX bank的引脚通常有专用位置,引脚绑错会导致布线距离过长或直接连不上。我把这个核对过程写成一个简单的脚本: bash # 从顶层模块提取端口名 grep -E "^(input|output|inout)" fpga_top.v | awk '{print $NF}' | tr -d ';,' > ports.txt # 从XDC提取被约束的端口名 grep "get_ports" fpga_top.xdc | awk -F'{' '{print $2}' | tr -d '}' > xdc_ports.txt # 对比两者差异 diff ports.txt xdc_ports.txt逻辑说明:这个脚本能快速找出“端口存在但未约束”和“约束了但端口不存在”的两类缺失。常见的输出差异就是SRIO的gt_rxp/gt_rxn这些差分引脚在端口名里带不带_n后缀的差异,代码里叫gt_rxp,XDC里写的是gt_rx_p,这类笔误用肉眼很难找。
5.4 仿真器连接不稳定,连上几秒就断开
现象:XDS100V2连接C6678时,CCS能识别到核心,但加载程序或读寄存器时连接中断,提示Error connecting to the target。
原因:通常是JTAG链上信号质量问题和电源稳定问题。C6678的JTAG引脚需要上拉电阻,如果板上上拉电阻配置和仿真器驱动能力不匹配,高速通信就容易中断。另外,K7和C6678双芯片JTAG链如果串联,前面芯片处于未配置状态会旁路掉后面的芯片,导致DSP压根连不上。
解决:创龙资料包里通常有双芯片JTAG链的跳线说明。先把FPGA侧旁路掉,用跳线帽短路JTAG链里FPGA的BYPASS,让仿真器直连DSP。然后确认仿真器供电方式是目标板自供电,XDS100V2最好不要从USB取电供给目标板,板上DSP核心电压在仿真器接入瞬间的跌落会导致连接失败。
6. 进阶验证:用点灯加回环手段做全链路自检
拿到一套全新板卡,我第一件事不是跑大工程,而是用最粗暴的方式确认“电源→时钟→FPGA配置→DSP启动→两片通信”这五件事全都正常。这套自检流程是我从上十块异构板卡里摸出来的,全程只需要LED例程、一个SRIO内部回环和万用表。
先把DSP拨码开关拨到No Boot,连仿真器,加载LED例程,看到开发板上的用户LED按预期闪烁时,说明DSP核心时钟、电源和IO都正常。这一步不花时间,但能挡住后面所有疑难杂症里最基础的一类——硬件板卡本身就没正常工作。
然后做FPGA自检,用Vivado Hardware Manager连接目标板,烧一个最简单的LED翻转工程,确认FPGA的配置链路正常。如果这一步过不了,SRIO例程里的FPGA侧就无从谈起,先回头查QSPI Flash和配置bank供电。
最后做双芯片通信验证,我的习惯是先把SRIO例程分别跑在DSP内部回环和FPGA外部回环,在这两个模式都过之后,再加一层数据完整性校验,用伪随机序列填充缓冲区,收发比对CRC值:
c /* 用LFSR生成伪随机数据发送,回环后比对/ #define BUFFER_SIZE 4096 uint32_t tx_buf[BUFFER_SIZE]; uint32_t rx_buf[BUFFER_SIZE]; uint32_t lfsr = 0xACE1u; for(int i = 0; i < BUFFER_SIZE; i++) { lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u); tx_buf[i] = lfsr; } /通过SRIO发送tx_buf,接收回来后存入rx_buf/ if(memcmp(tx_buf, rx_buf, BUFFER_SIZE * 4) == 0) { /链路正常/ } else { /定位误码位置或检查收发长度是否一致 */ }
**逻辑说明:** LFSR生成的伪随机序列遍历所有位宽的组合,比直接用递增数更能暴露数据线上的粘连或短路问题。比对失败时先确认接收长度是否等于发送长度,很多SRIO回环问题出在长度字段配置不一致,导致缓冲区尾部总是上一次残留数据。 从那以后,我每次验收异构板卡都把“LED→FPGA配置→SRIO回环”这套序列强制走一遍,没有一次例外。这套自检做下来,半小时内就能把板卡从“可能有问题”变成“确认能跑”,省下来的调试时间去处理真正的算法问题,比任何手册都值。希望帮到你。 <p> <a href="https://download.csdn.net/download/qinhe123/15446986" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>