I'm basing my answer completely on the code and documentation of the dvi_decoder module, and assuming it actually works as advertised. This file seems to be a (modified?) copy of the IP in the app notes Video Connectivity Using TMDS I/O in
Spartan-3A FPGAs and/or Implementing a TMDS Video Interface in the
Spartan-6 FPGA. These app notes are chock-full of important details, and I suggest you read them carefully.
As you indicated in the question, I will assume you are treating unencrypted streams, that is non-HDCP streams. I'm fairly certain that the information in the NeTV project can be adapted to decrypt HDCP, but it would involve a non-trivial amount of additional work and be on questionable legal grounds depending om your jurisdiction.
It looks like you will be able to obtain the data you need from the outputs of the dvi_decoder block. The block outputs 24-bit color information using the wires red
, green
and blue
, synced to the pixel clock pclk
. The outputs hsync
and vsync
alert the user to the end of a line/screen respectively. In general, you should be able to do on the fly averaging using these outputs.
You will need some basic logic to translate hsync
, vsync
and the pixel clock into an (X,Y) location. Just instantiate two counters, one for X
and one for Y
. Increment X
at every pixel clock. Reset X
to zero at hsync
. Increment Y
at every hsync
. Reset Y
to zero at every vsync
.
Using red
, green
, blue
, X
and Y
, you can do on the fly averaging. By comparing with X
and Y
, you can determine what box each individual pixel should contribute to, if any. Sum the color values into an accumulation register. To obtain the average value, you need to divide the value in the register by the number of pixels. If you are smart, you will make sure the number of pixels is a power of two. Then you can just wire the MSBs of the register to whatever you want to drive.
Because we want to drive displays while doing the accumulation, we will need to do double buffering. So we will need two registers per box per component. If you are using a 25-led string, this means you will need 25*3*2=150 registers. That's quite a bit, so you might want to use block ram instead of registers. It all depends on your exact requirements, experiment!
I assume you will be driving a led string like the one used in the original adafruit project kit. You should be able to figure out how to drive it from the values in the registers quite easily using SPI.
The dvi_decoder module is a fairly complex piece of kit. I suggest you study the app notes in detail.
As an aside, if you have not yet purchased an NeTV for use in this project, I recommend you also have a look at Digilent's Atlys board. With two HDMI inputs and two HDMI outputs, it appears to be tailor made for projects of this kind.
I'll add a bit to Brian Carlton's answer.
Within an FPGA, it's correct; gated clocks are not at all recommended. And the flip-flops will have a separate ENable input so that it's not necessary.
In your case, though, because your gated clock only goes to the output pin and isn't used internally to the FPGA, you can gate your clock without penalty. The way to do it is to make sure the clock gating is done in the output block. Assuming you're using Xilinx, instead of instantiating an OBUF
for your clock output, use an OBUFT
, and you'll get access to the tristate pin of the output buffer. If you're using another vendor's FPGAs there will be an equally easy way to do this.
If you prefer to do this using inference rather than instantiation, you'll need to be sure to enable an option during compiling to push logic into IO blocks. If the gated clock does actually fan-out (but you didn't show it in your diagram), you'll also need to enable an option that allows duplicate logic to be generated.
Best Answer
What you have to do is package sub modules as IP. Then you can use the IP as sub modules in a bigger design. The problem is that you can only package a whole block diagram. What you have to do is create a new block diagram, insert the blocks making a sub-module, package it as an IP and then add it to the main design. Repeat for all sub modules.
Created IPs can be used several times in another block diagram.
This Explains the process in detail.