第 8 章 AXI总线接口设计
8.1 任务与实践
完成本章的学习后,希望读者能够完成以下3个实践任务:
8.1.1 实践任务14:添加类SRAM总线支持
本实践任务要求在实践任务13实现的CPU基础上完成以下工作:
- 将CPU对外接口修改为类SRAM总线接口。
- 在采用握手机制的block RAM的SoC验证环境中完成exp14对应func的随机延迟功能验证。
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,不过验证时不再使用soc_bram/子目录,而应使用soc_hs_bram/子目录。
伴随着CPU访问的指令RAM和数据RAM的实现形式从普通的block RAM更换为带握手机制的block RAM,实验开发环境需要进一步调整:仍然是mycpu_env实验环境,gettrace/、func/ 和 myCPU/ 子目录的位置和用途依然维持不变,只是 soc_verify/ 子目录下不再使用 soc_bram/ 子目录而是改为使用 soc_hs_bram/ 子目录,soc_hs_bram/ 子目录中的文件组织结构和用途与 soc_bram/ 子目录中的相似。调整后的实验开发环境的目录结构及各部分功能简介如下所示:
|--gettrace/ 生成参考trace的部分。
|--func/ 实验任务所用的功能验证测试程序。
|--myCPU/ 自己实现的CPU的RTL代码。
|--soc_verify/ 自己实现的CPU的SoC系统验证环境
|--soc_hs_bram/ CPU对外连接handshaking block RAM接口时对应的验证环境。
| |--rtl/ SoC_Lite设计代码目录。
| | |--soc_lite_top.v SoC_Lite的顶层文件。
| | |--CONFREG/ confreg模块,用于访问CPU与开发板上数码管、拨码开关等外设。
| | |--BRIDGE/ 1×2的桥接模块, CPU的data sram接口同时访问confreg和data_ram。
| | |--ram_wrap/ 以类SRAM接口封装的RAM模块。
| | |--xilinx_ip/ 定制的Xilinx IP,包含clk_pll、inst_ram、data_ram。
| |--testbench/ 功能仿真验证平台。
| | |--mycpu_tb.v 功能仿真顶层,该模块会抓取debug信息与golden_trace.txt进行比对。
| |--run_vivado/ Vivado工程的运行目录。
| |--constraints/ Vivado工程的设计约束。
| |--mycpu_hs_bram_prj/ Vivado工程文件所在目录。
实验环境准备就绪后,请参考下列步骤完成本实践任务:
- 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
- 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp14的配置,编译。(如果是通过压缩包exp14.zip获取实验开发环境的,请跳过该步骤。)
- 打开gettrace工程——mycpu_env/gettrace/gettrace.xpr。(该Vivado工程中的IP核是使用Vivado2019.2创建的,如果使用更高版本的Vivado打开,请参考附录D.4节进行IP核升级。)运行gettrace工程的仿真(进入仿真界面后,直接点击run all等待仿真运行完成),生成新的参考trace文件golden_trace.txt(mycpu_env/gettrace/golden_trace.txt)。要等仿真运行完成,golden_trace.txt才有完整的内容。(如果是通过压缩包exp14.zip获取实验开发环境的,请跳过该步骤。)
- 进入 mycpu_env/soc_verify/soc_hs_bram/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。
- 参考第4章4.2.5.2小节,对工程中的inst_ram重新定制。(如果是通过压缩包exp14.zip获取实验开发环境的,请跳过该步骤。)
- 在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。
- 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。(如果无硬件实验平台,请跳过该步骤。)
1.上板验证的要求
上板验证时,要求“随意切换拨码开关后按复位键”,CPU能通过对应exp14的func中58个功能点的验证。
“随意切换拨码开关后按复位键”是为了设定初始的随机种子(随机种子用于生成inst/data ram访问时的随机延迟拍数),开始运行功能验证。由于功能验证程序里的指令较多,随机种子不同会导致取指或访存的随机延迟拍数不同,CPU执行状态也会大不相同,所以切换初始随机种子后出现错误是很常见的。
请注意上板验证的具体操作:将8个拨码开关切换为随意状态,按复位键;松开复位键后,数码管开始累加,此时可以切换开关来控制wait_1s
的累加速度。
2.拨码开关的功能
从上面的内容可以看出,上板验证时,拨码开关有两个功能:
- 功能一:复位期间,拨码开关控制初始随机种子,进而控制CPU取指及访存的随机延迟拍数的生成序列。
- 功能二:复位后,拨码开关控制
wait_1s
的循环次数,也就是控制数码管累加的速度。
对于功能二,在58个功能点测试中,每两个功能点之间会穿插一个wait_1s
函数,wait_1s
通过一段循环完成计时的功能:wait_1s
的循环次数由拨码开关控制,可设置循环次数为(0~0xaaaa) \(\times\) 29。上板验证时,建议在复位后,通过拨码开关选择合理的wait_1s
延时。
对于功能一,为尽可能验证myCPU的功能,CPU_CDE_SRAM里对访存延迟设定了一个随机机制:访存延迟拍数是通过一个32位的伪随机数发生器(在confreg.v文件里实现)生成的。在仿真验证时,该伪随机数发生器初始随机种子由confreg.v里的宏RANDOM_SEED
指定;在上板验证时,其初始随机种子由复位期间采样到的拨码开关状态来指定。
实验箱上共有8个拨码开关,实际电平是:拨上为0,拨下为1。但是为了便于以下的描述,我们记作:拨上为1,拨下为0。16个LED单色灯的实际电平是:驱动0亮,驱动1灭。同样,我们记作:驱动1亮,驱动0灭。
上板验证时,按下复位键,会自动采样8个拨码开关的值作为初始随机种子,且会显示初始随机种子低16位到单色LED灯上。上板时随机种子与拨码开关的对应关系如图8.1所示,需要注意的是,延迟类型依据拨码开关的值分为三类:长延迟、短延迟和无延迟类型。在上板验证时,应当覆盖这三类延迟。
3.“仿真通过,上板不过”的调试方法
【情况一】 上板验证时发现数码管没有任何累加。
这可能是由于以下问题之一导致的:
- 多驱动。
- 模块的input/output端口接入的信号方向不对。
- 时钟复位信号接错。
- 代码不规范,阻塞赋值乱用,always语句随意使用。
- 仿真时控制信号有“X”。仿真时,有“X”调“X”,有“Z”调“Z”。特别要注意的是,设计的顶层接口上不要出现“X”和“Z”。
- 时序违约。
- 模块里的控制路径上的信号未进行复位。
【情况二】 上板验证时发现在某些随机种子下测试通过,在另一些随机种子情况下出错。
请按以下步骤进行调试:
- 确认上板验证时出错的初始随机种子,修改
mycpu_env/soc_verify/soc_hs_bram/rtl/CONFREG/confreg.v
文件中宏RANDOM_SEED
的定义值,改为出错时的初始随机种子,随后进行仿真。如果有错,则进行调试;如果发现仿真没有出错,则在上板验证时寻找下一个出错的初始随机种子,同样设定好RANDOM_SEED
后进行仿真,如果尝试多个初始随机种子后仿真都没有出错则转到步骤2。 - 当遇到“相同初始随机种子,仿真无法复现上板的错误”的情况时,请采取以下措施:排查列出的可能原因,复查代码和反思设计,也可以使用Vivado的逻辑分析仪进行在线调试(参考附录D的D.5节)。
【情况三】 上板验证时发现任意随机种子下,都只有部分功能点测试通过。
这时可能以上两种情况的原因都存在,请依次排查。
8.1.2 实践任务15:添加AXI总线支持
本实践任务要求在实践任务14实现的CPU基础上完成以下工作:
- 将CPU顶层接口修改为AXI总线接口。CPU对外只有一个AXI接口,需在内部完成取指和数据访问的仲裁。推荐在本任务中实现一个类SRAM-AXI的2x1的转接桥,然后拼接上实践任务一完成的类SRAM接口的CPU,将myCPU封装为AXI接口。
- 在采用AXI总线的SoC验证环境里完成exp15对应func的固定延迟功能验证,要求成功通过仿真和上板验证。
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,不过验证时不再使用soc_hs_bram/子目录,而应使用soc_axi/子目录。
伴随着CPU对外访问接口由带握手机制的block RAM更换为AXI总线接口,实验开发环境需要进一步调整:仍然是mycpu_env实验环境,gettrace/、func/ 和 myCPU/ 子目录的位置和用途依然维持不变,只是 soc_verify/ 子目录下不再使用 soc_hs_bram/ 子目录而是改为使用 soc_axi/ 子目录。调整后的实验开发环境的目录结构及各部分功能简介如下所示:
|--gettrace/ 生成参考trace的部分。
|--func/ 实验任务所用的功能验证测试程序。
|--myCPU/ 自己实现的CPU的RTL代码。
|--soc_verify/ 自己实现的CPU的SoC系统验证环境
|--soc_axi/ CPU对外连接AXI接口时对应的验证环境。
| |--rtl/ SoC_Lite设计代码目录。
| | |--soc_lite_top.v SoC_Lite的顶层文件。
| | |--CONFREG/ confreg模块,用于访问CPU与开发板上数码管、拨码开关等外设。
| | |--ram_wrap/ 以支持随机延迟访问封装的AXI RAM模块。
| | |--axi_wrap/ AXI的1x1转接口,连接CPU和Crossbar,用于抹平仿真和上板的差异。
| | |--xilinx_ip/ 定制的Xilinx IP,包含clk_pll、axi_ram和axi_crossbar_1x2。
| |--testbench/ 功能仿真验证平台。
| | |--mycpu_tb.v 功能仿真顶层,该模块会抓取debug信息与golden_trace.txt进行比对。
| |--run_vivado/ Vivado工程的运行目录。
| |--constraints/ Vivado工程的设计约束。
| |--mycpu_axi_prj/ Vivado工程文件所在目录。
实验环境准备就绪后,请参考下列步骤完成本实践任务:
- 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
- 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp15的配置,编译。(如果是通过压缩包exp15.zip获取实验开发环境的,请跳过该步骤。)
- 打开gettrace工程——mycpu_env/gettrace/gettrace.xpr。(该Vivado工程中的IP核是使用Vivado2019.2创建的,如果使用更高版本的Vivado打开,请参考附录D.4节进行IP核升级。)运行gettrace工程的仿真(进入仿真界面后,直接点击run all等待仿真运行完成),生成新的参考trace文件golden_trace.txt(mycpu_env/gettrace/golden_trace.txt)。要等仿真运行完成,golden_trace.txt才有完整的内容。(如果是通过压缩包exp15.zip获取实验开发环境的,请跳过该步骤。)
- 进入 mycpu_env/soc_verify/soc_axi/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。
- 参考第4章4.2.5.2小节,对工程中的axi_ram重新定制。(如果是通过压缩包exp15.zip获取实验开发环境的,请跳过该步骤。)
- 在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。
- 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。在上板验证时,要求8个拨码开关处于“高4个拨下,低4个拨上”的状态(对应访存随机延迟类型为无延迟),能正确运行func。(如果无硬件实验平台,请跳过该步骤。)
8.1.3 实践任务16:完成AXI随机延迟验证
本实践任务要求在实践任务15实现的CPU基础上完成以下工作:
- 完善AXI总线接口设计使其在采用AXI总线的SoC验证环境里完成exp16对应func的随机延迟功能验证,要求成功通过仿真和上板验证。
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,且仍使用 soc_axi/ 子目录。
实验环境准备就绪后,请参考下列步骤完成本实践任务:
- 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
- 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp16的配置,编译。(如果是通过压缩包exp16.zip获取实验开发环境的,请跳过该步骤。)
- 打开gettrace工程——mycpu_env/gettrace/gettrace.xpr。(该Vivado工程中的IP核是使用Vivado2019.2创建的,如果使用更高版本的Vivado打开,请参考附录D.4节进行IP核升级。)运行gettrace工程的仿真(进入仿真界面后,直接点击run all等待仿真运行完成),生成新的参考trace文件golden_trace.txt(mycpu_env/gettrace/golden_trace.txt)。要等仿真运行完成,golden_trace.txt才有完整的内容。(如果是通过压缩包exp16.zip获取实验开发环境的,请跳过该步骤。)
- 进入 mycpu_env/soc_verify/soc_axi/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。如果该目录下已有前一实践任务创建过的工程,可以在打开工程后,参照附录D.3节介绍的步骤,更新项目中CPU实现文件的列表。
- 参考第4章4.2.5.2小节,对工程中的axi_ram重新定制。(如果是通过压缩包exp16.zip获取实验开发环境的,请跳过该步骤。)
- 修改
mycpu_env/soc_verify/soc_axi/rtl/CONFREG/confreg.v
文件中宏RANDOM_SEED
为不同值,在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。 - 重复上一步骤多次,要求宏
RANDOM_SEED
的修改值能覆盖本章前面介绍的三种随机延迟类型。 - 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。在上板验证时,要求“随意切换拨码开关后按复位键”,均能正确运行func。如果出现“仿真通过,上板不过”的现象,请按照前面8.1.1小节介绍的方法进行调试。(如果无硬件实验平台,请跳过该步骤。)