
紫光PGL22G FPGA上构建Cortex-M1软核系统的全流程实战指南1. 开发环境搭建与工具链配置在开始紫光PGL22G FPGA上的Cortex-M1软核开发前我们需要完成开发环境的搭建。与常见的STM32开发不同FPGA软核开发需要同时处理硬件描述和软件编程两个维度。必备工具清单Keil MDK开发环境推荐V5.15及以上版本ARM CMSIS软件包5.6.0版本紫光PDS开发工具2020.3版本官方评估板支持包包含RTL设计和示例工程环境配置中的几个关键点需要注意安装路径避免中文字符和空格CMSIS软件包需通过Keil的Pack Installer获取PDS工具需要正确的license配置提示建议保持工具版本与官方测试环境一致可减少兼容性问题工具安装完成后项目目录结构应如下所示pgr_FPGA_Cortex-M1_eval/ ├── rtl_design/ │ └── pgr_ARM_Cortex_M1_PGL22_324_eval/ └── software_design/ ├── boot/ └── module_design/2. Keil工程配置详解2.1 工程架构解析打开示例LED工程位于software_design/module_design/Cortex-M1_led我们会发现其工程结构与常规ARM工程存在显著差异启动文件使用专用的startup_Cortex-M1.s汇编文件链接脚本通过Keil的Target选项直接配置而非独立的ld文件外设库基于CMSIS封装了针对FPGA的特定驱动2.2 存储器地址配置Cortex-M1软核的存储器配置是开发中的第一个关键点。根据是否使用Cache存在两种配置模式配置类型ROM地址RAM地址备注无Cache0x00000000 (ITCM)0x20000000 (DTCM)直接访问模式有Cache0x10000000 (ICACHE)0x30000000 (DCACHE)推荐配置在Keil的Target选项中我们需要设置IROM1: 0x10000000, Size: 0x1000000 IRAM1: 0x30000000, Size: 0x100000注意ICACHE指令起始地址必须为0x10000000DCACHE数据起始地址必须为0x30000000超出映射范围会导致运行错误2.3 二进制文件生成配置FPGA软核开发需要生成特定格式的二进制文件这通过Keil的User选项卡配置Run #1命令fromelf.exe --bin -o cortex_M1_led.bin .\Objects\cortex_M1_led.axfRun #2命令make_hex.exe cortex_M1_led.bin关键点说明fromelf工具路径需指向本地Keil安装目录Run #2生成的ITCM文件在应用工程中实际不会使用最终需要的只是Run #1生成的.bin文件3. 程序烧录与硬件调试3.1 文件转换流程紫光PGL22G FPGA的程序烧录需要将多个文件合并转换为特定格式sbit文件FPGA配置比特流bin文件应用程序二进制sfc文件最终烧录到Flash的组合文件转换参数示例Flash型号: W25Q128Q sbit起始地址: 0x00000000 bin起始地址: 0x000C0000 读模式: SPI X4, 24-bit address3.2 烧录步骤连接JTAG调试器与开发板在PDS工具中执行Boundary Scan识别设备选择生成的sfc文件进行编程等待Flash编程完成约1-2分钟3.3 串口调试烧录完成后可通过串口观察程序输出波特率115200数据位8停止位1无校验典型的成功输出如下PANGO Cortex-M1 Start Run... JEDEC id 0xEF40184. 仿真与调试技巧4.1 无Boot仿真方法为加速开发周期可以采用跳过Bootloader的仿真方式修改应用工程的Run #2命令make_hex128.exe cortex_M1_demo.bin生成三个关键文件mem_addr.datmem_data.datmem_used.dat将这些文件复制到RTL工程的Simulation目录4.2 Modelsim仿真配置仿真环境搭建步骤编译Pango仿真库约需2分钟拷贝usim文件夹到仿真目录运行sim.bat启动仿真常见问题解决** Error: (vish-42) Unsupported ModelSim library format...→ 重新编译仿真库即可解决4.3 波形分析技巧在仿真波形中重点关注HADDR信号查看指令执行地址HWDATA信号观察数据变化GPIO输出验证外设行为例如当程序向0x70001000地址写入数据时可以在波形中看到HADDR和HWDATA的对应变化。5. 高级开发技巧5.1 系统时钟配置Cortex-M1软核默认使用DDR的axi_clk0作为系统时钟。如需改用外部PLL时钟需修改RTL代码// 在cm1_option_defs.v中取消注释 #define UNCACHE5.2 外设驱动开发开发新外设驱动时需注意在cm1_option_defs.v中启用对应模块正确配置GPIO复用功能处理时钟域交叉问题以I2C驱动EEPROM为例// 修改页大小定义 #define I2C_PageSize 16 // 确保数据长度小于页大小 #define DATA_LEN 105.3 网络功能配置评估板的网络接口需配置以下参数MAC地址配置#define MAC_ADDR0 0x00 #define MAC_ADDR1 0x0A #define MAC_ADDR2 0x35 #define MAC_ADDR3 0x01 #define MAC_ADDR4 0xFE #define MAC_ADDR5 0xC0IP地址配置#define IP_ADDR0 192 #define IP_ADDR1 168 #define IP_ADDR2 0 #define IP_ADDR3 26. 性能优化建议6.1 Cache优化策略ICACHE配置建议大小16-32KB关联度4-wayDCACHE配置写回模式优于写通合理使用Cache预取6.2 存储器访问优化关键技巧将频繁访问的数据放入DTCM大数据块使用DMA传输对齐内存访问4字节边界6.3 编译优化选项Keil中的推荐优化设置Optimization Level: -O2One ELF Section per Function: EnabledStrict ANSI C: Disabled在项目开发中我遇到过一个典型的性能问题当启用Cache后某些外设寄存器访问出现异常。最终发现是因为没有正确配置Cache的Non-cacheable区域。通过在代码中关键位置添加内存屏障指令__DSB()解决了这个问题。