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. 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. 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. 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 的代码和工程
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老皮芽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值