Zynq7 / Zedboard:Xil_in32 从 DRAM 读取时更改数据
Zynq7 / Zedboard: Xil_in32 alters data when reading from DRAM
我有一个 Zedboard,在 PL (FPGA) 中具有以下设置:
自定义 AXI(完整)主机 -> 互连 -> Zynq_PS(HP0 从端口)
- 自定义AXI主控产生数据(简单计数器,写入DRAM,从0x00000000开始)。
- 数据写入DRAM(根据XMD控制台->mrd 0x00000000 10)
- 当 PS 想要读取数据(main.c -> 调用 "Xil_in32(0x00000000)")时,数据被更改 !!!
问题:
在某些情况下调用函数 Xil_in32(用于从 DRAM 读取数据)是否会改变数据本身? (什么时候,为什么?)
除非调用 Xil_in32,否则数据不会改变。这是通过在从 main.c
调用 Xil_in32 之前从 XMD 控制台读取数据来证明的
C 代码:
#include <stdio.h>
#include "platform.h"
#include <unistd.h>
#include "xparameters.h"
#include "xil_io.h"
#include "xstatus.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "ps7_init.h"
#define PARAM_BASE_ADDRESS 0x00000000
int main()
{
// initialization
init_platform();
//ps7_init();
ps7_post_config();
// variables
u32 offset;
u32 param;
int i = 0;
xil_printf(" PL WRITING & PS READING DRAM MEMORY TEST ");
// loop
while ( 1 ) {
getchar();
offset = 0X00000000;
for (i = 0; i < 50 ; i++){
offset = offset + 4;
param = Xil_In32(PARAM_BASE_ADDRESS + offset);
xil_printf("mem_read %d : %x \n\r",i , param);
}
}
cleanup_platform();
return 0;
}
XMD读取数据:
这显示我停止读取内存的位置,然后计数器继续:
C8: 7252E9D5
CC: D7387D6F
D0: 1E998873
D4: 5DD8305F
D8: C4FEC147
DC: 347EBE2F <------ last memory read by Xil_in32
E0: 0000003F <------ counter
E4: 00000040
E8: 00000041
EC: 00000042
F0: 00000043
F4: 00000044
F8: 00000045
FC: 00000046
100: 00000047
104: 00000048
108: 00000049
10C: 0000004A
解决方案 1)
禁用缓存,通过 运行 cleanup_platform() 或 disable_caches(); (在 platform.c 中定义)解决了更改数据的问题。
问题:
2) 禁用缓存对实际应用意味着什么?一切都直接 taken/written 到 DRAM ?
3) 是否有任何解决方法,以便只有部分内存是 read/written 直接? (当ARM在计算某些东西时,不使用缓存似乎非常低效,因此我想避免它)
解决方案 2)
通过调用 Xil_DCacheFlushRange(PARAM_BASE_ADDRESS, 4*1) 从 DRAM 读取数据之前刷新缓存; (在 xil_cache.c 中定义)
#include <stdio.h>
#include "platform.h"
#include <unistd.h>
#include "xparameters.h"
#include "xil_io.h"
#include "xstatus.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "ps7_init.h"
#include "xil_cache.h"
#define PARAM_BASE_ADDRESS 0x00000000
int main()
{
// initialization
init_platform();
//ps7_init();
ps7_post_config();
// cleanup_platform(); // DISABLING CACHES
// variables
u32 offset;
u32 param;
int i = 0;
xil_printf(" PL WRITING & PS READING DRAM MEMORY TEST ");
// loop
while ( 1 ) {
getchar();
Xil_DCacheFlushRange(PARAM_BASE_ADDRESS, 4*1); // CACHE FLUSHING
offset = 0X00000000;
for (i = 0; i < 50 ; i++){ // LOOP FOR READING DATA
param = Xil_In32(PARAM_BASE_ADDRESS + offset);
xil_printf("mem_read %d : %x \n\r",i , param);
offset = offset + 4;
}
}
cleanup_platform();
return 0;
}
我有一个 Zedboard,在 PL (FPGA) 中具有以下设置:
自定义 AXI(完整)主机 -> 互连 -> Zynq_PS(HP0 从端口)
- 自定义AXI主控产生数据(简单计数器,写入DRAM,从0x00000000开始)。
- 数据写入DRAM(根据XMD控制台->mrd 0x00000000 10)
- 当 PS 想要读取数据(main.c -> 调用 "Xil_in32(0x00000000)")时,数据被更改 !!!
问题: 在某些情况下调用函数 Xil_in32(用于从 DRAM 读取数据)是否会改变数据本身? (什么时候,为什么?)
除非调用 Xil_in32,否则数据不会改变。这是通过在从 main.c
调用 Xil_in32 之前从 XMD 控制台读取数据来证明的C 代码:
#include <stdio.h>
#include "platform.h"
#include <unistd.h>
#include "xparameters.h"
#include "xil_io.h"
#include "xstatus.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "ps7_init.h"
#define PARAM_BASE_ADDRESS 0x00000000
int main()
{
// initialization
init_platform();
//ps7_init();
ps7_post_config();
// variables
u32 offset;
u32 param;
int i = 0;
xil_printf(" PL WRITING & PS READING DRAM MEMORY TEST ");
// loop
while ( 1 ) {
getchar();
offset = 0X00000000;
for (i = 0; i < 50 ; i++){
offset = offset + 4;
param = Xil_In32(PARAM_BASE_ADDRESS + offset);
xil_printf("mem_read %d : %x \n\r",i , param);
}
}
cleanup_platform();
return 0;
}
XMD读取数据: 这显示我停止读取内存的位置,然后计数器继续:
C8: 7252E9D5
CC: D7387D6F
D0: 1E998873
D4: 5DD8305F
D8: C4FEC147
DC: 347EBE2F <------ last memory read by Xil_in32
E0: 0000003F <------ counter
E4: 00000040
E8: 00000041
EC: 00000042
F0: 00000043
F4: 00000044
F8: 00000045
FC: 00000046
100: 00000047
104: 00000048
108: 00000049
10C: 0000004A
解决方案 1)
禁用缓存,通过 运行 cleanup_platform() 或 disable_caches(); (在 platform.c 中定义)解决了更改数据的问题。
问题:
2) 禁用缓存对实际应用意味着什么?一切都直接 taken/written 到 DRAM ?
3) 是否有任何解决方法,以便只有部分内存是 read/written 直接? (当ARM在计算某些东西时,不使用缓存似乎非常低效,因此我想避免它)
解决方案 2)
通过调用 Xil_DCacheFlushRange(PARAM_BASE_ADDRESS, 4*1) 从 DRAM 读取数据之前刷新缓存; (在 xil_cache.c 中定义)
#include <stdio.h>
#include "platform.h"
#include <unistd.h>
#include "xparameters.h"
#include "xil_io.h"
#include "xstatus.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "ps7_init.h"
#include "xil_cache.h"
#define PARAM_BASE_ADDRESS 0x00000000
int main()
{
// initialization
init_platform();
//ps7_init();
ps7_post_config();
// cleanup_platform(); // DISABLING CACHES
// variables
u32 offset;
u32 param;
int i = 0;
xil_printf(" PL WRITING & PS READING DRAM MEMORY TEST ");
// loop
while ( 1 ) {
getchar();
Xil_DCacheFlushRange(PARAM_BASE_ADDRESS, 4*1); // CACHE FLUSHING
offset = 0X00000000;
for (i = 0; i < 50 ; i++){ // LOOP FOR READING DATA
param = Xil_In32(PARAM_BASE_ADDRESS + offset);
xil_printf("mem_read %d : %x \n\r",i , param);
offset = offset + 4;
}
}
cleanup_platform();
return 0;
}