tinyriscv这个SoC工程的内核cpu部分,采用经典的三级流水线结构进行设计,即大家所熟知的:取值—>译码—>执行三级流水线。

另外,在最后一个章节中会上传额外添加详细注释的工程代码,完全开源,如有需要可自行下载。

上一篇博文中注释了执行模块,现在来介绍中断模块

目录

0 RISC-V SoC注解系列文章目录

1. 中断结构图

2. csr_reg 控制与状态寄存器

2.1 中断和异常概述

2.2 csr_reg.v基础知识

2.3 csr_reg.v注解

3. clint.v 模块注解

3.1 接口定义

3.2 程序内容

4. ctrl.v模块(跳转和流水线暂停)

4.1 ctrl接口定义

4.2 功能概述(可参考原博客)

参考:


0 RISC-V SoC注解系列文章目录

零、RISC-V SoC软核笔记详解——前言

一、RISC-V SoC内核注解——取指

二、RISC-V SoC内核注解——译码

三、RISC-V SoC内核注解——执行

四、RISC-V SoC内核注解——除法(试商法)

五、RISC-V SoC内核注解——中断

六、RISC-V SoC内核注解——通用寄存器

七、RISC-V SoC内核注解——总线

八、RISC-V SoC外设注解——GPIO

九、RISC-V SoC外设注解——SPI接口

十、RISC-V SoC外设注解——timer定时器

十一、RISC-V SoC外设注解——UART模块(终篇)

1. 中断结构图

RISC-V内核的中断部分:涉及到    csr_reg.v、clint.v、ctrl.v等模块。由于中断模块和三级流水线紧密相关,所以我们这里放置内核的整体结构图来注解中断控制部分:

2. csr_reg 控制与状态寄存器

2.1 中断和异常概述

  • 中断(Interrupt) 机制,即处理器核在顺序执行程序指令流的过程中突然被别的请求打断而中止执行当前的程序,转而去处理别的事情,待其处理完了别的事情,然后重新回到之前程序中断的点继续执行之前的程序指令流。
  • 异常(Exception)机制,即处理器核在顺序执行程序指令流的过程中突然遇到了异常的事情而中止执行当前的程序,转而去处理该异常。同步异常:是指令异常,可以定位到具有的指令。异步异常:不能定位到具体的指令。
  • 中断和异常的区别:异常一般是由于处理器内部事件或者程序执行中的事件引起的。
  • 在广义上讲:中断和异常都被称为异常。

RISC-V架构异常处理机制:

  • 当前RISCV架构文档主要分为“指令集文档”和“特权架构文档”。RISC-V架构的异常处理机制定义在“特权架构文档”中。RISC-V的架构不仅可以有机器模式(Machine Mode)的工作模式,还可以有用户模式(User Mode)、监督模式(Supervisor Mode)等工作模式。在不同的模式下均可以产生异常,并且有的模式也可以响应中断。RISC-V架构要求机器模式是必须具备的模式,其他的模式均是可选而非必选的模式。
  • 中断,跳转,暂停之间的区别:中断和跳转都是触发暂停的原因。中断操作是为了提高程序的执行效率。中断或者for循环中,都会有跳转操作。

• 退出中断:使用中断返回指令MRET,在机器模式下必备。

• 中断类型:

外部中断:外设发生的中断,发生在处理核外部的中断。

计时器中断(外部中断中的一种):用mie寄存器中的mtie域进行控制。

软件中断:来自软件(C语言等软件语言)自己触发的中断。

调试中断:Dubug时的中断。

• 中断屏蔽:通过MIE寄存器,来控制不同类型的中断使能和屏蔽(外部中断、计时器中断、软件中断)。

2.2 csr_reg.v基础知识

CSR寄存器模块(csr_reg.v)和通用寄存器模块reg.v的读、写操作是类似的,这里就不重复了。

csr_reg.v中,主要用到的寄存器以及含义如下:

  • mtvec(Machine Trap Vector):保存发生异常时处理器需要跳转的地址(用来设置中断和异常的入口)。中断和异常需要跳转的基地址不同。
  • mcause(Machine Exception Cause):当产生中断和异常时,mcause寄存器中会记录当前产生的中断或者异常类型。
  • mepc(Machine Exception PC):保存发生异常指令的地址(中断返回的地址)。 在RISCV下产生中断或异常时,硬件自动将返回地址保存在mepc寄存器中,当在中断处理中返回时,硬件自动将mepc中的地址赋值给pc运行。(pc+4)
  • mstatus(Machine Status):全局中断使能和其他状态信息。 这个寄存器顾名思义是用来控制cpu核当前的一些状态信息的,比如全局中断使能等。 具体解释如下(默认不能嵌套中断):

mstatus [3] mie:中断全局使能,1为开启全局中断,0为关闭全局中断。发生中断之后,1变为0。

mstatus [7] mpie:存储mie在中断发生之前的数值。

mie(Machine Interrupt Enable):指明处理器目前能处理和忽略的中断。三种中断类型在m模式和s模式下都有相应的中断使能位设置,这是通过mie寄存器实现的。
mscratch(machine srcatch register)机器模式擦写寄存器:mscratch寄存器用于机器模式下的程序临时保存某些数据。mscratch寄存器可以提供一种快速的保存、恢复机制。比如,在进入机器模式的异常处理程序后,将应用程序的某个通用寄存器的值临时存入mscratch寄存器中,然后在退出异常处理程序之前,将mscratch寄存器中的值读出恢复至通用寄存器。
   时钟周期计数器(64bit):mcycle、mcycleh

  • mcycle: 计数值的低32位
  • mcycleh:计数值的高32位

2.3 csr_reg.v注解

输入和输出接口如下:

input wire clk,
input wire rst,
// form ex
input wire we_i,                        // ex模块写寄存器标志
input wire[`MemAddrBus] waddr_i,        // ex模块写寄存器地址 32位
input wire[`RegBus] data_i,             // ex模块写寄存器数据 32位
// form id
input wire[`MemAddrBus] raddr_i,        // ex模块读寄存器地址 32位
// to id
output reg[`RegBus] data_o              // id模块读寄存器数据
// from clint
input wire clint_we_i,                  // clint模块写寄存器标志
input wire[`MemAddrBus] clint_raddr_i,  // clint模块读寄存器地址
input wire[`MemAddrBus] clint_waddr_i,  // clint模块写寄存器地址
input wire[`RegBus] clint_data_i,       // clint模块写寄存器数据
// to clint
output wire global_int_en_o,            // 全局中断使能标志
output reg[`RegBus] clint_data_o,       // clint模块读寄存器数据(未使用)
output wire[`RegBus] clint_csr_mtvec,   // mtvec 保存发生异常时处理器需要跳转的地址
output wire[`RegBus] clint_csr_mepc,    // mepc 保存发生异常指令的地址
output wire[`RegBus] clint_csr_mstatus, // mstatus 全局中断使能和其他状态信息  

csr_reg.v主要功能:

程序中定义了几种CSR寄存器,以及一个64位的计数器(复位撤销后就一直计数,计数器统计自CPU复位以来共运行了多少个周期。(核心时钟可能是动态调整的))。

写寄存器:根据写寄存器地址的后12位,将ex或者clint模块中的数据寄存在控制与状态寄存器(CSR寄存器)中;

读寄存器(组合逻辑):读寄存器的地址来自译码id模块,并将从寄存器中读到的数据,送给译码id模块(根据读寄存器地址的后12位)。读寄存器的地址来自中断clint模块,并将从寄存器中读到的数据,送给clint模块(根据读寄存器地址的后12位)。

3. clint.v 模块注解

3.1 接口定义

input wire clk,
input wire rst,  // from core
input wire[`INT_BUS] int_flag_i,         // 中断输入信号(定时器timer中断输入)  // from id
input wire[`InstBus] inst_i,             // 指令内容
input wire[`InstAddrBus] inst_addr_i,    // 指令地址  // from ex
input wire jump_flag_i,
input wire[`InstAddrBus] jump_addr_i,
input wire div_started_i, //除法开始标志(在执行除法操作时为1,程序不能响应同步中断)  // from ctrl
input wire[`Hold_Flag_Bus] hold_flag_i,  // 流水线暂停标志(未使用)  // from csr_reg
input wire[`RegBus] data_i,              // CSR寄存器输入数据(未使用)
input wire[`RegBus] csr_mtvec,           // mtvec寄存器
input wire[`RegBus] csr_mepc,            // mepc寄存器
input wire[`RegBus] csr_mstatus,         // mstatus寄存器  input wire global_int_en_i,              // 全局中断使能标志  // to ctrl
output wire hold_flag_o,                 // 流水线暂停标志  // to csr_reg
output reg we_o,                         // 写CSR寄存器标志
output reg[`MemAddrBus] waddr_o,         // 写CSR寄存器地址
output reg[`MemAddrBus] raddr_o,         // 读CSR寄存器地址
output reg[`RegBus] data_o,              // 写CSR寄存器数据  // to ex
output reg[`InstAddrBus] int_addr_o,     // 中断入口地址
output reg int_assert_o                  // 中断标志  

3.2 程序内容

• RISC-V中断分为两种类型,一种是同步中断,即ECALL、EBREAK等指令所产生的中断,另一种是异步中断,即GPIO、UART等外设产生的中断。

• 程序设计思路:当检测到中断(中断返回)信号时,先暂停整条流水线,设置跳转地址为中断入口地址,然后读、写必要的CSR寄存器(mstatus、mepc、mcause等),等读写完这些CSR寄存器后取消流水线暂停,这样处理器就可以从中断入口地址开始取指,进入中断服务程序。

程序:

1.中断仲裁(组合逻辑):同步中断>异步中断>中断返回

同步中断:如果执行阶段的指令为除法指令,则先不处理同步中断,等除法指令执行完再处理。

异步中断:定时器中断(外设中断)和全局中断使能(mstatus[3])打开时,触发异步中断。

中断返回:中断返回指令。

2.CSR寄存器状态机跳转

提取中断返回的地址和引起中断的编码,以及CSR寄存器状态跳转。

3.写CSR寄存器(mstatus、mepc、mcause)

先写中断返回地址mepc

再写mstatus,以关闭全局中断(mstatus[3]=0)

将中断异常编码写入mcause寄存器

中断返回,返回的同时需要将全局中断位恢复(mstatus[3]=mstatus[7])

4.发送中断信号给执行模块(将csr寄存器写完之后,才可以发送中断信号给执行模块)

inst_i:判断是否是同步中断。

inst_addr_i:当前指令的地址。

inst_flag_i:计时器中断的中断flag信号。

int_assert_o:中断有效信号,信号为1时,开始运行中断处理程序。

4. ctrl.v模块(跳转和流水线暂停)

4.1 ctrl接口定义

input wire rst,  // from ex
input wire jump_flag_i, //跳转标志
input wire[`InstAddrBus] jump_addr_i,
input wire hold_flag_ex_i,  //暂停标志  // from rib
input wire hold_flag_rib_i,  // from jtag
input wire jtag_halt_flag_i,  // from clint
input wire hold_flag_clint_i,  output reg[`Hold_Flag_Bus] hold_flag_o,  // to pc_reg
output reg jump_flag_o,
output reg[`InstAddrBus] jump_addr_o  

4.2 功能概述(可参考原博客)

跳转就是改变PC寄存器的值。又因为跳转与否需要在执行阶段才知道,所以当需要跳转时,则需要暂停流水线(正确来说是冲刷流水线。流水线是不可以暂停的,除非时钟不跑了)。
冲刷流水线指的是,在指令中流淌的是NOP的指令。
tinyriscv的流水线结构如下图所示:

1.其中长方形表示的是时序逻辑电路,云状型表示的是组合逻辑电路。过程如下:

2.在执行阶段,当判断需要发生跳转时,发出跳转信号和跳转地址给ctrl(ctrl.v)模块。ctrl模块判断跳转信号有效后会给pc_reg、if_id和id_ex模块发出流水线暂停信号,并且还会给pc_reg模块发出跳转地址。

3.在时钟上升沿到来时,if_id和id_ex模块如果检测到流水线暂停信号有效则送出NOP指令,从而使得整条流水线(译码阶段、执行阶段)流淌的都是NOP指令,已经取出的指令就会无效,这就是流水线冲刷机制。

为了提高MCU的效率。因此根据不同的暂停信号,暂停不同的流水线阶段。具体操作如下:

/*
`define Hold_None 3'b000
`define Hold_Pc   3'b001
`define Hold_If   3'b010
`define Hold_Id   3'b011
*/  always @ (*) begin  jump_addr_o = jump_addr_i;  jump_flag_o = jump_flag_i;  // 默认不暂停  hold_flag_o = `Hold_None;  // 按优先级处理不同模块的请求  if (jump_flag_i == `JumpEnable || hold_flag_ex_i == `HoldEnable || hold_flag_clint_i == `HoldEnable) begin  // 对于跳转操作、来自执行阶段的暂停、来自中断模块的暂停则暂停整条流水线。   hold_flag_o = `Hold_Id;  end else if (hold_flag_rib_i == `HoldEnable) begin  // 对于总线暂停,只需要暂停PC寄存器,让译码和执行阶段继续运行。  hold_flag_o = `Hold_Pc;  end else if (jtag_halt_flag_i == `HoldEnable) begin  // 对于jtag模块暂停,则暂停整条流水线。  hold_flag_o = `Hold_Id;  end else begin  hold_flag_o = `Hold_None;  end  end  

总线暂停,一般是因为要访问外设。暂停pc寄存器是为了将下一条指令所需的数据在当前指令的访存操作中提取出来;只暂停pc寄存器,是因为访问外设期间的操作,和当前指令的执行没有冲突。

五、RISC-V SoC内核——中断 代码讲解相关推荐

  1. 一、RISC-V SoC内核——取指 代码讲解

    在开篇中我们对RISC-V及其SoC软核工程进行了简单介绍,现在来介绍取指模块: tinyriscv这个SoC工程的内核cpu部分,采用经典的三级流水线结构进行设计,即大家所熟知的:取值->译码 ...

  2. 七、RISC-V SoC内核——总线 代码讲解

    上一篇博文中注释了通用寄存器reg.v模块,现在来介绍总线模块rib.v: 另外,在最后一个章节中会上传额外添加详细注释的工程代码,完全开源,如有需要可自行下载. (这个RIB总线协议为工程原作者自定 ...

  3. 二、RISC-V SoC内核注解——译码 代码讲解

    tinyriscv这个SoC工程的内核cpu部分,采用经典的三级流水线结构进行设计,即大家所熟知的:取值->译码->执行三级流水线. 另外,在最后一个章节中会上传额外添加详细注释的工程代码 ...

  4. 十、RISC-V SoC外设——timer定时器 代码讲解

    上一篇博文中注释了SPI外设模块,现在来介绍timer定时器模块. 另外,在最后一个章节中会上传额外添加详细注释的工程代码,完全开源,如有需要可自行下载. 目录 0 RISC-V SoC注解系列文章目 ...

  5. 零、RISC-V SoC软核代码笔记详解——前言

    目录 0 RISC-V SoC注解系列文章目录 1 前言(手绘RISC-V SoC内核RTL试图): 2. 开源工程tinyriscv使用教程: 3. 开源工程tinyriscv下载地址: 4. 开源 ...

  6. 【OS学习笔记】三十八 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----微型内核汇代码

    本文是以下几篇文章对应的微型内核代码汇编代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十六 保护模式十 ...

  7. 龙芯处理器内核中断讲解

    龙芯处理器内核中断讲解 这里以龙芯处理器ls2k1000为例讲解 1.和中断相关的协处理器 ① 原因寄存器(Cause) IP7-0指出等待的中断.该位将保持不变直到中断撤除.IP0~IP1 是软中断 ...

  8. (第16-17讲)STM32F4单片机,FreeRTOS中断管理简介【视频笔记、代码讲解】【正点原子】【原创】

    文章目录 视频笔记 实验现象 代码讲解(个人注释) 一个弹幕的问题? PendSV和Systick中断优先级最低? demo函数 定时器函数 视频笔记 老生常谈 老生常谈 老生常谈,FreeRTOS只 ...

  9. tx2 fpga pcie无法读写_Cyclone V SOC(ARM+FPGA)开发文档_之开发流程详解

    双击可查看大图(手动狗头) 目录 Altera Cyclone V soc开发文档 之软硬件开发 1 Cyclone V开发流程介绍 5 专业术语 5 Cyclone V软件开发介绍 6 U-BOOT ...

最新文章

  1. 中国电子学会青少年编程能力等级测试图形化三级编程题:海底寻宝
  2. AEAI WM v1.6.0 升级说明,开源工作管理系统
  3. div+css的布局方式进行设计成品作业_原创响应式php企业成品网站,清晰风格版
  4. 初试WebStorage之localstorage
  5. POJ2182-Lost Cows【树状数组,二分】
  6. conda安装特定版本的包
  7. 交互式多模型_体系化教学资源上新——小学数学交互式教学工具
  8. VMware虚拟机端口映射(NAT设置)
  9. Android paint 效果研究
  10. 如何自动化入侵海康设备
  11. VirtualLab基础实验教程-6.闪耀光栅
  12. setCookie时遇到的问题
  13. c语言 电阻器的分类,电阻器的分类
  14. PS CS6中文如何切换成英文版界面?
  15. 神经网络建模的基本思想,建模方法神经网络设计
  16. 用python-sklearn做广州房价预测——以此为例说明如何使用python做简单的数据分析
  17. 证明题 (转自和菜头)
  18. 我的世界潜影盒计算机存储器,我的世界:很多人以为自己了解潜影盒,其实他们只看到了表面!...
  19. WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
  20. Android Studio 文件Excluded不显示找回

热门文章

  1. 星际争霸 Android手机移植版,让《星际争霸》运行在你的Android手机上
  2. 基于人工智能的多肽药物分析的子问题——蛋白质的三级结构预测的第一周学习记录
  3. 在Chrome中选择了“始终允许在关联的应用中打开此类链接”,如何取消关联?
  4. python初体验-hello world答案_2.跟老韩学Python之hello初体验
  5. 【POJ3093】Margaritas on the River Walk【01背包变种】
  6. 采购管理系统--合同、采购单、发货单、返厂单管理
  7. 最严谨的计算机语言p,P=NP?这世界真有捷径?
  8. 马斯克与SEC再次寻求法庭延长期限 以解决马斯克使用推特纷争
  9. ​史上解释CRC最清楚的文章
  10. 页框,页表,页表项,页面大小,页表项 长度的理解