问题:在PS端使用AXI_GP口向PL侧写数据时,如何控制AXi 32bit的数据的哪一个字节有效?
- 在PS侧通过单字节发送方式进行数据的发送即可;
如要使得32bit数据的第3个字节有效只需
Xil_out8(0x43C10000 + 0x02,value)
即可(起始地址0x43C10000);此时在PL侧,对应的WSTRB = 4'b0100
,这样就可以通过使用WSTAB信号对逻辑进行控制了。
- 单字节(
Xil_Out8(addr+offset,value)
)发送偏移地址为1,4字节(Xil_Out32(addr+offset,value)
)发送偏移地址为4。 - AXI总线中使用了一个非常有趣的机制及strb信号,它的位数是[总线位宽]/8,即总线上的字节数。采用这个信号很可能是因为很多时候存储器的位宽远多于8位,而AXI总线是一个字节对齐的总线。例如,若一个32位的总线对接一个32位的存储器,存储器地址递增1实际上对应于字节地址递增4。所以AXI总线的做法是忽略AXI总线地址的低2位再接入存储器,转而使用这4位的strb信号来定义读取或修改这32位(4字节)里的哪一个字节,strb为1的时候才对该字节进行操作。这个思路在以下xilinx官方代码段里得到体现:ZYNQ开发进化史——AXI总线的使用
......
// Example-specific design signals
// local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
// ADDR_LSB is used for addressing 32/64 bit registers/memories
// ADDR_LSB = 2 for 32 bits (n downto 2)
// ADDR_LSB = 3 for 64 bits (n downto 3)
localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
localparam integer OPT_MEM_ADDR_BITS = 3;
......
case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
4'h0:
for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
// Respective byte enables are asserted as per write strobes
// Slave register 0
slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
end
......