【精品博文】lemonHe分享:NIOS中寄存器映射

我的开发环境:Quartus II 13.1 (64-Bit)  + Nios II 13.1 Software Build Tools for Eclipse

设计的初忠是利用Nios接收uart数据,然后通过寄存器的方式映射给逻辑,实现对数字图像帧频以及相关参数的调整。其实直接在逻辑中使用串口就行,还不用这么麻烦,但是由于程序中的串口指令比较复杂,使用了协议,如果用逻辑来做,解析指令太麻烦了。

言归正传,首先,在逻辑中新建一个带时钟、复位、一组avalon信号、一组对外接口的模块,代码如下:

//=============================================================================// File Name      : registerMap// Module Name    : Same with "File Name"// Function                  : 完成寄存器映射//============================================================================= module registerMap(//Avalon Clockinput                                           csi_clk,input                                           csi_rst_n,//Avalon-MMinput                                           avs_chipselect,input                 [7:0]                  avs_address,        //multiple of 4//    input    [1:0]    avs_byteenable_n,    //1,2,4,8,16,54,128input                                           avs_write,input                 [31:0]       avs_writedata,        //32bit cpuinput                                           avs_read,output     [31:0]       avs_readdata,        //32bit cpu//Avalon Conduit             //对外部接口output     reg   [7:0]                  Image_Test,          output     reg   [7:0]                  Parameter1,output     reg   [7:0]                  NUC_TwoPoint,          output     reg   [7:0]                  NUC_ByPass,          output     reg   [7:0]                  BPR_Bypass,          output     reg   [15:0]       Linear_Adjust,          output     reg   [31:0]       PHE_Adjust,          output     reg   [7:0]                  DRC_Select,                   output     reg   [23:0]       IRControl,          output     reg   [7:0]                  PowerOn); //write     nios中数据写至逻辑reg   [7:0]         coe_data_r;reg   [7:0]         coe_data_g; always @(posedge csi_clk or negedge csi_rst_n)         begin                  if (!csi_rst_n)                          coe_data_r <= 0;                  else if (avs_chipselect && avs_write)                          begin                                   case(avs_address)                                            0: Image_Test          <= avs_writedata[7:0];                                            1: Parameter1                  <= avs_writedata[7:0];                                            2: NUC_TwoPoint   <= avs_writedata[7:0];                                            3: NUC_ByPass       <= avs_writedata[7:0];                                            4: BPR_Bypass                 <= avs_writedata[7:0];                                            5: Linear_Adjust      <= avs_writedata[15:0];                                            6: PHE_Adjust          <= avs_writedata[31:0];                                            7: DRC_Select          <= avs_writedata[7:0];                                            8: IRControl             <= avs_writedata[23:0];                                            9: PowerOn              <= avs_writedata[7:0];                                   endcase                          end         end        assign coe_data0 = coe_data_r;assign coe_data1 = coe_data_g; //read      逻辑中数据读至niosreg   [7:0] avs_readdata_r;always @(posedge csi_clk or negedge csi_rst_n)         begin                   if (!csi_rst_n)                            avs_readdata_r <= 0;                   else if (avs_chipselect && avs_read)    //for steady state                          begin                                   case(avs_address)                                            0:avs_readdata_r <= coe_data0;                                   endcase                          end         endassign avs_readdata = avs_readdata_r; endmodule

在Qsys中将该模块新加到组件,编译。

进行端口分配

Nios中采用中断的方式接收数据,在程序中加收到的数据进行判断,满足一定条件时,给某个寄存器映射一个值,Nios部分代码如下:

static alt_u32 *registerMap = (alt_u16 *)(REGISTERMAP_0_BASE);alt_u32 i = 0;    printf("uartTask test is ok!\n");    while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK)));    //发送准备好,发送txdata    IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,txdata);     if(rxdata==0x01)    {        *(registerMap+0) = 1;    }    if(rxdata==0x02)    {        *(registerMap+1) = 2;    }    if(rxdata==0x03)    {        *(registerMap+2) = 3;    }    if(rxdata==0x04)    {        *(registerMap+3) = 4;    }    if(rxdata==0x05)    {        *(registerMap+4) = 5;    }    if(rxdata==0x06)    {        *(registerMap+5) = 6;    }    if(rxdata==0x07)    {        *(registerMap+6) = 7;    }    if(rxdata==0x08)    {        *(registerMap+7) = 8;    }    if(rxdata==0x09)    {        *(registerMap+8) = 9;    }    if(rxdata==0x0a)    {        *(registerMap+9) = 10;    }     rxdata = 0xaa;

Nios部分代码请参看博文【基于niosuart核设计】,上面这个例程中使用的是基地址+偏移地址(*(registerMap+i))的方式来映射,我觉得这种方式最简单,并且用起来特别方便。此外,还有结构体方式,在Nios中定义一个结构体,学过c语言的同学都知道,结构体中,数据按照先后顺序在地址空间中存放,如果寄存器较多,使用结构体不是很方便。

参考:

http://www.cnblogs.com/yuphone/archive/2010/04/22/1717779.html

(0)

相关推荐