一、下载xiaoerlang0359大佬的开源项目
项目链接如下:https://github.com/xiaoerlang0359/E203plus
该项目遵循
Apache License 2.0开源协议,允许商业和非商业使用,具体协议权限如下图:(使用大佬源码的同学自觉去GIT给ta点一颗星星)

二、工程解析
阅读该项目源码,我们很容易发现,xiaoerlang0359大佬的项目,并不是基于E203_hbirdV2版本的,而是hbirdv1版本。并
不能直接拿到我们的工程中使用。另外,他们的
开发板和我们的也有很大区别。我们的MCU200T或者DDR200T开发板都是赛灵思的XC7A200T系列,他们的开发板
FPGA型号也和我们今年比赛用板有很大的不同。这些地方都需要我们仔仔细细地阅读源码去做平台的移植工作。
三、平台移植
关于DDR的拓展工程都在yrtl文件夹内,打开文件夹。阅读readme说明文档,我们能够知道,原作者采用了vivado MIG IP来控制开发板上的DDR3,由于芯来科技的E203平台系统片内总线是icb总线,所以我们需要做跨时钟域和跨总线协议的“桥梁”。所幸的是,大佬的开源工程已经为我们提供了一个解决方案:通过时钟的整数倍频率关系完成DDR na
tive interface到系统icb总线的桥接转换器。这个模块就是项目中的icb_bridge.v模块。
我们将这个模块加入自己的工程
(不要忘了注释原作者的版权信息,这是引用的其他人的代码!!!!),然后根据大佬的README说明,在顶层例化对应自己开发板上DDR芯片的MIG控制器,将DDR控制器的DDR通道引出到IO,并根据自己开发板的原理图,完成DDR到FPGA IO bank的引脚分配和约束。
芯来科技的DDR200T原理图链接如下:
https://www.nucleisys.com/upload/files/fpga/doc/Nuclei_DDR200T.pdf
我以DDR200T开发板为例,展示我们使用的开发板的DDR引脚约束配置如下:
当MIG IP和DDR都连接完毕后,我们将MIG控制通道的wire都从system.v顶层逐层往下接,接到lsu单元和lsu_ctrl单元为止。每层都要仔细和GitHub的工程源码
仔细比对,并修改到自己的项目中去。
关于MIG的配置可以
参考自己的DDR芯片手册进行适配,也可以参考
芯来科技论坛的其他大佬的无私分享!
仔细比对!!!仔细比对!!!仔细比对!!!

(**提示:defines.v文件也需要修改)
四、修改时钟的mmcm IP
由于MIG模块需要系统时钟和参考时钟,我们需要在原本的mmcm模块之前再加一层mmcm用于产生MIG模块使用的系统时钟。
阅读readme说明文档,我们很容易知道,我们需要一个166.667MHZ的inputclk,以及一个200MHZ的refclk,给MIG模块输入。这个按照一般的mmcm配置方法便可以自行完成。难度不是很大。
配置完成以后,我们的E203_hbirdv2项目中就应该至少有以下4个IP核:(mmcm名字也不一定和我的一样)
五、使用vivado嵌入式逻辑分析仪ILA检查DDR是否初始化成功
创建ILA,将原始输入时钟
CLK100MHZ作为逻辑分析仪的ILA采样时钟,将DDR接口的“
init_calib_complete”线放进ila的探针probe中。
综合,实现完成以后,上板。将bitstream文件和debug文件都烧写进开发板。然后在弹出的ila面板中调整探针“
init_calib_complete”的触发方式为 " R: from 0 to 1" ,按下开发板上的MCU_RST按键,观察init_calib_complete有没有成功被拉到高电平。
如果DDR连接正常,并且上电初始化成功,这根wire应该在初始化后,被拉至高电平。
如下图所示:我们的DDR成功被上电复位初始化:
***注:关于vivado自带的嵌入式逻辑分析仪ila的使用可以直接百度,网上一堆图文教程,本人在此不再赘述。
六、通过nuclei studio软件读写测试
我们使用了芯来科技的nuclei studio IDE进行了软件读写测试。测试函数编写如下:
MAIN主函数如下:
内存读写子函数定义如下:
void read_mem( int *startp, int range) //input *start-addr and data-number to read{ int *p = startp; printf("********************LIST BEGIN*********************"); for(int i=0; i < range-1 ; i++ ) { printf("n%d",*p); p=p+1; } printf("*********************LIST END***********************");}void read_wrtest( int *startp, int range) //input *start-addr and data-number to read{ int *p = startp; printf("n********************write BEGIN*********************n"); for(int i=0; i < range-1 ; i++ ) { *p = i; p=p+1; printf("."); } printf("n*********************write END***********************nn");}
在main函数中调用这两个函数,测试DDR地址空间的读写。测试结果如下:
至此,我们成功完成了DDR拓展工程的平台移植!!!!!!!