• AXI EPC IP 使用详细说明


    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/qq_46621272/article/details/126969154


    AXI EPC IP 使用详细说明


    前言

    • AXI External Peripheral Controller (EPC) ,AXI 外部设备控制器(EPC)。
    • 可以通过 AXI 扩展各种计算机外设,支持同步和异步接口。
    • 支持地址数据复用/不复用总线。
    • 数据总线支持8/16/32位
    • 兼容 EMI(External Memory Interface) 外部存储器接口,可通过该接口外接多种外设芯片。
    • 有疑问可以联系 QQ:708907433

    简介

    • Xilinx FPGA 内嵌的 CPU ,可以通过 AXI EPC 在 FPGA 芯片外接多个多种外设芯片,比如 SJA1000 CAN 控制器,DM9000 以太网络控制器,16C550 串口控制器等。
    • 可以用 FPGA 做 PCIE to EMI 的桥接芯片,用PCIE 通过 FPGA 内的 AXI EPC 外接多个多种外设芯片,比如 SJA1000 CAN 控制器,DM9000 以太网络控制器,16C550 串口控制器等。
    • AXI EPC IP 使用很简单,但是有很多需要注意的地方,都是大坑。

    AXI EPC IP 使用介绍

    • AXI EPC IP 只能在 VIVADO 的 Block Design 下调用和使用。
      在这里插入图片描述

      1. EPC 时钟选择 AXI 时钟
      1. EPC 时钟选择外接的外设时钟
      1. AXI 时钟周期,单位皮秒(ps)。(这个选项一般是自动产生的不需要编辑修改)
      1. 外设时钟周期,单位皮秒(ps)
      1. 外设片选数量
      1. 外设基地址。(这个选项一般是在 Address Editor 中产生的不需额外的编辑修改)
      1. 外设地址大小。(这个选项一般是在 Address Editor 中产生的不需额外的编辑修改)
        在这里插入图片描述
      1. 地址宽度。(这里需要注意,在地址数据总线复用的模式下,地址线宽度和数据线宽度最好设置成一样,否则需要额外的编程代码才能正常的使用)
      1. 数据宽度。
      1. 数据宽度匹配选项,比如 AXI是32位,在读写 8/16 位外设空间时,启动这个功能就能用指针的方式任意读写 8/16位的外设空间。
      1. 数据地址复用选项,可以通过该选项减少 FPGA 的管脚数量。启动地址数据复用,总线就和8086/8088处理器的 AD 总线性质一样。C51单片机的 AD0-7 也是地址数据复用的总线。
      1. 同步模式选项。同步或异步模式的选项。
    • T1-T15 以 SJA1000 芯片的时序为例子,选的参数。波形图片也是从 SJA1000手册中截取的。
      在这里插入图片描述

      1. FIFO 访问选项。当Enable FIFO Access = 1时,AXI EPC IP 核支持访问 FIFO

    在这里插入图片描述

    应用举例

      1. EPC 外接 SJA1000 例子

    EPC 外接 SJA1000 原理图
    在这里插入图片描述

    • EPC 外接 SJA1000 顶层管脚代码(system verilog)
    //EPC 接 SJA1000 例子
    //Address Width						8
    //Data Bus Width					8
    //Enable Data Width Matching		1
    //Enable ADDR/DATA Multiplexing 	1
    //Enable SYNC Mode					0
    
    module	fpga_axi_epc_ad8_root		//这是顶层代码管脚的 EPC 相关部分
    (
    //..
    	inout	[7:0]	ad,
    	output 			ads,
    	output			cs_n,
    	output 			wr_n,
    	output 			rd_n,
    );
    
    	genvar			n;
    	
    	logic	[7:0]	epc_data_i;	// 8 位
    	logic	[7:0]	epc_data_o;
    	logic	[7:0]	epc_data_t;
    	logic	[7:0]	epc_addr;
    
    	for(n=0;n<8;n++)
    	begin:for_iobuf_xx
    		assign	ad[n] 			= 	epc_data_t[n] == 1 ?	1'bz:epc_data_o[n];
    		assign	epc_data_i[n]	=	ad[n];
    	end
    
    	cpu_block_design	ux	//Block Design EPC 接口部分
    	(
    		.epc_addr		(epc_addr),		//output [0:7]
    		.epc_ads		(ads),			//output
    		.epc_be			(),				//output [0:0]
    		.epc_burst		(),				//output
    		.epc_cs_n		(cs_n),			//output [0:0]
    		.epc_data_i		(epc_data_i),	//input	 [0:7]
    		.epc_data_o		(epc_data_o),	//output [0:7]
    		.epc_data_t		(epc_data_t),	//output [0:7]
    
    		.epc_rd_n		(rd_n),			//output
    		.epc_rdy		(1),
    		.epc_rnw		(),				//output
    		.epc_wr_n		(wr_n),			//output
    		.epc_clk		(1),
    		.epc_rst		(1),
    	);
    
    endmodule
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
      1. EPC 外接 6264 SRAM 例子

    EPC 外接 6264 SRAM 原理图
    在这里插入图片描述

    • EPC 外接 6264 SRAM 顶层管脚代码(system verilog)
    
    //EPC 接 SRAM 6264 例子
    //Address Width						16
    //Data Bus Width					8
    //Enable Data Width Matching		1
    //Enable ADDR/DATA Multiplexing 	0
    //Enable SYNC Mode					0
    
    module	fpga_axi_epc_d8_a16_root		//这是顶层代码管脚的 EPC 相关部分
    (
    //..
    	inout	[7:0]	d,
    	output	[15:0]	a,
    	output			cs_n,
    	output 			wr_n,
    	output 			rd_n,
    );
    
    	genvar			n;
    	
    	logic	[7:0]	epc_data_i;	// 8 位
    	logic	[7:0]	epc_data_o;
    	logic	[7:0]	epc_data_t;
    	logic	[7:0]	epc_addr;
    
    	for(n=0;n<8;n++)
    	begin:for_iobuf_xx
    		assign	d[n] 			= 	epc_data_t[n] == 1 ?	1'bz:epc_data_o[n];
    		assign	epc_data_i[n]	=	d[n];
    	end
    
    	cpu_block_design	ux	//Block Design EPC 接口部分
    	(
    		.epc_addr		(a),			//output [0:15]
    		.epc_ads		(),				//output
    		.epc_be			(),				//output [0:0]
    		.epc_burst		(),				//output
    		.epc_cs_n		(cs_n),			//output [0:0]
    		.epc_data_i		(epc_data_i),	//input	 [0:7]
    		.epc_data_o		(epc_data_o),	//output [0:7]
    		.epc_data_t		(epc_data_t),	//output [0:7]
    
    		.epc_rd_n		(rd_n),			//output
    		.epc_rdy		(1),
    		.epc_rnw		(),				//output
    		.epc_wr_n		(wr_n),			//output
    		.epc_clk		(1),
    		.epc_rst		(1),
    	);
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
      1. EPC 外接 2片6264 SRAM 例子

    EPC 外接 2片6264 SRAM 原理图
    在这里插入图片描述

    • EPC 外接 2片6264 SRAM 顶层管脚代码(system verilog)
    //EPC 接 SRAM 26264 例子
    //Address Width						16
    //Data Bus Width					16
    //Enable Data Width Matching		1
    //Enable ADDR/DATA Multiplexing 	1
    //Enable SYNC Mode					0
    
    module	fpga_axi_epc_ad16_root		//这是顶层代码管脚的 EPC 相关部分
    (
    //..
    	output	[15:0]	ad,
    	output 			ads,
    	output			cs_n,
    	output 			wr0_n,
    	output 			wr1_n,
    	output 			rd_n,
    );
    
    	genvar			n;
    	
    	logic	[15:0]	epc_data_i;	// 16 位
    	logic	[15:0]	epc_data_o;
    	logic	[15:0]	epc_data_t;
    	logic	[15:0]	epc_addr;
    	logic	[1:0]	epc_be;
    	logic			epc_wr_n;
    
    	for(n=0;n<16;n++)
    	begin:for_iobuf_xx
    		assign	ad[n] 			= 	epc_data_t[n] == 1 ?	1'bz:epc_data_o[n];
    		assign	epc_data_i[n]	=	ad[n];
    	end
    	assign	wr0_n	= (~epc_be[0])|epc_wr_n;
    	assign	wr1_n	= (~epc_be[1])|epc_wr_n;
    
    	cpu_block_design	ux	//Block Design EPC 接口部分
    	(
    		.epc_addr		(),				//output [0:15]
    		.epc_ads		(ads),			//output
    		.epc_be			(epc_be),		//output [0:1]
    		.epc_burst		(),				//output
    		.epc_cs_n		(cs_n),			//output [0:0]
    		.epc_data_i		(epc_data_i),	//input	 [0:15]
    		.epc_data_o		(epc_data_o),	//output [0:15]
    		.epc_data_t		(epc_data_t),	//output [0:15]
    
    		.epc_rd_n		(rd_n),			//output
    		.epc_rdy		(1),
    		.epc_rnw		(),				//output
    		.epc_wr_n		(epc_wr_n),		//output
    		.epc_clk		(1),
    		.epc_rst		(1),
    	);
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    注意事项

      1. AXI EPC 的数据,地址是大端模式,在我的例子里采用的是小端模式,数据线地址线全部需要交叉使用。
        在这里插入图片描述
      1. AXI EPC < Enable ADDR/DATA Multiplexing > 这个选项使能时,地址宽度和数据宽度最好相等,否则需要一些额外的代码
      1. AXI EPC < Enable Data Width Matching > 这个选项很好用,但是在一些与读写操作会改变寄存器的芯片里要谨慎使用。比如一些中断状态寄存器,读一下该寄存器中断状态会改变。比如一些 RC,WC 这样的寄存器。(RC 读该寄存器会清除某个状态。WC 写该寄存器会清除某个状态)这样的芯片在这里需要一些额外的代码才能正常的使用。

    相关连接

    • 可以浏览本博客写的文章《FPGA + SJA1000 实现 <PCIe to CAN> 网卡的设计》 有完整的 PCIE AXI EPC 的代码和工程
  • 相关阅读:
    CTFd-Web题目动态flag
    pytorch_trick(4) 模型本地保存与读取方法
    c# 多线程创建及线程同步
    QTreeView 使用 AbstractItemModel开发
    【Nearest Plane Algorithm】
    java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展
    Office技巧(持续更新)(Word、Excel、PPT、PowerPoint、连续引用、标题、模板、论文)
    固定资产管理系统的作用有哪些
    探索C语言中的联合体与枚举:数据多面手的完美组合!
    图像处理学习笔记-09-形态学图像处理
  • 原文地址:https://blog.csdn.net/qq_46621272/article/details/126969154