中断使用:zynq中的PCIE的XDMA IP核interrupt ack与interrupt req信号
当需要中断时,通过interrupt ack发起中断请求,并发送TLP中断数据包,当ARM侧收到中断,会回复一个ACK,当ARM完成中断请求,那么可以向用户的BAR空间写一个完成标志,当FPGA侧检测到该寄存器信号拉高,就把interrupt req请求拉低,结束此次中断。或者,接收到interrupt ack之后,延迟50000个周期,等待ARM处理完中断,再把interrupt req信号拉低。
不同的中断源,可使用多bit的interrupt ack,但是每次只能有一位拉高。
中断的顺序可以采用轮询的方式(每完成一次,标志位+1,可区分中断),依次置高。
interrupt ack与interrupt req都是物理链路完成的,和上位机没关系。
高速接口转PCIE要先设计AXI-STREAM转AXI-FULL协议,进行跨时钟域,然后再写到DDR的不同的地址空间。不同的协议的地址空间提前规划。内存管理模块对内存进行管理。内存管理模块要控制写道DDR的哪个位置,写了多长,并要进行记录。存储时,不同的高速口要发送给内存管理模块请求,并附带长度,内存管理模块会查找内存是否够,并回复地址和长度,内存管理模块根据数据优先级控制不同接口的AXIFULL往DDR写数据。内存管理模块同时会存储地址与长度的信息,形成链表,当存够一定数量,就会向XDMA的BAR空间写一个写请求,同时将链表的信息传给BAR空间,包括几个数据包,数据包的总长度是多少,起始地址是多少。内存管理模块写完BAR空间之后,会触发一个中断读请求,上位机收到中断请求之后,读取BAR空间,获取数据包的长度和起始地址。内存管理模块随后会向XDMA发送读数据请求中断,XDMA向上位机发送中断,XDMA收到读请求之后,会把读ready拉高,开始读数据,读数据模块读取数据,并将数据及逆行封装,上位机收到中断之后,读取数据,数据读取模块将封装好的数据传给上位机。上位机读取完数据包的信息之后,会向FPGA发送读完成中断,FPGA收到之后,内存管理模块会重新统计收了多少个数据包,检测内存中的数据量,等下次达到突发数量的传输之后,再向上位机发送数据包信息,上位机根据起始地址和长度读取DDR的数据。注意:数据从DDR读取出来之后,要对数据封装成自己的报文格式,报文格式需要指定每一个接口数据的起始地址,长度是什么,让上位机根据这些信息去截取相应字段的数据出来。
写数据的优先级要高于PCIE读数据的优先级。比如万兆网不能及时写数据,会造成FIFO爆掉。每个高速口的时钟和位宽不一样,还要考虑转位宽。
如何分别配给每个端口传输的长度呢?地址如何计算?优先级怎么算?
每路数据的缓存不为空时,就会触发写请求,那么内存管理模块就会根据不同接口的写请求,先回复一个接口地址长度,等这个接口读写完成,再给另一个接口回复地址长度,这个期间,如何确保其他FIFO不溢出呢?FIFO要设置多大?
当内存管理模块记录的数据大于100M或者超过15个时钟周期没有新数据传输,那就启动PCIE的传输。
输入数据的带宽计算:万兆 10gb/s + 千兆1gb/s +10g 8b10bPHY 8Gb/s
ddr的读/写带宽:1600M162(2片ddr)0.7(传输效率)/ 2(读写占一半)
PCIE2.04的带宽:写实测1.4GB/S,读1.2GB/S
使用AXI connect 进行多路传输的时候,需双击数据输出管脚,设置下所属的时钟域。跨时钟域要看跨过的数据给谁用,此处是DDR用。
要计算好每个端口每次传输的数据包长,用来计算跨时钟域中的FIFO不要被爆掉。跨时钟域和数据位宽转换重新计算的长度,可以通过AXI USER自定义接口发出去。
调用IP生成新的IP,需要以globle的形式进行综合,否则会报错。相当于生成一个整体的网表文件。
内存管理:数据来之后,接收数据长度,然后回复一个地址。
中断控制模块要去监测内存管理发出的中断请求信号,当收到时,向PC发送中断,PC收到中断请求之后,PC会向BAR读写控制模块发送中断清除标志,使得中断 清除寄存器标志置1,然后BAR读写控制模块会把清除寄存器标志置1的信息告诉中断控制模块,然后中断控制会返回一个中断应答,让内存管理模块的中断标志清除掉。
AXI的响应信号:在数据写完成之后,响应信号拉高。