Hi Brad,
There is a FIFO overflow, I think. Let me explain wht I think I see:
When valid frame data is available (vframe_2 = '1'), you start saving data
on the rising edge of the line indicator (vline1 = '1' AND vline_2 = '0').
Once the second line starts, you start reading out the FIFO. If a frame has
H lines, you will have stored H lines, but only read out (H - 1)!
[ASCII graph, use fixed font]
______________________ ______________________
FRAME ___/ \___/ \___
__ __ __ __ __ __
LINE ______/ \___/ \___/ \_________/ \___/ \___/ \______
___________________ ___________________
WRITE ______/ \______/ \___
____________ ____________
READ _____________/ \_____________/ \___
The fix is to start reading out the FIFO at the same time as you start
writing it, except for the very first line that you store (because you have
to fill the FIFO with 1 line of data). You can use the same starting
condition, except that you have to check the FIFO for not being empty before
launching the reads. There are 2 possibilities to do this:
1) check the FIFO's empty flag
2) have a register that is reset along with the other registers and only set
by the write enable (less resources if the FIFO hasn't the empty flag by
default).
My next comment is on the robustness of your design: what happens when you
switch on the video source or when you reset your design while the source is
running? There is no reason you will start saving the data from the first
line in a frame: if you see the 3th line pulse in a frame first after reset,
the you will currently start storing there. The solution is to have an
additional enable register that is reset like the others and is set when
frame is low: as such, no line will be stored before you have seen frame
going low.
Combining my remarks should give you the following waves:
[ASCII graph, use fixed font]
___
RESET
\_________________________________________________ ____________________
_______________ ______________________ ______________________
FRAME \___/ \___/
\___
__ __ __ __ __ __ __ __
LINE __/ \___/ \_________/ \___/ \___/ \_________/ \___/ \___/
\______
__________________________________________________ ______
FRMen+ ________________/
___________________ ___________________
WRITE ______________________/ \______/
\___
_________________________________________________
nEMPT+ _______________________/
____________ ___________________
READ _____________________________/ \______/
\___
Summarised:
WRITE start at the first line of a frame
READ start at the first line of a frame that the FIFO is not empty
If you're still up to some comments: the delay of the signal driving the mux
of vin_3 and the "10101010" constant puzzles me: assuming 1 cycle delay
between fiforden and the data coming out of the FIFO, then vin_3 and
fifodout are nicely aligned. But you add 2 more delays in process v5 by
using video_bits_2. Is this what you need (you're shifting the decision 2
pixels)?
Likewise, when you're checking for the treshold of the lines (current - 2)
and (current - 3), did you consider the wrapping from the bottom line to top
line in the next frame?
Some very last suggestion: do you check the timing of your asynchronous
reset? Without a flipflop clocking this signal, you will have no control
over it and you risk all kind of trouble (meta-stability when violating
setup/recovery timing of the resetable flipflops, flipflops coming out of
reset in a different clock cycle). In an
FPGA, it's safer to use a
synchronous reset and it won't cost you any more resources (see the
FPGA
registers).
Kind regards,
Alvin.