• 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 的代码和工程
  • 相关阅读:
    【Vue面试题十三】、Vue中的$nextTick有什么作用?
    【操作系统】进程是如何调度的?
    LLM之Colossal-LLaMA-2:Colossal-LLaMA-2的简介、安装、使用方法之详细攻略
    一言成文大模型:大模型实践之路
    进程(2)——进程状态(僵尸,睡眠……)【linux】
    docker-compose的部署
    Ajax学习:设置CROS响应头实现跨域(跨域资源共享)
    BPMN是什么
    未来的户外LED视频墙将怎么发展
    React Profiler 性能优化工具
  • 原文地址:https://blog.csdn.net/qq_46621272/article/details/126969154