Moving data between processes in Spartan 3

2019-07-09 13:57发布

I have two processes A and B, each with its own clock input.

The clock frequencies are a little different, and therefore not synchronized.

Process A samples data from an IC, this data needs to be passed to process B, which then needs to write this data to another IC.

My current solution is using some simple handshake signals between process A and B. The memory has been declared as distributed RAM (128Bytes as an array of std_logic_vector(7 downto 0)) inside process A (not block memory).

I'm using a Spartan 3AN from Xilinx and the ISE Webpack.

But is this the right way to do it?

I read somewhere that the Spartan 3 has dual-port block memory supporting two clocks, so would this be more correct?

The reason I'm asking, is because my design behaves unpredictable, and in cases like this I just hate magic. :-)

标签: vhdl xilinx
3条回答
Fickle 薄情
2楼-- · 2019-07-09 14:10

Except for very specific exceptional cases, the only correct way to move data between two independent clock domains is to use an asynchronous FIFO (also more correctly called a multi-rate FIFO).

In almost all FPGAs (including the Xilinx parts you are using), you can use FIFOs created by the vendor -- in Xilinx's case, you do this by generating yourself a FIFO using the CoreGen tool.

You can also construct such a FIFO yourself using a dual-port RAM and appropriate handshaking logic, but like most things, this is not something you ought to go reinvent on your own unless you have a very good reason to do so.

You also might consider whether your design really needs to have multiple clock domains. Sometimes it's absolutely necessary, but that's much, MUCH less often than most people just starting out believe. For instance, even if you need logic that runs at multiple rates, you can often handle this by using a single clock and appropriately generated synchronous clock enables.

查看更多
欢心
3楼-- · 2019-07-09 14:31

The magic you are experiencing is most likely because either you haven't constrained your design correctly in synthesis, or you haven't done your handshaking properly. You have two options:

  1. FIFO

Use a multirate FIFO as stated by wjl, which is a very common solution, works always (when done properly) and is huge in terms of resources. The big plus of this solution is that you don't have to take care about the actual clock domain crossing issues, and you'll get maximum bandwidth between the two domains. Never try to build up an asynchronous FIFO in VHDL because that won't work; even in VHDL there are some things that you simply can't do properly; use the appropriate generators from Xilinx, I think thats CoreGen

  1. Handshaking

Have at least two registers for your data in the two domains and build a complete request/acknowledge handshaking logic, it won't work properly if you don't include those. Make sure that the handshaking logic is properly synchronized by adding at least two registers for the handshaking signals in the receiving domain, because otherwise you will most likely have unpredictable behaviour because of metastability issues.

查看更多
The star\"
4楼-- · 2019-07-09 14:34

For getting a "valid/ack" set of flags across clock domains, you may wish to look at the Flancter and here's an application of it

But in the general case, using a dual-clock FIFO is the order-of-the-day. Writing your own will be an interesting exercise, but validating across all the potential clock timing cases is a nightmare. This is one of the few places I'll instantiate a Coregen block.

查看更多
登录 后发表回答