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

这篇具有很好参考价值的文章主要介绍了蜂鸟E203学习笔记(五)——执行。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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处理器的执行实现

蜂鸟e203 源码,蜂鸟E203,学习,fpga开发,嵌入式硬件

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 源码,蜂鸟E203,学习,fpga开发,嵌入式硬件
写端口通过比较输入的结果寄存器索引和通用寄存器号来产生写使能信号。读端口是纯粹的并行多路选择器。选择信号就是读操作数的寄存器索引,放到专用的寄存器寄存来降低功耗。
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个部分
蜂鸟e203 源码,蜂鸟E203,学习,fpga开发,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-693522.html

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

到了这里,关于蜂鸟E203学习笔记(五)——执行的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Acer宏碁笔记本电脑Aspire蜂鸟FUN S50-51原装Windows10系统镜像,恢复出厂系统

    自带所有驱动、办公软件、出厂主题壁纸LOGO、 Acer Care Center、Quick Access等预装程序 所需工具:32G或以上的U盘(非必需) 文件格式:多个ISO文件组合 ,19.3GB 注:恢复时会清空电脑上所有盘的数据,请提前转移备份好重要资料!! 链接:https://pan.baidu.com/s/1GCCc4_-Fbp5PjmsnoGsd4A?

    2024年02月11日
    浏览(94)
  • CPT203-Software Engineering 笔记

    failure reason  professional software development*** maintain, security, efficiency, acceptability two kinds***: generic, customized reduce changes/ side effects after changes 4 fundamental activities:s,d,v,e(迭代优化) Lec1 p24 •软件规范(Software specification)(需求明确) •软件开发(Software development) •软件验证(Softw

    2024年01月17日
    浏览(38)
  • Fpga开发笔记(二):高云FPGA发开发软件Gowin和高云fpga基本开发过程

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/135620590 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… 上一篇:《Fpga开发笔记(一):

    2024年01月16日
    浏览(71)
  • unity学习笔记-延迟执行方法

    我辣鸡,不会用

    2024年02月06日
    浏览(36)
  • Fpga开发笔记(一):高云FPGA芯片介绍,入手开发板套件、核心板和底板介绍

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/135551179 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… 上一篇:没有了 下一篇:《Fpga开

    2024年02月02日
    浏览(40)
  • FPGA 学习笔记:Vivado 工程更改FPGA 型号

    FPGA 不同系列,型号有些区别,并且不同型号FPGA 工程生成的 bit 文件,无法下载 当前最好的方式是每个型号都重新创建一个工程,不过这样多少有点繁琐,Vivado可以更改FPGA型号 设置里面,可以查看当前的FPGA型号 也可以通过【Window】 - 【Project Summary】,查看当前工程的FPGA

    2024年02月11日
    浏览(41)
  • FFmpeg开发笔记(三)FFmpeg的可执行程序介绍

    ​  外界对于FFmpeg主要有两种使用途径,一种是在命令行运行FFmpeg的可执行程序,该方式适合没什么特殊要求的普通场景;另一种是通过代码调用FFmpeg的动态链接库,由于开发者可以在C代码中编排个性化的逻辑,因此该方式适合厂商专用的特制场景。更多详细的FFmpeg开发知识

    2024年03月09日
    浏览(39)
  • FPGA学习笔记(2)

    程序语句 assign assign 语句是连续赋值语句,一般是将一个变量的值不间断地赋值给另一变量,格式一般为:         assign a = b (逻辑运算符)c…; assign 语句的功能属于组合逻辑的范畴,应用范围可以概括为一下几点: (1)持续赋值; (2)连线; (3)对 wire 型变量赋值

    2024年02月08日
    浏览(31)
  • FPGA学习笔记

    FPGA(Field Programmable Gate Array)现场可编程逻辑门阵列,ASIC(Application Specific Integrated Circuit)即专用集成电路。 比速度 相同的工艺和设计,在FPGA上的速度应该比ASIC跑得慢。因为FPGA内部是基于通用的结构,也就是LUT(lookuptable),它可以实现加法器,组合逻辑等等,而ASIC,一般

    2024年02月11日
    浏览(33)
  • FPGA — FIFO学习笔记

    使用软件: Vivado 参考文档 :FIFO Generator v13.2 FIFO(Fist In Fist Out),即为先进先出,常被用于数据的缓存或高速异步数据的交互,与普通存储器区别是没有外部读写地址线,使用简单,缺点是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像

    2024年02月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包