首页 > 其他分享 >RISC-V CPU流水线仿真

RISC-V CPU流水线仿真

时间:2024-04-08 19:45:40浏览次数:21  
标签:文件 ELF RISC test release 流水线 加载 CPU 模拟器

RISC-V CPU流水线仿真
1.简介
RISC-V是一个开源体系结构和指令集标准,源于伯克利。该项目要求您实现一个基于标准的五级管道。您将需要实现指令的子集来自RISC-V规范2.2中指定的RV32I指令集。实施完整的CPU模拟器可以有效地锻炼系统编程能力加深对建筑相关知识的理解。
2.项目简介
2.1. 项目要求
该项目最重要的部分是实现RISC-V CPU流水线模拟器。具体要求如下:命令行参数解析器模块,允许解析RISC-V二进制文件的路径在命令行中指定的文件。它还提供了启用或禁用打印的选项文件末尾的历史日志。请确保您的模拟器可以由运行模拟器xxx.riscv,其中xxx.riscv是riscv二进制代码的路径。加载ELF文件(已在模板中实现)。历史模块(在模板中具有参考结构)。内存管理(在模板中有一个参考结构,这是一些人所需要的指示模拟所需指令(见第2.7节),包括处理系统调用(见第2.6节)。处理数据危害、控制危害和内存访问危害。
2.2. 可能的结构
注:这只是一种可能的结构。你可以设计自己的结构。
模拟器代码体系结构的概览图(图1)如下所示。这个模拟器的入口点是Main.cpp,其中包括解析参数、加载ELF文件,初始化模拟器模块,最后调用simulate()函数进入模拟器的执行。除非在执行模拟器时存在错误,理论上,simulate()函数不会返回。
模拟器本身被设计为一个大类,即模拟器中的数据类类包括PC、通用寄存器、流水线寄存器、执行历史记录器、内存模块和分支预测模块(对您来说不是必需的,不会影响您的分数)。其中,由于内存模块和分支预测模块相对独立的,它们被实现为两个独立的类MemoryManager和BranchPredictor。模拟器中最核心的功能是simulate()函数,它在模拟器上执行循环级模拟。在每次模拟中,它都会执行fetch()、decode(),execute()、accessMemory()和writeBack()五个函数,每个函数都将上一个循环的流水线寄存器,并输出到下一个周期的流水线寄存器周期在循环结束时,新寄存器的内容被复制到用作输入的寄存器中。在执行过程中,每个功能都处理与数据危害、控制危害相关的内容以及存储器访问危险,并在适当的地方记录历史信息。
图1:模拟器体系结构
2.3. 内存管理
MemoryManager的功能是提供简单易用的内存访问模拟器的接口,必须支持任意内存大小和内存地址访问,并且可以检测非法的存储器地址访问。您需要做的是加载根据节的虚拟内存地址和内存大小(而不是文件大小)。然后,当模拟执行读/写指令时,您只需要解析内存地址并直接
在MemoryManager中使用此内存地址进行操作,而不需要任何介于两者之间的转换。MemoryManager的以下实现使用了一种类似于x86体系结构中使用的两级页表(单层页表也可以)的机制。明确地一般来说,它将32位内存空间(4GB)逻辑地划分为大小为4KB的页面(2^12),使用存储器地址的前10位作为一级页表的索引,然后是另外1位作为二级页表的索引,最后使用最后12位作为单个页面内的偏移。注意:这是一个内存管理器示例。您可以创建自己的设计。但你必须确保ELF文件加载到正确的位置。有了以上内容实现时,您不需要一次分配4GB的内存;你只需要根据需要进行分配。当然,您也可以直接分配加载所需的内存ELF文件以及一个额外的堆栈区域(图2)。
2.4. ELF加载和初始化
您需要根据第3节来实现ELF文件加载程序,并初始化模拟器。ELF文件加载器负责将ELF文件加载到模拟器的内存,初始化过程负责设置的初始状态模拟器,包括设置PC的初始值,设置通用的初始值寄存器,并设置堆栈指针的初始值等。
图2:内存布局
图2显示了带有文本的简单计算机程序存储器的典型布局,各种数据以及堆栈和堆部分。文本和数据段被放置在加载ELF文件时的相应位置。加载ELF文件后,初始化通过将堆栈指针设置为内存顶部并将堆栈大小调整为例如需要4MB。堆管理通常由软件处理,因此您
不用担心。
2.5. 模拟器实现
对于RISC-V流水线模拟器,您需要实现五级流水线,包括获取,RV32I指令集中的所有指令都是固定长度的4字节。将指令解码、翻译成RISC-V汇编格式字符串。此外,仿通过从中抽象op1、op2和dest等公共字段实现硬件说明书执行,代 写 RISC-V CPU流水线仿真简单地根据不同的类型执行相应的行为。总之,它根据
解码阶段期间的当前命令和情况,并相应地采取行动。此时,jump命令获取是否发生跳转,并将气泡插入
当分支到错误的路径时,管道注册。内存访问,执行内存读写操作,并检测数据危害和转发。在检测数据危害时,需要同时考虑一般数据危害和管道由于上一个周期的内存访问危险而暂停的情况。此外,优先级还必须考虑转发的级别。写回,将执行结果写回寄存器,并像以前一样处理数据危害。对于RISC-V管道危险,我建议您参考以下链接:伯克利RISCV-V管道危险
华盛顿RISCV-V管道危险
2.6. 系统调用
此项目使用以下系统调用。系统调用使用ecall指令进行触发。这个a7寄存器保存系统调用号,a0寄存器保存系统呼叫参数,并且返回值将被保存在a0寄存器中。
系统调用
名称
系统调用
数字参数返回值
打印字符串0
初始地址
的字符串无
打印char 1 char的值None
打印编号2
的值
number无
退出程序3无无
Read char 4 None char的值
读取数字5无的值
数字
关于系统调用的详细信息可以在testrelease/lib.c中找到。2.7. 所需说明
下表列出了您需要在模拟器中实现的说明。你
有关这些的详细信息,请参阅RISC-V规范2.2
说明书
“lui”、“auipc”、“jal”、“Jarr”、“beq”、“bne”、“blt”,“bge”、“bltu”、“bgeu”、“lb”、“lh”、“lw”和“lbu”,“lhu”、“sb”、“sh”、“sw”、“addi”、“slti”、“seltiu”,“xori”、“ori”、“andi”、“slli”、“srli”、”srai“、”add“,“sub”,“sll”,“slt”,“sltu”,“xor”,“srl”,“或”,“和”,“ecall”
2.8. 历史
模拟器需要记录周期数和执行的指令数
在模拟过程中,并输出循环次数和
当输入参数指示需要打印这些参数时执行的指令。
注意:此部分不受测试脚本的测试,但您需要实现它并提供它在ReadMe.md中的用法。请确保您的ReadMe清晰详细。2.9. 高级功能
您可以实现以下高级功能来改进模拟器:
实现分支预测模块,以提高模拟器的性能。
实现缓存模块以提高模拟器的性能。这将是
与下一个项目相关。
实现无序执行模块,以提高模拟器的性能。
您感兴趣的其他一些高级功能。
注意:这些高级功能不是本项目所必需的,也不会影响
你的分数。如果你有兴趣,你可以实施它们。
2.10. 测试用例
我们为您提供一些测试案例来验证您的模拟器。您可以在testrelease目录中找到它们。我们还有其他程序来进一步验证您的模拟器,所有这些测试用例将成为你最终成绩的一部分。
如何运行测试用例:
从课程平台下载test-release.zip文件。解压缩项目根目录中的test-release.zip文件,您将获得testrelease目录并运行test-release.sh。在项目的根目录中运行Run-test-release.sh脚本,如bash runest-release.sh请确保您的

The example output:

bash run-test-release.shComparing ./test-release/add.out and ./test-release/add.refSucceed! Files ./test-release/add.out ./test-release/add.ref are the sameComparing ./test-release/mul-div.out and ./test-release/mul-div.refSucceed! Files ./test-release/mul-div.out ./test-release/mul-div.ref are thesame
Comparing ./test-release/n!.out and ./test-release/n!.refSucceed! Files ./test-release/n!.out ./test-release/n!.ref are the sameComparing ./test-release/qsort.out and ./test-release/qsort.refSucceed! Files ./test-release/qsort.out ./test-release/qsort.ref are the sameComparing ./test-release/simple-function.out and ./test-release/simplefunction.refSucceed! Files ./test-release/simple-function.out ./test-release/simplefunction.ref are the same五分之五的测试通过!
3.ELF文件加载器
3.1. ELF文件格式
ELF(可执行文件和链接格式)中有三种主要类型的对象文件总体安排
可重新加载文件:保存适合与其他对象文件链接的代码和数据。可执行文件:保存适合执行的程序。
共享对象文件:保存适合在两个上下文中链接的代码和数据。对象文件参与程序链接(构建程序)和程序执行
(运行程序)。为了方便和高效,对象文件格式提供了并行文件内容的视图,反映这些活动的不同需求。图3显示了ELF对象文件的基本结构。
图3:对象文件格式
对象文件格式的节:
章节在链接和编译过程中使用
它们表示ELF文件中不同类型的数据,例如初始化的代码(.text)数据(.data)、未初始化的数据(.bss)、符号表(.symtab)、字符串表(.strtab),重新定位信息(.rel.text、.rel.data)和调试信息。部分包含对链接和调试有用的信息,但它们不是
在执行程序时必须加载到存储器中。
ELF文件包含一个节头表,该表列出了所有节及其属性。对象文件格式的段:
分段在执行过程中使用。
它们通常是需要作为一个单元加载到内存中的部分的集合。总之,各节用于组织和在编译和链接期间使用,而
段用于在执行期间将ELF文件映射到内存中。对象文件segment包含一个或多个部分,称为“segment Contents”。3.2. 程序加载
当系统创建或扩充进程映像时,它会从逻辑上将文件的段复制到虚拟内存段。SYSTEM V体系结构的虚拟地址和文件偏移量分段是模4KB(0x1000)全等的或大于2的幂,这意味着当将虚拟地址和文件偏移量除以4KB,余数相同。因为
4KB是最大页面大小,无论物理大小,文件都适合映射页面大小。图4显示了ELF可执行文件的基本结构。
图4:可执行文件
尽管该示例的文件偏移量和虚拟地址都是模4KB一致的文本数据,最多四个文件页包含不纯净的文本或数据(取决于页面大小和文件系统块大小)。
第一个文本页包含ELF标题、程序标题表和其他信息。最后一个文本页包含数据开头的副本。
第一个数据页有一个文本末尾的副本。
最后一个数据页可能包含与运行过程无关的文件信息。图5:处理图像片段
从逻辑上讲,系统强制执行内存权限,就好像每个段都是完整的一样和分离;调整段的地址以确保地址中的每个逻辑页
空间只有一组权限。在上面的示例(图4)中,文件的区域持有文本的末尾和数据的开头将被映射两次;在一个虚拟文本的地址和数据的不同虚拟地址。
数据段的末尾需要对未初始化的数据进行特殊处理(通常指作为.bss段(由符号启动的块),是程序中内存的一部分为尚未由给定显式初始值的变量保留的
程序员系统将其定义为从零值开始。因此,如果文件的最后数据页面包含不在逻辑内存页面中的信息,必须设置无关数据为零,而不是可执行文件的未知内容。其他三种中的“杂质”页面在逻辑上不是过程图像的一部分;系统是否删除它们未指明。该程序的内存图像(图5)如下,假设为4KB(0x1000)页。
在这个项目中,你不需要关心页面中的“杂质”。只需处理未初始化的数据。
3.3. 程序加载示例
下面是一个将ELF文件加载到内存中的示例。以下是的输出加载add.riscv文件时使用模拟器。您需要为分段分配内存根据MSize(存储器大小)。对于大于FSize(文件大小)的地址,您需要填写具有0的内存。
./模拟器/test inclass/add.riscv-s-v=ELF信息型号:ELF32
编码:Little Endian
ISA:RISC-V(0xf3)
节数:14
ID名称地址大小
[0]0x0 0
[1] .text 0x100e8 8636
[2] .eh_帧0x13000 4
[3] .init_array 0x13008 16[4] .fini_array 0x13018 8[5] .data 0x13020 2472
[6] .sdata 0x139c8 32
[7] .sbss 0x139e8 56
[8] .bss 0x13a20 1416
[9] .注释0x0 45
[10] .rescv.attributes 0x0 28[11] .symtab 0x0 4632
[12] .strtab 0x0 1478
[13] .shstrtab 0x0 118
分段数量:3
ID标志地址FSize MSize
[0]0x4 0x0 28 0
[1] 0x5 0x10000 8868 8868[2] 0x6 0x13000 2536 4008===================================内存页:
0x0-0x400000:
0x10000-0x11000
0x11000-0x12000
0x12000-0x13000
0x13000-0x14000
在地址0x1012c处获取指令0x00003197注意:我们提供了一个示例ELF文件加载程序。您可以按原样使用,也可以根据需要进行修改您的需求。使用前请确保您理解它。
3.4. 其他一些信息
对于入口点,您可以在ELF标头中找到它(ELF标头的e_entry)。它提供了虚拟系统首先将控制权转移到的地址,从而开始处理。如果文件具有没有相关的入口点,它保持为零。
您可以选择创建自己的ELF文件加载程序或使用像elfio这样的现有库。你的选择不会影响你的分数,但为了更好,我建议你自己写了解ELF文件格式和程序加载过程。
有关ELF文件格式的更多信息,可以参考以下链接:cmu-ELF注意:所有用于测试的ELF文件都是小端序文件。确保管理文件的端序照着
4.提交
对于这个项目,您必须使用C/C++/Rust来实现模拟器。如果你使用python,你会得到0分。您需要提交以下文件:
src/,包括所有源代码文件
include/
,如果使用C/C,则包括所有头文件++CMakelists.txt,如果您使用C++/C,则是您项目的cmake文件Cargo.toml,如果您使用Rust,则为您的项目提供货物文件projetc-report.pdf,详细介绍您的项目。需要做的具体事情包括以下内容:
使用模拟器
模拟器的实施细节(如何处理危险,如何实施
管道等)
模拟器的历史信息
环境,如何编译和运行您的项目
你对内存管理的理解,ELF文件加载程序。
测试发布/*,包括我们提供的所有测试用例,不更改文件名build.sh,一个用于构建项目的脚本,它应该能够编译您的项目通过运行bash build.sh
请将所有文件压缩为一个zip文件并提交给课程平台。文件name应该是您的学生ID,如xxxxxxxxx.zip。请确保您的项目可以在Linux平台上编译并运行。如果您的项目无法编译和运行,您将获得0分。请确保您的模拟器可以由cmake与gcc一起编译/g++或货物。如果你使用其他工具,这是不可接受的。如果您对提交过程有任何问题或建议,请
请随时在课程组中询问我(TA张杨林)或发送电子邮件([email protected] / [email protected])对我来说。5.分级
对于这项任务,我们将提交一个RISC-V CPU流水线模拟器。如果你有很难完成这项工作,您可以提交模拟器的顺序版本;然而您将获得最高30%的分数。
总分计算如下:
未提供测试用例:45%
提供的测试用例:25%
历史(如第2.8节):5%
报告:20%
代码风格和注释:5%
高级功能(奖金):5%
一些需要注意的事项:代码应结构良好,易于理解。ReadMe.md应清晰易懂。请提供详细信息关于模拟器的介绍,包括模拟器的使用模拟器的实现细节,模拟器的历史信息,如何编译和运行您的项目,以及您认为重要的其他信息。请勿抄袭。如果我们发现你抄袭了,你不仅会收到这个项目的分数为零,但你也会直接不及格。此外,我们将向书记官处报告您的行为。如果我们使用剽窃检测软件和在TA确认后,发现你确实抄袭了,我们会通知你通过电子邮件。请确保您的项目能够通过上述测试脚本(第2.10节);我们将为您提供一些示例测试。如果您的项目没有达到预期效果输出时,它最初将获得零分。之后,您可以通过联系我们测试脚本,但项目中与代码样式和评论将直接为0。

标签:文件,ELF,RISC,test,release,流水线,加载,CPU,模拟器
From: https://www.cnblogs.com/gzashang/p/18122389

相关文章

  • py脚本实现监控(内存、磁盘、CPU负载)发送邮件
    #!usr/local/python3/bin/python3importsubprocess#引用模块importyagmail#引用模块defsendmail(user,passwd,text,subject,touser):yag=yagmail.SMTP(user=user,password=passwd,host="smtp.163.com"......
  • CPU怎么实现LOCK指令
    概述在CPU实现LOCK指令时,需要考虑到多核CPU的并发访问问题。一种常用的实现方式是在CPU内部添加一个锁控制单元,该单元负责控制对共享资源的访问锁控制单元通常由几个逻辑门组成在实现基于总线的锁机制时,锁控制单元可以由一个锁定信号线和一个锁定控制器组成当一个CPU需......
  • 【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(八)- 向量整数算术指令
     1.引言以下是《riscv-v-spec-1.0.pdf》文档的关键内容:这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量算术指令格式、向量整数和浮点算术指......
  • 【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(七)- 向量算术指令格式
      1.引言以下是《riscv-v-spec-1.0.pdf》文档的关键内容:这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量算术指令格式、向量整数和浮点算术......
  • 操作系统综合题之“采用实时调度,可调度的限制条件和可调度的最大X值是是多少ms的CPU时
    一、问题:单处理器情况下,m个周期性实时进程,若进程i处理时间为Ci,周期时间为Pi<(1≤i ≤m)1.要使系统可调度的限制条件什么?2.设置一个实时系统使用了4个周期事件,其周期分别为50ms,100ms,200ms,200ms。假设这4个周期时间分别需要25ms,20ms,10ms和xms的CPU时间。保持系统可调度的最......
  • 【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(四)- 配置和设置指令(vsetvli/vsetivli
      1.引言以下是《riscv-v-spec-1.0.pdf》文档的关键内容:这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量算术指令格式、向量整数和浮点算术......
  • 【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(五)- 向量加载和存储
      1.引言以下是《riscv-v-spec-1.0.pdf》文档的关键内容:这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量算术指令格式、向量整数和浮点算术......
  • CPU 是怎样进行任务切换的?
    通过“中断+任务门”进行任务切换好处好处抢占式任务调度,所有任务都有运行的机会例子在8258A中,把时钟的中断向量号设置为0x20,因此在中断描述符表IDT的第0x20个中断描述符中注册了时钟的中断处理程序随着时钟中断的定期发生,满足一定条件后,该中断处理程序又调用schedule......
  • 利用 Optimum Intel 和 fastRAG 在 CPU 上优化文本嵌入
    嵌入模型在很多场合都有广泛应用,如检索、重排、聚类以及分类。近年来,研究界在嵌入模型领域取得了很大的进展,这些进展大大提高了基于语义的应用的竞争力。BGE、GTE以及E5等模型在MTEB基准上长期霸榜,在某些情况下甚至优于私有的嵌入服务。HuggingFace模型hub提供了多种尺......
  • cpu如何执行指令
    重点:理解cpu执行指令的大概过程.c源代码文件->编译->.exe可执行文件(二进制)->点击运行.exe文件->操作系统把这个文件加载到内存cpu根据PC程序计数器,取指令解析执行指令  例子:......