How To Allocate PL DDR4 on RFSoC4x2 in PYNQ 3.0.1

Thanks for your response @njachimi. I’m a little confused about a two things. First:

The RFSoC4x2 PS and PL DDR4 memory are both 8GB and same components.

They are both 4GB per the product page. Do you mean together the PS and PL DDR4 make up one 8 GB memory? I think in your MTS project the DDR4 range should be 4G not 8G and instead of reg = <0x10 0x00 0x02 0x00>; in your .dts it should be reg = <0x10 0x00 0x01 0x00>;. With your project, I am able to erroneously allocate 8 GB of PL DDR4. If I do two separate 4 GB buffers, they are the same as in if I write to one buffer, the changes are reflected in the other. Maybe there is a reason for this I’m not seeing.

The second thing is that in my project with a different DDR4 base address I have not been able to allocate the memory on the 4x2.

Details:
In my project the PL DDR4 is at 0x500000000 and so the register specification for the reserved memory node should read <0x05 0x00 0x01 0x00>. I recompiled the .dtbo with this new specification and added it to the device tree using the insert_dtbo.py. I appened python3 /usr/local/share/pynq-venv/pynq-dts/insert_dtbo.py to the pynq_venv.sh startup script which worked for me on the ZCU111. I think what I did should have worked but allocate is returning this error.

buff1 = pynq.allocate(int(1.5*1024**3), dtype=np.uint8, target=ol.capture.ddr4_0)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [3], in <cell line: 1>()
----> 1 buff1 = pynq.allocate(int(1.5*1024**3),'u8',ol.capture.ddr4_0)

File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynq/buffer.py:158, in allocate(shape, dtype, target, **kwargs)
    156 if target is None:
    157     target = Device.active_device
--> 158 return target.allocate(shape, dtype, **kwargs)

File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynq/pl_server/xrt_device.py:156, in XrtMemory.allocate(self, shape, dtype, **kwargs)
    145 def allocate(self, shape, dtype, **kwargs):
    146     """Create a new  buffer in the memory bank
    147 
    148     Parameters
   (...)
    154 
    155     """
--> 156     buf = _xrt_allocate(shape, dtype, self.device, self.idx, **kwargs)
    157     buf.memory = self
    158     return buf

File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynq/pl_server/xrt_device.py:104, in _xrt_allocate(shape, dtype, device, memidx, cacheable, pointer, cache)
    102     bo, buf, device_address = pointer
    103 else:
--> 104     bo = device.allocate_bo(size, memidx, cacheable)
    105     buf = device.map_bo(bo)
    106     device_address = device.get_device_address(bo)

File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynq/pl_server/xrt_device.py:410, in XrtDevice.allocate_bo(self, size, idx, cacheable)
    408 bo = xrt.xclAllocBO(self.handle, size, xrt.xclBOKind.XCL_BO_DEVICE_RAM, idx)
    409 if bo >= 0x80000000:
--> 410     raise RuntimeError("Allocate failed: " + str(bo))
    411 return bo

RuntimeError: Allocate failed: 4294967295

I checked the device tree using dtc -I fs /sys/firmware/devicetree/base and sure enough I see my memory node in there:

reserved-memory {
		ranges;

		reserved {
			reg = <0x05 0x00 0x01 0x00>;
		};
	};

The address returned in the allocate error message is 0xffffffff . I’m not totally sure what to make of that. Please let me know if you spot any issues with my approach.

P.S.
I did try to just change my DDR4 base address to 0x1000000000 to match yours but the address editor was giving me errors related to “memory aperture”. I think it’s not compatible with the rest of the IP I have in my design on the same network?

1 Like