diff --git a/doc/计算机结构设计实验/RV64.vsdx b/doc/计算机结构设计实验/RV64.vsdx index 109aef3..38747b0 100644 Binary files a/doc/计算机结构设计实验/RV64.vsdx and b/doc/计算机结构设计实验/RV64.vsdx differ diff --git a/doc/计算机结构设计实验/实现R型运算类指令的理想流水线设计实验/typst/main.typ b/doc/计算机结构设计实验/实现R型运算类指令的理想流水线设计实验/typst/main.typ index b17eb99..6010b14 100644 --- a/doc/计算机结构设计实验/实现R型运算类指令的理想流水线设计实验/typst/main.typ +++ b/doc/计算机结构设计实验/实现R型运算类指令的理想流水线设计实验/typst/main.typ @@ -29,6 +29,9 @@ #let dir_name = "这里填开发环境名称" #let soc_freq = "100MHz" +#let inst_ram_date_wid = 32 +#let paddr_wid = 32 + = 实验目的 + 掌握R型运算类指令的数据通路 + 掌握经典单发射五级流水线的设计方法 @@ -127,13 +130,13 @@ RISC-V单周期CPU设计实现简单,控制器部分是纯组合逻辑电路 #fakepar #figure( image("../image/image-20240109155256358.png"), - caption: "取指单元" -)<取指单元> + caption: "取指单元及指令RAM" +)<取指单元及指令RAM> #fakepar -pc的输出将送到指令SRAM中用于获取指令,由于我们的指令SRAM的地址宽度只有32位,因此只有pc的低32会被使用。目前来看,PC的输入有两个,一个是复位值0x80000000(由于发送给指令SRAM的是pc_next,所以pc的真正复位值其实是0x80000000-0x4),一个是复位撤销之后pc_next的值。 +pc的输出将送到指令SRAM中用于获取指令,由于我们的指令SRAM的地址宽度只有#paddr_wid 位,因此只有pc的低#paddr_wid 会被使用。目前来看,PC的输入有两个,一个是复位值0x80000000(由于发送给指令SRAM的是pc_next,所以pc的真正复位值其实是0x80000000-0x4),一个是复位撤销之后pc_next的值。 -因为取指单元只会对内存进行读操作,因此inst_sram_en只要在reset无效时使能即可,而inst_sram_wen应该恒为低电平。@取指单元 展示了取指单元的结构。 +因为取指单元只会对内存进行读操作,因此inst_sram_en只要在reset无效时使能即可,而inst_sram_wen应该恒为低电平。@取指单元及指令RAM 展示了取指单元的结构。 #noindent #text(fill: blue)[(#unitcnt_inc)虚实地址转换] @@ -143,11 +146,13 @@ pc的输出将送到指令SRAM中用于获取指令,由于我们的指令SRAM 得到取指所需的物理地址后,接下来就要将该地址送往内存。我们采用片上的RAM作为内存,并且将RAM进一步分拆为指令RAM和数据RAM两块物理上独立的RAM以简化设计。 -指令RAM输出的32位数据就是指令码。本书中我们实现的CPU采用小尾端的寻址,所以指令RAM输出的32位数据与指令系统规范中的定义的字节顺序是一致的,不需要做任何字节序调整。 +指令RAM输出的#inst_ram_date_wid 位数据就是指令码。本书中我们实现的CPU采用小尾端的寻址,所以指令RAM输出的#inst_ram_date_wid 位数据与指令系统规范中的定义的字节顺序是一致的,不需要做任何字节序调整。 + +@取指单元及指令RAM 展示了指令RAM的结构。指令RAM保留了写接口,这样的接口设计,是为了和之后的AXI的设计保持一致性。 #noindent #text(fill: blue)[(#unitcnt_inc)指令队列] -我们将Fetch/Decode之间的流水线缓存称为指令队列。我们将指令队列之前的阶段称为前端,将指令队列之后的阶段称为后端。当取指单元一次取指的数量大于译码单元可以解码的数量时,又或是后端流水线发生暂停时,取指单元可以继续取指,多余的指令可以在指令队列中排队等待,而不用暂停取指。通过指令队列这个部件可以解耦前后端。 +我们将取指单元/译码单元之间的流水线缓存称为指令队列。我们将指令队列之前的阶段称为前端,将指令队列之后的阶段称为后端。当取指单元一次取指的数量大于译码单元可以解码的数量时,又或是后端流水线发生暂停时,取指单元可以继续取指,多余的指令可以在指令队列中排队等待,而不用暂停取指。通过指令队列这个部件可以解耦前后端。 #fakepar #figure( @@ -306,7 +311,7 @@ ADD指令需要写回通用寄存器堆,因此我们需要在写回级访问 // #fakepar // #figure( - // //TODO:增加目录结构图 +TODO:增加目录结构图 // caption: "开发环境目录结构" // )<开发环境目录结构> // #fakepar @@ -338,7 +343,7 @@ myCPU和dram、Peripherals之间有一个“一分二”部件。这是因为在 由于上板的限制条件很多,这里我们再介绍我们实现的软件仿真方法,其运行效果与上板仿真几乎无异,但效率更高且更加方便。 -// TODO:仿真结构 +TODO:仿真结构 === myCPU的顶层接口 @@ -377,14 +382,14 @@ myCPU和dram、Peripherals之间有一个“一分二”部件。这是因为在 [reset], [1], [input], [复位信号,高电平同步复位], colspanx(3)[], text(red)[指令端访存接口], [inst_sram_en], [1], [output], [RAM使能信号,高电平有效], - [inst_sram_wen], [8], [output], [RAM字节写使能信号,高电平有效], - [inst_sram_addr], [32], [output], [RAM读写地址,字节寻址], - [inst_sram_wdata], [64], [output], [RAM写数据], - [inst_sram_rdata], [64], [input], [读数据], + [inst_sram_wen], [#{inst_ram_date_wid/8}], [output], [RAM字节写使能信号,高电平有效], + [inst_sram_addr], [#paddr_wid], [output], [RAM读写地址,字节寻址], + [inst_sram_wdata], [#inst_ram_date_wid], [output], [RAM写数据], + [inst_sram_rdata], [#inst_ram_date_wid], [input], [读数据], colspanx(3)[], text(red)[数据端访存接口], [data_sram_en], [1], [output], [RAM使能信号,高电平有效], [data_sram_wen], [8], [output], [RAM字节写使能信号,高电平有效], - [data_sram_addr], [32], [output], [RAM读写地址,字节寻址], + [data_sram_addr], [#paddr_wid], [output], [RAM读写地址,字节寻址], [data_sram_wdata], [64], [output], [RAM写数据], [data_sram_rdata], [64], [input], [读数据], colspanx(3)[], text(red)[debug信号,供验证平台使用], @@ -427,11 +432,21 @@ myCPU和dram、Peripherals之间有一个“一分二”部件。这是因为在 = 实验要求 -+ 根据本实验提供的五级流水线编程框架,在流水线 CPU 中添加以下指令:ADD、SLL、SLT 、SLTU、XOR 、SRL 、OR、AND 、SUB 、SRA -+ 通过本实验提供的所有测试用例 ++ 根据本实验提供的五级流水线编程框架,在流水线 CPU 中添加以下指令:ADD、SUB、SLL、SLT、SLTU、XOR、SRL、SRA、OR、AND、ADDW、SUBW、SLLW、SRLW、SRLW、SRAW。 ++ 通过本实验提供的所有仿真验证测试用例 ++ 通过本实验提供的所有板级验证测试用例 ++ 撰写实验报告:撰写报告时要求叙述以下内容,以及你对本实验的思考与探索。 + #[ + #set enum(numbering: "a)") + + 选择需要实现的指令中的一条,按照你自己的理解,逐步介绍其数据通路设计的思路以及实现过程 + + 尝试自己绘制一幅属于自己的数据通路图。(注意:以后数据通路的添加都需要在该图上继续增加。因此打一个好的地基很重要,现在偷懒之后还是需要补的。) + + TODO:增加更多内容 + ] = 实验步骤 ++ 实验平台的使用 ++ 如何上板 + 如何打开工程文件进行编程 + 如何使用模拟器进行仿真 + 如何提交测评 @@ -443,4 +458,5 @@ myCPU和dram、Peripherals之间有一个“一分二”部件。这是因为在 + SLT 和 SLTU 这类比较指令的实现是为了什么目的,比如是为了实现什么样的目标才有了这类指令?(方便实现大数计算的进位操作) + SLL、SRL 和 SRA 这三条指令在 src2 高 63 至 6 位不全为 0 的时候,指令的执行结果是什么?(手册规定只需要看 src2 低 6 位即可,高位忽略) + RISC-V 的运算指令有进行运算结果的溢出判断吗,为什么要这样设计?可以对比 MIPS 指令集进行说明(无溢出判断,相比 MIPS 少了 ADDU 等不判断溢出的指令,应该是为了节省指令编码空间,况且溢出判断可以用软件实现) -+ ++ 为什么并不是所有的R型计算指令都有对应的字指令? ++ 谈谈你在实验中碰到了哪些问题?又是如何解决的?