By constraining the dual port block RAMs to bels next to the LVDS pins means that the pixel wrangler meets the HDMI timing requirements!
@th just spitballing, but could it be an asynchronous boundary problem? clock domain crossing that works right in one build will fail in another, just due to randomness in the place and route.
Despite meeting the timing constraints, something is very unstable. Sometimes the decode is perfect, but making minor changes in the Verilog like adding an unused wire results in glitches or even no TMDS sync at all. This makes normal debugging techniques unusable and I feel like I lack the tools to diagnose what’s wrong.