本帖最后由 瓜弟 于 2023-3-3 08:24 编辑
本文中主要研究安路SF1系列FPGA的硬核RISCV的AHB接口的细节。
1、片上逻辑分析仪
片上逻辑分析仪是指,在硬件代码中加入一个IP,配置该IP时钟、触发、观察对象等信号,在调试过程中,经过过触发信号触发后,将采集到的结果通过JTAG上传至电脑进行观察。以下介绍如何配置片商逻辑分析仪。
A、先依据需求建立完整的项目,并编译、综合通过;
B、在TD软件菜单栏,点击Tools->Debug Tools->ChipWatcher
C、在弹出的对话框中选中“Create a new ChipWatcher”
D、在ChipWatcher界面下,在Chip Configuration 中点击Clock栏的三个点按钮
E、选择采样时钟信号,采样结果将以时钟信号作为驱动,所以选择时钟信号时,需要依据待测信号频率、时钟域进行考虑。在下图中,先选择时钟信号,点击小箭头添加至右侧,在点击OK即可。
F、在D步骤中,Chip Configuration栏中,选择采样深度,该采样深度依据FPGA剩余的RAM、待测信号数量进行评估,过多将会导致综合不通过。
G、如下图所示,在空白处右键,点击 Add Nodes
H、在弹出的对话框中,选择需要观测的信号名称,如同步骤E一样添加即可
I、配置触发信号,如下图所示,触发信号跟需求,图中所示为当U3/HADDR[31:0]的值等于“01000000000000000000000000000000b”时,触发采样开始,当采集深度到达设定的深度后,将自动通过JTAG将数据传输至电脑进行显示
J、点击File-> Save,回到TD软件,重新综合、生成bit流文件,然后再ChipWatcher界面点击下载。
H、观察、对比、分析
2、AHB的细节
提出问题:以下不同位宽的数据,在AHB上将会如何传输?
unsigned long * ADD32_0 = (unsigned long *)0x40000000; //32位对齐
unsigned long * ADD32_1 = (unsigned long *)0x40000001;
unsigned long * ADD32_2 = (unsigned long *)0x40000002;
unsigned long * ADD32_3 = (unsigned long *)0x40000003;
unsigned short * ADD16_0 = (unsigned short *)0x40000100; //16位对齐
unsigned short * ADD16_1 = (unsigned short *)0x40000101;
unsigned long long * ADD64_0 = (unsigned long long*)0x40000300; //64位对齐
unsigned long long * ADD64_1 = (unsigned long long*)0x40000301;
unsigned long long * ADD64_2 = (unsigned long long*)0x40000302;
unsigned long long * ADD64_3 = (unsigned long long*)0x40000303;
unsigned long long * ADD64_4 = (unsigned long long*)0x40000304;
unsigned long long * ADD64_5 = (unsigned long long*)0x40000305;
unsigned char * ADD8_0 = (unsigned char *)0x40000400;
unsigned char * ADD8_1 = (unsigned char *)0x40000401;
unsigned char * ADD8_2 = (unsigned char *)0x40000402;
unsigned char * ADD8_3 = (unsigned char *)0x40000403;
int main(void)
{
while(1)
{
* ADD32_0 = 0x12345678;
* ADD32_1 = 0x12345678;
* ADD32_2 = 0x12345678;
* ADD32_3 = 0x12345678;
* ADD16_0 = 0x1234;
* ADD16_1 = 0x1234;
* ADD64_0 = 0x123456789ABCDEF0;
* ADD64_1 = 0x123456789ABCDEF0;
* ADD64_2 = 0x123456789ABCDEF0;
* ADD64_3 = 0x123456789ABCDEF0;
* ADD64_4 = 0x123456789ABCDEF0;
* ADD64_5 = 0x123456789ABCDEF0;
* ADD8_0 = 0x12;
* ADD8_1 = 0x12;
* ADD8_2 = 0x12;
* ADD8_3 = 0x12;
}
}
参考上一篇文章构建RISCV硬核运行环境,依据上述代码,编译hex文件,将所有代码下载至FPGA后,在ChipWatcher上观察各个信号。
A、32位数据对齐传输:数据传输在一个操作周期内完成,如下图所示,可见在地址(H3/HADDR[31:0])0x40000000上,写入了0x12345678,HSIZE为2,代表数据总线上传输的时32位数据,HTRANS为2,代表当前时单笔传输或者第一帧传输。
B、32位数据非对齐传输:如下图所示,分别是在32位对齐的地址基础上偏移1、2、3个地址后的传输方式。可见一个32位数据被分成了四次传输,每次只传输一个字节,且在32位数据总线上,各字节位置均相同。可见,如果32位数据传输,地址不对齐的情况下,将会极其浪费总线资源。
C、64位数据对齐传输:由于数据总线是32位的,所以64位数据的传输必定会分两次进行,如下图所示
D、64位数据非对齐传输:分为两种情况,非64位对齐但是32位对齐、非32位对齐。当非64位对齐但32位对齐时,数据传输与64位数据对齐传输一致,因为数据总线是32位的,64位对齐无意义,如下第一图。当地址非32位对齐时,数据传输将会分为8次进行,每次一个字节,如下第二图,第三图为局部放大。
E、16位对齐传输:对齐情况下,16位数据一次性就传输完成,注意HSIZE的值
F、16位非对齐传输:此时,数据将拆分为两次传输,每次一个字节
综上所述,在编写软件代码时,应注意数据对齐,否则数据传输效率非常低