Jump to content
  • 0

Aligning two video sources in Atlys Spartan 6


Hassan Iqbal

Question

Hi,

For a project, I want to align two input HDMI video sources in Atlys Spartan 6. I want to implement an asynchronous FIFO which will synchronize video source B with video source A timings (picture attached). However, the FIFO should be of the size to store atleast 8 MB (frame size of each video source = 1920*1080*32 bits). How to implement this asynchronous FIFO in Atlys Spartan 6? My atlys kit has MIRA P3R1GE4JGF DDR2 IC on it instead of Micron MT47H64M16xx-25E which is in older boards of Atlys Spartan 6. I am using ISE Design Suite 14.2 and running Xapp495. The frame rate that I am working on is 120 FPS and resolution is 1080p. The pixel speed is 146.3616Mhz. If possible, then share some sample code which can be modified to implement this FIFO.

Thanking you in anticipation.

Capture.PNG

Link to comment
Share on other sites

6 answers to this question

Recommended Posts

3 hours ago, jpeyron said:

Hi Hassan,

I have not implemented this type of design. I have reached out to a more experienced engineer about your question. In the mean time, I wanted to make sure you were aware of the resources pages here for the ATYLS and here for the retire VmodCAM.  I also found this from xilinx. 

cheers,

Jon

Thank you @jpeyron. I cannot understand the retire VmodCAM projects as they are in VHDL and I have been learning and using Verilog. I have read other links already. Thanking you again and waiting for the response anxiously. 

Link to comment
Share on other sites

@Hassan Iqbal,

Can I try to answer?

Your solution will have two parts.  The first part will feed the camera image constantly into memory.  When you get the vertical sync to start again at the top of the page, you just reset your write memory pointer.  The second part of your solution will read the image out of memory on your other clock.  This will read out with the synchronization parameters you are trying to achieve.  This way, if you write faster than you read, you'll quietly and slowly drop a frame, and if you read faster than you write, you'll eventually get a full frame stuffed into your stream--but either way things will work.  This approach will use a "nearest-neighbor" interpolator, and will handle over and underruns by frame dropping or stuffing respectively.

The trick you will have is that you only have one interface to memory.  For that reason, both video streams will need to buffer their work into a FIFO.  When the writer's FIFO is roughly half full, then it will need to write to memory until it's FIFO is empty.  Likewise, when the reader's FIFO is half full, it'll want to initiate a read until its FIFO is full.  This way, if both the writer and the reader want to access memory at the same time, they'll both be able to wait until the other completes it's memory access request/requirement.

I haven't checked on your memory timing requirements at all.  That could make things difficult.  If it makes things impossible, then drop color bits and you should be able to get back into the realm of possible again.

As for how to handle the multiple clocks, you will have three clocks you will need to deal with and work from.  Two of these are your pixel clocks.  The third is your memory clock.  You can synchronize from the pixel to the memory clock and back again using the single "FIFO is half-full" wire.

Dan

Link to comment
Share on other sites

@D@n,

Thank you for such a comprehensive answer. Since I am beginner, I have a few queries:

1. You mentioned that there is only one interface to DRAM memory. However, in Xilinx MIG, you can configure the memory to have multiple ports (screenshot attached below). Can't a 32 bit read port be used to read from the memory and a 32 bit write port be used to write to the memory at the SAME time by selecting such configuration?

Image may contain: text

2. A diagrammatic representation of your proposed solution can be:

Image may contain: text

Here, I have to interface internal FIFOs (implemented in block RAM of FPGA) to MCB for reading and writing. Another solution can be to implement logic on top of DRAM (if it can be used as dual port memory?) to make it a large asynchronous FIFO itself as shown in the figure? 

No automatic alt text available.

Can the later solution be implemented to achieve the same task? If yes, then can you mention the pros and cons of the two solutions? Which solution is easier to implement etc. ?

3. Last but not the least, these solutions seem quite trivial for video processing applications in FPGA boards. Still, I am unable to find any tutorial which explains step by step procedure and gives module by module explanation of verilog code to IMPLEMENT them in any Spartan 6 development board. If there is no tutorial available, I want to understand an example (similar) code or ISE project to be able to modify it for my application. Its challenging for a beginner to implement the above solutions starting from scratch. Xilinx manuals for memory interface generator and interfacing MCBs are quite baffling for me. In this regard, can you please share some useful resource(s) which can be studied? 

Thank you.

- Hassan 

Link to comment
Share on other sites

@Hassan Iqbal,

1. There is only one interface to RAM memory.  Sure, the MIG can be used to give you two, but they are only arbitrating between two sources.  There is only one.  (Arbitration's not the hard part of this design--that part is easy.)

Can a 32-bit read port and a 32-bit write port be configured to write to the memory at the same time?  Not if those memory accesses require the same wires between your Spartan FPGA and your memory.  Since there's only one set of wires, there will only ever be one ultimate interface.

Now, about that 32-bit read/write ... DDR2 memory only ever operates on burst lengths of 4 or 8.  On the Atlys, your memory width is 16 bits, so this means memory operations happen on bursts of 64 or 128 bits at any time (16*4 or 16*8).  I know with DDR3 SDRAM (Atlys has DDR2), the burst length of 8 can be continuous, whereas the burst length of 4 requires spacing between pairs of bursts.  My point is, sure, MIG will give you a 32-bit data channel if that's what you want.  MIG will then struggle to convert your 32-bits of data in to a 128-bit request.  It may end up turning this into multiple 128-bit requests, and I doubt your application can afford that.  Set yourself up for 128-bit transfers, and you'll be closer to using the full speed of the device.

2. I like your hand-drawn diagram.  Nice.  Shows you understand my proposal.  Cool.  The block RAM within the FPGA is dual ported.  The DDR2 SDRAM is not.

3. Sorry, I don't work for Digilent.  If I did, I might have access to any or all of their boards on my desktop to try these things, or at least access to someone who has.  My point is, I don't have an Atlys and I've never used a Spartan 6 MIG generated MCB.  Looking over the Spartan 6 MIG users guide, ahm, yeah, that looks pretty ugly, doesn't it?  (I was hoping to offer you some encouragement, say that I had done it before, etc. -- but the interface changed completely between the Spartan 6 and the Artix-7 that I'm used to.)

As for sources of examples you can use in your project, you can use the examples listed for the Atlys system on its resource page.  Personally, I find the memory example a touch wanting there.  You might find a better example in the OpenRISC Atlys example project within orpsoc-cores.  You can also find a variety of video related resources on OpenCores.  In particular, there's a VGA driver on there whose main page looks promising.

Hopefully that'll help get you off the ground.  Remember to always leave yourself a means of accessing your core internals for the purpose of debugging them!

Dan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...