1. A memory controller comprising: a command FIFO (first-in first-out memory) having a plurality of storage locations, wherein the command FIFO is configured to receive, from a scheduler of the memory controller, an identical command into two consecutive storage locations, wherein the command FIFO is further configured to convey commands to a memory, wherein the command FIFO is configured to store commands into two consecutive locations of the FIFO each cycle of the first clock signal and further configured to convey one command to the memory each cycle of a second clock signal, wherein a frequency of the first clock signal is at least one half of a frequency of the second clock signal, wherein writes to the command FIFO are conducted based on a write pointer, and wherein reads of the command FIFO are conducted based on a read pointer, wherein the write pointer is configured to advance at a first rate corresponding to the frequency of the first clock signal, wherein the read pointer is configured to advance at a rate corresponding to the frequency of the second clock signal; a skip unit configured to cause writes to the command FIFO to be periodically inhibited based on a deterministic pattern generated from a ratio of the frequency of the first clock signal to the second clock signal; a data queue coupled to receive data read from the memory; and a register configured to provide a value indicative of a number of cycles of a first clock signal after which data is valid subsequent to a command being written into the command FIFO; wherein, the memory controller is configured to, during a startup routine: convey a read command to the memory; compare data received by the data queue to a known data pattern after a specified number of cycles of the first clock signal have elapsed subsequent to writing the read command to the command FIFO, the specified number indicated by a first value stored in the register; decrement the first value and repeat conveying and comparing if the data received matches the data pattern; attempt one or more additional reads, without decrementing the first value, if the data received does not match the data pattern; and program a second value into the register, the second value being a memory read latency value expressed as a number of cycles of the first clock signal, wherein the second value is based on a lowest number of cycles of the first clock signal at which the data received matches the data pattern.