Tuesday, October 25, 2022

Bizarre clock domain discovered by logic analyzer core - digging deep

 CROSS CLOCK DOMAIN AND RESET SIGNAL DESIGN COMPLICATIONS

My design has multiple clock domains which brings with it the challenge of synchronizing signals going across domains. The board has a 100MHz hardware clock (also 12MHz but I didn't use that) which generates various clocks for the RAM controller and another (50MHz) used for my general logic. The controller gets 100MHz and 200Mhz, then it will generate a ramclk of 25MHz for driving my memory interface logic. Finally, the Serial Peripheral Interface (SPI) link has its own 4MHz clock which runs intermittently. 

We therefore have five active clock domains driving logic, plus two hardware clock domains one of which generates most of the others. Even if two of the domains would be at the same frequency, they are not in phase nor do they have aligned clock edges. 

Any external signal such as the SPI data lines but also all the signals from the 1130 disk drive, should be synchronized as they might otherwise be changing right near a logic clock edge leading to metastable state errors. As such I had a pool of synchronizers to make sure very signal in a particular clock domain changes only at clock edges. 

Too, I needed to reset various state machines and elements in a proper sequence, thus there are reset signals generated in steps - original, a FIFO clearing state, and a reset for the logic running under the ram clocks. In that ballet of startup steps, I had an issue which resulted in my main ram handling state machine stalling. This didn't occur in the regular simulation, but when I did a functional simulation with the post-synthesis design, I was able to dig out the issue previously. The fix was easy even if finding it was not. This was several rounds of testing ago, but interesting to understand the wrinkles involved in this sort of project.

INTEGRATED LOGIC ANALYZERS ASSOCIATE SIGNALS WITH CLOCK DOMAINS

When I select signals to watch with the integrated logic analyzer cores, the Vivado tool chain will determine the clock domain and build an analyzer core for each clock domain which has signals to monitor. I decided to watch the SPIbyteout bus signal which is the eight bits that are sent to the SPI protocol module to shift out to the Arduino. This was the last point outside the SPI module logic and thus I could monitor to see whether I was passing the RAM values properly.

STRANGE ASSOCIATION OF SIGNAL WITH CLOCK DOMAIN

The toolchain built a third logic core for the 100 MHz clock domain. That is only passed into the memory interface module and not involved in any of my logic. There is no way that the bus value I want to monitor should be tied to that clock domain. This suggests some subtle error which is the root cause of my difficulties but it is a very opaque sign. 

The logic that is generating SPIbyteout is clocked by the 50MHz clock domain but also tests an unsynchronized input from the SPI clock domain (SlaveSelect). That is a flaw that I have to correct, altering the logic to remove any reference to SlaveSelect or at least synchronizing it properly. In spite of the issue I see, I cannot imagine how that produces the errant clock domain assignment by Vivado. 

No comments:

Post a Comment