赞
踩
在多模块共享同一资源时,需要仲裁器来决定谁可以使用共享资源(如memory access).所以输入是各模块的请求(req),输出是grant。
仲裁器(arbiter) 在FPGA主要用于多个source源同时发出请求时,根据相应的优先级来响应哪一个source。FPGA的仲裁器分为轮询仲裁器(Round-Robiin)和固定优先级仲裁器(Fixed-Priority)。
轮询仲裁器规则
轮询仲裁的规则是当0、1、2、、、N-1个source信号源同时向仲裁器发出请求时,初始情况下source 0的优先级最高,当仲裁器响应了source0后,source1的优先级最高,依次类推。
轮询仲裁器实现
轮询仲裁器的实现分为检测仲裁器输入口source信号源的request,根据当前仲裁器的优先级响应相应的request,仲裁器grant输出source端的请求,更新仲裁器的优先级。
固定优先级仲裁器规则
Fixed-priority Arbiter顾名思义当0、1、2、、、N-1个source同时发起request,Source 0的优先级最高,即便source0被响应完后,仍为最高优先级,其中优先级按照序号逐渐降低。
固定优先级仲裁实现
固定优先级仲裁器在FPGA实现与轮询仲裁器类似,唯一不同的是轮询仲裁在每次响应完request后会对优先级进行更新,而固定优先级则不需要此步骤。
SoC 设计广泛采用共享总线式的片上通信,其中的仲裁器是共享总线的关键技术之一。AMBA AXI 总线协议以高性能、高频率的系统设计为目标,适合高带宽、低延迟的系统设计,可以达到高频率的操作而不需要复杂的总线桥,满足众多部件的接口要求,具备高度灵活的互联结构,并且向后兼容 AHB 和 APB 接口。
共享总线是一种常见的总线结构,多个总线上的设备拥有共同的地址线和数据线。
当一个总线设备希望占据总线进行数据收发操作时,需要通过属于自己的arequest信号向仲裁器发出申请,只有得到仲裁器的许可(对应的agrant置1 )时才能进行数据收发操作,没有得到许可的总线设备不能发起数据操作,否则将会出现多个设备同时驱动总线的错误。
下图是有两个总线设备的总线仲裁器电路,areq0和areq1以及agnt0和agnt1分别是master1和master2的请求和确认信号,rid是仲裁方式选择信号。当多个总线设备同时发出请求时,仲裁器根据内部控制寄存器的值按照固定优先级( rid=1, master2拥有高优先级)或者循环判断( rid=0,从master1->master2->master1循环判断)两种机制给相应的总线设备发出确认信号。
设计代码
- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Design Name:
- // Module Name: Arbiter
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- //
- //
-
- module Arbiter(clk,reset,areq0,areq1,agnt0,agnt1,rid);
- input clk,reset;
- input areq0,areq1;
- input rid;
- output agnt0,agnt1;
- reg [1:0] current_state,nx_state;
- parameter idle=2'b00,master1=2'b01,master2=2'b10;
- /
- always @(posedge clk or posedge reset)
- if(reset)
- current_state<=idle;
- else
- current_state<=nx_state;
- /
- always @(current_state or areq0 or areq1 or rid)
- begin
- case(current_state)
- idle:if(areq1==1 && areq0==0)
- nx_state=master2;
- else if(areq1==0 && areq0==1)
- nx_state=master1;
- else if(areq1==1 && areq0==1 && !rid)
- nx_state=master1;
- else if(areq1==1 && areq0==1 && rid)
- nx_state=master2;
- else nx_state=idle;
- master1:if(areq1==1)
- nx_state=master2;
- else if(areq1==0 && areq0==0)
- nx_state=idle;
- else nx_state=master1;
- master2:if(areq0==1)
- nx_state=master1;
- else if(areq1==0 && areq0==0)
- nx_state=idle;
- else nx_state=master2;
- default:nx_state=idle;
- endcase
- end
- assign agnt0=(current_state==master1)?1:0;
- assign agnt1=(current_state==master2)?1:0;
- endmodule
测试代码
- `timescale 1ns / 1ps
- module Arbiter_tb;
- reg clk;
- reg reset;
- reg areq0,areq1;
- reg rid;
- wire agnt0,agnt1;
- always begin
- #10 clk=1;
- #10 clk=0;
- end
- /
- initial begin
- clk=0;
- reset=1;
- areq0=0;
- areq1=0;
- rid=0;
- #100;
- reset=0;
-
- //rid=0,路径1->2
- repeat(1)@(posedge clk);
- #2; areq0=1;areq1=1;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=0;
- repeat(1)@(posedge clk);
- #2; areq0=1;areq1=1;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=0;
-
- //rid=0,路径4->3
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=1;rid=1;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=0;
- repeat(1)@(posedge clk);
- #2; areq0=1;areq1=1;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=0;
-
- //路径1->5->6->2
- repeat(4)@(posedge clk);
- #2; areq0=1;areq1=0;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=1;
- repeat(1)@(posedge clk);
- #2; areq0=1;areq1=0;
- repeat(1)@(posedge clk);
- #2; areq0=0;areq1=0;
- end
- Arbiter U1(
- .clk (clk ),
- .reset (reset ),
- .areq0 (areq0 ),
- .areq1 (areq1 ),
- .agnt0 (agnt0 ),
- .agnt1 (agnt1 ),
- .rid (rid ));
- endmodule
参考链接:https://blog.csdn.net/Hennys/article/details/107662757
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。