当前位置: 首页 > news >正文

AMBA-AHB仲裁机制

前文        

        仲裁机制保证了任意时刻只有一个 master 可以接入总线。Arbiter 决定了哪个向其发出接入请求的 master 可以接入总线,这通过优先级算法实现。AHB规范并没有给出优先级算法,需要设计者根据具体的系统要求定义。一般情况下 arbiter 不会中断一个 burst 传输,将总线接入权让给其他 master。当然未定义长度的 burst 传输是可以打断的。这都要看优先级算法 是如何规定的。如果一笔 burst 被打断,master 再度获得接入权限,是会传递剩余的部分。 如一笔长度为 INCR8 的传输在传递 3beat 后被打断,master 再次获得接入授权后,会继续传 输剩余的 5beat,剩余部分可以由一个 SINGLE 和一个 INCR4 组成,或者是一个 INCR。
        用于仲裁的信号有:
HBUSREQx:master 向 arbiter 发出接入请求的信号。
HLOCKx:指示是否要进行不可中断的传输。这一信号与 HBURSEQx 同时由 master 向
arbiter 发出。
HGRANTx: arbiter 产生指示 master 获得授权。当 HGRANTx 信号为高同时 HREADY
为高时,master 可以向总线传输地址信号。
HMASTER[3:0]: arbiter 产生指示那个 master 获得授权。这一信号用于地址控制多路来
选择哪个 master 接入总线。
HMASTERLOCK: arbiter 产生指示当前传输是否为锁定序列传输。
HSPLIT: 供支持 SPLIT 传输使用。

 

​AHB协议仲裁机制详解​

​1. 仲裁机制核心功能​

仲裁器(Arbiter)是AHB总线的核心模块,用于在多主(Multi-Master)系统中协调总线访问权。其核心功能如下:

  • ​单主占用​​:确保同一时刻只有一个主设备(Master)接入总线。
  • ​优先级决策​​:基于自定义优先级算法(如固定优先级、轮询、动态优先级)选择授权的主设备。
  • ​突发完整性保护​​:通常不打断固定长度的突发传输(如INCR4WRAP8),但未定义长度的突发(如INCR)可能被中断。
​2. 仲裁信号与交互流程​

AHB协议通过以下信号实现仲裁控制:

​信号名称​​方向​​功能描述​
HBUSREQxMaster→Arbiter主设备请求总线访问(例如HBUSREQ0表示Master0请求总线)。
HLOCKxMaster→Arbiter指示当前传输为​​不可中断的锁定序列​​(如原子操作、关键数据搬运)。
HGRANTxArbiter→Master仲裁器授权主设备访问总线,需在HREADY=1时生效。
HMASTER[3:0]Arbiter→Slave标识当前获得总线授权的主设备编号,用于Slave选择数据源或响应。
HMASTERLOCKArbiter→Slave指示当前传输是否为锁定序列(与HLOCKx联动)。
HSPLIT[15:0]Slave→Arbiter支持SPLIT传输,从设备通知仲裁器释放指定主设备的总线占用。
​3. 优先级算法设计​

AHB协议未规定具体算法,设计者需根据系统需求选择:

​3.1 固定优先级(Fixed Priority)​
  • ​规则​​:主设备按预设优先级排序(如Master0 > Master1 > ...)。
  • ​场景​​:实时性要求高的系统(如中断控制器、DMA)。
  • ​示例​​:
    // 固定优先级仲裁器逻辑(Master0优先级最高)
    assign HGRANT0 = HBUSREQ0;
    assign HGRANT1 = HBUSREQ1 && !HBUSREQ0;
    assign HGRANT2 = HBUSREQ2 && !HBUSREQ0 && !HBUSREQ1;
​3.2 轮询(Round-Robin)​
  • ​规则​​:主设备按循环顺序获得授权,避免低优先级设备“饿死”。
  • ​场景​​:公平性要求高的多任务系统(如CPU与GPU协同)。
  • ​示例​​:
    使用状态机记录当前授权设备,每次授权后切换至下一设备。
  • 轮询仲裁主要是通过循环调整优先级,避免低优先级设备长期无法获得总线。其核心是​​优先级寄存器轮转​​和​​突发传输周期控制​,下面是示例代码:

        轮询仲裁的规则是当0、1、2、、、N-1个data模块同时向仲裁器发出请求 (request) 时,初始情况下data_req_0的优先级最高,当仲裁器响应了data_req_0后,data_req_1的优先级最高,存在规律:当仲裁器响应了data_req_i后,就令data_req_(i+1)的优先级最高(假设i不是最高位)。

        轮询仲裁器实现:轮询仲裁器的实现分为检测仲裁器输入口data模块的request,根据当前仲裁器的优先级响应相应的request,仲裁器grant输出data端的请求,更新仲裁器的优先级。假设模块的请求为8bit的request,每1bit代表第1个模块发起的request,当request中有多个bit位同时为1时,代表有多个模块同时申请总线,这时候我们就需要根据轮询仲裁规则,给优先级最高的模块一个grant信号,因此我们设置grant信号也为一个8bit的信号,当总线把控制权给第i个模块时,就把grant信号的第i位拉高,其他位为0。

例如:request = 8'b1101_0011时,共有五个模块同时申请总线,此时优先级最高的为第0个模块,所以输出grant = 8'b0000_0001。并把第0个信号的优先级调到最低,第1个信号的优先级调到最高。此时优先级顺序为1>2>3>4>5>6>7>0,若此时又来一个request = request = 8'b1101_0101,由于bit 0位置的优先级最低,所以继续往后搜索,搜索到bit 2位置,所以输出grant = 8'b0000_0100,第2个信号优先级调到最低,第3个信号优先级调到最高,即输出后优先级顺序变为:3>4>5>6>7>0>1>2,以此类推,这就是轮询仲裁。

module rr_arbiter(input                clk         ,input                rstn        ,input        [7:0]   req         ,output  reg  [7:0]   grant       
);reg  [7:0] shift_req;
wire [7:0] prio_grant;
wire [2:0] shift_length;// 根据上一周期的grant,修改request,使得最低bit位优先级最高。
always @(*)begincase(grant)     //this grant is pre-cycle request's result8'b0000_0001:shift_req = {req[0:0],req[7:1]};8'b0000_0010:shift_req = {req[1:0],req[7:2]};8'b0000_0100:shift_req = {req[2:0],req[7:3]};8'b0000_1000:shift_req = {req[3:0],req[7:4]};8'b0001_0000:shift_req = {req[4:0],req[7:5]};8'b0010_0000:shift_req = {req[5:0],req[7:6]};8'b0100_0000:shift_req = {req[6:0],req[7:7]};default:shift_req = req;endcase
end// 找到修改后最低位的one-hot码(参考fixed_arbiter设计)
assign prio_grant = shift_req & (~(shift_req-1));  // 如果grant信号是1,那么移动长度计算需要+1,如果grant信号是0则不+1.
// 这是因为$clog2函数,有$clog2(0)=$clog2(1)=0的缘故,所以我们需要区分grant是不是0.
assign shift_length = grant?($clog2(prio_grant) + $clog2(grant)+1):($clog2(prio_grant) + $clog2(grant));always @(posedge clk)beginif(!rstn)begingrant <= 8'd0;endelse if(req==0) // 如果输入为0,那么grant信号直接给0grant <= 8'd0;elsecase(shift_length)3'd0:grant <= 8'b0000_0001;3'd1:grant <= 8'b0000_0010;3'd2:grant <= 8'b0000_0100;3'd3:grant <= 8'b0000_1000;3'd4:grant <= 8'b0001_0000;3'd5:grant <= 8'b0010_0000;3'd6:grant <= 8'b0100_0000;3'd7:grant <= 8'b1000_0000;endcase
endendmodule
module rr_arbiter_tb();
reg clk,rstn;
reg [7:0] req;wire [7:0] grant;initial beginforever #5 clk = ~clk;
endinitial beginclk = 0;rstn = 0;req = 8'd0;#10rstn = 1;#5req = #1 8'b1011_1110;#10req = #1 8'b0101_0010;#10req = #1 8'b1010_1000;#10req = #1 8'b1100_1000;#10req = #1 8'd0;#50$finish();
endrr_arbiter u_rr_arbiter(.clk    (clk)  ,.rstn   (rstn) ,.req    (req)  ,.grant  (grant)
);initial begin$fsdbDumpfile("rr_arbiter.fsdb");$fsdbDumpvars(0);
endendmodule

 

​3.3 动态优先级(Dynamic Priority)​
  • ​规则​​:优先级根据系统状态(如负载、紧急任务)动态调整。
  • ​场景​​:复杂SoC中的资源调度(如AI加速器突发负载)。
  • ​示例​​:
    结合HSPLIT信号动态提升等待时间过长的主设备优先级。
  • 动态优先级结合固定优先级和等待时间阈值,提升公平性.

下面是一个例子,关键设计点​​:

  1. ​两级优先级​​:默认按固定优先级授权,若某设备等待时间超过阈值则临时提升其优先级。
  2. ​等待时间计数器​​:记录每个主设备从发出请求到获得授权的延迟,超过阈值时触发优先级调整。
  3. ​防止饿死​​:低优先级设备在长时间等待后可通过超时机制获得总线
// 动态优先级仲裁器(固定优先级 + 等待时间阈值)
module dynamic_priority_arbiter (input clk,input resetn,input [3:0] busreq,       // 4个主设备请求input [3:0] wait_time,    // 各设备等待时间计数input [3:0] time_threshold, // 等待时间阈值output reg [3:0] grant
);// 优先级判定逻辑
always @(*) begin// 检测是否有设备等待超时if (|(wait_time >= time_threshold)) begin// 优先授权超时设备(按固定优先级顺序)casex (wait_time >= time_threshold)4'b1xxx: grant = 4'b1000; // 设备3超时4'b01xx: grant = 4'b0100; // 设备2超时4'b001x: grant = 4'b0010; // 设备1超时4'b0001: grant = 4'b0001; // 设备0超时default: grant = 4'b0000;endcaseend else begin// 默认固定优先级(设备3 > 2 > 1 > 0)casex (busreq)4'b1xxx: grant = 4'b1000;4'b01xx: grant = 4'b0100;4'b001x: grant = 4'b0010;4'b0001: grant = 4'b0001;default: grant = 4'b0000;endcaseend
end// 等待时间计数器更新逻辑
always @(posedge clk) beginif (!resetn) beginwait_time <= 0;end else beginfor (int i=0; i<4; i++) beginif (busreq[i] && !grant[i]) wait_time[i] <= wait_time[i] + 1; // 未授权则累加else wait_time[i] <= 0;                // 授权或未请求则清零endend
endendmodule
​4. 突发传输中断与恢复​
​4.1 可中断条件​
  • ​未定义长度突发(INCR)​​:允许仲裁器中断,释放总线给更高优先级设备。
  • ​锁定传输(HLOCK=1)​​:不可中断,仲裁器必须等待传输完成。
​4.2 中断恢复机制​
  • ​示例​​:INCR8传输在3拍后被打断,剩余5拍需拆分传输:
    • ​拆分方式1​​:SINGLE(第4拍) + INCR4(第5~8拍)。
    • ​拆分方式2​​:INCR5(直接继续剩余传输)。
  • ​代码逻辑​​:
    // Master中断恢复逻辑
    if (burst_interrupted) beginHBURST = (remaining_beats == 1) ? SINGLE : INCR;HTRANS = NONSEQ; // 重新启动传输
    end
​5. 关键设计考量​
  1. ​总线效率与实时性平衡​
    • 高优先级设备频繁打断可能导致低优先级设备延迟激增,需设置最大等待阈值。
  2. ​锁定传输(Locked Transfer)​
    • 用于关键操作(如缓存一致性协议),需通过HLOCKx信号禁止仲裁器中断。
  3. ​SPLIT传输支持​
    • 从设备通过HSPLIT通知仲裁器释放指定主设备,适用于资源冲突场景(如共享外设忙)。
6.零周期等待示例

         下图显示了零等待周期,HREADY 为高时的判决情况。第一个周期 master 发出总线接入请求,第二个周期 arbiter 做出判决,第三个周期 arbiter 发出授权信号,第四周期master开始传递地址。

总结​

AHB仲裁机制通过灵活的优先级算法和信号交互,实现了多主系统的高效总线管理。设计时需重点考虑:

  • ​算法选择​​:根据实时性、公平性需求选择固定、轮询或动态优先级。
  • ​突发完整性​​:优先保障固定长度突发的完整执行,未定义突发需支持动态拆分。
  • ​异常处理​​:通过HSPLIT和锁定传输优化资源冲突与关键任务调度。
    该机制在复杂SoC中广泛用于平衡CPU、DMA、加速器等模块的总线竞争,是高性能系统设计的核心基础。

 

http://www.xdnf.cn/news/711901.html

相关文章:

  • RabbitMQ备份与恢复技术详解:策略、工具与最佳实践
  • 如何在WSL的Ubuntu里面启动腾讯微搭
  • excel表格记账 : 操作单元格进行加减乘除 | Excel中Evaluate函数
  • 关于DDOS
  • SQL Server 中创建链接服务器
  • android无root抓包(PCAPdroid)
  • Spring框架学习day1--基础概念
  • 深度解析UniApp盲盒系统开发:从源码架构到多端部署全流程
  • 基于STM32F10X的BMP280程序
  • 滚珠导轨:电子制造“纳米级”精度的运动基石
  • 如何用命令行将 PDF 表格转换为 HTML 表格
  • 责任链模式:构建灵活可扩展的请求处理体系(Java 实现详解)
  • ZYNQ移植FreeRTOS和固化和openAMP双核
  • 设备制造行业项目管理难点解析,如何有效解决?
  • 塔能科技:为多行业工厂量身定制精准节能方案
  • Kotlin 活动事件通讯跳转深度讲解
  • 职业本科院校无人机专业人才培养解决方案
  • KeePass安装与KeePass设置中文教程
  • springboot多模块父pom打包正常,单模块报错
  • clickhouse如何查看操作记录,从日志来查看写入是否成功
  • 湖北理元理律师事务所债务优化实践:在还款与生活间寻找平衡支点
  • [NOIP 2001 普及组] 数的计算 Java
  • 高防IP能抗住500G攻击吗?
  • PostgreSQL的聚集函数
  • Nest全栈到失业(三):半小时图书管理系统-User
  • Ubuntu 22.04 上安装 PostgreSQL(使用官方 APT 源)
  • CRMEB 单商户Java版 v2.3公测版发布,欢迎体验!
  • 收集飞花令碎片——C语言(数组+函数)
  • 酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方法
  • 小程序为什么要安装SSL安全证书