The main reason that frequency-domain processing isn't done directly is the latency involved. In order to do, say, an FFT on a signal, you have to first record the entire time-domain signal, beginning to end, before you can convert it to frequency domain. Then you can do your processing, convert it back to time domain and play the result. Even if the two conversions and the signal processing in the middle are effectively instantaneous, you don't get the first result sample until the last input sample has been recorded. But you can get "ideal" frequency-domain results if you're willing to put up with this. For example, a 3-minute song recorded at 44100 samples/second would require you to do 8 million point transforms, but that's not a big deal on a modern CPU.
You might be tempted to break the time-domain signal into smaller, fixed-size blocks of data and process them individually, reducing the latency to the length of a block. However, this doesn't work because of "edge effects" — the samples at either end of a given block won't line up properly with the corresponding samples of the adjacent blocks, creating objectionable artifacts in the results.
This happens because of assumptions that are implicit in the process that converts between time domain and frequency domain (and vice-versa). For example, the FFT and IFFT "assume" that the data is cyclic; in other words, that blocks of identical time-domain data come before and after the block being processed. Since this is in general not true, you get the artifacts.
Time-domain processing may have its issues, but the fact that you can control the latency and it doesn't produce periodic artifacts make it a clear winner in most real-time signal-processing applications.
(This is an expanded version of my previous answer.)
The USB port can be used to communicate with a design running on the FPGA, as well as for programming it. The Digilent Adept software can be used to interact with a design which implements this protocol; it's also possible to use the Digilent libraries to write your own software which uses this protocol. (I've also written a Perl module, Device::Digilent
, if you'd prefer that to C.)
Information on the protocol is available at:
https://www.digilentinc.com/Data/Products/ADEPT/DpimRef%20programmers%20manual.pdf
In short, though: there is a parallel bus between the USB interface chip and FPGA consisting of:
- An 8-bit bidirectional bus, used for both addresses and data.
- Address and data strobes, and a write flag, all signalled from the host
- A "wait" signal used by the FPGA to indicate when it has serviced a read/write
The protocol used treats the FPGA as having 256 byte-wide "registers", each of which can be read or written by the host at any time. The order of events for a read is:
- Host asserts the address strobe with the write flag on, and drives the data bus with the index of the register it will be writing.
- Host asserts the data strobe with the write flag off, and the FPGA drives the data bus with the value of the register.
A write works similarly, except the second transfer has the write flag on, and the host drives the data bus with the value to be written.
Best Answer
Any electromagnetic signal is real-valued, and hardware filters thus have real inputs and outputs, so their transfer function must be real-valued as well.
In principle it would be possible to build a complex-valued hardware filter, by creating two filters and using one of the outputs as I and the other as Q signal, however this is useful only with a complex input, requiring you to build four filters (I->I, I->Q, Q->I, Q->Q), one adder (for the Q outputs) and one subtractor (for the I outputs), which is difficult to do in hardware.
Thus, you can see complex-valued filters in digital signal processing mostly.
Complex filters are useful if you need an asymmetric frequency response.
In digital communication, many transceivers are built using the direct conversion paradigm for cost reasons, which leaves the (complex-valued) signal centered around 0 Hz.
Filtering that signal does not require an asymmetric transfer function, so the complex signal is passed through a real-valued filter, using two separate filters with the same transfer function.
There are a few use cases for complex-valued filters on complex-valued signals, but these are usually few and far between, so you stumble over them seldom.