# hzv **Repository Path**: HiDark/hzv ## Basic Information - **Project Name**: hzv - **Description**: riscv - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-01-31 - **Last Updated**: 2023-10-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HZV ## 简介 * **参考** [实验十一 RV32I单周期CPU — 南京大学 计算机科学与技术系 数字逻辑与计算机组成 课程实验 documentation (nju-projectn.github.io)](https://nju-projectn.github.io/dlco-lecture-note/exp/11.html#pc) * **参考** [流水线 CPU 的基础知识 | Build Your PC (spencerwoo.com)](https://zanpu.spencerwoo.com/3_Pipelining/3-1_Basic.html#无关阶段的处理) * **目标** 五级流水 *** ## 控制通路 ( ctrl_gen.sv ) 1. **Branch真值表** | Branch | Zero | Less | PCAsrc | PCBsrc | NextPC | | --------- | ---- | ---- | ------- | ------ | ------- | | 1000 NOJ | x | x | A_4BYTE | B_PC | PC+4 | | 1001 JAL | x | x | A_IMM | B_PC | PC+imm | | 1010 JALR | x | x | A_IMM | B_RS1 | rs1+imm | | 0000 BEQ | 0 | x | A_4BYTE | B_PC | PC+4 | | 0000 BEQ | 1 | x | A_IMM | B_PC | PC+imm | | 0001 BNE | 0 | x | A_IMM | B_PC | PC+imm | | 0001 BNE | 1 | x | A_4BYTE | B_PC | PC+4 | | 01x0 BLT | x | 1 | A_IMM | B_PC | PC+imm | | 01x0 BLT | x | 0 | A_4BYTE | B_PC | PC+4 | | 01x1 BGE | x | 0 | A_IMM | B_PC | PC+imm | | 01x1 BGE | x | 1 | A_4BYTE | B_PC | PC+4 | ## 流水线 * 五级流水 if id ex mem wb ### Hazard 冲突有数据冲突、访存冲突以及控制冲突,下面依次介绍 #### 数据冲突 > 数据冲突来源于ALU的计算,rs1和rs2 > > 1. **前递一级:当前(EX)阶段的rs与上一级(MEM)的rd冲突** > > ![image-20230428130850806](README.assets/image-20230428130850806.png) > > 2. **前递两级:当前(EX)阶段的rs与上上级(WB)的rd冲突** > > ![image-20230428131343760](README.assets/image-20230428131343760.png) > > **检测逻辑:** > > ```verilog > always_comb begin > if (wb_addr_ex2mem == rs1_id2ex&&wb_en_ex2mem&&wb_addr_ex2mem!=5'd0) > forwardA = `FORWARD_ONE; > else if (wb_addr_mem2wb == rs1_id2ex > &&wb_en_mem2wb&&wb_addr_mem2wb!=5'd0 > &&(wb_addr_ex2mem != rs1_id2ex||!wb_en_ex2mem)) > forwardA = `FORWARD_TWO; > else > forwardA = `FORWARD_ZERO; > end > ``` > 3. **前递三级:当前(ID)阶段的rs与上上上级(WB)的rd冲突,使得写回和取rs同时发生,取得的仍是写回前的数据,示例如下** > > > ```assembly > > addi x1,x0,1 > > addi x2,x0,2 > > addi x3,x0,3 > > addi x4,x1,3 > > ``` > > **解决方法** > > ```verilog > always_comb begin > if (wb_addr_mem2wb == rs1_if2id && wb_en_mem2wb && wb_addr_mem2wb!=5'd0) > forwardC = `FORWARD_ONE; // rs1 > else if (wb_addr_mem2wb == rs2_if2id && wb_en_mem2wb && wb_addr_mem2wb!=5'd0) > forwardC = `FORWARD_TWO; // rs2 > else > forwardC = `FORWARD_ZERO; > end > ``` > > #### 访存冲突 > 访存冲突来源于Load和Store指令 > > 1. **Store冲突** > > Store指令的格式为:rs1与立即数偏置形成写地址,rs2寄存写数据,而写地址来源于ALU的计算,通过数据前递避免冲突,而写数据需要将原本ex的rs2替换为考虑数据冲突后的rs2。本质还是数据冲突。 > > 2. **Load冲突** > > 如果本级EX需要的操作数来源上一级的Load指令,由于Load在流水线第四阶段才能取得数据,反而落后本级EX,因此无法前递,需要nop掉当前指令,然后重新发送。 > > ![image-20230428133103276](README.assets/image-20230428133103276.png) > > ```Verilog > // 检测得到flag 通知取指模块,重新取指,PC不变,并将此级写内存和写寄存器置零,使指令无效 > assign refetch_flag = mem_rd_id2ex > &&(rd_id2ex == rs1_if2id||rd_id2ex == rs2_if2id); > ``` #### 控制冲突 > 当发生跳转操作(J、B)时,在EX阶段才分析出来,因此此时IF和ID阶段的指令要作废。ID阶段的无效与Load访存冲突处理情况类似,IF阶段的无效需要把指令清空。另外要保证清空的ID阶段指令中,J和B类型的指令跳转也要无效,因此把跳转标志PCjump_flag打一拍,从而控制PC的生成。 1. 无序列表 ,- (短杠+/*/-加空格,回车默认连续,连续打两个回车自动恢复)若嵌套,下一个之前打4空格 - 列表1 * 列表1.1 * 列表1.1.1 2. 分隔线,连续三个及以上的星号*,减号-然后加空格。如 *** ,--- 。 --- 3. 删除线,只需要在文字的两端加上两个波浪线 ~~ 即可,如![image-20220515103046808](C:\Users\DFY\AppData\Roaming\Typora\typora-user-images\image-20220515103046808.png) ~~BAIDU.COM~~ 4. 有序列表 数字加. ,两次回车取消 4. 区块(引用块) > ,>> ,>>> . > 最外层 > > > 第一层嵌套 > > > > > 第二层嵌套 5. 列表中使用区块,如果要在列表项目内放进区块,那么就需要在 > 前添加四个空格的缩进 * 第一项 > 区块一 * 第二项 > 区块二 7. 粗体 前后各两个** **加粗** 8. 斜体 前后各一个* *倾斜* 9. 高亮 前后各== ==highlight== 10. 图表 (ctrl+ T) | 图表 | | | | ---- | ---- | ---- | | | | | | | | | | | | | 11. 插入目录 “[TOC]” 12. emoji表情 :内容 :smile: