当前位置: 首页 > ops >正文

RISC-V三级流水线项目:总体概述和取指模块

前言

一个三级流水线的RISC-V项目,但是更新的会比较慢。因为手上有别的项目,所以只能闲的时候学习。

RISC-V介绍

RISC,即精简指令集处理器,是相对于X86这种CISC(复杂指令集处理器)来说的。RISC-V中的V是罗马数字,也即阿拉伯数字中的5,就是指第5代RISC。
RISC-V是一种指令集架构,和ARM、MIPS这些是属于同一类东西。RISC-V诞生于2010年,最大的特点是开源,任何人都可以设计RISC-V架构的处理器并且不会有任何版权问题。

流水线

本处理器使用了三级流水线,即取指、译码和执行,设计的目标就是要对标ARM的Cortex-M3系列处理器。如果是五级流水线的话就是:取指(IF),译码(ID),执行(EX),访存(访问存储器,MEM),写回(数据写回到目标寄存器,write back)。三级流水线中的执行包括了访存和写回。

实现目标

本项目实现的是一个三级流水线设计,顺序、单发射、单核的32位RISC-V处理器。采用verilog语言编写。设计目标是对标ARM Cortex-M3系列处理器。

开发环境

RTL代码编写:Notepad–
仿真及查看波形:
Linux VCS+Verdi(前面出过一篇博客 ,有兴趣的可以去看看)

本章内容

编写取指代码并进行简单的验证
即if模块 if_id模块(打一拍)

编写思路

在这里插入图片描述

IF模块

module ifu #(parameter bit          BranchPredictor      = 1'b1)(input wire                      clk,input wire                      rst_n,input wire                      flush_i,      // 冲刷标志input wire[31:0]                flush_addr_i, // 冲刷地址input wire[`STALL_WIDTH-1:0]    stall_i,      // 流水线暂停标志input wire                      id_ready_i,   // ID模块可以接收指令// to ifu_iduoutput wire[31:0]               inst_o,output wire[31:0]               pc_o,output wire                     inst_valid_o,// 指令总线信号(核内部信号)output wire                     instr_req_o,   //请求输出信号input  wire                     instr_gnt_i,   //判断指令是否正常,能否从指令中接收到正确的命令 	input  wire                     instr_rvalid_i,output wire[31:0]               instr_addr_o,  //指令地址输出信号input  wire[31:0]               instr_rdata_i,input  wire                     instr_err_i);

取指的作用就是从PC的到指令地址,然后从ROM中根据指定的地址取出对应的指令
需要注意的是流水线冲刷机制

取指操作

这个过程我们用组合逻辑和一个状态机实现。
状态机主要判断是复位、正在取指还是取值有效结束。

状态机编写
  //req_valid代表请求有效  指令正常且取值流水线未暂停assign req_valid = instr_gnt_i & (~stall_i[`STALL_IF]);always @ (*) beginstate_d = state_q;case (state_q)// 复位S_RESET: begin// 复位撤销后转到取指状态if (rst_n) beginstate_d = S_FETCH;endend// 取指S_FETCH: begin// 取指有效if (req_valid) beginstate_d = S_VALID;endend// 指令有效S_VALID: begin// 取指无效if (~req_valid) beginstate_d = S_FETCH;endenddefault: ;endcaseend
指令有效和给打拍输入的信号(组合逻辑实现)
    // 指令有效assign inst_valid   = (state_q == S_VALID) & instr_rvalid_i & id_ready_i;assign inst_valid_o = inst_valid;// 指令无效时有nop指令代替assign inst_o       = inst_valid ? instr_rdata_i: `INST_NOP;assign pc_o         = fetch_addr_q;   //PC给的指令地址
更新地址

主要要考虑b型指令,看是否进行分支预测

    // 更新取指地址assign fetch_addr_n = flush_i            ? flush_addr_i:prdt_taken         ? prdt_addr:inst_valid         ? fetch_addr_q + 4'h4:fetch_addr_q;// 取指请求assign instr_req_o  = (~stall_i[`STALL_IF]) & (state_q != S_RESET);// 取指地址(4字节对齐)assign instr_addr_o = {fetch_addr_n[31:2], 2'b00};//分支预测 看是否进行地址的跳转 按照手册的opcode和fun3和fun7确定if (BranchPredictor) begin: g_branch_predictorbpu u_bpu(.clk(clk),.rst_n(rst_n),.inst_i(instr_rdata_i),.inst_valid_i(inst_valid),.pc_i(fetch_addr_q),.prdt_taken_o(prdt_taken),.prdt_addr_o(prdt_addr));end else begin: g_no_branch_predictorassign prdt_taken = 1'b0;assign prdt_addr  = 32'h0;end

总结

完成了取指代码的编写
单独对这一块进行测试没有意义
等到后面全部编写完再进行测试吧

http://www.xdnf.cn/news/14594.html

相关文章:

  • 基于java SSM的房屋租赁系统设计和实现
  • python基于微信小程序的广西文化传承系统
  • 【入门级-基础知识与编程环境:3、计算机网络与Internet的基本概念】
  • VLN论文复现——VLFM(ICRA最佳论文)
  • AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)
  • 虚拟 DOM 与 Diff 算法:现代前端框架的核心机制
  • 边缘-云协同智能视觉系统:实时计算与云端智能的融合架构
  • PillarNet: Real-Time and High-PerformancePillar-based 3D Object Detection
  • MySQL 8.x配置MGR高可用+ProxySQL读写分离(二):ProxySQL配置MySQL代理及读写分离
  • HarmonyOS 5 多端适配原理与BreakpointSystem工具类解析:附代码
  • Flutter ListTile 徽章宽度自适应的真正原因与最佳实践
  • 十四天机器学习入门——决策树与随机森林:从零构建智慧决策模型
  • Python Django全功能框架开发秘籍
  • Jenkins部署及反向代理
  • 【JS-4.7-表单value属性】深入理解DOM操作中的表单value属性
  • 雷达高度计 RA-6500
  • AI浪潮拐点:MCP与A2A协议如何重塑AI智能体协作生态
  • 金融行业B端系统布局实战:风险管控与数据可视化的定制方案
  • 动手用 Web 实现一个 2048 游戏
  • 如何预防电磁铁损坏
  • Data Vault 初探(九) —— 定期装载_Kettle_附属表
  • Java性能优化权威指南-操作系统性能监控
  • HarmonyOS NEXT应用元服务布局优化ArkUI框架执行流程
  • 从java角度理解io多路复用和redis为什么使用io多路复用
  • PixPin:一个强大且免费的截图贴图工具
  • SpringBoot+Vue服装商城系统 附带详细运行指导视频
  • 群晖 NAS Docker 镜像加速配置详细教程
  • 开源 python 应用 开发(二)基于pyautogui、open cv 视觉识别的工具自动化
  • RSA加密原理及推导
  • Qt项目,记事本