【SoC FPGA】外设PIO按键点灯

文章目录

  • 一、前期准备
  • 二、添加PIO外设
    • 一、黄金参考工程
    • 二、配置PIO外设
    • 三、Generation生成
    • 四、黄金参考工程代码修改
    • 五、编译黄金工程
  • 三、生成相应的文件,转移至sd卡内
    • 一、dtb设备树文件
    • 二、rbf文件
    • 三、替换sd卡内的dtb和rbf文件
    • 四、生成hps_0.h
  • 三、C语言实现
    • 一、 创建并配置工程
    • 二、C语言实现按键点灯
  • 四、连接SoC FPGA
  • 五、执行效果
  • 六、总结

一、前期准备

SoC学习篇—实现hello FPGA打印
要把该准备好的硬件给准备好

二、添加PIO外设

一、黄金参考工程

1.打开黄金参考工程
【SoC FPGA】外设PIO按键点灯_第1张图片
2.打开Platform Designer
在这里插入图片描述
3.打开相应的qsys文件
【SoC FPGA】外设PIO按键点灯_第2张图片
4.添加PIO_LED和PIO_KEY
【SoC FPGA】外设PIO按键点灯_第3张图片

名称 位宽 输入输出
PIO_LED 4位宽 output

【SoC FPGA】外设PIO按键点灯_第4张图片

名称 位宽 输入输出
PIO_KEY 2位宽 input

【SoC FPGA】外设PIO按键点灯_第5张图片
添加到soc system中
【SoC FPGA】外设PIO按键点灯_第6张图片

二、配置PIO外设

连线,双击,重设地址
【SoC FPGA】外设PIO按键点灯_第7张图片
待下面没有error绿色即可
【SoC FPGA】外设PIO按键点灯_第8张图片

三、Generation生成

1.Generate HDL 生成HDL语言
【SoC FPGA】外设PIO按键点灯_第9张图片

【SoC FPGA】外设PIO按键点灯_第10张图片
2.Show Instantiation Template 生成例化模板
【SoC FPGA】外设PIO按键点灯_第11张图片
将添加的外设例化模板复制
【SoC FPGA】外设PIO按键点灯_第12张图片
3.Finish结束Platform Designer
【SoC FPGA】外设PIO按键点灯_第13张图片

四、黄金参考工程代码修改

1.添加外设端口

    output   [ 3: 0]   LED,
    input    [ 1: 0]   KEY

【SoC FPGA】外设PIO按键点灯_第14张图片

 // pio_led
   .pio_led_external_connection_export    (LED),     // pio_led_external_connection.export

 // pio_key
   .pio_key_external_connection_export    (KEY)     // pio_key_external_connection.export

【SoC FPGA】外设PIO按键点灯_第15张图片
完整代码

module C5MB_top(
    / FPGA /
    input              FPGA_CLK1_50,

    / HPS /
    output   [14: 0]   HPS_DDR3_ADDR,
    output   [ 2: 0]   HPS_DDR3_BA,
    output             HPS_DDR3_CAS_n,
    output   [ 0: 0]   HPS_DDR3_CKE,
    output             HPS_DDR3_CK_n,
    output             HPS_DDR3_CK_p,
    output   [ 0: 0]   HPS_DDR3_CS_n,
    output   [ 3: 0]   HPS_DDR3_DM,
    inout    [31: 0]   HPS_DDR3_DQ,
    inout    [ 3: 0]   HPS_DDR3_DQS_n,
    inout    [ 3: 0]   HPS_DDR3_DQS_p,
    output   [ 0: 0]   HPS_DDR3_ODT,
    output             HPS_DDR3_RAS_n,
    output             HPS_DDR3_RESET_n,
    input              HPS_DDR3_RZQ,
    output             HPS_DDR3_WE_n,
    output             HPS_ENET_GTX_CLK,
    inout              HPS_ENET_INT_n,		//hps_gpio_GPIO35
    output             HPS_ENET_MDC,
    inout              HPS_ENET_MDIO,
    input              HPS_ENET_RX_CLK,
    input    [ 3: 0]   HPS_ENET_RX_DATA,
    input              HPS_ENET_RX_DV,
    output   [ 3: 0]   HPS_ENET_TX_DATA,
    output             HPS_ENET_TX_EN,    

    inout              HPS_EMMC_SEL,		//hps_io_gpio_inst_GPIO44
    output             HPS_SDMMC_CLK,
    inout              HPS_SDMMC_CMD,

    inout    [ 7: 0]   HPS_SDMMC_DATA,
    output             HPS_EMMC_RST_n,

    input              HPS_UART_RX,
    output             HPS_UART_TX,
                    //## HPS_USB ##
    input              HPS_USB_CLKOUT,
    inout    [ 7: 0]   HPS_USB_DATA,
    input              HPS_USB_DIR,
    input              HPS_USB_NXT,
    output             HPS_USB_STP,

    output   [ 3: 0]   LED,

    input    [ 1: 0]   KEY
);


//=======================================================
//  REG/WIRE declarations
//=======================================================
wire hps_fpga_reset_n;

wire fpga_clk_50;
wire fpga_clk_100;

// wire pwm;

// assign LED = {4{pwm}};

pll pll_inst (
    .refclk    (FPGA_CLK1_50),   		//  refclk.clk
    .rst       (~hps_fpga_reset_n),     //   reset.reset
    .outclk_0  (fpga_clk_50),		    // outclk0.clk	
    .outclk_1  (fpga_clk_100) 
);

//=======================================================
//  Structural coding
//=======================================================
soc_system u0 (
    .clk_clk (fpga_clk_50),                              //                clk.clk
    .reset_reset_n (hps_fpga_reset_n),                                  //                reset.reset_n
    //HPS ddr3
    .memory_mem_a (HPS_DDR3_ADDR),                        //                memory.mem_a
    .memory_mem_ba (HPS_DDR3_BA),                          //                .mem_ba
    .memory_mem_ck (HPS_DDR3_CK_p),                        //                .mem_ck
    .memory_mem_ck_n (HPS_DDR3_CK_n),                        //                .mem_ck_n
    .memory_mem_cke (HPS_DDR3_CKE),                         //                .mem_cke
    .memory_mem_cs_n (HPS_DDR3_CS_n),                        //                .mem_cs_n
    .memory_mem_ras_n (HPS_DDR3_RAS_n),                       //                .mem_ras_n
    .memory_mem_cas_n (HPS_DDR3_CAS_n),                       //                .mem_cas_n
    .memory_mem_we_n (HPS_DDR3_WE_n),                        //                .mem_we_n
    .memory_mem_reset_n (HPS_DDR3_RESET_n),                     //                .mem_reset_n
    .memory_mem_dq (HPS_DDR3_DQ),                          //                .mem_dq
    .memory_mem_dqs (HPS_DDR3_DQS_p),                       //                .mem_dqs
    .memory_mem_dqs_n (HPS_DDR3_DQS_n),                       //                .mem_dqs_n
    .memory_mem_odt (HPS_DDR3_ODT),                         //                .mem_odt
    .memory_mem_dm (HPS_DDR3_DM),                          //                .mem_dm
    .memory_oct_rzqin (HPS_DDR3_RZQ),                         //                .oct_rzqin
    //HPS ethernet
    .hps_0_hps_io_hps_io_emac1_inst_TX_CLK (HPS_ENET_GTX_CLK),        //                             hps_0_hps_io.hps_io_emac1_inst_TX_CLK
    .hps_0_hps_io_hps_io_emac1_inst_TXD0 (HPS_ENET_TX_DATA[0]),    //                             .hps_io_emac1_inst_TXD0
    .hps_0_hps_io_hps_io_emac1_inst_TXD1 (HPS_ENET_TX_DATA[1]),    //                             .hps_io_emac1_inst_TXD1
    .hps_0_hps_io_hps_io_emac1_inst_TXD2 (HPS_ENET_TX_DATA[2]),    //                             .hps_io_emac1_inst_TXD2
    .hps_0_hps_io_hps_io_emac1_inst_TXD3 (HPS_ENET_TX_DATA[3]),    //                             .hps_io_emac1_inst_TXD3
    .hps_0_hps_io_hps_io_emac1_inst_RXD0 (HPS_ENET_RX_DATA[0]),    //                             .hps_io_emac1_inst_RXD0
    .hps_0_hps_io_hps_io_emac1_inst_MDIO (HPS_ENET_MDIO),          //                             .hps_io_emac1_inst_MDIO
    .hps_0_hps_io_hps_io_emac1_inst_MDC (HPS_ENET_MDC),          //                             .hps_io_emac1_inst_MDC
    .hps_0_hps_io_hps_io_emac1_inst_RX_CTL (HPS_ENET_RX_DV),          //                             .hps_io_emac1_inst_RX_CTL
    .hps_0_hps_io_hps_io_emac1_inst_TX_CTL (HPS_ENET_TX_EN),          //                             .hps_io_emac1_inst_TX_CTL
    .hps_0_hps_io_hps_io_emac1_inst_RX_CLK (HPS_ENET_RX_CLK),         //                             .hps_io_emac1_inst_RX_CLK
    .hps_0_hps_io_hps_io_emac1_inst_RXD1 (HPS_ENET_RX_DATA[1]),    //                             .hps_io_emac1_inst_RXD1
    .hps_0_hps_io_hps_io_emac1_inst_RXD2 (HPS_ENET_RX_DATA[2]),    //                             .hps_io_emac1_inst_RXD2
    .hps_0_hps_io_hps_io_emac1_inst_RXD3 (HPS_ENET_RX_DATA[3]),    //                             .hps_io_emac1_inst_RXD3
    //HPS SD card
    .hps_0_hps_io_hps_io_sdio_inst_CMD (HPS_SDMMC_CMD),            //                               .hps_io_sdio_inst_CMD
    .hps_0_hps_io_hps_io_sdio_inst_D0 (HPS_SDMMC_DATA[0]),       //                               .hps_io_sdio_inst_D0
    .hps_0_hps_io_hps_io_sdio_inst_D1 (HPS_SDMMC_DATA[1]),       //                               .hps_io_sdio_inst_D1
    .hps_0_hps_io_hps_io_sdio_inst_CLK (HPS_SDMMC_CLK),             //                               .hps_io_sdio_inst_CLK
    .hps_0_hps_io_hps_io_sdio_inst_D2 (HPS_SDMMC_DATA[2]),       //                               .hps_io_sdio_inst_D2
    .hps_0_hps_io_hps_io_sdio_inst_D3 (HPS_SDMMC_DATA[3]),       //                               .hps_io_sdio_inst_D3

    .hps_0_hps_io_hps_io_sdio_inst_D4 (HPS_SDMMC_DATA[4]),       //                               .hps_io_sdio_inst_D4
    .hps_0_hps_io_hps_io_sdio_inst_D5 (HPS_SDMMC_DATA[5]),       //                               .hps_io_sdio_inst_D5
    .hps_0_hps_io_hps_io_sdio_inst_D6 (HPS_SDMMC_DATA[6]),       //                               .hps_io_sdio_inst_D6
    .hps_0_hps_io_hps_io_sdio_inst_D7 (HPS_SDMMC_DATA[7]),       //                               .hps_io_sdio_inst_D7
    .hps_0_hps_io_hps_io_sdio_inst_PWREN (HPS_EMMC_RST_n),   //                               .hps_io_sdio_inst_PWREN

    //HPS USB
    .hps_0_hps_io_hps_io_usb1_inst_D0 (HPS_USB_DATA[0]),       //                               .hps_io_usb1_inst_D0
    .hps_0_hps_io_hps_io_usb1_inst_D1 (HPS_USB_DATA[1]),       //                               .hps_io_usb1_inst_D1
    .hps_0_hps_io_hps_io_usb1_inst_D2 (HPS_USB_DATA[2]),       //                               .hps_io_usb1_inst_D2
    .hps_0_hps_io_hps_io_usb1_inst_D3 (HPS_USB_DATA[3]),       //                               .hps_io_usb1_inst_D3
    .hps_0_hps_io_hps_io_usb1_inst_D4 (HPS_USB_DATA[4]),       //                               .hps_io_usb1_inst_D4
    .hps_0_hps_io_hps_io_usb1_inst_D5 (HPS_USB_DATA[5]),       //                               .hps_io_usb1_inst_D5
    .hps_0_hps_io_hps_io_usb1_inst_D6 (HPS_USB_DATA[6]),       //                               .hps_io_usb1_inst_D6
    .hps_0_hps_io_hps_io_usb1_inst_D7 (HPS_USB_DATA[7]),       //                               .hps_io_usb1_inst_D7
    .hps_0_hps_io_hps_io_usb1_inst_CLK (HPS_USB_CLKOUT),        //                               .hps_io_usb1_inst_CLK
    .hps_0_hps_io_hps_io_usb1_inst_STP (HPS_USB_STP),           //                               .hps_io_usb1_inst_STP
    .hps_0_hps_io_hps_io_usb1_inst_DIR (HPS_USB_DIR),           //                               .hps_io_usb1_inst_DIR
    .hps_0_hps_io_hps_io_usb1_inst_NXT (HPS_USB_NXT),           //                               .hps_io_usb1_inst_NXT
   
    //HPS UART
    .hps_0_hps_io_hps_io_uart0_inst_RX (HPS_UART_RX),           //                               .hps_io_uart0_inst_RX
    .hps_0_hps_io_hps_io_uart0_inst_TX (HPS_UART_TX),           //                               .hps_io_uart0_inst_TX
     
    .hps_0_hps_io_hps_io_gpio_inst_GPIO35 (HPS_ENET_INT_n),  //                              .hps_io_gpio_inst_GPIO35
    .hps_0_hps_io_hps_io_gpio_inst_GPIO44 (HPS_EMMC_SEL),   //                               .hps_io_gpio_inst_GPIO44
      
    .hps_0_h2f_reset_reset_n (hps_fpga_reset_n),                 //                hps_0_h2f_reset.reset_n
    
    .hps_0_f2h_cold_reset_req_reset_n (1'b1),       //       hps_0_f2h_cold_reset_req.reset_n
    .hps_0_f2h_debug_reset_req_reset_n (1'b1),      //      hps_0_f2h_debug_reset_req.reset_n
    .hps_0_f2h_warm_reset_req_reset_n (1'b1),     //       hps_0_f2h_warm_reset_req.reset_n

    // pio_led
    .pio_led_external_connection_export    (LED),     // pio_led_external_connection.export

    // pio_key
    .pio_key_external_connection_export    (KEY)     // pio_key_external_connection.export

    // pwm
    // .pwm_conduit_wire                      (pwm)                       //                 pwm_conduit.wire
);
endmodule

五、编译黄金工程

一般的电脑都需要6-8分钟

三、生成相应的文件,转移至sd卡内

一、dtb设备树文件

进入到黄金参考工程的目录下

【SoC FPGA】外设PIO按键点灯_第16张图片
生成.dtb文件

make dtb

在这里插入图片描述
像我这种已经生成了外设的就无须生成了,如果第一次就需要等待个几分钟

二、rbf文件

进入到output_files/目录下
运行sof_to_rbf.bat脚本文件

cd output_files/
./sof_to_rbf.bat

【SoC FPGA】外设PIO按键点灯_第17张图片

三、替换sd卡内的dtb和rbf文件

【SoC FPGA】外设PIO按键点灯_第18张图片

四、生成hps_0.h

 ./generate_hps_qsys_header.sh

这个hps_0.h是为了后续的C语言所需要的
【SoC FPGA】外设PIO按键点灯_第19张图片

三、C语言实现

一、 创建并配置工程

1.打开SoC EDS Command Shell
在这里插入图片描述
2.打开eclipse

eclipse&

在这里插入图片描述
3. New 一个新的 C Project
【SoC FPGA】外设PIO按键点灯_第20张图片
4. 选择GCC编译
【SoC FPGA】外设PIO按键点灯_第21张图片
5.对创建好的新工程右键属性
【SoC FPGA】外设PIO按键点灯_第22张图片
6.添加额外的两个库

D:\intelFPGA\18.1\embedded\ip\altera\hps\altera_hps\hwlib\include\soc_cv_av
D:\intelFPGA\18.1\embedded\ip\altera\hps\altera_hps\hwlib\include

【SoC FPGA】外设PIO按键点灯_第23张图片
7.将黄金工程的hps_0.h文件放入工程中
【SoC FPGA】外设PIO按键点灯_第24张图片
【SoC FPGA】外设PIO按键点灯_第25张图片

二、C语言实现按键点灯

1.New 一个新的C文件main.c
【SoC FPGA】外设PIO按键点灯_第26张图片
2.编写C语言代码

//gcc标准头文件
#include 
#include 
#include 
#include 

//HPS厂家提供的底层定义头文件
#define soc_cv_av //开发平台Cyclone V 系列

#include "hwlib.h"
#include "socal/socal.h"
#include "socal/hps.h"

//与用户具体的HPS 应用系统相关的硬件描述头文件
#include "hps_0.h"

#define HW_REGS_BASE (ALT_STM_OFST)     //HPS外设地址段基地址
#define HW_REGS_SPAN (0x04000000)		//HPS外设地址段地址空间 64MB大小
#define HW_REGS_MASK (HW_REGS_SPAN - 1) //HPS外设地址段地址掩码

static volatile unsigned long *led_pio_virtual_base = NULL;
static volatile unsigned long *key_pio_virtual_base = NULL;

//fpga初始化
int fpga_init(int *virtual_base)
{
	int fd;
	void *perph_virtual_base;
	//1.open打开mmu
	fd = open("/dev/mem",(O_RDWR | O_SYNC));
	if(fd == -1)
	{
		printf("open failed..\n");
		exit(1);
	}
	//mmap 映射虚拟地址
	perph_virtual_base = mmap(NULL,HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ),MAP_SHARED,fd,HW_REGS_BASE);

	if(perph_virtual_base == MAP_SHARED)
	{
		printf("mmap() is failed..\n");
		return 1;
	}
    //接口
	led_pio_virtual_base = perph_virtual_base + ((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_LED_BASE) & (unsigned long)(HW_REGS_MASK));
	key_pio_virtual_base = perph_virtual_base + ((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_KEY_BASE) & (unsigned long)(HW_REGS_MASK));

	//保存虚拟地址
	*virtual_base = perph_virtual_base;

	return fd;
}

int main()
{
	int virtual_base;
	int fd;
	fd = fpga_init(&virtual_base);
	unsigned int data;
	while(1)
	{
//		data = ~(*(key_pio_virtual_base + 0));
//		*(led_pio_virtual_base + 0) = ~(*(key_pio_virtual_base + 0));
//		*(led_pio_virtual_base + 0) = data;
		if(*(key_pio_virtual_base + 0) == 0x01)
		{
			*(led_pio_virtual_base + 0) = 0xf;
		}
		else if(*(key_pio_virtual_base + 0) == 0x02)
		{
			*(led_pio_virtual_base + 0) = 0x0;
		}
	}
	if(munmap(virtual_base,HW_REGS_SPAN) != 0)
	{
		printf("munmap() is failed..\n");
		close(fd);
		return 1;
	}
	close(fd);
	return 0;
}

保存并且编译后会生成一个二进制文件
【SoC FPGA】外设PIO按键点灯_第27张图片

四、连接SoC FPGA

【SoC FPGA】外设PIO按键点灯_第28张图片
将C语言的二进制文件放到opt文件内
【SoC FPGA】外设PIO按键点灯_第29张图片
将执行文件运行需要权限

cd opt/
chmod 777 pio_key_test
./pio_key_test

颜色变绿说明有权限
【SoC FPGA】外设PIO按键点灯_第30张图片

五、执行效果

这里不方便拍摄效果,就是按键点灯的效果

六、总结

SoC去实现功能,就是添加ip外设,计算外设的虚拟映射地址,然后通过C语言去对基地址赋值,最后连接到板子上去执行,基本步骤是会了,但是有些C语言的内容不太懂。

你可能感兴趣的:(SoC,FPGA,fpga,soc)