第 5 章 简单流水线CPU设计

通过前一章的学习实践,我们设计并实现一个支持20条指令的单周期CPU。本章我们将学习如何将单周期CPU改造成单发射五级流水CPU。从单周期CPU到流水线CPU,对初学者来说还是有些难度的。为了让学习曲线不过于陡峭,我们进一步将简单流水线CPU的设计工作分解成三个逐级递进的小任务:

  • 第一阶段:我们将尝试在单周期CPU的基础上引入流水线,但是暂时不考虑处理各类相关所引发的冲突。
  • 第二阶段:我们会介绍流水线中各类相关所引发的冲突,并给出用阻塞方式解决冲突的设计方案。在本章的实践任务中,读者可根据我们给出的设计方案,基于第一阶段的CPU实现进行改进。
  • 第三阶段:我们会介绍流水线前递技术,并给出一种设计方案。在本章的实践任务中,读者可根据我们给出的设计方案,基于第二阶段的CPU实现进行设计和调整。

【本章学习目标】

  • 继续建立设计方案与Verilog代码实现之间的认知联系。
  • 形成良好的Verilog代码编写习惯。
  • 进一步提升CPU功能仿真验证中调试错误的能力。

【本章实践目标】

本章有三个实践任务(见本章第5.1节)。读者可以在学习本章内容的基础上完成这些任务,两者之间的对应关系如下:

  • ??节的内容对应实践任务7(5.1.1节)。
  • ??节的内容对应实践任务8(5.1.2节)。
  • ??节的内容对应实践任务9(5.1.3节)。

5.1 任务与实践

完成本章的学习后,希望读者能够完成以下3个实践任务:

  1. 不考虑相关引发的冲突的简单流水线CPU,参见下面第5.1.1小节。
  2. 阻塞技术解决相关引发的冲突,参见下面第5.1.2小节。
  3. 前递技术解决相关引发的冲突,参见下面第5.1.3小节。

5.1.1 实践任务7:不考虑相关冲突处理的简单流水线CPU

本实践任务要求在实践任务6实现的单周期CPU基础上完成以下工作:

  1. 调整CPU顶层接口,增加指令RAM的片选信号 inst_sram_en 和数据RAM的片选信号 data_sram_en
  2. 调整CPU顶层接口,将inst_sram_wedata_sram_we 都从1比特的写使能调整为4比特的字节写使能。
  3. 设计一个不考虑相关引发的冲突的单发射五级流水CPU。
  4. 运行exp7对应的func,要求成功通过仿真和上板验证。

请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,不过验证时不再使用soc_dram/子目录,而应使用soc_bram/子目录

伴随着CPU访问的指令RAM和数据RAM的实现形式从distributed RAM更换为block RAM,实验开发环境也需要有所调整:仍然是mycpu_env实验环境,gettrace/、func/ 和 myCPU/ 子目录的位置和用途依然维持不变,只是 soc_verify/ 子目录下不再使用 soc_dram/ 子目录而是改为使用 soc_bram/ 子目录,soc_bram/ 子目录中的文件组织结构和用途与 soc_dram/ 子目录中的相似。调整后的实验开发环境的目录结构及各部分功能简介如下所示:

|--gettrace/                生成参考trace的部分。
|--func/                    实验任务所用的功能验证测试程序。
|--myCPU/                   自己实现的CPU的RTL代码。
|--soc_verify/              自己实现的CPU的SoC系统验证环境
   |--soc_bram/             CPU对外连接block RAM接口时对应的验证环境。
   |  |--rtl/               SoC_Lite设计代码目录。
   |  |  |--soc_lite_top.v  SoC_Lite的顶层文件。
   |  |  |--CONFREG/        confreg模块,用于访问CPU与开发板上数码管、拨码开关等外设。
   |  |  |--BRIDGE/         1×2的桥接模块, CPU的data sram接口同时访问confreg和data_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_bram_prj/ Vivado工程文件所在目录。

从实践任务7开始的指令RAM和数据RAM均采用block RAM实现,其访问时需要给出片选信号。为此myCPU 顶层接口中增加指令RAM的片选信号 inst_sram_en 和数据RAM的片选信号 data_sram_en。两个信号均为1比特,均为高电平有效。

尽管实践任务7中存数指令仅实现了st.w,但考虑到后续实践任务的需求,myCPU 顶层接口中的 inst_sram_we 和 data_sram_we 都从1比特改为4比特,其含义也从RAM的写使能调整为RAM的字节写使能。

实验环境准备就绪后,请参考下列步骤完成本实践任务:

  1. 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
  2. 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp7的配置,编译。(如果是通过压缩包exp7.zip获取实验开发环境的,请跳过该步骤。)
  3. 打开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才有完整的内容。(如果是通过压缩包exp7.zip获取实验开发环境的,请跳过该步骤。)
  4. 进入 mycpu_env/soc_verify/soc_bram/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。
  5. 参考第44.2.5.2小节,对工程中的inst_ram重新定制。(如果是通过压缩包exp7.zip获取实验开发环境的,请跳过该步骤。)
  6. 在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。
  7. 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。(如果无硬件实验平台,请跳过该步骤。)

5.1.2 实践任务8:阻塞技术解决相关引发的冲突

本实践任务要求在实践任务7实现的CPU基础上完成以下工作:

  1. 加入适当的逻辑处理寄存器写后读数据相关引发的流水线冲突(本任务中只要求使用阻塞技术)。
  2. 运行exp8对应的func,要求成功通过仿真和上板验证。

请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,且仍使用soc_bram/子目录。

实验环境准备就绪后,请参考下列步骤完成本实践任务:

  1. 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
  2. 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp8的配置,编译。(如果是通过压缩包exp8.zip获取实验开发环境的,请跳过该步骤。)
  3. 打开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才有完整的内容。(如果是通过压缩包exp8.zip获取实验开发环境的,请跳过该步骤。)
  4. 进入 mycpu_env/soc_verify/soc_bram/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。如果该目录下已有前一实践任务创建过的工程,可以在打开工程后,参照附录D.3节介绍的步骤,更新项目中CPU实现文件的列表。
  5. 参考第44.2.5.2小节,对工程中的inst_ram重新定制。(如果是通过压缩包exp8.zip获取实验开发环境的,请跳过该步骤。)
  6. 在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。
  7. 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。(如果无硬件实验平台,请跳过该步骤。)

5.1.3 实践任务9:前递技术解决相关引发的冲突

本实践任务要求在实践任务8实现的CPU基础上完成以下工作:

  1. 加入适当的数据前递通路来减少阻塞。
  2. 运行exp9对应的func,要求成功通过仿真和上板验证,并且仿真运行时间较exp8的结果有下降。

请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境仍位于 mycpu_env/ 目录下,且仍使用soc_bram/子目录。

实验环境准备就绪后,请参考下列步骤完成本实践任务:

  1. 将所实现CPU的代码更新至mycpu_env/myCPU/目录中。
  2. 修改func配置文件——mycpu_env/func/include/test_config.h,选择exp9的配置,编译。(如果是通过压缩包exp9.zip获取实验开发环境的,请跳过该步骤。)
  3. 打开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才有完整的内容。(如果是通过压缩包exp9.zip获取实验开发环境的,请跳过该步骤。)
  4. 进入 mycpu_env/soc_verify/soc_bram/run_vivado/ 目录下启动验证myCPU的工程。如果该目录下尚未创建工程,请参照附录D.2节介绍的步骤,利用该目录下的 create_project.tcl 文件创建工程。如需要,请参考附录D.4节进行IP核升级。如果该目录下已有前一实践任务创建过的工程,可以在打开工程后,参照附录D.3节介绍的步骤,更新项目中CPU实现文件的列表。
  5. 参考第44.2.5.2小节,对工程中的inst_ram重新定制。(如果是通过压缩包exp9.zip获取实验开发环境的,请跳过该步骤。)
  6. 在验证myCPU的工程中运行仿真(进入仿真界面后,直接点击run all),进行功能验证与调试,直至仿真测试通过。
  7. 在验证myCPU的工程中综合实现后生成bit流文件,进行上板验证。(如果无硬件实验平台,请跳过该步骤。)