-
Notifications
You must be signed in to change notification settings - Fork 0
microblaze_w25q64_xip调试
minichao9901 edited this page May 9, 2024
·
8 revisions
# qspi_flash, v3_board, d1-6
set_property -dict {PACKAGE_PIN G18 IOSTANDARD LVCMOS33} [get_ports SPI_PL_ss_io]
set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports SPI_PL_sck_io]
set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports SPI_PL_io0_io]
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports SPI_PL_io1_io]
set_property -dict {PACKAGE_PIN H16 IOSTANDARD LVCMOS33} [get_ports SPI_PL_io2_io]
set_property -dict {PACKAGE_PIN N15 IOSTANDARD LVCMOS33} [get_ports SPI_PL_io3_io]
#其余不用的输入/输出可以不分配引脚,并避免报错
set_property IOSTANDARD LVCMOS33 [get_ports *]
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
set_property SEVERITY {Warning} [get_drc_checks RTSTAT-1]
set_property SEVERITY {Warning} [get_drc_checks UCIO-1]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports Clk]
create_clock -period 20.000 -name sys_clk [get_ports Clk]
set_property -dict {PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports rst_n]
/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_io.h"
#include "sleep.h"
u8 arr8[256];
u16 arr16[256];
u32 arr32[256];
#define CDMA_BASE 0x44A20000
#define QSPI_XIP_BASE 0xC1000000
#define BRAM_BASE 0xC0000000
void loop_read_test()
{
memcpy(arr8, (void *)QSPI_XIP_BASE,256);
usleep(100);
memcpy(arr16, (void *)QSPI_XIP_BASE,256*2);
usleep(100);
memcpy(arr32, (void *)QSPI_XIP_BASE,256*4);
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr8[i]);
}
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr16[i]);
}
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr32[i]);
}
}
void loop_read_test2()
{
for(int i=0; i<256; i++){
arr8[i]=*(u8 *)(QSPI_XIP_BASE+i);
}
usleep(100);
for(int i=0; i<256; i++){
arr16[i]=*(u16 *)(QSPI_XIP_BASE+2*i);
}
usleep(100);
for(int i=0; i<256; i++){
arr32[i]=*(u32 *)(QSPI_XIP_BASE+4*i);
}
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr8[i]);
}
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr16[i]);
}
for(int i=0; i<256; i++){
xil_printf("%x\r\n", arr32[i]);
}
}
void wait_for_idle()
{
u32 tmp;
while(1){
tmp=Xil_In32(CDMA_BASE+04);
if(((tmp>>1)&0x1) == 1){
break;
}
}
}
void cdma_read_test()
{
//Xil_Out32(CDMA_BASE+0x00, 0x00000020); //key_hole_wr=1
Xil_Out32(CDMA_BASE+0x18, QSPI_XIP_BASE); //src_addr
Xil_Out32(CDMA_BASE+0x20, (u32)BRAM_BASE); //dest_addr
Xil_Out32(CDMA_BASE+0x28, 512); //burst_length
wait_for_idle();
for(int i=0; i<512; i++){
xil_printf("%d\r\n",Xil_In8(BRAM_BASE+i));
}
}
int main()
{
init_platform();
xil_printf("Hello World\n\r");
//loop_read_test();
loop_read_test2();
//cdma_read_test();
cleanup_platform();
return 0;
}
- 用memcpy读,u8/u16/u32都不ok。应该是读取的速度太快了。
- 用for循环读取,u32 ok, u8/u16不ok。每次读4bytes。
- 用cdma读取ok,任意长度都可以,1个cs完成整个读。
- 用xsct的mrd读取ok,任意长度都可以。实际拆分为1个一个的读,每次读4bytes。
- 因此建议用u32的for循环读,或者cdma读。这种确实适合于实际程序执行的过程。(比如给microblaze做程序存储器,如果mb没有cache,则是按u32一个一个的读;如果mb有cache,如果不命中,则一次读取一行cache,这就相当于是burst-incr读,cache一行的长度一般是64bytes。可见,它这个Qspi IP,几乎就是给mb执行程序所定制的)
这个图是mb的cache配置,可见cache-line长度是可配置,最大16, 也就是64bytes。
可以看到mrd读N个,是把它拆分为1个1个的读,相当于是一个for循环。这种读法是正确的。
可以看到,dma读取任意长度,它是在1个cs里面完成的
打印的值不连续。在接口处的波形,cs拆分为多个,每次读32bytes,但是每次的地址增加只有16。也就是存在重复读取。
这是u8读取
这是u16读取
这是u32读取
可见u8/u16读取,存在重复读取。每次地址只增加1/2,但是读4个。
- for循环读取,结果不正确,主要表现为地址乱发
- memcpy循环读取,结果不正确,主要表现为地址乱发
- cdma读取,结果不正确,主要是读取的数据跳跃。
for循环读取,结果不正确,主要表现为地址乱发
memcpy循环读取,结果不正确,主要表现为地址乱发
接口处波形正确,因为只发了一次地址。qspi-flash的行为是没有问题的。 内部读取数据和print的结果异常,体现会数据跳跃和循环。 内部抓取ILA波形,发现axi_full总线接口处的rdata就是错误的,顺序是乱的。 Flash的axi_full接口,rready一直是1,感觉这个是有问题的。因为读的速度快,flash获取数据的速度慢。