zoukankan      html  css  js  c++  java
  • 完整的SOPC开发流程体验

    课程目标:学习并掌握完整的SOPC开发流程。

    开发环境:Quartus15.1

    学习内容:1、使用QSYS工具建立能够运行流水灯项目的NIOS II处理器系统

         2、在quartus ii中添加NIOS II 系统文件(完成SOPC系统搭建);

         3、在nios II EDS中创建NIOS ii软件工程,实现流水灯代码;

         4、在开发板上运行流水灯程序。

    设计流程:

     创建一个新的project 工程

    新建一个GHRD.v顶层文件

    打开QSYS

     选择最新的NIOS II CPU 核

    由于是第一次使用NIOS ii 的CPU 核,所以选择默认的设置点击finish即可

    添加on-chip-ram作为CPU的运行内存

    修改一下内存大小,保证内存足够大

    添加只输出型的四位PIO

     

    同样,将其重命名为易观察的名字

    主要单元添加完毕后,即可进行总线类型的连接了

    首先是数据总线主机与从机相连

    然后是指令总线与从机存储数据的模块的数据总线相连

    连接时钟

    创建全局复位网络

    连接完毕后的连接图

    导出PIO信号

    分配基地址

    此时,警告框还是有两个错误,这是因为,在设置CPU时,没有设置复位地址和异常地址,双击nios2_gen2_0,将vector指向指令存储器

     

    保存并生成.qsys文件

    生成HDL文件

     生成例化模板

    点击copy,将内容粘贴到之前创建的GHRD的顶层文件中

    至此,系统的NIOS II处理器就搭建完成了

    下面就是对SOPC系统进行完善,在quartus II 软件中添加NIOS ii处理器系统并分配引脚

    添加quartus II处理器系统QSYS文件

    对顶层的GHRD文件进行编写

    module GHRD(
                                        clk50m,
                                        rst_n,
                                        led,
                                        );
                                        input clk50m;
                                        input rst_n;
                                        output [3:0]led;
        cpu u0 (
            .clk_clk        (clk50m),      //     clk.clk
            .reset_reset_n  (rst_n),  //   reset.reset_n
            .pio_led_export (led)  // pio_led.export
        );
    
         
         endmodule 

    编译完成了可以对比编译结果查看自己所用的FPGA,观察逻辑结构是否够用,由图可知是够用的。

    分配引脚

     编写EDS代码

    打开后将工作空间设置到GHRD开发环境的工作空间

     新建一个模板工程

    led_run_bsp的板级支持包的工程结构

    为了保证工程在后面可以直接调用,这里新建一个文件夹来编写代码

    在文件夹下创建两个文件夹啊inc(存放头文件.h)src(存放源文件.c)

    创建一个.h文件

     

     

    编写led.h代码

    #ifndef LED_H_
    #define LED_H_
    
    #include"system.h"
    #include"altera_avalon_pio_regs.h"
    #include"alt_types.h"
    
        typedef void *LED_HANDLE;
    
        typedef struct{
    
            alt_u32 led_base;
            alt_u32 led_data;
    
        }CoreCourse_LED;
    
        #define LED_ALL_OFF 0xffffffff
    
        #define LED0    0x00000001
        #define LED1    0x00000002
        #define LED2    0x00000004
        #define LED3    0x00000008
    /*
        #define LED4    0x00000010
        #define LED5    0x00000020
        #define LED6    0x00000040
        #define LED7    0x00000080
        #define LED8    0x00000100
        #define LED9    0x00000200
        #define LED10    0x00000400
        #define LED11    0x00000800
        #define LED12    0x00001000
        #define LED13    0x00002000
        #define LED14    0x00004000
        #define LED15    0x00008000
        #define LED16    0x00010000
        #define LED17    0x00020000
        #define LED18    0x00040000
        #define LED19    0x00080000
        #define LED20    0x00100000
        #define LED21    0x00200000
        #define LED22    0x00400000
        #define LED23    0x00800000
        #define LED24    0x01000000
        #define LED25    0x02000000
        #define LED26    0x04000000
        #define LED27    0x08000000
        #define LED28    0x10000000
        #define LED29    0x20000000
        #define LED30    0x40000000
        #define LED31    0x80000000
    */
    
        LED_HANDLE LED_Init(const alt_u32 led_base);
        void LED_Off(CoreCourse_LED *p, alt_u32 ledx);
        void LED_On(CoreCourse_LED *p, alt_u32 ledx);
        void LED_Toggle(CoreCourse_LED *p, alt_u32 ledx);
        void LED_WriteData(CoreCourse_LED *p, alt_u32 leds);
    
    #endif /* LED_H_ */

    创建一个.c空文件

     同样编写led.c代码

    #include  "led.h"
    #include <string.h>
    #include <stdlib.h>
    
    /******************************************************************************
    * 函数名  : LED_Init
    * 描述    : 初始化LED结构体并返回结构体指针地址
    * 输入    : led_base ,system.h中定义的LED的基地址
    * 输出    : 无
    * Return    :经过初始化的LED结构体指针
    *******************************************************************************/
    LED_HANDLE LED_Init(const alt_u32 led_base) {
    
        CoreCourse_LED *p;
    
        p = malloc(sizeof(CoreCourse_LED));
        if (!p)
            return p;
    
        memset(p, 0, sizeof(CoreCourse_LED));
    
        p->led_base = led_base;
        p->led_data = 0xffffffff;
    
        IOWR_ALTERA_AVALON_PIO_DATA(p->led_base, p->led_data);
    
        return p;
    }
    
    /******************************************************************************
    * 函数名  : LED_Off
    * 描述    : 关闭一个或多个LED
    * 输入    : p ,LED结构体指针
    *         :LEDx,需要关闭的LED
    * 输出    : 无
    * Return    :无
    *******************************************************************************/
    void LED_Off(CoreCourse_LED *p, alt_u32 ledx) {
        p->led_data = p->led_data | ledx;
        IOWR_ALTERA_AVALON_PIO_DATA(p->led_base, p->led_data);
    }
    
    /******************************************************************************
    * 函数名  : LED_On
    * 描述    : 打开一个或多个LED
    * 输入    : p ,LED结构体指针
    *         :LEDx,需要打开的LED
    * 输出    : 无
    * Return    :无
    *******************************************************************************/
    void LED_On(CoreCourse_LED *p, alt_u32 ledx) {
        p->led_data = p->led_data & (~ledx);
        IOWR_ALTERA_AVALON_PIO_DATA(p->led_base, p->led_data);
    }
    
    /******************************************************************************
    * 函数名  : LED_Toggle
    * 描述    : 翻转一个或多个LED
    * 输入    : p ,LED结构体指针
    *         :LEDx,需要翻转的LED
    * 输出    : 无
    * Return    :无
    *******************************************************************************/
    void LED_Toggle(CoreCourse_LED *p, alt_u32 ledx) {
        p->led_data ^= ledx;
        IOWR_ALTERA_AVALON_PIO_DATA(p->led_base, p->led_data);
    }
    
    /******************************************************************************
    * 函数名  : LEDS_WriteData
    * 描述    : 直接控制所有LED的状态,输入的LED将被点亮,未输入的将被关闭
    * 输入    : p ,LED结构体指针
    *         :LEDx,需要点亮的LED
    * 输出    : 无
    * Return    :无
    *******************************************************************************/
    void LED_WriteData(CoreCourse_LED *p, alt_u32 leds){
        p->led_data = leds;
        IOWR_ALTERA_AVALON_PIO_DATA(p->led_base, p->led_data);
    }
    
    
    /*    main函数中初始化示例代码
     *
     * LED_HANDLE hLED;
        hLED = LED_Init(PIO_LED_BASE);
        if (!hLED) {
            //    printf("Failed to init LED
    ");
        }
    */
    
    /*    LED_WriteData()函数使用示例代码
     *
     *LED_WriteData(hLED, LED0 | LED2); //LED0和LED2点亮,LED1和LED3关闭
        }
    */
    
    /*    LED_On()函数使用示例代码
     *
     *LED_On(hLED, LED0 | LED2);    //点亮LED0和LED2
        }
    */
    
    /*    LED_Off()函数使用示例代码
     *
     *LED_Off(hLED, LED1 | LED3);    //熄灭LED1和LED3
        }*/
    
    /*    LED_Toggle()函数使用示例代码
     *
     *LED_Toggle(hLED, LED3);        //翻转LED3
        }*/

    将helloworld.c文件更改为main.c文件,并编写main.c

    /********************************************************************
     * 文 件 名:main.c
     * 功    能:LED显示控制。
     *           通过PIO直接控制4个LED产生亮灭效果
     * 说    明:
     *
     ********************************************************************/
    #include  "system.h"
    #include  "altera_avalon_pio_regs.h"
    #include  "alt_types.h"
    #include  "led.h"
    
    /******************************************************************************
    * 函数名  : DelayNs
    * 描述    : 简易延时
    * 输入    : 需要延时的数值
    * 输出    : 无
    * Return    :无
    *******************************************************************************/
    void DelayNs(alt_u32 i)
    {
        while (i--)
            ;
    }
    
    /********************************************************************
     * 名    称:main()
     * 功    能:使用所有LED API控制LED运行
     ********************************************************************/
    int main(void) {
        alt_u32 i;
        //volatile alt_u32 j;
    
        LED_HANDLE hLED;
        hLED = LED_Init(PIO_LED_BASE);
        if (!hLED) {
            //    printf("Failed to init LED
    ");
        }
    
        while (1) {
            //测试LED_WriteData函数功能
            i = 2;
            while (i--){
                LED_WriteData(hLED, LED0 | LED2); //LED1和LED3点亮,LED0和LED2关闭
                DelayNs(5000000);
    
                LED_WriteData(hLED, LED1 | LED3); //LED0和LED2点亮,LED1和LED3关闭
                DelayNs(5000000);
            }
    
            LED_WriteData(hLED, LED_ALL_OFF);    //关闭所有的LED
    
            DelayNs(10000000);
    
            //测试LED_On函数和LED_Off函数功能
            i = 2;
            while (i--){
                LED_On(hLED, LED0 | LED2);    //点亮LED0和LED2
                DelayNs(5000000);
    
                LED_On(hLED, LED1 | LED3);    //点亮LED1和LED3
                DelayNs(10000000);
    
                LED_Off(hLED, LED0 | LED2);    //熄灭LED0和LED2
                DelayNs(5000000);
    
                LED_Off(hLED, LED1 | LED3);    //熄灭LED1和LED3
                DelayNs(10000000);
            }
    
            LED_WriteData(hLED, LED_ALL_OFF);    //关闭所有的LED
    
            //测试LED_Toggle函数功能
            i = 8;
            while (i--){
                LED_Toggle(hLED, LED3);        //翻转LED3
                DelayNs(5000000);
            }
        }
        return 0;
    }

    添加led_run_bsp的路径

    添加led.h的路径

     

    对工程进行编译

    将quartus之前生成的.sof文件烧写到FPGA开发板中,然后在NIOS ii中选择进行仿真运行

     

     等待一会后会弹出如下界面,之后可以按照keil仿真的方法进行

     

    实验现象http://v.youku.com/v_show/id_XMjk0NDQwOTQyOA==.html?spm=a2h3j.8428770.3416059.1 

    本文的源代码将在下篇文章上传,并讲解如何将别人的NIOS ii工程转换成自己开发可以使用的工程。

  • 相关阅读:
    npm镜像切换
    vue组件样式覆盖问题-module
    实现微信小程序多文件同时上传,并且携带参数
    提交现有代码到gitee
    富文本框 字段存入数据库
    js动态添加 <select>标签disable属性
    validate验证,rules属性名为特殊属性名
    springboot themleaf ajax总结
    th:field,th:value
    直接在页面上显示当前年份
  • 原文地址:https://www.cnblogs.com/noticeable/p/7268059.html
Copyright © 2011-2022 走看看