-
Notifications
You must be signed in to change notification settings - Fork 81
Description
I am trying to create a way that my software test can notify the simulator for the Programmable Logic (in my case I use QuestaSim) that it has passed or failed the test.
I notice that the reserved RemotePort in the QEMU-devicetrees are allocated to reserved memory according to the ZYNQ or ZYNQ UltraScale+ TRM.
Zynq devicetree: (https://github.com/Xilinx/qemu-devicetrees/blob/master/zynq-pl-remoteport.dtsi#L146)
/* This area can be used for implentation specific emulation*/ rp_cosim_reserved: rp_cosim_reserved@0{ compatible = "remote-port-memory-master"; remote-ports = <&cosim_rp_0 12>; reg = <0xFE000000 0x100000>; };
Zynq UltraScale devicetree: (https://github.com/Xilinx/qemu-devicetrees/blob/master/zynqmp-pl-remoteport.dtsi#L130)
/* This area can be used for implentation specific emulation*/ rp_cosim_reserved: rp_cosim_reserved@0{ compatible = "remote-port-memory-master"; remote-ports = <&cosim_rp_0 15>; reg = <BASE_ADDR(0xFF4E0000) 0x100000>; };
When trying to write to the reserved memory master (on the Zynq) I notice that my bare metal application(main.c compiled in Vitis 2021.1) stops. And does not continue with the other write transactions. I am wondering if the reserved address are interfering with the RemotePort communication.
I would like to know if this is the correct way to access the reserved memory master for communication with the PL.
The main.c is shown below:
init_platform();
u32 WValue = 0;
u32 RValue = 0;
volatile u32 *Localwriteaddr = (volatile u32*) 0x40000000;
volatile u32 *Localaddr = (volatile u32*) XPAR_GPIO_0_BASEADDR;
volatile u32 *start_gp0 = (volatile u32*) 0x40000000;
volatile u32 *end_gp0 = (volatile u32*) 0x4ffffffc;
volatile u32 *start_gp1 = (volatile u32*) 0x80000000;
volatile u32 *end_gp1 = (volatile u32*) 0x8ffffffc;
volatile u32 *start_gp2 = (volatile u32*) 0xfe000000; //Reserved address space, Address for simulation information
volatile u32 *end_gp2 = (volatile u32*) 0xfe0ffffc;
for(int i = 0; i < 10; i++){
//Count Write value
WValue++;
// Write WValue to localaddr in the PL
*Localaddr = WValue;
// Read localaddr in the PL
RValue = *Localaddr;
if(i < 5){
printf("RValue: %lx\n", RValue);
// xil_printf("RValue: %lx\n", RValue);
}
// Shift the RValue 1 byte
// Write Shifted value to localwriteaddr in PL
*Localwriteaddr = RValue << 4;
// Readback the shifted value
RValue = *Localwriteaddr;
// Increment the localwrite addr
Localwriteaddr = Localwriteaddr + 1;
}
*start_gp0 = 10;
*end_gp0 = 1023;
*start_gp1 = 10;
*end_gp1 = 1023;
//Application hangs after reading or write to the *start_gp2 which are reserved address for the user specific implementation features.
*start_gp0 = *start_gp2;
*start_gp2 = 10;
*end_gp2 = 1023;
*start_gp0 = pow(2,32)-1;
*end_gp0 = pow(2,32)-1;
*start_gp1 = pow(2,32)-1;
*end_gp1 = pow(2,32)-1;
cleanup_platform();