E203的IFU(instruction fetch unit)模块主要功能和接口如下:

  1. IFU的PC生成单元产生下一条指令的PC。
  2. 该PC传输到地址判断和ICB生成单元,就是根据PC值产生相应读指请求,可能的指令目的是ITCM或者外部存储,外部存储通过BIU访问。
  3. 该PC值也会传输到和EXU单元接口的PC寄存器中。
  4. 取回的指令会放置到和EXU接口的IR(Instruction register)寄存器中。EXU单元会根据指令和其对应的PC值进行后续的操作。
  5. 因为每个周期都要产生下一条指令的PC,所以取回的指令也会传入Mini-Decode单元,进行简单的译码操作,判别当前指令是普通指令还是分支跳转指令。如果判别为分支跳转指令,则在同一周期进行分支预测。最后,根据译码的信息和分支预测的信息生成下一条指令的PC。
  6. 来自commit模块的冲刷管线请求会复位PC值。

因为蜂鸟IFU要在同一个时钟周期完成取指,译码,分支预测,生成PC等多个操作,所以时序上的关键路径会制约它的最高主频。

IFU模块的接口包括如下信号:

inspect_pc, output,  位宽:32

当前IFU所取指令的pc值,如果当前ifu_reset_req信号置高,则为pc复位值,即pc_rtvec值=0x1000,因为指令被放在itcm中,itcm起始地址为0x8000_0000,所以通常pc值为itcm的某个地址值。

当rom启动系统时候,复位pc是0x1000=4096,通过指令0x7ffff297,auipc x5,0x7ffff, 当前x5=当前pc值+7ffff000=0x1000+0x7ffff000=0x8000_0000,指向了itmc的首地址。

然后通过指令jalr=0x28067, 指令跳转到x5指定的地址。

rom的初始化在文件sirv_mrom.v 中

  genvar i;
generate
if(1) begin: jump_to_ram_gen
// Just jump to the ITCM base address
for (i=0;i<1024;i=i+1) begin: rom_gen
if(i==0) begin: rom0_gen
assign mask_rom[i] = 32'h7ffff297; //auipc t0, 0x7ffff
end
else if(i==1) begin: rom1_gen
assign mask_rom[i] = 32'h00028067; //jr t0
end
else begin: rom_non01_gen
assign mask_rom[i] = 32'h00000000;
end
end
end
else begin: jump_to_non_ram_gen

ifu_active, output, 位宽1

这个输出信号总是1,意味着ifu模块会一直处于活动状态。

pc_rtvec, input, 位宽32

pc复位值,如果用simulation,其值为0x1000, 如果用fpga,外部qspi flash地址为0x2000_0000。这个信号从常开域传入。

sirv_aon_wrapper.v

  //  This signal will be passed to the main domain, since this is kind of pad selected signal
// we dont need to sync them in main domain, just directly use it
assign pc_rtvec = aon_io_bootrom ? 32'h0000_1000 :
// This is the external QSPI flash base address
32'h2000_0000;

ifu2itcm_holdup, input, 位宽1

上次访问itcm的模块是ifu,则设置该信号为高。

itcm_region_indic, input, 位宽32

itcm 起始地址指示信号,它的值为 0x8000_0000

该值在cpu_top.v中实例化e203_core时候,传入宏E203_ITCM_BASE_ADDR的值。

ifu2itcm_icb_cmd_valid, output, 位宽1

ifu2itcm_icb_cmd_ready,input,位宽1

ifu和itcm命令通道通讯的握手信号,采用icb协议,icb协议会在单独的文章中详细介绍。

ifu2itcm_icb_cmd_addr,output,位宽16

ifu请求读/写itcm数据的起始地址,因为itcm是64K大小,所以itcm地址位宽为16位。

ifu2itcm_icb_rsp_valid, input, 位宽1

ifu2itcm_icb_rsp_ready,output,位宽1

ifu和itcm响应通道通讯的握手信号,采用icb协议,icb协议会在单独的文章中详细介绍

ifu2itcm_icb_rsp_err, input, 位宽1

读或写itcm反馈的错误标志,如果该信号为低,则ifu接受itcm的返回结果。

ifu2itcm_icb_rsp_rdata, input, 位宽64

从itcm返回的32位数据。

ifu2biu_icb_cmd_valid, output, 位宽1

ifu2biu_icb_cmd_ready,input,位宽1

ifu和biu命令通道通讯的握手信号,采用icb协议,icb协议会在单独的文章中详细介绍。这个接口用于从system memory中读取数据

ifu2biu_icb_cmd_addr,output,位宽32

ifu请求读/写biu数据的起始地址,32位地址。

ifu2biu_icb_rsp_valid, input, 位宽1

ifu2biu_icb_rsp_ready,output,位宽1

ifu和biu响应通道通讯的握手信号,采用icb协议,icb协议会在单独的文章中详细介绍

ifu2biu_icb_rsp_err, input, 位宽1

读或写biu反馈的错误标志,如果该信号为低,则ifu接受biu的返回结果。

ifu2biu_icb_rsp_rdata, input, 位宽32

从biu返回的32位数据。

ifu_o_ir,output, 位宽32

指令寄存器中的值,是当前从itcm或biu中读取的32位指令数据,传输到exu的decoder中进行解码操作。

当指令来自于biu(system memory)时候,取得数据是32位,ifu_o_ir是ifu2biu_icb_rsp_rdata寄存一个周期。

当指令来自于itcm时候,因为itcm是64位,所以ifu2itcm_icb_rsp_rdata,返回的数据是64位,因为itcm是sram,上次访问的数据会一直holdup住。但ifu每次只取其中32位数据。因为会连续两次或多次在一个lane(64位对齐的数据成为一个lane)里面访问。如果上次访问的itcm的sram,下一次取指在同一个lane里面,则不会真的读取sram,会利用sram holdup的特性,直接使用其保持不变的输出。如果顺序取一个32位的指令其非对齐的地址跨越了64位边界,那么会将sram当前输出的最高16位放在leftover buffer之中。并发起新的itcm sram访问操作,然后将新访问itcm sram返回的低16位与leftover buffer中的值拼接成一个完整的32位指令。因此等效于一个周期读取一条指令,不会造成性能损失。如果是非顺序取指,比如分支或跳转指令,且地址为非对齐地址跨越了64位边界,那么就需要发起两次itcm读操作。第一个读回的数据的高16位放入leftover buffer中,第二次读回的数据的低16位和leftover buffer中的16位数据组合想成一个32位的指令。因此需要两个周期才能取回指令。

ifu_o_pc,output,位宽32

当前的指令pc值,注意:ifu_o_pc和inspect_pc的区别,ifu_o_pc相当于被寄存一个周期的inspect_pc值。

ifu_o_pc_valid, output, 位宽1

pc信号是有效的

ifu_o_misalgn,output,位宽1

该信号总是0,在e203中,不会发生不对齐的情况。

ifu_o_buserr,output,位宽1

该信号=ifu_rsp_err

ifu_o_rs1idx,output,位宽5

当前指令 源寄存器rs1的索引,来自于mini decoder模块的输出

ifu_o_rs2idx,output,位宽5
当前指令 源寄存器rs2的索引,来自于mini decoder模块的输出

ifu_o_prdt_taken,output,位宽1
当前指令预测是否需要跳转,来自于ifu中的bpu模块。

ifu_o_mul2div_b2b,output,位宽1

// For multiplicaiton, only the MUL instruction following
// MULH/MULHU/MULSU can be treated as back2back
( minidec_mul & dec2ifu_mulhsu)
// For divider and reminder instructions, only the following cases
// can be treated as back2back
// * DIV--REM
// * REM--DIV
// * DIVU--REMU
// * REMU--DIVU

pipe_flush_ack,output,位宽1

总是1,

pipe_flush_req,input,位宽1

pipe flsuh请求,来自于exu模块,冲刷现在管线,根据新的pc值从新取指。

pipe_flush_add_op1,input,32

pipe flsuh操作的op1,和op2一起决定新的pc

pipe_flush_add_op2,input, 32

pipe flsuh操作的op2,和op1一起决定新的pc

ifu_halt_req,input,位宽1

ifu_halt_ack,output,位宽1

ifu halt请求响应信号,请求置高后,ifu停止取新的指令,ack响应置高后,恢复取指令。

// The halt request come from other commit stage
// If the ifu_halt_req is asserting, then IFU will stop fetching new
// instructions and after the oustanding transactions are completed,
// asserting the ifu_halt_ack as the response.
// The IFU will resume fetching only after the ifu_halt_req is deasserted

oitf_empty,input,位宽1

oitf为空,不用进行数据冲突判断,肯定不存在RAW和WAW数据冲突

rf2ifu_x1,input,位宽32

当前x1寄存器的值

rf2ifu_rs1,input,位宽32

当前指令中rs1寄存器的值

dec2ifu_rden,input,位宽1

当前指令包括目的寄存器寄存器rd

dec2ifu_rs1en,input,位宽1

当前指令包括源寄存器rs1

dec2ifu_rdidx,input,位宽5

当前指令目的寄存器rd索引

dec2ifu_mulhsu,input,位宽1

当前指令为mulh,mulhsu, mulhu

dec2ifu_div,input,位宽1

当前指令为div

dec2ifu_rem,input,位宽1

当前指令为rem

dec2ifu_divu,input,位宽1

当前指令为divu

dec2ifu_remu,input,位宽1

当前指令为remu

clk,input,位宽1
时钟信号

rst_n,input,位宽1

复位信号

蜂鸟E203 IFU模块的更多相关文章

  1. E203 译码模块(1)

    E203是两级流水线结构,第一级是IFU进行取指操作,第二级包括译码.执行.交付和写回等功能.架构图如下: https://www.cnblogs.com/images/cnblogs_com/mik ...

  2. 蜂鸟E203系列——Linux开发工具

    欲观原文,请君移步 Vivado安装 vivado是运行工程的工具,所以必须安装 后台回复[vivado2017]可获取vivado 2017.4 | 后台回复[vivado2020]可获取vitis ...

  3. 蜂鸟E203系列——Linux调试(GDB+Openocd)

    欲观原文,请君移步 本文基于文章<蜂鸟E203系列--利用 Hbrid-E-SDK 环境开发程序> GDB 简介 GDB(GNU Project Debugger),是 GNU 工具链中的 ...

  4. E203 译码模块(2)

    常用的alu算术运算指令(包括ecall和 ebreak)在regular alu单元处理.regular alu单元为alu单元的一个子单元.regular单元的信息总线共21位,格式如下图所示,其 ...

  5. 蜂鸟E203系列——Linux下运行hello world例程

    欲观原文,请君移步 创建程序 在 -/hbird-e-sdk-master/software 路径下创建一个"helloworld"中文件夹 在 -/hbird-e-sdk-mas ...

  6. E203译码模块(3)

    下面的代码译码出指令的立即数,不同的指令有不同的立即数编码形式. //I类型指令的imm,[31:20],符号位扩展成32位. wire [31:0] rv32_i_imm = { {20{rv32_ ...

  7. 真正的RISC-V开发板——VEGA织女星开发板开箱评测

    前言 由于最近ARM公司要求员工"停止所有与华为及其子公司正在生效的合约.支持及未决约定",即暂停与华为的相关合作,大家纷纷把注意力投向了另一个的处理器架构RISC-V,它是基于精 ...

  8. RISCV 入门 (学习笔记)

    文章目录 1. risv 相关背景 1.1 arm 授权费 1.2 riscv 发展历史 1.3 riscv 风险 2. 指令集 2.1 可配置的通用寄存器组 2.2 规整的指令编码 2.3 简洁的存 ...

  9. E203 CSR寄存器

    RiscV架构则定义了一些控制和状态寄存器(CSR),用于配置或记录一些运行的状态.CSR寄存器是处理器内核内部的寄存器,使用专有的12位地址编码空间,对一个hart,可以配置4k的CSR寄存器. 蜂 ...

随机推荐

  1. ThinkPHP 3.2,配置 'URL_MODEL'=>2。 APP_DEBUG设为false,U函数生成的URL的index.php不能去掉,只有将APP_DEBUG改成true,才能去掉index.php,求解~~

    ThinkPHP 3.2,配置 'URL_MODEL'=>2.APP_DEBUG设为false,U函数生成的URL的index.php不能去掉,只有将APP_DEBUG改成true,才能去掉in ...

  2. 海思Hi3519A MPP从入门到精通(二 系统控制)

    系统控制根据 Hi35xx 芯片特性,完成硬件各个部件的复位.基本初始化工作,同时负责完成 MPP(Media Process Platform 媒体处理平台)系统各个业务模块的初始化.去初始化以及管 ...

  3. Linux命令: cat

    -s  连续多个空行显示为一个空行. -n 给每一行前显示行号. -b 只给非空行前显示行号. -E  在每行后显示一个$ cat f - g  把文件f的内容.STDIN.文件g的内容连接起来 .

  4. windows系统下mount创建的.vhd

    自己无聊时候分出了几个磁盘用来练习,存放个人东西,cdef盘除了c盘都是随便乱存的(粗心-_-),于是分出了两个20G的vhd文件,但是每次开机都要去d盘点击挂载太麻烦,现在分享自己的方法. 创建mo ...

  5. 高阶JS---函数柯里化

    什么是函数柯里化? 百度百科: 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.通 ...

  6. 日志分析利器Splunk的搭建、使用、破解

    博主对splunk的了解不多,博主的使用目的是为了同步,分析日志.当初的搭建也是为了公司申请牌照需要日志服务器分析日志,顺便自己也对这方面感兴趣就买了本书看了看搭建玩的,后来检查来了博主也给他们演示了 ...

  7. 4. jenkins 构建任务

    这边说一下 ,服务器的分布.  因为我这边 测试环境的项目比较多,不能修改主机名 1号机器 节点机器(node) 最终项目发布到这台机器 2号机器  jenkins jenkins的部署,发布 3号机 ...

  8. LeetCode 二进制问题

    338. Counting Bits(计算小于n的各个数值对应的二进制1的个数) 思路:通过奇偶判断,if i是偶数,a[i]=a[i/2],if i是奇数,a[i]=a[i-1]+1. class ...

  9. CF358D Dima and Hares

    CF358D Dima and Hares 洛谷评测传送门 题目描述 Dima liked the present he got from Inna very much. He liked the p ...

  10. npm ERR! Cannot read property 'resolve' of undefined

    一 .有可能是版本过低,或者软件损坏,重新安装一下试试 地址