搭建FPGA SOC系统(1)自定义Avalon总线组件

学习主要参考https://rocketboards.org/foswiki/Documentation/EmbeddedLinuxBeginnerSGuide
本学习以altera cyclone V系列FPGA为例。本例程设计一个自定义PIO接口,并将其添加到GHRD工程中。该工程可在上面的链接的最底下下载到。

1.在qsys工具上设计自定义IP(Avalon接口)

1.1.设计操作

1.在qsys系统中点击New Component…新建一个组件
在这里插入图片描述
2.如下图,可设置组件类型、rtl文件、参数、接口信号等。
在这里插入图片描述
注意:Group这一项需要另外设置,你可以选择quartus自带的IP组,也可以直接在窗口编写自己的,如下图编写成自己的:dyq_component
在这里插入图片描述

3.编写一个avalon接口的逻辑
顶层:(注意:顶层模块的模块声明必须按下面的方式,也就是先声明端口名称,之后再在下面进行输入、输出、位宽、类型的定义。不要写成像本文内部模块dyq_pio那样的定义,qsys会识别不出来)

module dyq_pio_top
#(parameter PIO_WIDTH = 7)
(
	clk,
	reset,
	avs_s0_address,//Avalon读写地址
	avs_s0_read,//Avalon读请求
	avs_s0_write,//Avalon写请求
	avs_s0_readdata,//Avalon读数据总线
	avs_s0_writedata,//Avalon写数据总线
	pio //外部控制LED灯
	);
	input 	 		clk;
	input	 		reset;
	input 	[2:0] 	avs_s0_address;//Avalon读写地址
	input	 		avs_s0_read;//Avalon读请求
	input	 		avs_s0_write;//Avalon写请求
	output	[31:0] 	avs_s0_readdata;//Avalon读数据总线
	input 	[31:0]	avs_s0_writedata;//Avalon写数据总线
	inout	[PIO_WIDTH-1:0]	pio; //外部控制LED灯
	wire [PIO_WIDTH-1:0] o_pio,i_pio;


assign pio = avs_s0_read ? 7'dz : o_pio; //hps读pio数据时,三态门高阻态
assign i_pio = avs_s0_read ? pio : 7'dz; //hps写pio端口时,三态门做输出
//内部例化
dyq_pio #(.PIO_WIDTH(PIO_WIDTH) )
	u_pio(
	.clk(clk),
	.reset(reset),
	.avs_s0_address(avs_s0_address),
	.avs_s0_read(avs_s0_read),
	.avs_s0_write(avs_s0_write),
	.avs_s0_readdata(avs_s0_readdata),
	.avs_s0_writedata(avs_s0_writedata),
	.o_pio(o_pio),
	.i_pio(i_pio)
	);
endmodule

内部模块:

module dyq_pio
#(parameter PIO_WIDTH = 7)
(
	input 	 		clk,
	input	 		reset,
	input 	[2:0] 	avs_s0_address,
	input	 		avs_s0_read,
	input	 		avs_s0_write,
	output	reg [31:0] 	avs_s0_readdata,
	input 	[31:0]	avs_s0_writedata,
	input		[PIO_WIDTH-1:0] i_pio,//做输入
	output	reg [PIO_WIDTH-1:0]	o_pio//做输出
	);

//Avalon读控制逻辑
always@(*) begin
	if (avs_s0_read) begin
		case(avs_s0_address)
			3'd1 : avs_s0_readdata = {24'b0,i_pio};//将LED地址设置为0x01
			default: avs_s0_readdata = 32'dx;
		endcase
	end
	else begin
		avs_s0_readdata = 32'dx;
	end
end
//Avalon写控制逻辑
always @(posedge clk) begin
	if (reset) begin
		// reset
		o_pio <= 7'd0;
	end
	else if (avs_s0_write) begin
		case(avs_s0_address)
			3'd2 : o_pio <= avs_s0_writedata;//将pio写入地址设置为0x02
			default : o_pio <= o_pio;
		endcase
	end
end
endmodule

这里的pio控制的写地址设置为2,不是0,后面软件测试时需要注意
4.添加逻辑文件到组件。点击 Files >> Add File… 添加对应的文件模块,然后将dyq_pio_top.v设置为顶层文件。最后点击Analyze Synthesis Files对Verilog代码进行综合.
在这里插入图片描述
在这里插入图片描述
5. 分析之后如下图,表示成功。如果有报错,往下看。
在这里插入图片描述
6.如下图在signals&interfaces里面,选中pio这一项,按图中所示进行设置。主要修改的有将端口类型设置为Conduit,也就是可被外部连接。Name随便改,也可以改成我的这样的。
在这里插入图片描述
7.选中avalone接口部分,将复位信号选择reset(就是上面的reset的名字)。基本就可以解决掉所有报错了。
在这里插入图片描述

8.点击Finish 保存,然后在工程里面就会生成一个_hw.tcl脚本文件该文件就是描述我们的自定义IP的。
在这里插入图片描述

1.2.设置自定义IP可被设备树生成器识别

在该工程的工程目录下找到并打开生成的_hw.tcl文件(dyq_pio_hw.tcl),添加如下代码;

# 
# module assignments
# 
set_module_assignment embeddedsw.dts.compatible " dev,dyq-pio"
#按照前面设置的自定义IP Group名称进行定义,这里定义成dyq_component
set_module_assignment embeddedsw.dts.group dyq_component 
set_module_assignment embeddedsw.dts.vendor dsa

保存之后重新打开自定义的组件编辑,重新构建一次即可。
详细了解学习可去官方参考:https://rocketboards.org/foswiki/Documentation/DeviceTreeGenerator140#Adding_Device_Tree_Generation_Support_to_an_IP_Block

2.添加使用自定义IP到GHRD工程

1.双击自定义IP,点击finish就成功加入qsys系统了。
在这里插入图片描述
2.对于连线,直接照抄该工程的其他PIO的连接方式就行。(对于avalon接口,需要通过桥接的方式接到HPS系统外设)

3.将PIO端口引到外部
在这里插入图片描述
4.点击下图地方,最后点击generate生成qsys系统即可
在这里插入图片描述

3.修改顶层代码

如下图把这个新生成的端口复制下来。
在这里插入图片描述
打开GHRD顶层v文件,把原先的led_pio端口的信号删掉,例化自己新增的端口,链接到这个位置。目的是可以在后续检设计软件检测自定义IP是否能够正常使用。在这里插入图片描述
在这里插入图片描述

4.硬件编译

1.直接点击编译即可,然后进入output文件夹,双击sof_to_rbf.bat文件,将sof文件转换成rbf文件。
2.在EDS终端的工程目录下执行generate_hps_qsys_header.sh以生成新的硬件头文件hps_0.h

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值