# Register timing violation due to output enable operation

I have relatively complex device filling almost 100% after compilation. Fitter has to perform relatively hard task to route the signals. Everything works fine, except one state machine. The frequency of issue and impact differs from build to build, and it must be clearly some metastability and badly designed circuitry.

During troublehooting, I found out that circut gets wrong data from the external device (SRAM chip), and there's a pattern: values are somehow close, but there're bits falling out of the value (either erroneously becoming 1 or 0).

I have the following code of the state machine under suspicion:

case 4'h10: begin
data_register[7:0] <= ram_data_bus[7:0]
ram_chip_cs <= 1'b1;
end
...
assign ram_chip_CS_pin = ram_chip_cs;


I expect this circuit, at the state 'h10, latches data from RAM data bus, and at the same time deactivates the chip and changes the address. There must be some data hold time for the chip, thus data must be latched properly.

May it happen that, due to the complex design, clock driving state machine arrives to the registers above with the such slack that ram_data_bus starts changing when data register latches the signals?

I am sure there must be related timing information available generated by the Quartus, but I doubt I will be able to locate it without assitance and guidance.

In overall, is the way I designed the access to external device valid, correct and acceptable? What are your recommendations? Do your recommendation would differ for external devices and inernal FPGA circuits?

As a workaround I will change control signals' modification one clock cycle later (in state 'h11) the data latch and see if situation improves.

Clock operates at about 115 MHz. Device is Cyclone III grade 8. SRAM is CY62158EV30 connected through GPIO.

Update: I decided to abandon the overall circuit, and design new one having helicopter view on its required capabilities and performance. New circuit works now with the same assignments as above at specific states. However the fact that I have workaround for the problem does not eliminate the original question on the best practice.

• Your assign ram_address_bus ... represents a combinatorial mux that adds directly to the external SRAM access time. I would recommend making that assignment directly inside the state machine, making ram_address_bus a register. – Dave Tweed May 28 at 12:30