• 【笔记】关于NIOS II PIO的几个问题


    一下均来自ALTERA 《9. PIO Core》V9.0的datasheet。建议多多阅读官方文档。
    1.几个示例
          (1)控制LEDS。
          (2)获得来自外部的开关信息。
          (3)控制显示设备。
          (4)与外部设备通讯。
          注意PIO可以连接至片外与外部设备交互,亦可直接与FPGA内部逻辑相连接。
    2.PIO所具有的功能
          (1)输入
                此种只能设置PIO为输入,此时对direction、interruptmask或者edgecapture三个寄存器的读写均无效。
          (2)输出
                此种只能设置PIO为输入,此时对direction、interruptmask或者edgecapture三个寄存器的读写均无效。
          (3)双向
                可三态控制。通过设置direction寄存器控制PIO的方向。当为高时,PIO为输出状态;为低时,PIO为输入状态。这种状态可以单独对每一位设置方向。
          (4)输入输出
                该方式与双向的区别在于:在该方式下,能对每一位设置输入或者输出,但是一旦确定之后,不能软件更改。该方式其实就是n位宽的单向总线。
          (5)边沿出发外部中断
                必须是输入引脚才能设置该方式,在SOPC builder里面双击PIO实例可以设置为上跳沿触发或者下跳沿触发或者双沿触发
           (6)电平触发
                必须是输入引脚才能设置该方式,默认情况下,是高电平触发。若开发者需要低电平触发,可以在QUARTUS里面加个非门。
    3.控制PIO所需要的几条指令
          在编写程序的时候,必须单独加入#include "altera_avalon_pio_regs.h"头文件,否则不能对PIO的寄存器进行操作。
          打开头文件,程序如下:(注释是笔者对该宏的功能描述)
          

          #ifndef __ALTERA_AVALON_PIO_REGS_H__
          #define __ALTERA_AVALON_PIO_REGS_H__
          #include <io.h>
          #define IOADDR_ALTERA_AVALON_PIO_DATA(base)           __IO_CALC_ADDRESS_NATIVE(base, 0)
          #define IORD_ALTERA_AVALON_PIO_DATA(base)             IORD(base, 0)                                                 //读数据寄存器DATA
          #define IOWR_ALTERA_AVALON_PIO_DATA(base, data)       IOWR(base, 0, data)                                    // 写数据寄存器DATA
          #define IOADDR_ALTERA_AVALON_PIO_DIRECTION(base)      __IO_CALC_ADDRESS_NATIVE(base, 1)      
          #define IORD_ALTERA_AVALON_PIO_DIRECTION(base)        IORD(base, 1)                                                //读方向寄存器DIRECTION
          #define IOWR_ALTERA_AVALON_PIO_DIRECTION(base, data)  IOWR(base, 1, data)                                    //写方向寄存器DIRECTION
          #define IOADDR_ALTERA_AVALON_PIO_IRQ_MASK(base)       __IO_CALC_ADDRESS_NATIVE(base, 2)
          #define IORD_ALTERA_AVALON_PIO_IRQ_MASK(base)         IORD(base, 2)                                                 //读中断标志寄存器interruptmask
          #define IOWR_ALTERA_AVALON_PIO_IRQ_MASK(base, data)   IOWR(base, 2, data)                                    //写中断标志寄存器interruptmask
          #define IOADDR_ALTERA_AVALON_PIO_EDGE_CAP(base)       __IO_CALC_ADDRESS_NATIVE(base, 3)
          #define IORD_ALTERA_AVALON_PIO_EDGE_CAP(base)         IORD(base, 3)                                                  //读边沿触发寄存器edgecapture
          #define IOWR_ALTERA_AVALON_PIO_EDGE_CAP(base, data)   IOWR(base, 3, data)                                     //写中断标志寄存器edgecapture

          /* Defintions for direction-register operation with bi-directional PIOs */
          #define ALTERA_AVALON_PIO_DIRECTION_INPUT  0
          #define ALTERA_AVALON_PIO_DIRECTION_OUTPUT 1

          #endif /* __ALTERA_AVALON_PIO_REGS_H__ */

     4.PIO的位宽
          PIO可以被设置为1~32位的宽度。例如,笔者需要对4个LED进行测试,那么,在SOPC builder当中设置为4,且为只输出。生成系统之后,在目录下会生成PIO.V的硬件语言描述。如下:
           

          module pio (
                       // inputs:
                        address,
                        chipselect,
                        clk,
                        reset_n,
                        write_n,
                        writedata,

                       // outputs:
                        out_port,
                        readdata
                     )
          ;

            output  [  3: 0] out_port;            //注意此点,该PIO只占用四位寄存器
            output  [  3: 0] readdata;
            input   [  1: 0] address;
            input            chipselect;
            input            clk;
            input            reset_n;
            input            write_n;
            input   [  3: 0] writedata;

            wire             clk_en;
            reg     [  3: 0] data_out;
            wire    [  3: 0] out_port;
            wire    [  3: 0] read_mux_out;
            wire    [  3: 0] readdata;
            assign clk_en = 1;
            //s1, which is an e_avalon_slave
            assign read_mux_out = {4 {(address == 0)}} & data_out;
            always @(posedge clk or negedge reset_n)
              begin
                if (reset_n == 0)
                    data_out <= 0;
                else if (chipselect && ~write_n && (address == 0))
                    data_out <= writedata[3 : 0];
              end


            assign readdata = read_mux_out;
            assign out_port = data_out;

          endmodule
          可能开发者在开发时,会遇到对外部电路位操作的需求。笔者建议,每个需要单独操作的位都分配成1位宽,这样,即可以方便移植C51的程序,也不会增加PIO的存储空间。(但会增加地址空间)。不知读者有没好建议另行参考?..

    5.ptf文件深入
          生成ptf文件之后不如用文本打开看看。。还是以4个LED为例,其在ptf文件当中有如下定义:
          WIZARD_SCRIPT_ARGUMENTS
          {
             Do_Test_Bench_Wiring = "0";
             Driven_Sim_Value = "0";
             has_tri = "0";                              //是否为双向状态,若为1,则has_out,has_in无效
             has_out = "1";                              //为1时输出状态
             has_in = "0";                                    //为1时输入状态
             capture = "0";                              //捕获
             Data_Width = "4";                         //数据位宽。若,has_in=has_out=1,则产生Data_Width位个输入,Data_Width个输出。
             reset_value = "0";
             edge_type = "NONE";                  //NONE, RISING, FALLING,ANY四种选择
             irq_type = "NONE";
             bit_clearing_edge_register = "0";
          }

  • 相关阅读:
    IDA断点和搜索
    shell grep正则匹配汉字
    吐槽一下jsoup
    mysql函数
    hutools之批量更新
    Hutools之http工具类
    Java通过腾讯邮箱发送邮件
    访问网络资源的方式--application/json和x-www-form-urlencoded
    HttpClient获取数据
    URLConnection类的使用
  • 原文地址:https://www.cnblogs.com/oneseven/p/OneSeven.html
Copyright © 2020-2023  润新知