TA的每日心情 | 开心 2021-12-29 14:09 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
|
在ZYNQ中有支持三种AXI总线, 拥有三种AXI接口, 当然用的都是AXI协议。 其中三
种AXI总线分别为:
AXI4: ( For high-performance memory-mapped requirements.) 主要面向高性能
地址映射通信的需求, 是面向地址映射的接口, 允许最大256轮的数据突发传输;
AXI4-Lite: ( For simple, low-throughput memory-mapped communication ) 是
一个轻量级的地址映射单次传输接口, 占用很少的逻辑单元。
AXI4-Stream: ( For high-speed streaming data.) 面向高速流数据传输; 去掉
了地址项, 允许无限制的数据突发传输规模。
在第四期报告中针对第三种AXI4-Stream数据流进行了解析处理,并在PL设置简单接口的FIFO以便于后期具体项目中的使用。
本期通过对AXI4-Lite总线进行解析,并通过一个简单的小例子进行验证。
首先说AXI4总线和AXI4-Lite总线具有相同的组成部分:
( 1) 读地址通道, 包含ARVALID, ARADDR, ARREADY信号;
( 2) 读数据通道, 包含RVALID, RDATA, RREADY, RRESP信号;
( 3) 写地址通道, 包含AWVALID, AWADDR, AWREADY信号;
( 4) 写数据通道, 包含WVALID, WDATA, WSTRB, WREADY信号;
( 5) 写应答通道, 包含BVALID, BRESP, BREADY信号;
( 6) 系统通道, 包含: ACLK, ARESETN信号。
通过vivado软件可建立相应的AXI总线端口程序:
菜单栏->Tools->Creat and Package IP
如图选择最后一项建立一个新的总线接口IP。
选择总线接口形式及寄存器数量,三种总线区别已在上文中进行解释。本次选择AXI4-Lite,下一步。
选择Edit IP,vivado会打开一个新的窗口,如下图所示,可打开程序,每个信号都有官方的注释,可详细阅读,已了解总线的时序。
在此段代码中,可看见4个寄存器,该部分为PS写寄存器,通过PS端对该寄存器进行配置。
- assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
- always @( posedge S_AXI_ACLK )
- begin
- if ( S_AXI_ARESETN == 1'b0 )
- begin
- slv_reg0 <= 0;
- slv_reg1 <= 0;
- slv_reg2 <= 0;
- slv_reg3 <= 0;
- end
- else begin
- if (slv_reg_wren)
- begin
- case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
- 2'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
- 2'h1:
- 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 1
- slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
- end
- 2'h2:
- 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 2
- slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
- end
- 2'h3:
- 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 3
- slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
- end
- default : begin
- slv_reg0 <= slv_reg0;
- slv_reg1 <= slv_reg1;
- slv_reg2 <= slv_reg2;
- slv_reg3 <= slv_reg3;
- end
- endcase
- end
- end
- end
复制代码
在此段代码中,也可看见4个寄存器,该部分为PL写寄存器,通过PS端对该寄存器进行读取。对整体代码进行修改。将读写寄存器进行区分,并引出。
修改完成后将.V文件复制粘贴至原工程文件中,并将其加入到Block Design中,并添加DDS模块。
- <span style="white-space: pre-wrap;">assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;</span>
- <span style="white-space: pre-wrap;"> always @(*)</span>
- <span style="white-space: pre-wrap;"> begin</span>
- <span style="white-space: pre-wrap;"> // Address decoding for reading registers</span>
- <span style="white-space: pre-wrap;"> case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )</span>
- <span style="white-space: pre-wrap;"> 2'h0 : reg_data_out <= slv_reg0;</span>
- <span style="white-space: pre-wrap;"> 2'h1 : reg_data_out <= slv_reg1;</span>
- <span style="white-space: pre-wrap;"> 2'h2 : reg_data_out <= slv_reg2;</span>
- <span style="white-space: pre-wrap;"> 2'h3 : reg_data_out <= slv_reg3;</span>
- <span style="white-space: pre-wrap;"> default : reg_data_out <= 0;</span>
- <span style="white-space: pre-wrap;"> endcase</span>
- <span style="white-space: pre-wrap;"> end</span>
复制代码 在此段代码中,可看见4个寄存器,该部分为PS写寄存器,通过PS端对该寄存器进行配置。
DDS模块参数设置如上图所示,最终将DDS模块相关接口与寄存器0相连接,将其余接口与相应信号连接,最终引出DDS的M_AXIS_DATA端口并对其进行Debug。
并将所有PS输出配置寄存器信号进行引出,并加1赋值给PS读取寄存器。以便PS端调试使用并对其进行Debug。
将PL端程序进行综合实现。最终导出XSA文件(本文最终将提供该文件以便大家下载测试)。
////////////////////*******************幼稚的分割线*****************************////////////
PS端程序
- int main()
- {
- XAxiDma_Config *CfgPtr;
- int Tries = NUMBER_OF_TRANSFERS;
- int Index;
- u8 *TxBufferPtr;
- u8 *RxBufferPtr;
- u8 Value;
- int Status;
- UartPsHelloWorldExample(UART_DEVICE);
- Status = XAxiDma_INT(DMA_DEV_ID);
- Status = XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID);
- XGpio_DiscreteWrite(&Gpio, fifo_en, 0);
- XGpio_DiscreteWrite(&Gpio, fifo_en, 1);
- TxBufferPtr = (u8 *)TX_BUFFER_BASE ;
- RxBufferPtr = (u8 *)RX_BUFFER_BASE ;
- u32 data = 0;
- u32 reg = 0;
- while (1){
- XUartPs_Recv(&Uart_Ps,RxBufferPtr,8);
- XUartPs_Send(&Uart_Ps,TxBufferPtr,8);
- sleep(1);
- memcpy(®,RxBufferPtr+4,4);
- memcpy(&data,RxBufferPtr,4);
- switch(reg){
- case 1: out_slv_reg(out_slv_reg0,data);
- }
- // data = in_slv_reg(in_slv_reg0 ); //
- }
- return XST_SUCCESS;
- }
- int UartPsHelloWorldExample(u16 DeviceId)
- {
- int Status;
- XUartPs_Config *Config;
- Config = XUartPs_LookupConfig(DeviceId);
- Status = XUartPs_CfgInitialize(&Uart_Ps, Config, Config->BaseAddress);
- XUartPs_SetBaudRate(&Uart_Ps, 115200);
- }
复制代码
PS端调用串口,通过对串口数据进行读取并将其值进行处理创送至寄存器0,(预留寄存器读取程序供测试)供PS配置PL端DDS。完成不同频率正弦波的输出。PS端程序通过case可对不同寄存器进行配置。通过串口对寄存器进行配置,可通过debug观察DDS输出信号频率会发生变化。
但由于串口数据大小端装换问题,本文并未对其进行处理,在串口配置时应注意。
desk.zip
(1.72 MB, 下载次数: 1, 售价: 1 与非币)
|
|