Well, since you think it responds correctly with linear data... Maybe you are forgetting about the delay between putting in the read address and the data appearing on DOUT? By way of test you could do 4 chunks of 4. So 0-3, 4-7, 8-12 , 13-15 and randomly shuffle those 4 chunks, put them in your .coe. And then see if you recognize the pattern. Or just do a proper testbench, but the 4x4 random shuffle is something you can do real quick with what you have right now. My guess would be that you're forgetting about the delay between asserting address and the data appearing at the output.