I'd really need to see a block diagram of what you're proposing. Generally speaking, the existing setup of Caravel assumes that you would extend the function of the processor by putting everything in the memory mapped space of the user project area; if you wanted to implement a systolic array as a peripheral of the SoC, then you would need to copy all data into the array through wishbone bus transfers and read the result back the same way. There is no access back to the SoC memory from the user project, and likely not enough memory there anyway. You could stuff a bunch of SRAM into your user project and let that be an extension of the existing RAM for the SoC. You could also implement a separate SPI flash controller which would then give you access to a large amount of external memory without interfering with the SoC program; you would then have the option of using an external SPI RAM, not necessarily flash. The "best" option in some sense is to use the Openframe chip and implement the entire SoC yourself, including the systolic array, additional memory, and possibly RISC-V instruction extensions specifically for the systolic array operations. But that increases the size and complexity of the project, and it depends on how much time you want to spend doing timing closure.