首页 > 其他分享 >总线总结

总线总结

时间:2024-07-05 16:33:10浏览次数:19  
标签:总结 slave +-----+ IDU 总线 --- valid master

不同的计算机内部需要通信,例如CPU和内存控制器通过一套协议通信,而内存控制器和内存颗粒通过另一套协议通信。

CPU   <---> Memory Controller  <-----> Memory Device

而在CPU内部,IFU和IDU需要通过信号通信,IDU和EXU通过信号通信。
软件模块中也有类似的需求,例如Difftest中NEMU需要和Spike通信,NPC需要和NEMU进行通信。

而广义的总线就叫通信系统-> TCP/IP 以太网,网线,RTL信号,系统调用等等
而我们用到的是狭义的总线-硬件模块的通信协议。


最简单的总线

IFU ->  (inst) -> IDU

主动发起通信的模块叫master(主设备),响应通信的模块叫做slave(从设备)。
其背后的通信协议有:

  • master(IFU)往slave(IDU)发送消息(也就是当前的inst),
  • 协议规定,只要master发送,slave就立即收到
  • 上述的发送行为每个周期都会发生
    • 即每个周期master都往slave发送有效的指令
    • 单周期处理器就是上述的协议。

较为真实的处理器总线:
IFU并非每个周期都能取到指令

  • IDU需要等待IFU完成取值后,才能进行译码。
      ->inst ->
IFU  ->valid -> IDU

需要添加valid信号,用来指示何时发送有效的指令。通信协议如下:

  • master(IFU)需要往slave(IDU)发送消息(当前指令inst)
  • 双方约定,只要master发送,slave立即收到
    总结来说只有valid有效的时候IDU才开始工作,但是inst在无时无刻都在传递。

更真实的处理器:
如果IDU并非每周期都能译码指令,

  • IFU需要㩐带IDU完成当前的译码工作后才能发送下一条指令
     inst -> 
IFU  valid ->  IDU
     <-ready

需要添加ready信号,通信协议如下:

  • master(IFU)往slave(IDU)发送消息(即当前指令inst)
  • 双方约定 ,若master发送,仅在ready有效的时候才认为slave收到。
  • 上述发送行为仅在valid有效的时候才发生。
  • 上述发送行为仅在valid有效发生
    这就是异步总线,需要注意的点有:
  • 通信发生的时刻无法提前与之,在 valid & ready时才发生,称之为握手。
  • valid & ready时,master需要暂存消息,避免丢失。

异步总线的RTL实现,也就是接口信号,Chisel提供了Decoupled模板,通过元编程实现异步总线接口。
Decoupled模板自带valid和ready

class Message extends Bundle {  
  val inst = Output(UInt(32.W))   //定义类Message中有啥,有指令inst32位
}
class IFU extends Module {
  val io = IO(new Bundle { val out = Decoupled(new Message) })  //把Message塞到Decoupled里面,IFU是发送方
  // ...
}
class IDU extends Module {
  val io = IO(new Bundle { val in = Filpped(Decoupled(new Message)) }) //IDU是接受方,Chisel里接受方只需要外套一个Filpped
  // ...
}

用这种高级语言的思想,我们想加一个信号的话只需要:

class Message extends Bundle {
   val inst = Output(UInt(32.W))
+  val pc = Output(UInt(32.W)) //只需要加一行,其余的指令都不用改
 }

异步总线的RTL实现-模块逻辑
master和slave需要根据握手信号的情况来实现约定的总线协议,其中master的状态转移图:

# master的状态转移图
   +-+ valid = 0
   | v         valid = 1
1. idle ----------------> 2. wait_ready <-+
   ^                          |      |    | ready = 0
   +--------------------------+      +----+
              ready = 1

master处于空闲,valid就一直等于0,则master下一个状态也是idle。
如果master有消息要发,valid就设置为1,进入下一个状态(wait_ready)。也就是等slave的ready信号就绪
如果valid和ready的信号状态同时为1,就算成功握手,那么master就从wait_ready状态进入到idle状态了。
上面是IDU和IFU的总线协议,那么不同微结构的处理器,只是模块间的通信协议不同。例如:

  • 单周期:每周期上游发送消息均有效,下游均就绪收到新消息。
  • 多周期:模块空闲的时候消息无效,模块忙碌时候不接收新消息,IFU收到WBU的完成信号后在取下一条指令。
  • 流水线:IFU一直取值,各模块每周期都尝试往下游发送消息
  • 乱需执行:下游模块有一个队列,上游只需要把消息发送到队列,即可继续处理新消息
+-----+ inst  ---> +-----+  ...  ---> +-----+  ...  ---> +-----+
| IFU | valid ---> | IDU | valid ---> | EXU | valid ---> | WBU |
+-----+ <--- ready +-----+ <--- ready +-----+ <--- ready +-----+

分布式控制和集中式控制

                   +--------------+
   +-------------> |  Controller  | <--------------+
   |               +--------------+                |
   |                ^            ^                 |
   v                v            v                 v
+-----+  inst   +-----+   ...   +-----+   ...   +-----+
| IFU | ------> | IDU | ------> | EXU | ------> | WBU |
+-----+         +-----+         +-----+         +-----+

其中集中式控制:控制器需要收集所有模块状态,并决定如何控制各模块的工作。

  • 可扩展性比较低,随着模块数量增加,控制器越来越难设计
    分布式控制:各模块的行为仅仅取决于自身状态和下游模块状态,也就是:
  • 各模块可以独立工作,直到下游无法接收消息
  • 容易插入新模块,只需修改上下游模块的接口实现。
    所以乱序执行天生就是分布式控制的。

最简单的系统总线就是连接处理器和存储器以及设备之间的总线,其中读是最基本的需求。
而npc中提供的接口pm_read在真实的处理器中是不可能实现的。
对于可读可写的系统总线来说:

+-----+ raddr[log2(N)-1:0] ---> +-----+
|     | <---        rdata[31:0] |     |
|     | waddr[log2(N)-1:0] ---> |     |
| CPU | wdata[31:0]        ---> | MEM |
|     | wen                ---> |     |
|     | wmask[3:0]         ---> |     |
+-----+                         +-----+

我们需要添加新信号:

  • 写地址 waddr,写数据wdata
  • 并非每个周期都要写,因此需要写使能wen
    允许只写入部分的字节,所以需要写掩码wmask,例如lb lh lw
    若同时读写同一地址,读出结果可能会undefine(需要RTFM)

而常用的存储器延迟更大, 所以我们有了新的需求:

  • slave需要识别master何时发送有效请求
  • master也需要识别slave何时可以接收请求

这就需要了握手信号。

  • 握手 = 双方对请求的发送和接收达成共识。 而且不会遗漏或重复

异步的系统总线:

+-----+ raddr[log2(N)-1:0] ---> +-----+
|     | rvalid             ---> |     |
|     | <---             rready |     |
|     | <---        rdata[31:0] |     |
| CPU | waddr[log2(N)-1:0] ---> | MEM |
|     | wdata[31:0]        ---> |     |
|     | wen                ---> |     |
|     | wmask[3:0]         ---> |     |
+-----+                         +-----+

上图就是CPU和Memory之间的交互,其中CPU可读的地址有raddr位宽个,rvalid为1时代表读有效 ,等待rready,实现读请求raddr的握手。
但是此刻又有新问题了

  • 例如slave读出rdata的时刻无法提前确定
    • 例如DRAM会定时对存储单元的电容进行充电刷新,此时需要等待
  • master也不一定总接收slave读出的数据。(例如上一次读出的数据还没用完,取决于状态机的状态)

而握手的意义就是解耦
通信的一方无法得知另一方处于什么状态,因此也无法的值另一方的处理延迟方法。
但是只要有了握手信号,双方均无需关心上述细节,只要等待握手即可,也就是只要模块遵循同一套通信协议,即可替换/接入,各模块皆可顺利工作。
同时我们也需要有错误处理:

+-----+ araddr[log2(N)-1:0] ---> +-----+
|     | arvalid             ---> |     |
|     | <---             arready |     |
|     | <---         rdata[31:0] |     |
|     | <---          rresp[1:0] |     |
|     | <---              rvalid |     |
|     | rready              ---> |     |
| CPU | waddr[log2(N)-1:0]  ---> | MEM |
|     | wdata[31:0]         ---> |     |
|     | wmask[3:0]          ---> |     |
|     | wvalid              ---> |     |
|     | <---              wready |     |
|     | <---          bresp[1:0] |     |
|     | <---              bvalid |     |
+-----+ bready              ---> +-----+

读写请求可能会出错,例如超过存储区域的边界,通过resp和bresp(b表示backward)向master回复读写操作是否成功)
优先判断resp是否符合预期值,如果符合的话rdata才有效。
若失败,CPU可抛出异常,通过软件处理。

得到手册的AXI-Lite总线规范
1、将写地址和写数据分开,写地址通过单独握手
2、分组,并将wmask改名为wstrb

araddr  --->               araddr  --->              araddr  ---> -+
arvalid --->               arvalid --->              arvalid --->  AR
<--- arready               <--- arready              <--- arready -+
<--- rdata                 <--- rdata                
<--- rresp                 <--- rresp                <--- rdata   -+
<--- rvalid                <--- rvalid               <--- rresp    |
rready  --->       1       rready  --->      2       <--- rvalid   R
waddr   --->      ===>     awaddr  --->     ===>     rready  ---> -+
wdata   --->               awvalid ---> *            
wmask   --->               <--- awready *            awaddr  ---> -+
wvalid  --->               wdata   --->              awvalid --->  AW
<--- wready                wmask   --->              <--- awready -+
<--- bresp                 wvalid  --->              
<--- bvalid                <--- wready               wdata   ---> -+
bready  --->               <--- bresp                wstrb   --->  |
                           <--- bvalid               wvalid  --->  W
                           bready  --->              <--- wready  -+

                                                     <--- bresp   -+
                                                     <--- bvalid   B
                                                     bready  ---> -+

对于读地址,分为AR的三个通道。也就是araddr arvalid 和arready
读数据的话分为R 也就是rdata rresp rvalid rready
写地址 awaddr awvalid awready
写数据 wdata wstrb wvalid wready


如果想使用总线,那么我们需要把NPC升级为多周期的处理器。
如果想要获得更高的主频,还需要在多模块之间添加暂存信号。
避免两种情况,
例如系统死锁(OS!!),master和slave都在等待对方先将握手信号置为1。

  • master:我等slave将ready置为1后,再将valid置为1
  • slave:我等master将valid置为1后,在将ready置为1
    相互等待直接G!
    活锁(OS!!!)
    局部看没卡死,全局看没进展
    master和slave都在试探性的握手,但试探失败后都取消握手。

而B就是back bresp 写回复,看写没写成功,bvalid同理。

标签:总结,slave,+-----+,IDU,总线,---,valid,master
From: https://www.cnblogs.com/ink-bai/p/18285369

相关文章

  • 干货丨渗透测试常用方法总结,大神之笔!_数据库渗透测试
    一、渗透流程信息收集漏洞验证/漏洞攻击提权,权限维持日志清理信息收集一般先运行端口扫描和漏洞扫描获取可以利用的漏洞。多利用搜索引擎端口扫描有授权的情况下直接使用nmap、masscan、自己写py脚本等端口扫描工具直接获取开放的端口和获取服务端的banner......
  • 回溯算法套路①子集型回溯 - 灵神视频总结
    我回来了,前两天模型出了问题,忙于工作。加上回溯有点想不清楚,查了查资料。汗颜。这节课主要讲回溯的基本概念和回溯的基本套路。首先各位思考一个问题:如果生成一个长度为2的字符串,该怎么操作?我们通常的想法是用两层循环拼接就好,如果用两层循环,如果我要生成长为2或者3......
  • 三菱PLC内部常用的特殊辅助继电器总结
    辅助继电器是plc中数量最多的一种继电器,一般的辅助继电器与继电器控制系统中的中间继电器相似。辅助继电器不能直接驱动外部负载,负载只能由输出继电器的外部触点驱动。辅助继电器的常开与常闭触点在PLC内部编程时可无限次使用。辅助继电器采用M与十进制数共同组成编......
  • Sentinel限流算法总结
    文章目录一、线程隔离二、滑动窗口算法三、令牌桶算法四、漏桶算法一、线程隔离线程隔离有两种方式实现:线程池隔离:给每个服务调用业务分配一个线程池,利用线程池本身实现隔离效果信号量隔离:不创建线程池,而是计数器模式,记录业务使用的线程数量,达到信号量上限时,禁止新......
  • CSS基础知识总结(1)
    1、CSS引入有哪几种方式?分别说说三种方式的使用方法和优缺点。三种:元素选择器,类选择器,id选择器。元素选择器就直接使用该HTML元素名称,在该元素名称下面写样式并进行应用。类选择器在CSS样式中,需要在类名的前面加上.,在HTML元素当中,我们应用起来就是元素名class="类名“。Id选......
  • python作业题百度网盘,python大作业总结
    大家好,小编来为大家解答以下问题,python作业题百度网盘,python大作业总结,现在让我们一起来看看吧!大家好,本文将围绕python大作业代码及文档展开说明,python大作业代码100行是一个很多人都想弄明白的事情,想搞清楚python期末大作业题目需要先了解以下几个事情。大家好,给大家分......
  • Delphi 常用控件之TlistView总结
    TlistView组件功能:(1)TListView控件可以用来显示各项带图标的列表,包括大图标和小图标的;也可以用来显示带有子项的列表,Windows操作系统的资源管理器中文件夹窗口就是最好的应用例子,就是我们打开"我的电脑"后能够看到各个盘符的界面(2)TListView控件基本能实现和DBGrid控件一......
  • 7.4日BootlLoad总结
    最近在研究单片机远程升级方法,看了网上许多资料后了解到,远程升级就是用IAP方法去烧写flash区,而IAP方法在EEPROM中有用到,也就是所说的掉电记忆,掉电不丢失的情况,而相较于51单片机,网上的资料大多是有关STM32单片机的,且使用操作系统,适合于芯片内存较大的芯片,分区成3-4块,首先是BOOT引导......
  • 设计模式-设计原则与设计模式总结
    设计原则,是设计模式的基础。在实际开发中,并不是一定要求所有代码都遵循设计原则,我们需要综合考虑人力、时间、成本、质量,不是可以追求完美,要在设当的场景遵循合适的设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。设计模式(DesignPattern)是前辈们经过相当长的......
  • JAVA每日作业day7.1-7.3小总结
    ok了家人们前几天学了一些知识,接下来一起看看吧一.APIJava的API(API:Application(应用)Programming(程序) Interface(接口))JavaAPI就是JDK中提供给我们使用的类,这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何......