蜂鸟E203学习笔记(五)——执行

news2024/11/18 21:44:28

1.1 执行概述

1.1.1 指令译码

指令所包含的信息编码在有限长度的指令字中,信息如下:

  • 指令所需要读取的操作数寄存器索引
  • 指令需要写回的寄存器索引
  • 指令的其他信息如指令类型、指令的操作信息等

顺便注意:并非所有的处理器流水线都会在译码阶段读取操作数。在目前众多高性能处理器中,普遍采用在每个运算单元前配置乱序发射队列的方式,待指令的相关性解除之后并从发射队列中发射出来时读取通用寄存器组,然后送给运算单元开始计算

1.1.2 指令执行

常见的运算单元有以下几种:

  • 算术逻辑运算单元(ALU),主要负责普通逻辑运算、加减法运算、和移位运算等基本运算。
  • 整数乘法单元,主要负责有符号或无符号数中整数的乘法
  • 整数除法单元
  • 浮点运算单元,常常分为不同的运算单元

1.1.3 流水线的冲突

除了根据指令的具体类型运算之外,指令执行阶段另外一个最重要的只能就是维护并解决流水线的冲突,包括资源冲突和数据冲突(WAR,WAW等)

1.1.4 指令的交付

1.1.5 指令发射、派遣、执行、写回的顺序

将指令发射给运算单元,由运算单元执行,然后写回的相对顺序,是执行阶段需要解决的重要问题。

  • 派遣(dipatch):可以按顺序派遣,也可以乱序派遣。
  • 发射(issue):可以按顺序发射,也可以乱序发射。

以上两个定义很容易被混淆,在简单的处理器中两者属于同一概念,都是指令经过译码之后被派发到不同的运算单元并执行的过程。
根据每个时钟周期一次能够发射的指令数,处理器可以分为单发射处理器和多发射处理器。根据各种顺序,处理器可以分为很多种流派:

  1. 顺序发射,顺序执行,顺序写回
    如经典的5级流水线。这种方式的性能比较低,但是硬件实现最简单面积最小
  2. 顺序发射,乱序执行,顺序写回
    执行不同指令所需的时钟周期不同,如除法指令往往要耗费几十个时钟周期,而最简单的逻辑运算仅需要一个时钟周期。乱序执行是指在指令的执行阶段由不同的运算单元同时执行不同的指令从而提高性能。但是在最终的写回阶段仍要要严格地按照顺序写回,因此很多时候运算单元需要等待其他的先写回,从而导致停滞。
  3. 乱序写回
    有些处理器会配备重排序缓冲器(ROB),但是这种方案会占用过大的空间,并且会增加功耗。还有一些别的方法。
  4. 顺序派遣,乱序发射
    存在于高性能超标量处理器

1.1.6 分支解析

主要是对于带条件的分支指令
在执行阶段需要使用ALU对指令进行条件判断(如大小)。计算结果与之前的预测结果进行比较如果结果不一致则代表之前的预测是错误的,需要进行流水线冲刷。需要放在流水线比较前端的位置。

1.2 蜂鸟E203处理器的执行实现

在这里插入图片描述

1.3 译码模块

译码模块完全由组合逻辑组成。其主要逻辑即根据RISC-V架构的指令编码规则进行译码,产生不同的指令类型信息、操作数寄存器索引等。相关源代码片段如下所示。
RISC-V指令标准参考

module e203_exu_decode(

  //
  // The IR stage to Decoder
  input  [`E203_INSTR_SIZE-1:0] i_instr,  //指令
  input  [`E203_PC_SIZE-1:0] i_pc,  //该指令的pc值
  input  i_prdt_taken,  //预测为需要跳转
  input  i_misalgn,              // The fetch misalign  //产生取址非对齐异常
  input  i_buserr,               // The fetch bus error //取址存储其访问错误标志
  input  i_muldiv_b2b,           // The back2back case for mul/div //暂时不知道

  input  dbg_mode,  //来自外部
  //
  // The Decoded Info-Bus

  output dec_rs1x0,   //该指令原操作数1的寄存器索引为x0
  output dec_rs2x0,   //该指令原操作数2的寄存器索引为x0
  output dec_rs1en,   //需要读取原操作数1
  output dec_rs2en,    //需要读取原操作数2
  output dec_rdwen,   //该指令需要写结果操作数
  output [`E203_RFIDX_WIDTH-1:0] dec_rs1idx,  //该指令原操作数1的寄存器索引
  output [`E203_RFIDX_WIDTH-1:0] dec_rs2idx,  //该指令原操作数2的寄存器索引
  output [`E203_RFIDX_WIDTH-1:0] dec_rdidx, //该指令结果寄存器索引
  output [`E203_DECINFO_WIDTH-1:0] dec_info,  //该指令的其他信息
  output [`E203_XLEN-1:0] dec_imm,  //该指令使用的立即数值
  output [`E203_PC_SIZE-1:0] dec_pc,  //该指令的pc值
  output dec_misalgn, //产生取址非对齐异常
  output dec_buserr,  //取址存储其访问错误标志
  output dec_ilegl, //该指令是一个非法指令

  `ifdef E203_HAS_NICE//{
  //
  //nice decode
  input  nice_xs_off,  //接1‘b0
  output dec_nice,  //接1‘b0
  output nice_cmt_off_ilgl_o,        //接1‘b0
  /
  `endif//}

  output dec_mulhsu,  //指令是mulshu指令
  output dec_mul   ,//指令是乘法指令
  output dec_div   , //指令是除法指令
  output dec_rem   , //指令是取余指令
  output dec_divu  , //指令是无符号除法指令
  output dec_remu  , //指令是无符号取余指令

  output dec_rv32, //指令是32位指令还是16位指令
  output dec_bjp,//指令是普通指令还是分支指令(跳转指令)
  output dec_jal, //指令是无条件直接跳转指令
  output dec_jalr, //指令是无条件间接跳转指令
  output dec_bxx,//指令是带条件直接跳转指令

  output [`E203_RFIDX_WIDTH-1:0] dec_jalr_rs1idx,//无条件间接跳转指令rs1的索引 5bit
  output [`E203_XLEN-1:0] dec_bjp_imm  //分支指令中的立即数 32bit
  );

对于32位指令的译码比较直接,因为RISC-V的32位指令较规整

wire [32-1:0] rv32_instr = i_instr;
  wire [16-1:0] rv16_instr = i_instr[15:0];

  wire [6:0]  opcode = rv32_instr[6:0];

  wire opcode_1_0_00  = (opcode[1:0] == 2'b00);
  wire opcode_1_0_01  = (opcode[1:0] == 2'b01);
  wire opcode_1_0_10  = (opcode[1:0] == 2'b10);
  wire opcode_1_0_11  = (opcode[1:0] == 2'b11);

  wire rv32 = (~(i_instr[4:2] == 3'b111)) & opcode_1_0_11; //该指令是一个32位指令  指令的234位不全是1且指令的最低两位全是1
 
  wire [4:0]  rv32_rd     = rv32_instr[11:7]; //32位指令码分段表示不同的含义
  wire [2:0]  rv32_func3  = rv32_instr[14:12];
  wire [4:0]  rv32_rs1    = rv32_instr[19:15];
  wire [4:0]  rv32_rs2    = rv32_instr[24:20];
  wire [6:0]  rv32_func7  = rv32_instr[31:25];

指令译码:

 wire rv32_load     = opcode_6_5_00 & opcode_4_2_000 & opcode_1_0_11;  //opcode==0000011 属于I类load指令
  wire rv32_store    = opcode_6_5_01 & opcode_4_2_000 & opcode_1_0_11;  //opcode==0100011 属于S类存储指令
  wire rv32_madd     = opcode_6_5_10 & opcode_4_2_000 & opcode_1_0_11; 
  wire rv32_branch   = opcode_6_5_11 & opcode_4_2_000 & opcode_1_0_11; //opcode==1100011 属于32位分支指令

  wire rv32_load_fp  = opcode_6_5_00 & opcode_4_2_001 & opcode_1_0_11; 
  wire rv32_store_fp = opcode_6_5_01 & opcode_4_2_001 & opcode_1_0_11; 
  wire rv32_msub     = opcode_6_5_10 & opcode_4_2_001 & opcode_1_0_11; 
  wire rv32_jalr     = opcode_6_5_11 & opcode_4_2_001 & opcode_1_0_11; //opcode==1100111 属于I类无条件间接跳转指令

1.4 整数通用寄存器组

整数通用寄存器组(Inter Register File, IRF)主要用于实现RISC-V架构定义的整数通用寄存器组。整数指令最多两个操作数,而且蜂鸟是单发射,则只需要两个读端口,一个写端口。结构如下图所示。
在这里插入图片描述
写端口通过比较输入的结果寄存器索引和通用寄存器号来产生写使能信号。读端口是纯粹的并行多路选择器。选择信号就是读操作数的寄存器索引,放到专用的寄存器寄存来降低功耗。
E203_exu_regfile.v

module e203_exu_regfile(
  input  [`E203_RFIDX_WIDTH-1:0] read_src1_idx, // 从minidecode的指令源操作数rs1的索引  在读数据时候用
  input  [`E203_RFIDX_WIDTH-1:0] read_src2_idx, // 从minidecode的指令源操作数rs2的索引  在读数据时候用
  output [`E203_XLEN-1:0] read_src1_dat,  // 取出的源操作数的值
  output [`E203_XLEN-1:0] read_src2_dat,  // 取出的源操作数的值

  input  wbck_dest_wen,  //写回操作的写使能,由wbck模块给出
  input  [`E203_RFIDX_WIDTH-1:0] wbck_dest_idx,  // 写回操作的寄存器地址,由wbck模块给出
  input  [`E203_XLEN-1:0] wbck_dest_dat,     // 写回操作的待写入数据,由wbck模块给出

  output [`E203_XLEN-1:0] x1_r,  // 由于x1常用于link寄存器用于函数的跳转返回,这里直接接出来的x1的值做加速,读x1不需要读端口,但是需要检查数据相关性

  input  test_mode,
  input  clk,
  input  rst_n
  );

  wire [`E203_XLEN-1:0] rf_r [`E203_RFREG_NUM-1:0];    //3232位通用寄存器
  wire [`E203_RFREG_NUM-1:0] rf_wen;   //控制打开哪个寄存器进行写入数据

1.5 CSR(控制和状态寄存器)

RISC-V架构中国定义了一些控制和状态寄存器用于配置或者记录一些运行的状态。CSR是处理器核内部的寄存器,使用其自己的地址编码空间,与存储器寻址的地址空间完全没有关系。
CSR的访问采用专用的CSR读写指令。包括csrrw、csrrs、csrrc、csrrwi等
e203_exu_csr.v就是用来实现E203处理器所支持的CSR功能。
端口定义代码如下所示

module e203_exu_csr(
  ////用于配置或记录一些运行状态////
  input nonflush_cmt_ena, //这个信号只有输入,但啥也没干,来自commit
`ifdef E203_HAS_NICE
  output nice_xs_off, //跟写处理器相关,接了0
`endif

  input csr_ena,  //来自alu的csr读写使能信号  来自alu的csrctrl
  input csr_wr_en,  //csr的写使能信号  来自alu的csrctrl
  input csr_rd_en,  //csr的读使能信号  来自alu的csrctrl
  input [12-1:0] csr_idx,//csr寄存器的地址索引  来自alu的csrctrl

  output csr_access_ilgl,   //固定接1'b0
  output tm_stop,          //自定义的配置寄存器的配置信息相应位段的输出,停止timer计数指示信号 
  output core_cgstop,     //停止cpu core逻辑的clk gating
  output tcm_cgstop,     //停止TCM clk gating
  output itcm_nohold,    //itcm 不hold数据的指示信号
  output mdv_nob2b,      //mul/div 不采用back2back特性的指示信号

1.6 指令发射派遣

表示指令经过译码且从寄存器组中读取操作数之后被派发到不同的运算单元并执行的过程

1.7 流水线冲突、长指令和OITF

资源冲突
比如将指令派遣给除法单元并进行计算,但是除法单元需要数十个时钟周期才可以完成此指令。后续的指令派遣就需要等待时防。因此采用了严谨的valid-ready握手接口。一旦出现资源冲突ready信号就会拉低从而无法完成握手。
假设指令需要派遣到AGU子单元并执行,那么agu_op为高,但是AGU在占用,那么她的agu_i_ready为低这样i_ready就为低。反馈给上游模块的话就无法完成握手。

  assign i_ready =   (agu_i_ready & agu_op)
                   `ifdef E203_SUPPORT_SHARE_MULDIV //{
                   | (mdv_i_ready & mdv_op)
                   `endif//E203_SUPPORT_SHARE_MULDIV}
                   | (alu_i_ready & alu_op)
                   | (ifu_excp_i_ready & ifu_excp_op)
                   | (bjp_i_ready & bjp_op)
                   | (csr_i_ready & csr_op)
                   `ifdef E203_HAS_NICE//{
                   | (nice_i_ready & nice_op)
		   `endif//}

数据冲突
E20将所有需要执行的指令分为两类

  • 单周期执行的指令。
  • 多周期执行的指令。

由于E203是按顺序派遣和顺序写回的架构,因此不会发生WAR相关性。
对于RAW。如果前序指令为多周期指令则会发生这种相关性。
对于WAW。同RAW

为了能够检测出与长指令的RAW和WAW相关性,蜂鸟E203设计了一个滞外指令追踪FIFO(OITF)模块。

1.8 ALU

一共分为5个部分
在这里插入图片描述

  1. 普通ALU模块,主要负责普通的ALU指令(逻辑运算、加减法和移位等指令)的执行。
  2. 地址生成单元(AGU)模块,主要负责load、Store和A拓展指令的地址生成。
  3. 分支预测(BJP)模块 ,主要负责跳转和分支指令的分析和执行。
  4. CSR读写控制模块,主要负责分支与跳转指令的结果分析和执行
  5. 多周期乘除法模块,对于有符号的乘法采用常用的Booth编码算法计算部分积,然后使用迭代的方法对部分积进行累加得到最终的乘积。;对于有符号的整数除法采用常用的加减交替法,然后使用迭代的方法进行计算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL进阶篇(二) - 索引

一、索引概述(P66) 1. 介绍 索引(index)是帮助 MySQL 高效获取数据的数据结构(有序)。 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用&…

浅析Python中的struct模块

最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结。 了解c语言的人,一定会知道…

同花顺Python量化交易接口有什么功能?

为了进一步满足私募机构“本地化交易接口”的诉求,“同花顺Python量化交易接口”就出现了,目前仅支持同花顺模拟资金账户,您可以在本地对模拟资金账户进行下单、撤单、资产查询、委托查询等操作!那么同花顺Python量化交易接口可以…

如何实现随机生成坐标点,并且使每个坐标点之间的距离大于某个距离?(用于散点图的绘制,进行数据的处理)

背景: 最近需要开发一个新需求,需要绘制一个随机生成数字的散点图,要求点与点的距离要大于某个特定值。 解决思路: 通过循环获取每个坐标点,每获取一个新的坐标点,都要与之前生成的坐标点进行对比&#…

为你揭秘保健品平台利用“消费全返”,半年净赚过百万背后的原因

​大家好,我是每天分享电商模式咨询的林工,最近林工了解到某一家保健品企业,利用做会员招商活动一招“消费全返”的商业模式,在短短半年内裂变近数十万会员,净挣过百万营业额,这个模式值得各行各业的企业家…

Python实战案例,tkinter+random模块,实现课堂随机抽选提问并语音播报学生姓名

前言 今天给大家介绍Python实现课堂随机抽选提问并语音播报学生姓名实战案例,废话不多说直接开整~ 开发工具 Python版本: 3.8 相关模块: tkinter模块 time模块 random模块 环境搭建 安装Python并添加到环境变量,pip安装需…

计算机毕业设计ssm+vue基本微信小程序的琴房管理系统 uniapp 小程序

项目介绍 随着互联网技术的发发展,计算机技术广泛应用在人们的生活中,逐渐成为日常工作、生活不可或缺的工具,钢琴培训企业各种管理系统层出不穷,为钢琴培训企业琴房管理开发必要的系统,能够有效的提升管理效率。一直以来,钢琴培训企业琴房预约一直没有进行系统化的管理,学生无…

sharing-jdbc-1-5.x版本应用

1总结 2:详解 运行模式 :: ShardingSphere 用户手册,开发手册。这俩比较重要 spring.shardingsphere.mode.type 默认内存模式 3官网案例 不同的依赖坐标,配置方式不一样。按照官网的配置来一步一步配置。 4 整合springboot方式 行表达式 :…

【JS】postMessage 用法(可以给iframe传值)

文章目录基本概念代码案例基本概念 跨文档消息,有时候也简称为XDM(cross-document messaging) 是一种在不同执行上下文(如不同源的页面)间传递信息的能力。例如:www.wrox.com上的页面想要与包含在内嵌窗格中的p2p.wrox.com上面的页…

第一个Spring Boot程序

⭐️前言⭐️ 本文主要介绍Spring Boot项目的创建流程,及Spring Boot项目目录的一些注意事项。 🍉博客主页: 🍁【如风暖阳】🍁 🍉精品Java专栏【JavaEE进阶】、【JavaEE初阶】、【MySQL】、【数据结构】 &…

JAVA SCRIPT设计模式--行为型--设计模式之Command命令模式(14)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代…

服务器硬件规格常用查看命令——CPU相关命令

使用lscpu 命令可以从sysfs和/proc/cpuinfo中收集CPU体系结构信息,并解析优化为易阅读的格式。该信息包括:CPU的线程、核心、套接字数量和非一致内存访问(NUMA)节点的数量,以及CPU缓存、共享缓存、系列、型号等信息。 …

英文写作—Grammarly安装及下载

Grammarly是一款在线语法纠正和校对工具,支持Windows、Mac、iOS和Android等多个平台。 主要功能包括检查单词拼写、纠正标点符号、修正语法错误、调整语气以及给出风格建议等;对学术写作来说,Grammarly还可以帮助查重。 登陆界面&#xff1a…

每日一题:折半查找法,二分查找法

每日一题:折半查找法,二分查找法每日一题:折半查找法,二分查找法二分查找法定义:代码1:代码2:每日一题:折半查找法,二分查找法 ​ 💖💖个人博客:比…

SpringBoot之自定义注解

目录 1.java注解简介 1.1.java注解分类 1.1.1.JDK基本注解 1.1.2.JDK元注解 1.1.3.自定义注解 1.1.4 在这里如何自定义注解? 2、自定义注解 3.Aop应用自定义注解 1.java注解简介 Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解…

可靠性udp传输大文件

高级计算机网络大作业-可靠性udp传输大文件实验数据zstd压缩1G文件(延迟100ms、丢包1%)0.1G文件(延迟100ms、丢包1%)0.01G文件(延迟100ms、丢包1%)多线程lzma压缩1G文件(延迟100ms、丢包1%&…

N子棋(外加双人对战)详解!推荐!!!

文章目录准备工作创建菜单进入游戏初始化棋盘、打印棋盘玩家下棋、电脑下棋、生成随机数判断输赢大家好!时隔多天,我终于写博客了,真的是开心!这一次带来的是N子棋有双人对战和单人下棋,请认真看下去,我会竭…

虚拟人纷纷「出道」,社交泛娱乐场景如何迎接新顶流?

⬆️“政企数智办公行业研究报告及融云新品发布会”明天直播! 本月 12 日,花房集团即将于香港上市。关注【融云全球互联网通信云】回复【融云】抽取高颜值大容量高端可乐保温杯哦~ 中国政企数智办公平台 在带货直播平台的赫赫之名下,娱乐直播…

Git —— 那些在工作中日常使用的操作

Git —— 那些在工作中日常使用的操作 《工欲善其事,必先利其器》—— 既然点进来了,麻烦你看下去,希望你有不一样的收获~ 一、同一项目关联不同平台的远程仓库 格式:git remote add 命名 仓库链接 git remote add github ssh:/…

六、排序算法介绍2

1、冒泡排序 1.1 基本介绍 冒泡排序(Bubble Sorting) 的基本思想是: 通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值, 若发现逆序则交换, 使值较大的元素逐…