zoukankan      html  css  js  c++  java
  • (原创)由XPS生成AXI Lite 从设备IP模板我们能学到的东西

    查看由XPS的向导生成的AXI Lite IP代码模板中,我们能学习到用户自定义IP的结构和实现方式。拿写寄存器来说,我们能看到这样的一段代码

     1   // implement slave model register(s)
     2   always @( posedge Bus2IP_Clk )
     3     begin
     4 
     5       if ( Bus2IP_Resetn == 1'b0 )
     6         begin
     7           slv_reg0 <= 0;
     8           slv_reg1 <= 0;
     9           slv_reg2 <= 0;
    10           slv_reg3 <= 0;
    11           slv_reg4 <= 0;
    12           slv_reg5 <= 0;
    13           slv_reg6 <= 0;
    14           slv_reg7 <= 0;
    15         end
    16       else
    17         case ( slv_reg_write_sel )
    18           8'b10000000 :
    19             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    20               if ( Bus2IP_BE[byte_index] == 1 )
    21                 slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    22           8'b01000000 :
    23             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    24               if ( Bus2IP_BE[byte_index] == 1 )
    25                 slv_reg1[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    26           8'b00100000 :
    27             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    28               if ( Bus2IP_BE[byte_index] == 1 )
    29                 slv_reg2[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    30           8'b00010000 :
    31             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    32               if ( Bus2IP_BE[byte_index] == 1 )
    33                 slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    34           8'b00001000 :
    35             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    36               if ( Bus2IP_BE[byte_index] == 1 )
    37                 slv_reg4[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    38           8'b00000100 :
    39             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    40               if ( Bus2IP_BE[byte_index] == 1 )
    41                 slv_reg5[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    42           8'b00000010 :
    43             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    44               if ( Bus2IP_BE[byte_index] == 1 )
    45                 slv_reg6[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    46           8'b00000001 :
    47             for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    48               if ( Bus2IP_BE[byte_index] == 1 )
    49                 slv_reg7[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
    50           default : begin
    51             slv_reg0 <= slv_reg0;
    52             slv_reg1 <= slv_reg1;
    53             slv_reg2 <= slv_reg2;
    54             slv_reg3 <= slv_reg3;
    55             slv_reg4 <= slv_reg4;
    56             slv_reg5 <= slv_reg5;
    57             slv_reg6 <= slv_reg6;
    58             slv_reg7 <= slv_reg7;
    59                     end
    60         endcase
    61 
    62     end // SLAVE_REG_WRITE_PROC

    代码实现的功能是将总线上的数据按字节写入到寄存器中。代码中有: 

    slv_reg0~slv_reg7为8个寄存器

    C_SLV_DWIDTH为数据位宽,是一个参数

    slv_reg_write_sel 为寄存器选择信号,如slv_reg_write_sel = 8‘1000_0000时,slv_reg0将在写操作时被选中。

    Bus2IP_Data为写数据端口

    Bus2IP_BE为字节使能信号

    从这段代码中,我们可以看到:

    1、AXI Lite 从设备接口也是memory mapped的,但不像AVALON memory mapped 。一个从设备的基地址C_BASEADDR设定后,设备的寄存器是通过Bus2IP_WrCE / Bus2IP_RdCE 信号(这里即slv_reg_write_sel) 信号选择的。当然,slv_reg_write_sel 信号的编码源是地址线,AXI Lite 规定最高位为1时的基地址,在这里slv_reg_write_sel 为8’b1000_0000,寄存器slv_reg0地址就是基地址;slv_reg_write_sel 为8’b0100_0000,寄存器slv_reg1地址就是基地址+0x04;以此类推。从设备的地址空间由参数设定,而不是由地址线直接决定。

    2、对于寄存器中的字节,代码是这样实现

    1 for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
    2     if ( Bus2IP_BE[byte_index] == 1 )
    3        slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];

    假如数据宽度C_SLV_DWIDTH是32bit,那么把参数用数字代入后,代码是这样的

    1  for ( byte_index = 0; byte_index <= 3; byte_index = byte_index+1 )
    2     if ( Bus2IP_BE[byte_index] == 1 )
    3         slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];

    很好理解,就是字节使能Bus2IP_BE对应为有效,则将对应字节从数据总线传输到相应寄存器上。能看到XPS生成的模板,很巧妙的用到了这样的表达式

    slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];

    形式即为

    a[startbit+: 8] <= b[startbit +: 8];

    8为长度,等效为

    a[startbit+7: startbit] <= b[startbit+7: startbit]

    这种简略写法可以在以后的编程中参考

  • 相关阅读:
    The Mac Application Environment 不及格的程序员
    Xcode Plugin: Change Code In Running App Without Restart 不及格的程序员
    The property delegate of CALayer cause Crash. 不及格的程序员
    nil localizedTitle in SKProduct 不及格的程序员
    InApp Purchase 不及格的程序员
    Safari Web Content Guide 不及格的程序员
    在Mac OS X Lion 安装 XCode 3.2 不及格的程序员
    illustrate ARC with graphs 不及格的程序员
    Viewing iPhoneOptimized PNGs 不及格的程序员
    What is the dSYM? 不及格的程序员
  • 原文地址:https://www.cnblogs.com/surpassal/p/2721655.html
Copyright © 2011-2022 走看看