尝一下DE1-SoC—HPS--FPGA
关键词:Cyclone V 、5CSEMA5、 DE1-SoC 学习DE1-SoC也有三个星期了,来个小结性总结吧。 这篇帖子,并不是技术,而只是个科普而已,仅供娱乐,开心的我也是不行。
感想:我也是开心 的快要哭了,整个人感觉都不好了。整体的对这个SoC的印象就是ARM和FPGA关于AMBA4.0的一段恋情。。。开发起来也是复杂的不行,首先你得会ARM和FPGA,还得会用AMBA。作为一个基本不知道FPGA是什么的东东的我来说确实有点难度。 走在学习的小路上。。。
一、拆机器卖零件
起因:听这次altera体验活动的组织者也就是论坛管理员@phantom7说芯片加起来比板子值钱的。当时感觉她在逗我玩,怎么可能芯片加起来比板子还贵,那不是赔钱卖板子的么。
经过:自己去arrow随便点了几个板子上有的芯片放到了购物车。
结果:发现了一条发家致富的道路,就是拆机器卖零件。。。
世界太复杂,我搞不明白呀。 还是看图片吧,有图有真相。
图3-1:DE1-SoC价格
图3-2:芯片价格 有了上面的经验,瞬间也是开心的不行,机智的我拿起来来了米尔科技的Z-turnBoard 开发板(RMB850),准备拆机器卖零件。结果发现板载Xilinx的zynq7000家族的那个小芯片 (ZC7z010)大概是$60+。这次不能拆机器卖零件了。两颗SoC都是dual ARM Cortex-A9,一个85K、一个25K,具体的细节,倘若后面有时间,写个小小的对比与大家分享。
二、CycloneV SE简介
图3-3:Cyclone简介 Cyclone V较CycloneIV的提升
图3-4:CycloneIV和V的区别
Cyclone V下的各种的种类也是各种的各种多。
图3-5:Cyclone V种类
所以来讲个命名规则吧,因为要围绕DE1-SoC的板载芯片来讲,所以看看CycloneV(SE、SX、ST)命名规则如下:
图3-6:SE、SX、ST DE1-SoC板载一颗型号为:5CSEMA5F31C6N的芯片,关于这个芯片的性能与功能,请参照图3-3自行脑补,或者参看下面的图3-7、8、9:
图3-7:5CESA5功能
图3-8:5CESA5F31封装
图3-9:5CESA5F31 JESD51-1
(上面这个测试,细节我也不懂,只不过好大上,就贴在上面了)
三、HPS---FPGA
DE1-SoC开发板入门资料还是不错的,不过都是英文,四六级都没过的我,开着这些资料开心的我也是快要哭了。 看看下面这个图,可能对Cyclone的开发工具和CycloneV的内部结构有点了解,如下:
图3-A:Cyclone V 首先看一下面的几个单词,其实用过Cortex-M的单片记得同学,除了AXI对下面的应该很熟悉的 AMBA(AdvancedMicrocontroller Bus Architecture) AHB(theAdvanced High-performances Bus) ASB(theAdvanced System Bus) APB(theAdvanceed Peripheral Bus) AXI(AdvancedeXtensible Interface) AMBA® 4 : AXI4™, AXI4-Lite™, or AXI4-Stream™Protocol.
AMBA是ARM公司设计的通信总线。AXI4.0是对3.0的升级,可以通过它来进行ARM和FPGA的通信。具体的就参考ARM官网的用户手册吧。 ARM和FPGA来直观的看一看,其实就是下面这个样子的:
图3-B:SoC 两个独立的东东,做到了一个芯片上,通过总线互联。 其实是这个样子的:
图3-C:总线 M:master S: slave FPGA-to-HPS bridge HPS-to-FPGA bridge Lightweight HPS-to-FPGA bridge DE1-SoC提供了QuartusII 的一个基本的项目,DE1-SoC板子的资源已经设置好,可以在这个基础上做一些开发。 例程是做了一个简单的流水灯的程序。 只需要做点小小的改动就可以完成对HPS和FPGA这块相应的简单的开发。在Qsys中添加好PIO模块之后,设置好系统总线。编译好项目之后,通过JTAG配置到FPGA中。
图3-D:JTAG调试
接着,将IO口地址虚拟映射到虚拟地址之后,通过“/dev/mem”就可以操作了,在HPS上执行的C语言代码如下:
- <blockquote>#include <stdio.h>
复制代码- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include "hwlib.h"
- #include "socal/socal.h"
- #include "socal/hps.h"
- #include "socal/alt_gpio.h"
- #include "hps_0.h"
- #define HW_REGS_BASE ( ALT_STM_OFST )
- #define HW_REGS_SPAN ( 0x04000000 )
- #define HW_REGS_MASK ( HW_REGS_SPAN - 1 )
- int main() {
- void *virtual_base;
- int fd;
- int loop_count;
- int led_direction;
- int led_mask;
- void *h2p_lw_led_addr;
- // map the address space for the LED registers into user space so we can interact with them.
- // we'll actually map in the entire CSR span of the HPS since we want to access various registers within that span
- if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) {
- printf( "ERROR: could not open "/dev/mem"...\n" );
- return( 1 );
- }
- virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE );
- if( virtual_base == MAP_FAILED ) {
- printf( "ERROR: mmap() failed...\n" );
- close( fd );
- return( 1 );
- }
-
- h2p_lw_led_addr=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + PIO_LED_BASE ) & ( unsigned long)( HW_REGS_MASK ) );
-
- // toggle the LEDs a bit
- loop_count = 0;
- led_mask = 0x01;
- led_direction = 0; // 0: left to right direction
- printf(" HelloWorld! \n");
- while( loop_count < 60 ) {
-
- // control led
- *(uint32_t *)h2p_lw_led_addr = ~led_mask;
- // wait 100ms
- usleep( 400*1000 );
-
- // update led mask
- if (led_direction == 0){
- led_mask <<= 1;
- if (led_mask == (0x01 << (PIO_LED_DATA_WIDTH-1)))
- led_direction = 1;
- }else{
- led_mask >>= 1;
- if (led_mask == 0x01){
- led_direction = 0;
- loop_count++;
- }
- }
-
- } // while
-
- // clean up our memory mapping and exit
-
- if( munmap( virtual_base, HW_REGS_SPAN ) != 0 ) {
- printf( "ERROR: munmap() failed...\n" );
- close( fd );
- return( 1 );
- }
- close( fd );
- return( 0 );
- }
复制代码
图3-E:编译环境
感觉上面那个东东就是一个类似的Cygwin。完美执行linux指令,开心的我也是不行。。
图3-F:调试
编译之后将,可执行文件放到开发就可以发布运行了。
至此,也是结束了,开心的我也是不行。
总算有点明白了ARM与FPGA之间的这段 “奸情” 。
|