Why does iSim give a different result than hardware
The issue was caused by RAMB16WER reading data on the positive edge. My fetch code was changing these signals on the positive edge too. Moving this code to the negative always block fixed it. 

Its odd that it worked up to a certain point on the device, and that it worked fully on iSim, but I guess this is due to the way iSim executes the always blocks.