一.概述
本人不具fpga开发经验,本文章供新手朋友参考
第一次试图在fpga上运行自己的M3内核,这一步是生成并连接自己的AHB总线。
系统架构我选择了参考如下的图片其中数据从哪个总线取是由地址空间决定的,从0x00000000-0x1fffffff之间的地址m3内核会自动的从i-code和d-code总线中取(其中icode是只读的,dcode是可读可写的)对于在0x00000000-0x1fffffff的读写操作都将通过dcode总线进行,而pc寄存器指向的取指操作将通过icode总线读取。
二.总线做什么用?
用于多主机多从机时的总线协调,或者单主机多从机时的多路选择器功能,以及提供地址映射功能。即在stm32单片机的操作时,我们会知道某个基地址以及偏移来决定操作何种外设。
而这里总线便承担了将预设好的地址映射提供给处理器作为一块内存编写的功能
三.如何生成总线
在cmsdk中提供了生成ahb总线的脚本,你需要提前编写其配置文件,并按照说明txt文档来运行脚本生成文件
其文件夹在以下路径:
\Cortex-M3 DesignStart Eval\Cortex-M3 DesignStart Eval\AT421-MN-80001-r0p0-02rel0\cmsdk\logical\cmsdk_ahb_busmatrix
其中提供了两个示例的xml文件:
example2x3_sparse.xml example2x3_full.xml
其中一个是总线全连接的(即每一个主机都能访问每一个从机)
另一个是非全连接的(即根据需要确定哪个主端口能访问哪个从端口)
四.总线的各个接口
这是我编写这篇博客的原因,对于总线主机和从机的概念我并不太能分清,下面尝试做出阐述:
1.应当只有主机能够发起通讯:
每次主机发起通讯时,将地址放到地址端口上,并且表明对从机进行读操作/写操作,随后总线根据地址映射关系选中对应的从机,并且将地址提供给从机,随后主机将数据写给从机或从机将数据返回给主机。
2.如何理解上图中的接口关系?
可以看到master如cpu等连接到的是总线的s口(我理解为slave)而sram等连接到的是master口。意味着在总线上主从关系是换掉的。
五.如何连接
经过生成后,我们可以获得其接口,下面给处接口的解释
HCLK(clk50m),
HRESETn(cpuresetregn),
这里不用过多说,即时钟信号以及复位信号
s0的相关信号:
// Input port SI0 (inputs from master 0)
input [31:0] HADDRS0; // Address bus
input [1:0] HTRANSS0; // Transfer type
input HWRITES0; // Transfer direction
input [2:0] HSIZES0; // Transfer size
input [2:0] HBURSTS0; // Burst type
input [3:0] HPROTS0; // Protection control
input [31:0] HWDATAS0; // Write data
input HMASTLOCKS0; // Locked Sequence
input [31:0] HAUSERS0; // Address USER signals
input [31:0] HWUSERS0; // Write-data USER signals
// Input port SI0 (outputs to master 0)
output [31:0] HRDATAS0; // Read data bus
output HREADYS0; // HREADY feedback
output HRESPS0; // Transfer response
output [31:0] HRUSERS0; // Read-data USER signals
其中上半部分即(inputs from master 0)是input信号,而下半部分是output信号
即上半部分为此接口的设备提供的信号,下半部分是接口提供给设备的信号
可以看到设备要为接口提供地址,读/写信号,写入的数据等,
同时从总线获取数据,以及传输完毕信号
则此接口符合我们上文对主设备的描述(即cpu总线接口,dma)
从设备即Mx(X=1,2,3)同理提供输出数据和ready标志,
// Output port MI0 (inputs from slave 0)
input [31:0] HRDATAM0; // Read data bus
input HREADYOUTM0; // HREADY feedback
input HRESPM0; // Transfer response
input [31:0] HRUSERM0; // Read-data USER signals
// Output port MI0 (outputs to slave 0)
output HSELM0; // Slave Select
output [31:0] HADDRM0; // Address bus
output [1:0] HTRANSM0; // Transfer type
output HWRITEM0; // Transfer direction
output [2:0] HSIZEM0; // Transfer size
output [2:0] HBURSTM0; // Burst type
output [3:0] HPROTM0; // Protection control
output [31:0] HWDATAM0; // Write data
output HMASTLOCKM0; // Locked Sequence
output HREADYMUXM0; // Transfer done
output [31:0] HAUSERM0; // Address USER signals
output [31:0] HWUSERM0; // Write-data USER signals
综上可知SIx接主机,MIx接从机。
六.有哪些线,如何接?
我们来看看cpu上一组接口有哪些线,考虑到Icode功能不完整,以dcode为例:
// Code (instruction & literal) bus
output [1:0] HMASTERD; // DCode-bus master
output [1:0] HTRANSD; // DCode-bus transfer type有对应关系
output [2:0] HSIZED; // DCode-bus transfer size有对应关系
output [31:0] HADDRD; // DCode-bus address有对应关系
output [2:0] HBURSTD; // DCode-bus burst length有对应关系
output [3:0] HPROTD; // DCode-bus protection有对应关系
output [1:0] MEMATTRD; // ICode-bus memory attributes
output EXREQD; // ICode-bus exclusive request
output HWRITED; // DCode-bus write not read有对应关系
output [31:0] HWDATAD; // DCode-bus write data有对应关系
input HREADYD; // DCode-bus ready有对应关系
input [31:0] HRDATAD; // DCode-bus read data有对应关系
input [1:0] HRESPD; // DCode-bus transfer response有对应关系
input EXRESPD; // DCode-bus exclusive response
下面和总线进行对应
// Input port SI0 (inputs from master 0)
input [31:0] HADDRS0; // Address bus有对应关系
input [1:0] HTRANSS0; // Transfer type有对应关系
input HWRITES0; // Transfer direction有对应关系
input [2:0] HSIZES0; // Transfer size有对应关系
input [2:0] HBURSTS0; // Burst type有对应关系
input [3:0] HPROTS0; // Protection control有对应关系
input [31:0] HWDATAS0; // Write data有对应关系
input HMASTLOCKS0; // Locked Sequence
input [31:0] HAUSERS0; // Address USER signals
input [31:0] HWUSERS0; // Write-data USER signals
// Input port SI0 (outputs to master 0)
output [31:0] HRDATAS0; // Read data bus有对应关系
output HREADYS0; // HREADY feedback有对应关系
output HRESPS0; // Transfer response有对应关系
output [31:0] HRUSERS0; // Read-data USER signals
可以看到总线有三组32位宽的接口提供给用户使用,这里我们不接,
那么总线没链接的端口
input HMASTLOCKS0; // Locked Sequence
直接接0即可,此为上锁端口
cpu还剩的端口
output [1:0] HMASTERD; // DCode-bus master
output [1:0] MEMATTRD; // ICode-bus memory attributes
output EXREQD; // ICode-bus exclusive request
input EXRESPD; // DCode-bus exclusive response
其中 .EXRESPD直接接到0即可(这里未继续查证,看到别的工程这么接的)
剩下三个output留空
如此便接好了端口,