Replies: 3 comments 4 replies
-
Further investigation has isolated the problem to this line:
I can store the value to another register and simultaneously update the ram_address on the same clock, but setting the ram_address from the incoming data becomes unstable once the rest of the design is more complex. |
Beta Was this translation helpful? Give feedback.
-
I'm continuing to explore this issue. The static RAM chip is more than capable of continuous reads Even without using the value in one read to control the address in the next, if the address selection logic is moderately complex, then reading a value and updating the address on the same clock cycle can cause metastability depending on how Yosys synthesises the logic.
This appears to be independent of clock speed. Depending on the tool's mood, the resulting binary can be either rock solid or consistently unstable. The problem is all of the solutions I can think of involve halving the RAM bandwidth (e.g. set up address on one clock, read value on the next) - with 50% of the time just spent idling. Is there a reliable way to ensure the sequence (and avoid any unwanted optimisation) of read-value -> update-address that doesn't involve clock domain crossing, or unnecessarily long idle cycles? A rough illustration of the timing (times in nanoseconds): |
Beta Was this translation helpful? Give feedback.
-
Are you using IO registers for this? If not the placement and routing will throw everything off. |
Beta Was this translation helpful? Give feedback.
-
I'm interfacing an external SRAM to a Lattice part, and coming up against a timing issue that makes the design unstable. Frustratingly, the simple cases work fine, with problems emerging as the overall design gets larger.
Essentially, I'm doing a continuous lookup, where the results of the previous read are used to set the address of the next read. Something a bit like this (other cases and additional computation removed).
Output enable, chip select and so on are all held continuously active (low).
This works just fine... some of the time (and of course, always in simulation). Then small changes elsewhere in the project knock everything out of whack. The overall clock rate is well within the limits of the SRAM.
My assumption (hard to verify) is that setting the ram_address with it's own data is the root of the problem, since the
other_value
read in phase_two appears stable, and both phases do the same simultaneous set address and read data functions. When the project is reduced to bare bones, this all works, but it becomes unstable as other functionality is added.Any suggestions for checking/debugging/diagnosing the issue? I really want to avoid breaking this out into multiple steps as it dramatically reduces the available bandwidth..
The ram interface is declared as a module that takes the ram_address and control signals and mediates the bidirectional bus to the physical device (somewhat simplified):
In general, how are people getting help for larger projects, when it moves beyond the 'casual hacking' phase? Since this runs on custom hardware, it's not really something that can be usefully explored by other developers on a whim, so it might be helpful to find advisors who can perhaps handle a slightly more formal arrangement..
Beta Was this translation helpful? Give feedback.
All reactions