1
\$\begingroup\$

I'm very new to digital design (my background is software). I'm trying to make use of some block RAM on a Xilinx FPGA, and I want to know what the usual methods are for setting up the RAM control signals w.r.t. the clock.

I currently have a single clock used by all of my design. The RAM can perform a read/write every rising edge, and I want to use it at that rate. Of course, the control signals need to be set some time before the rising edge of the clock. I imagine there are a few ways to do this:

  1. Set the signals on the falling edge of the clock.
  2. Set the signals on the rising edge. The synthesis tool is clever enough to know what I want, knows the required setup time, and takes care of everything.
  3. Set the signals on the rising edge. The synthesis tool isn't clever enough, but I can do funny things with timing constraints to get the signals set up early enough.
  4. Use two clocks slightly out of phase, set the signals on the rising edge of the leading clock.
  5. Some other approaches?

Which of these are possible, which are actually good or usually used, and are there any advantages or disadvantages to help choose between them?

Edit: I'm using plain VHDL for reasons of portability, and not using Xilinx-specific CoreGen or primitives. I'm following Xilinx documenation though, and writing the VHDL in such a way as to let the tools infer the correct RAM type ("RAM HDL Coding Guidelines in UG687 if anyone is interested). The tools seem to be doing this correctly.

\$\endgroup\$
2
\$\begingroup\$

You don't need to use the other edge, or phase shift the clock.

Just set the data up on the rising edge, and then the next rising edge will clock it in to the memory (as per option 2).

Running static timing analysis will tell you of any hold/setup violations. But if you add proper waveform constraints to your clock (i.e. frequency, duty), the fitter will do its best to meet the timing requirements.


This is the fundamental basis of synchronous design. Every register clocks on the same edge at the same time, so theoretically the data from the last cycle at any register input will always be loaded in on the current cycle. This is achieved primarily using low-skew H-tree clock architectures - where the distance from the clock source to any register is pretty much the same length with the same delays - so theoretically every register should clock at the same time.

The data will take a bit longer to arrive (as it has DFF propagation delay and routing delay) before it gets to the next register, meaning that the input of a register will change at some point after the clock edge that set it up (and hopefully before the edge that is supposed to load it).

\$\endgroup\$
0
\$\begingroup\$

You work synchronous always, and rising edge alone. Remember that for writing you can use a single clock, but for reading you need at least two, one for providing address and the second for reading the data

\$\endgroup\$
0
\$\begingroup\$

I'm probably not going to answer the 5 sub questions but I will answer your main question

I want to know what the usual methods are for setting up the RAM control signals w.r.t. the clock

The usual method is the manufacturer has a fairly detailed app note on the timing to their RAM interface. for example a quick google search found this app note for a QDR II SRAM using a virtex-5.

Typically these interfaces are instantiated using a core editor. This editor will tell you what interfaces and options are allowed. This might be optional parameters like block size, number of data bits, etc. Just as important a good app note will tell you the limitations of the core.

It sounds like you want to do this by hand but there are a couple of advantages when instantiating a block.

  1. You are leveraging the knowledge of the chip designers and application engineers at the company

  2. The block will already take care of timing, setup, holds, multiple clocks, etc as long as you stay within its limitations and don't feed it garbage

  3. The block already knows every available type of block in the target silicon and will try its best to keep a small footprint or fast speed (that's sometimes another setting)

I can do funny things with timing constraints to get the signals set up early enough

if you a new digital designer there are lots of issues to messing with timing. Remember the timing/slack/setup/hold tools, etc are there to help you. This may not bite you now but could be a problem if the design changes a little and suddenly your LUT is placed in another slice b/c you changed the timing settings but not placement constraints.

As with most rules these are rules unless you really know what you are doing, then they are guidelines.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.