AHB总线用于性能要求比较高的系统互联,比如内部memory、高宽带的外设、GMAC和SD等,但仍然为分时独占式总线,也就是说一个时间点总线只会完成一个传输事件。下图是一个简单的AHB总线互联的例子:
Manager:总线的Master设备
Subordinate:总线的Slave设备
Decoder:地址译码器用于将Master发送的地址转换成合适的sel选择信号
多路选择器:将各个Slave的输出数据合理的选择给Master。
目前最新的AHB总线版本为AHB5和AHB-Lite,对于只有一个Master的总线,结构简化很多,因此可单独使用AHB-Lite协议。
信号 | 源/方向 | 位宽 | 信号 |
---|---|---|---|
HCLK | 全局变量 | 1 | 时钟,上升沿数据有效 |
HRESETn | 全局变量 | 1 | 复位,低有效,该信号可直接和系统总线复位连接 |
HADDR | Master输出 | MAX=64 | AHB总线地址,最大64bits |
HBURST | Master输出 | MAX=3 | 传输数据的个数 |
HMASTLOCK | Master输出 | 1 | 锁定Master传输,锁定期间传输无法打断 |
HPROT | Master输出 | 0/4/7 | 保护控制信号,用于指示本次传输类型 |
HSIZE | Master输出 | 3 | 指示每次传输数据的大小 |
HNONSEC | Master输出 | 1 | 指示当前传输是否安全 |
HEXCL | Master输出 | 1 | 指示该传输是否为独占传输(Exclusive Access) |
HMASTER | Master输出 | MAX=8 | 指示当前是哪个Master发起的传输,每个Master有一个唯一的HMASTER ID |
HTRANS | Master输出 | 2 | 指示传输类型,有四种类型:IDLE、BUSY、NONSEQ、SEQ |
HWATA | Master输出 | MAX=1024 | 写数据,最大位宽支持1024bits,建议在32bits-256bits之间 |
HWSTRB | Master输出 | MAX=128 | 写数据字节使能,位宽为HWDATA的位宽除以8 |
HWRITE | Master输出 | 1 | 读写指示信号,“1”为写,“0”为读 |
HRDATA | Slave输出 | MAX=1024 | 读数据,最大位宽支持1024bits,建议在32bits-256bits之间 |
HREADYOUT | Slave输出 | 1 | Slave端设备准备就绪信号 |
HRESP | Slave输出 | 1 | Slave端设备的应答信号,表明当前传输是否成功,“1”错误 |
HEXOKAY | Slave输出 | 1 | 表示独占传输(Exclusive Transfer)是否成功 |
HSELx | Slave输出 | 1 | Slave设备选择信号,用法和APB的PSEL类似。当该Slave被选中进行传输时,该信号必须和地址、控制信号在同一拍有效 |
HREADY | Slave输出 | 1 | 该信号由总线内部产生,用于通知Master和Slave上次传输已经结束,总线已经准备就绪开始下一次传输 |
HTRANS[1:0] | 类型 | 说明 |
---|---|---|
00 | IDLE | IDLE表示没有数据传输,Master使用IDLE来表示非数据传输,一般用IDLE传输终止一次locked传输。Slave必须立即响应Master发送的IDLE传输,并将OKAY应答到HRESP上,传输内容Slave必须忽略 |
01 | BUSY | BUSY传输允许在Burst传输的中间插入空闲周期,以表示Master会继续burst但下一次传输不能立即发送。当Master使用BUSY传输时,下一次传输的地址和控制信号必须准备好。只有未定义长度的Burst可以在Burst结束的时候插入BUSY传输标志。Slave必须立即响应BUSY传输,并将内容忽略。 |
10 | NONSEQ | NONSEQ用于指示一次Single传输,或一次burst传输的开始。地址和控制信号和前一次传输无关。总线上的单次传输被视为长度为1的突发事件,因此传输类型是非顺序的 |
11 | SEQ | Burst传输的剩余部分被标记为SEQ,表示连续传输,地址和控制信号和前一次保持一致。该地址等于前一次传输的地址加上传输大小,以字节为单位,传输大小由HSIZE[2:0]信号决定。 |
HBURST[2:0] | 类型 | 说明 |
---|---|---|
000 | SINGLE | 单次传输 |
001 | INCR | 未定义长度的增量Burst传输 |
010 | WRAP4 | 4拍回环Burst传输 |
011 | INCR4 | 4拍增量Burst传输 |
100 | WRAP8 | 8拍回环Burst传输 |
101 | INCR8 | 8拍增量Burst传输 |
110 | WRAP16 | 16拍回环Burst传输 |
111 | INCR16 | 16拍增量Burst传输 |
根据上表可以看出,传输可以分为SINGLE、INCR和WRAP类型,每种又按照每次Burst节拍数分为不同情况。一拍为Burst传输的最小传输单位。INCR burst的每次传输的地址是连续的,且每次传输的地址数值相较于上一次是递增的。WRAP burst在地址增加到地址边界时,地址会返回到最开始的地址。地址边界根据拍数和传输大小计算,HBURST和HSIZE确定总传输数据量大小。例如,一个WRAP4传输4bytes数据,如果开始地址位0x34,那么4拍的数据地址为0x34,0x38,0x3C和0x30。
单次传输可以使用SINGLE标识,或使用未定义大小的INCR标识,一般使用SINGLE标识。
HSIZE[2:0] | 类型 | 说明 |
---|---|---|
000 | Byte | 8bits,传输一个字节 |
001 | Halfword | 16bits,传输半个字 |
010 | Word | 32bits,传输一个字 |
011 | DoubleWord | 64bits,传输两个字 |
100 | 4 Words | 128bits,传输四个字 |
101 | 8 Words | 256bits,传输八个字 |
110 | 16 Words | 512bits,传输十六个字 |
111 | 32 Words | 1024bits,传输三十二个字 |
HSIZE用于表示单次数据传输的大小,其数值等于数据位宽,比如数据宽度是32bits,那么HSIZE只能是000/001/010三个数值。在Burst传输过程中,该数值必须保持不变。
HPORT[3:0] | 说明 |
---|---|
[0] | 0:Opcode fetch 1:Data access |
[1] | 0:User access 1:Privileged access |
[2] | 0:Non-bufferable 1:Bufferable |
[3] | 0:Non-cacheable 1:Cacheable |
HPORT[6:0] | 名称 | 说明 |
---|---|---|
[0] | Data/Inst | 0:Opcode fetch 1:Data access |
[1] | Privileged | 0:unprivileged access 1:Privileged access |
[2] | Bufferable | 如果[4:3]均无效的话,那么该bit位生效: 0:No-bufferable,写响应必须由最终的目的地址提供,而不是中间的buffer。1:Bufferable,写响应可由中间经过的节点提供,但需要及时传递写传输到目的端。 |
[3] | Modifiable | 0:传输的数据不可纠正修改 1:传输的数据等可纠正修改 |
[4] | Lookup | 0:传输不需要查找cache,且必须传递到目的端 1:传输必须查找cache |
[5] | Allocate | 0:传输不会分配到cache;1:传输分配到cache |
[6] | Shareable | 0:传输不可共享,访问的memory区域不能被其他Master访问,访问的应答不会确保被其他Master可见。Device类型位memory,该bit为0;1:传输时可以共享,访问的memory区域可以被其他Master访问。 |
对于Memory类型,可通过HPROT[6:2]判断memory类型,具体如下表表示:
HPROT[6] | HPROT[5] | HPROT[4] | HPROT[3] | HPROT[2] | Memory类型 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | Device-nE |
0 | 0 | 0 | 0 | 1 | Device-E |
0 | 0 | 0 | 1 | 0 | Normal Non-cacheable,non-shareable |
0 | 0/1 | 1 | 1 | 0 | Write-through,Non-shareable |
0 | 0/1 | 1 | 1 | 1 | Write-back,Non-shareable |
1 | 0 | 0 | 1 | 0 | Normal Non-cacheable,shareable |
1 | 0/1 | 1 | 1 | 0 | Write-through,shareable |
1 | 0/1 | 1 | 1 | 1 | Write-back,shareable |
信号 | 方向 | 说明 |
---|---|---|
HAUSER | Master->总线 | 用户自定义,推荐宽度0-128bits |
HWUSER | Master->总线 | 用户自定义,推荐宽度0-DATA_WIDTH/2 |
HRUSER | Slave->总线 | 用户自定义,推荐宽度0-DATA_WIDTH/2 |
HBUSER | Slave->总线 | 用户自定义,推荐宽度0-16bits |
该组信号为用户自定义信号,具体传输内容和含义需要用户自己定义,一般不建议使用改组信号。AHB协议不定义这些信号的功能,因此,在多个拥有用户自定义信号的系统中,可能会带来信号不兼容的问题。
INCR和WRAP burst地址计算方式分析:
首先,需要了解的是INCR和WRAP地址的突发步长都是根据HSIZE[2:0]来决定,以字节为单位,例如HSIZE=0(8bits/一个字节),则地址突发的步长就是1;如果HSIZE=2(32bits/word=4个Bytes),则地址的突发步长为4。
以WRAP4举例,假设HSIZE=2(4Bytes),那么总的传送大小为4*4=16Bytes。同时,假设起始地址为0x38,那么WRAP4的地址变化如下:0x38,0x3C,0x30,0x34,那么问题就来了,0x3C+0x4(步长)=0x40,为什么会变成0x30呢?
位置计算,将当前的位置与总的传送大小相除:
(1)若除数不为0,则当前的位置保持不变;
(2)若除数为0,则将当前的位置减去总的传送大小后的结果,为当前的位置。
根据上面的计算原则,当0x3C加上0x4(步长)为0x40(64),64可以被16整除,所以当前位置变为64-16=48(0x30)
注意:如果起始地址是0x40,是不需要编程0x30的,当前地址就是0x40
AHB传输分成两个阶段:地址阶段和数据阶段。地址阶段HWRITE、HADDR等控制信号等控制信号同一拍有效,数据阶段HWDATA、HRDATA等和数据相关的信号有效,表示数据读写开始,数据阶段可能会跨越多个HCLK时钟周期。
需要注意的是,如果进行多次连续传输,地址阶段和数据阶段是可以pipeline的,可以在A的数据阶段,启动下一次传输的地址阶段。
其他burst传输类型请查阅最后的参考文档。
如果需要提供更多的时间或者采样数据,Slaves可以用HREADYOUT去插入等待。在等待传输过程中,master有以下几种情况限制被改变:
从上图中可以看出:
T0-T1: master在地址A处启动一个SINGLE burst传输
T1-T2: master在地址Y处启动一个IDLE传输
slave将HREADYOUT拉低插入一个IDLE传输
T2-T3: master在地址Z处启动一个IDLE传输
T3-T4: master改变传输类型为NONSEQ,并在地址B启动INCR4传输
T4-T6: HREADY为低,master必须保持HTRANS不变
T5-T6: HREADY为高,地址A的SINGLE burst传输完成,同时地址B开始第一拍的传输
T6-T7: 地址B的INCR4第一拍传输完成,同时master开始下一个拍B+4地址的传输
2. BUSY传输,固定长度burst
在固定长度的等待传输过程中,master允许改变传输类型从BUSY到SEQ。当HTRANS传输类型变为SEQ,master必须保持HTRANS不变,直到HREADY为高。
因为BUSY传输必须只插入到一个突发的连续节拍之间,所以这并不适用于单个突发。因此,这种情况适用于以下突发类型:
INCR4,INCR8,INCR16,WRAP4,WRAP8,WRAP16
从上图可以看出:
T0-T1: master从地址0x24启动一个INCR4的突发传输
T1-T3: master在地址0x28插入BUSY传输
slave插入等待状态并且HREADY=0
T3-T4: master改变传输类型为SEQ,并且下一节拍启动地址0x28地址的突发
T4-T6: 因为HREADY=0,master必须保持HTRANS保持不变
T5-T6: 0x24地址的突发完成同时HREADY=1
T6-T7: INCR4传输的0x28地址完成并且master开始地址0x2C的突发传输
3. BUSY传输,不固定长度burst
在不固定长度的(INCR)等待传输,当HREADY=0时,master允许从BUSY到其他传输任何类型的改变。如果执行了SEQ传输,则突发继续,但如果执行了IDLE或NONSEQ传输,则突发终止。
从上图可以看出:
T0-T1: master在0x64地址启动一个INCR突发
T1-T3: master在地址0x68插入BUSY传输
slave插入等待状态并且HREADY=0
T3-T4: master改变传输类型为NONSEQ同时在地址0x10启动一个新的突发
T4-T6: HREADY=0,master必须保持HTRANS不变
T5-T6: HREADY=1,完成不定长度的突发,并且master开始0x10地址第一节拍
T6-T7: 地址0x10的INCR4传输的完成同时master开始地址0x14的传输
T0-T1: master在地址A开始SINGLE突发
T1-T2: master在地址Y插入IDLE传输
slave插入等待状态并且HREADY=0
T2-T3: master在地址Z插入一个IDLE传输
T3-T4: master改变传输类型为NONSEQ并且在地址B开始INCR4传输。直到HREADY=1,不运行更待地址。
T5-T6: HREADY=1,地址A的SINGLE突发完成。并且master开始地址B突发传输。
T6-T7: 地址B的INCR4突发传输完成并且master开始地址B+4的传输
2. ERROR响应之后
在等待传输之后,如果slave有ERROR响应,那么当HREADY=0,master允许改变地址。
本文使用的synopsys家的AMBA总线vip,以AHB为例,具体安装步骤如下:
% cd
% mkdir design_dir
% $DESIGNWARE_HOME/bin/dw_vip_setup -path ./design_dir -e amba_svt/tb_ahb_svt_uvm_baseic_sys -svtb
安装完成之后,文件列表如下:
vip安装完成之后,直接可以按照以下流程使用:
例如,run ts.directed_test.sv
gmake USE_SIMULATOR=vcsvlog directed_test WAVES=1
vip中的自带的makefile有点复杂,根据自己的习惯,重新写一个makefile:
根据需求,写相关sequences和testcase,下面以HSIZE=32bit,起始地址为0x34为止进行地址变化,仿真结果如下:
参考资料:AHB5,AHB-Lite总线协议