All Projects → fluctlight001 → SampleCPU

fluctlight001 / SampleCPU

Licence: other
No description, website, or topics provided.

Programming Languages

Verilog
626 projects
SystemVerilog
227 projects

SampleCPU

报告要求(4分/30分)

1. 格式要求:

  1. 正文小四号字体
  2. 1.25倍行距
  3. 10页左右

2. 内容要求:

  1. 封面(1页)目录(1页)PS:封面在doc文件夹里,自行取用
  2. 每个人的工作量,总体设计,不同流水段之间的连线图,完成了多少条指令,程序运行环境及使用工具。(1-2页)
  3. 单个流水段说明: 该流水段的整体功能说明,端口介绍,信号介绍,包含的功能模块说明,大致的结构示意图。(不要贴大段源码,可以选择一小部分,并对其进行解释。比如说贴一个选择器,介绍一下是怎么控制优先级,又或者这个选择器没有优先级,是并行选择器)(5页-8页)
  4. 组员的实验感受,改进意见(这部分三人加起来不要超过1页)
  5. 参考资料(1页)

3. 时间安排

  1. 纸质版1份:于最后一次实验课时上交
  2. 电子版:使用pdf格式,添加到小组的repo里(实验课时会发在线表格收集repo地址) 给老师QQ邮箱发一份

更新内容说明

1. 添加地址映射处理模块,把mmu.v加到本地的lib里,并用更新后的mycpu_top.v覆盖原来的同名文件即可。修复了程序中的部分笔误。

2. 增加乘除法部件,可自行选择使用,正常使用得基础分,自己实现乘除法(要求能综合实现)可额外加分。

  1. 在lib目录中加入mul部件和div部件
  2. 添加defines.vh的更新部分
  3. 自行在EX段添加乘除法器,调用方法已在 EX.v 中添加。一般来说将需要的线路连接以后即可正常使用。 注意 除法是32个周期的,所以有stallreq需要处理,至于在哪里插入空泡请自行研究,相信处理了load相关的各位已经轻车熟路了。
  4. 注意 乘除法需要hilo寄存器的支持,其功能为存储乘除法结果,可以当成是只有两个32bit存储位置的 regfile ,但其两个存储位置都有独立的写使能信号。和 regfile 一样,hilo寄存器也会存在数据相关的问题。所以同样的,可以使用regfile的数据通路和定向路径来进行读写。如果没有概念,可先参考《自己动手写CPU》中的对应章节,但其实现方法较为混乱,个人建议把 hilo寄存器 和 regfile 放在一起,有效复用线路。

3. 关于自制乘除法器的几点提示:

  1. 禁止直接使用 * 或者 / 的运算符号来计算,编译器会自行给你配置对应的ip核,但是效果非常差,不认为可以加分
  2. CPU中所有的数据采用补码形式,所以查找资料的时候请注意是补码乘除法,和直接进行乘除会有一些区别。一般运算顺序:补码 -> 原码 -> 计算 -> 得到原码结果 -> 生成补码结果。
  3. 当前提供的乘法器为 booth-Wallace 乘法器,除法为《自己动手写CPU》中用到的除法。使用这两种不加分。
  4. 推荐实现的选项:
  1. 只修改乘法,制作一个32周期的移位乘法器。需要随项目附带该乘法器的说明文档。当作 可选模块 算分,占总成绩4分。
  2. 整合乘法器和除法器,制作一个复用主要逻辑的移位乘除法器。同样需要附带说明文档。作为 可选模块 算分,视情况给4-8分。 最差情况 ,在内部分别写了一个乘法器和除法器,没有任何关联性,通过选择信号选择启动哪个, 给4分最佳情况 ,复用了主要的控制逻辑,只在移位方向和加减法上做选择, 给8分

4. 除法器运行结果补充说明:

-除法结果的符号位规则表-

被除数 除数 余数

5.访存接口补充说明:

  1. 因为现在的存储器用的一般都是字节编址,所以data_sram_wen这个写使能信号是4位,每一位控制一个字节的数据。故sw指令对应4'b1111,lw指令对应4'b0000.
  2. sb指令一次只写入一个字节,所以可能是4'b0001 4'b0010 4'b0100 4'b1000这四种情况,具体选择那种,根据写地址的最低两位(addr[1:0])判断。00对应低位字节,11对应高位字节。
  3. sh指令类似于sb指令,但其只有两种情况,地址最低两位为00时,4'b0011,即写低位两个字节;地址最低两位为10时,4'b1100,即写高位两个字节。
  4. load类指令与store类指令略有不同,由于这个存储器只配置了片选使能和字节写使能,所以读取的时候一律是先读回CPU(此时不区分是哪个load指令,一律使用4'b0000),再进行更细分的操作。那么就需要把细分的指令操作随流水线传到MEM段,使MEM段能知道应该根据哪种方式处理数据。
  5. load类指令的字节选择和store类相同,可参考 2.3.
  6. 由于访存地址需要在EX段才能得出,所以地址的最低两位最早也只能在EX段得出。可能有同学就发现了现在的CPU里ID段那个data_ram_wen的设置其实是有问题的,其实1bit的位宽用来判断读或写就够了(这个确实是我写的时候疏忽了)。
  7. 修改方法有两种:
  1. 直接把ID到EX的线宽改掉,在EX段对四位的选择信号进行赋值。EX到MEM由于MEM段中load指令分析时本身就需要四位的字节选位,不需要进行修改。(改的时候希望各位不会漏改和改错)
  2. 不修改线宽,直接借用已有的四位通道,自己对控制信号进行一些编码和解码,达到和 1. 一样的效果。

简单说明

  1. 该CPU现在可以执行ori lui addiu beq这四种指令,但并没有完成数据相关,请自行添加相关数据通路。

  2. 之后出现的问题可直接在群里提问,然后会被记录在这里形成Q&A。

  3. 请使用github进行版本管理,便于验收时检查。至于使用organization还是直接在个人账号里生成repo可自行选择。


使用方法

  1. 下载群文件中的nscscc2021_group_v0.01.7z到本地并解压,密码:nscscc2021

  2. clone本项目到本地

  3. 启动路径 nscscc2021_group_v0.01\func_test_v0.01\soc_sram_func\run_vivado\mycpu_prj1 下的 mycpu.xpr项目

  4. 在vivado中添加源文件,把这个项目的.v文件都导入(包括lib文件夹下)。

  5. 点击simulation进行仿真,第一次仿真时会对项目使用的ip核进行综合,可能需要等待10-25分钟不等(视电脑性能而定)。

  6. 点击播放进行仿真,如果停止可在vivado下方的控制台看到提示信息,这是龙芯实验平台提供的比对机制会告诉你当前在哪条 指令出现错误。

  7. 运行的汇编指令可在 nscscc2021_group_v0.01\func_test_v0.01\soft\memory_game\obj\test.s D:\nscscc2020_group_v0.01\func_test_v0.01\soft\func\obj\test.s 该文件中查找,直接搜索PC值即可。(不好意思之前写错了)

  8. 指令集文件可在doc文件夹的A03文件中查看。

  9. 其他相关问题基本都可在doc文件夹中的文件中找到答案。

  10. 欢迎留言,看到会回复,另外请注意Q&A的更新。


指令添加方法

  1. 阅读 A03 指令集文件,查看该指令会进行哪些操作

  2. 对于IF段,新指令一般对其没有影响(除了在添加异常的时候,需要检查指令地址是否出错)。

  3. 对于ID段

    • 需要在该级进行指令分析
    • 从寄存器中读取需要的数据
    • 完成数据相关处理
    • 生成发给EX段和MEM段的控制信号。
  4. 对于EX段

    • alu模块已经提供,基本通过给alu提供控制信号就可以完成逻辑和算术运算
    • load/store指令需要添加指令计算模块并控制data_sram_*信号组的输出,从而完成数据读写
    • branch/jump指令需要自己添加比较语句和判断逻辑并控制br_bus信号组,从而控制IF段正确完成跳转
  5. 对于MEM段

    • 接收并处理访存的结果,并选择写回结果是ex_result还是mem_result。
    • 之后会在MEM段处理中断异常,不过暂时用不到
  6. 对于WB段

    • 和ID段类似,暂时没有需要改动的东西

debug建议

  1. 查看console(控制台)中的trace比对机制的提示,记下提示的PC值,并猜测可能发生的错误。

  2. 打开test.s文件,使用提示的PC值进行查找,查看该PC值对应的指令是什么,判断是否添加该指令。

  3. 如果没添加指令,则前往 A03 文件阅读指令集,学习对应指令如何添加。

  4. 如果指令已经被添加,则到波形图中去检查运算结果错误原因。

  5. 当找到错误波形图时,请逐步添加其源头信号,直至发现引入错误的源信号,并改正。

  6. 修改后可能会出现新的错误,此时请重复步骤5。

  7. 可能会遇到波形图并未自动停止的情况,已知有两种情况:测试程序因为错误执行陷入死循环,写回级的输出出现错误导致比对机制失效。

  8. 如果不知道新的指令如何添加可以参考《自己动手做CPU》或者问助教。

    • PS:这本书原理说的还算明白,代码真别抄了,always写出来的组合逻辑你们把握不住。
  9. 如果助教也不知道你们错在哪了,请陪他一块反思。


提示

如果有同学遇到访存指令的正确结果为0000aaaa,但是一直不对的时候请联系助教


Q & A

  1. Q: 关于如何检查工作量?

    A: 建议各位同学每天写完代码都push到github上,到最后代码量一目了然,工作进度也很清楚。
    (如果一定要最后几天扎堆提交,我也愿意听你解释,当然分数好不好看就不知道了)

  2. Q: 拿到这个模板我应该如何入手?

    A: 群里有《自己动手写CPU》这本书的PDF,如果对流水线、旁路、数据相关之类的内容还没有概念,可以先看看这本书。 在掌握每章的内容后把该章节的内容写到自己的CPU里去。

    • PS:请不要妄图直接使用这本书里的源码,最后验收的时候会检查代码,两套代码长什么样我还是一清二楚的。
    • 对于别的学校的代码,如果你去观摩学习,然后把里面的好东西拿来用,那我非常支持。
    • 如果你直接把别人的代码copy过来用,那看一下代码风格,问几个问题基本就露馅了,没意思的。
    • 所以有问题就快问,别一直拖着。
  3. Q: 波形图左侧的列表里为什么和我选中的时刻的数值不一样啊?

    A: 波形图左侧列表里显示的数值是波形图运行到的最后一个时刻的数值,并不是鼠标点击时刻的数值。

    • 查看波形图时,先把需要的信号添加到波形图中,然后用鼠标点选锁定信号,再用下一个/上一个上升沿的按钮进行移动。
    • (点选信号,然后用方向键也能控制,更多控制方法可自行尝试)
  4. Q: 模块间的接线是接在哪里?

    A: mycpu_core.v内有所有模块的实例化和对应的接线。

    tips:接线的时候记得设置位宽,不然线是1位宽度,剩下的都是X。

  5. Q: core和top分别是干什么用的,为什么要分成两个文件?

    A: core是用来写cpu里的数据通路的,对应《自己动手写CPU》书中的顶层模块。top和core之间是为了后面补充地址映射模块的。

    待更新

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].