1 (edited by WoS 2013-11-09 20:10:40)

Topic: "Replay_VideoConverter" added to support library

This is a follow-up of the discussion about converting core video formats to common HDMI/DVI/VGA/Composite/SVIDEO compatible formats found here: http://www.fpgaarcade.com/punbb/viewtopic.php?pid=269

The result is a generic approach which could be used for any core. After making it "more general" to use and also after some more testing (using quite some cores already) I moved the module to the replay_lib tree.

Here a rough overview of the block:

===== runs on sysclk======                                       ======runs on vidclk===========

Arcade video sync -> H/V counter    --(frame retrigger)-->  Replay video generator H/V counter & sync
                          |                                                    |
                       aligment                                                |
                          |                      ,---------------- aligment ---|
                          V                     V                              |
Arcade video rgb   --> ######(few) linebuffers######  ---> video rgb --> Replay video interface  
                    (sync. write)     (async. read)                            |
                                                                               V
                                                                    DVI-A/VGA  &  DVI-D/HDMI

The module interface is very simple:

INPUT VIDEO/CLOCK:
- the first clock domain clk_sys as used by the (arcade) core generating the video input to this block
- the video input containing the usual RGB lines, hsync, vsync and blanking from the core

OUTPUT VIDEO/CLOCK:
- the second clock domain clk_vid as used by the Replay video interface
- the video output using the RGB lines and 3 structured signals Sync, Timing and Std

GENERICS:
Some are obvious, though (like the bit width of the RGB input signals etc. ).

    g_Vid_Param     : r_Vidparam_int := c_Vidparam_720x480p_60;

Output format the (embedded) video generator will use - can be found in Replay_VideoTiming_Pack.vhd.

    g_R_Bitwidth    : integer := 3;  -- color bitwidths
    g_G_Bitwidth    : integer := 3;  -- color bitwidths
    g_B_Bitwidth    : integer := 2;  -- color bitwidths

Bitwidth of the r/g/b input channels - will be properly scaled to the output format.

    g_Vsize         : integer := 208;-- visible vertical frame size
    g_Hsize         : integer := 512;-- visible horizontal frame size

Size of the picture to show on the output in case it should be cut somehow. The actual input size is generated out of the blanking and sync signals from the input video.

    g_Match_Line    : integer := 0;  -- input line used for frame sync

Input line at which the frame-sync of the video generator is set to synchronize input to output. Depends if the input lines are shorter than the output lines, the frame is synced on the top lines, if the input lines are longer than the output lines, the input needs to be buffered up first and the frames need to be aligned on the bottom lines of the video frames. With this parameter the aligment can be achieved.

    g_Vadr_Width    : integer := 3;  -- buffer vertical address width
    g_Hadr_Width    : integer := 9;  -- buffer horizontal address width

These defines the video buffers. In this example 2^9=512 pixel by 2^3 =8 lines max. buffer size. Synthesis will then be able to select FF for small amounts of will infer a RAMB if it grows larger.

    g_Hres_half     : integer := 0;  -- half output pixels horizontally (=double-pixel)
    g_Vres_half     : integer := 1;  -- half output lines vertically (=double-scan)

This sets either directly the pixel counters of the video generator or half the counter value for the output generation. This allows to define single/double pixels and single/double lines on the output for each input pixel.

    g_Voffset       : integer := 18; -- vertical buffer offset on output
    g_Hoffset       : integer := 104 -- horizontal buffer offset on output

Sets the starting point where the video buffer is positioned on the output video signal.
So the first output pixel starts where hpix counter of the output minus this hoffset is zero and the lines starts where vpix counter of the output minus this voffset is zero.

    g_Loffset       : integer := 2;  -- buffer line offset on output

When reading the video buffer at the output a offset correction is needed to align the first line written in the video buffer to the first line read from the buffer. It could be for sure calculated somehow in the code, but I found it easier to start a simulation and check where it actually starts to readout and set the required difference to this parameter.  wink

/WoS

Re: "Replay_VideoConverter" added to support library

Neat idea. Presuming I understand it:-)

From checking it out and reading the code I think this is a:
i) Scandoubler (vertical count bits shifted by 1)
ii) Stores a few lines data in dual port ram, so it can output them at an industry standard dot clock. Depending on the different line lengths may need a larger vertical line buffer (default 8 lines).
iii) Uses vertical frame rate from input core.
iv) Chops off borders.

I'm new to crossing clock domains - but shouldn't the vsync transfer have a chain of 2-3 flip flops in case of metastability?

When extending colour bits from 3 bits to 8 bits. Why is it better to do:
R1R2R3 -> R1R2R3r1r2r3r1r2
than;
R1R2R3 -> R1R2R300000
?

I guess the input vertical count shift vs output vertical count shift could be in the generics too?    So we can normalize the dot clock on modes that do not need scan doubling.

One day would be fun to have HQ2X or similar in the output stage:)

Is HDMI resilient to a few extra scan lines? e.g. I think my Atari core is currently about 50.4Hz rather than 50Hz so with standard hsync timing it will have a few extra lines.

3 (edited by WoS 2013-09-19 17:46:42)

Re: "Replay_VideoConverter" added to support library

Credit goes to Mike, was his idea smile

You understood quite right, it converts any video frame to a given std. frame. But it requires a pixel clock adoption - see below. Everything else destroys the frame integrity (does not work, tried a lot) or requires a full frame buffer (using the external DRAM).

Yes, the clock transition is done with 3 FF before doing the edge detection  and frame reset of the vid timing.

My actual solution gives the best gain scaling with min. HW effort, your proposal won't generate full colour. Eg. white will result in gray, as the LSBs are never set.

You are right, actually I have the frame reset fixed to vsync-in, this should be done based on vcnt from the input counter. I am working on that (incl. proper CLK transition again)...

You wont add scanlines, but adopt the pixelclock to get the required frame frequency (eg. 27*f_arcade/f_vidstd MHz) as they need to fit. For Phoenix it is also about 61Hz, but the h/v pixel counts on the output are still fully conform (also OSD will directly work) - thus I set the vclk from 27 to 27.5 MHz (approx. - I did of course an acc. calculation on that...).

/WoS

Re: "Replay_VideoConverter" added to support library

Checked in an updated version, now also allows to set the synchronisation timepoint of the frames (at which line of the input frame to start with the output frame). Furthermore it can do single/double-scanline and single/double-pixel scaling.

Tested with my Phoenix and Galaga setup. In the Galaga doc directory, I added an excel file which helps to define the settings for the video converter block for this game as example. Need to improve documentation of it, I am aware it is not easy to read yet wink

/WoS

Re: "Replay_VideoConverter" added to support library

scanlines FTW!

Re: "Replay_VideoConverter" added to support library

Had quite some discussions with Arnim and Mike about the re-synchronisation of the video frames from the core to the video generator.

Now it should be more stable against clock jitter as this was a possible cause for loss of sync for some monitors as Mike assumed. Now the video generator is only reset if the core video and the generator video is off more than a few pixel clock cycles. So now either it syncs (if it well supported by the monitor) or it is simply not syncs and the monitor stays black.
At least as long as the PLL settings are correctly configured in the INI file...

I recompiled galaga, phoenix (720x480p60 mode) and vic-20 (720x576p50 mode) with this fixed converter and checked everything in again.

/WoS

Re: "Replay_VideoConverter" added to support library

spotUP wrote:

scanlines FTW!

Year, can do - as soon as the basic things work well.  wink

/WoS

Re: "Replay_VideoConverter" added to support library

Nice reading, i will get to the little assignment you gave me now!

9 (edited by spotUP 2013-11-17 17:49:47)

Re: "Replay_VideoConverter" added to support library

Wolfgang i did the tests and reported back to you via mail.

10

Re: "Replay_VideoConverter" added to support library

Added improved H scaler for odd display ratios of cores. Now the VIC-20 fills the (4:3) screen properly.

Could do something similar for V as well - for now I have no core to test it, so I keep it on the "todo" list for now...

/WoS

Re: "Replay_VideoConverter" added to support library

Wolfgang, did you ever change the video buffering so that we can rotate the display 90 degrees?

Re: "Replay_VideoConverter" added to support library

no, that requires DRAM support. I have a frame buffer running with some of the arcade games, but still work in progress.
/MikeJ

Re: "Replay_VideoConverter" added to support library

OK, thanks... I need to get a 2nd monitor that is flipped on its side.  smile

14

Re: "Replay_VideoConverter" added to support library

The Arcade stuff got a little out of my view lately. I didn't even adopt my cores for quite some time, so I don't know if they even build or run with the latest setup.

But as I have now a good feeling using the dram setup on the Replay, it should be no problem for me to use it as dedicated framebuffer to implement such a 90 degree turn.  At least many of the upright games should have enough memory with the RAM blocks on FPGA, this might be a simple solution for now, it's on my todo list. smile

/WoS

Re: "Replay_VideoConverter" added to support library

wolfgang wrote:

it should be no problem for me to use it as dedicated framebuffer to implement such a 90 degree turn.

If anyone goes down that road he should please also consider 270 degree rotation. You'll find both angles on the old arcade boards.

Re: "Replay_VideoConverter" added to support library

With a 1 frame lag, via framebuffer, to get a a rotated image - isn't mame/mess far better suited to the task?

17 (edited by tcdev 2014-02-22 02:42:39)

Re: "Replay_VideoConverter" added to support library

If you're going to implement a frame buffer, why not go full-featured with a triple buffer so you can do frame rate conversion (eg. 50-60Hz)?

Also, I know this is not suited to the general case, but it's possible to rotate, for example, monochrome bitmap displays (eg. Space Invaders) on-the-fly. I've been meaning to experiment with other simple tilemap/sprite displays as well... one trick is to use dual-port on the graphics ROMs to pull out pixel bits in parallel that were never meant to be on the same scanline. But again, no good for the general case you guys are talking about.

EDIT: When I first started doing arcade ports, I'd simply pre-convert all the graphics ROMs for a rotated view. Then every game would play on a horizontal VGA monitor. These days I tend to avoid that though...

18

Re: "Replay_VideoConverter" added to support library

Yes, I had a talk with Mike about that. The Replay has plenty of memory and bandwidth to do that. A good implementation should work very generic, that one can use it for all kind of cores also to do a proper format conversion to regular HDMI/DVI formats and 50/60Hz conversion, not only screen rotation itself.

Currently we are still busy with fixing some stuff here and there (especially e.g. common floppy support for Amiga & VIC).

/WoS

Re: "Replay_VideoConverter" added to support library

I'm using the video converter now.

Great idea. A couple of comments from using it:
i) If i feed in my real blank (h or v blank) signal this can vary in height depending on the Atari display list length. Since the video converter just stops storing on blank it ends up repeating the previous lines for the visible area.
ii) My composite output does not have sync on it when I select 'SD' - surprised since I thought the video converter guaranteed a standard mode. Is there more I need to do to activate this?
iii) I get the last vertical line of the picture on the right displayed on the left. This is fine if its black, but if not its a problem...
iv) I like the Android app for choosing the pll speeds. If an Android phone is not handy it can be run on virtualbox/genymotion. Its not entirely clear to me how to choose the 'best' from the resulting list. I just close a close match to the clock I suggested with relatively small dividers, but its a display of about 50 things in 3 lines so its tricky;-)
v) I'd like to allow selection of PAL/NTSC. Ideally the clock should be changed slightly, but the vid converter will also need adjustments. What is the best way of achieving this? I guess the video converter could have 4 modes with 2 bits to select, but in addition it may need e.g. a different offset. I guess I should just have two video converters and select the outputs with a mux?
vi) (Not really video converter, but related). I see some colour overlaps on the output on colour changes. Is this adjustable via a filter or a 'real' hardware issue?

Re: "Replay_VideoConverter" added to support library

Regarding point vi, you can enable/disable a luma trap on the coder from the ARM.
There are 5 settings for the coder, off, pal / ntsc both with/without trap.
/MikeJ

21

Re: "Replay_VideoConverter" added to support library

Thanks for yor comments, they are very valuable.
Yes, there is still room for improvement big_smile

About the other 5 items:
i) yes, for now the last output value stays if the output picture reaches the defined generics for h/v-size (shifted by h/v-offset)
   should we better go to a default output value? E.g. defined by a generic?
ii) do you set the proper PAL/NTSC settings for the coder as Mike mentions?
iii) interesting, seems to be a problem with the address generation, it seems the g_hoffset calculation overflows
    As soon as I have a silent minute, I can take a look at the setup.
iv) was just a quick hack. I think it took me an hour or so to set up the app, just put all input/output fields one after the other. I had some thoughts to sort the output for closest match at lowest frequencies upwards, but as it is usually only required once for a complete core, I didn't spent further efforts to it. Maybe there are some App exerts out there making it more useful and more pretty?
v) sthat's not so easy to do with the actual generic menu system. The menu as defined in the INI for now modifies configuration bits to the FPGA, but can't modify the coder settings (no way to specify it). Maybe the best is to have a specific PAL/NTSC menu item to insert in the INI to define a bit mask for the FPGA config bits and modifying the coder in parallel. I'll have some thoughts about that...

For changing the replay_lib code by any of us, I have a proposal:

If you have some good ideas for an improved converter code you want to try out, I'd suggest you copy it in your project and modify there first. The batch script copies first the replay_lib and afterwards your local files. So an local code should always override the replay_lib code with same name. That way you can do local modifications and even check them in - and it will not break other cores requiring the lib files.

Then you can notify us here and everyone can check the changes by temporarly trying your version. If there are no complaints, we can update the replay_lib version.

Any concerns going this way? I'd say it is much easier and more transparent than using SVN branches, as long as we talk only about a very few files...

/WoS

Re: "Replay_VideoConverter" added to support library

"Any concerns going this way? I'd say it is much easier and more transparent than using SVN branches, as long as we talk only about a very few files..."
Agreed.
/MikeJ

23 (edited by foft 2014-03-21 20:00:50)

Re: "Replay_VideoConverter" added to support library

wolfgang wrote:

About the other 5 items:
i) yes, for now the last output value stays if the output picture reaches the defined generics for h/v-size (shifted by h/v-offset)
   should we better go to a default output value? E.g. defined by a generic?

Well for now I generated a blank signal by extending my hsync, which is working fine;-) I guess if hblank is set for over a whole hsync period it could blank the line.

ii) do you set the proper PAL/NTSC settings for the coder as Mike mentions?

I'm using coder of PAL no trap.

Actually svideo works fine, just not composite. I presume that port above svideo is composite out? Perhaps I'm mistaken.

v) sthat's not so easy to do with the actual generic menu system. The menu as defined in the INI for now modifies configuration bits to the FPGA, but can't modify the coder settings (no way to specify it). Maybe the best is to have a specific PAL/NTSC menu item to insert in the INI to define a bit mask for the FPGA config bits and modifying the coder in parallel. I'll have some thoughts about that...

Yeah I think this one might not be trivial. Perhaps we just build two core versions and allow it to be easily switched in the firmware?

Also on the PAL/NTSC subject - need to check if I can output 50p/60p rather than 50i/50p. On the CRT it is too flickery with interlace and the real Atari was 50p...

...svn proposal...

Yes makes a lot of sense. I was hesitant to change the videoconverter since I didn't want to break anyone.

Re: "Replay_VideoConverter" added to support library

I'm using coder of PAL no trap.
Actually svideo works fine, just not composite. I presume that port above svideo is composite out? Perhaps I'm mistaken.

Enabling the trap will reduce the distortion on the composite out (the port above svideo).
In the ini file

# sets composite/svhs coder, if fitted
CODER = CODER_PAL

You may also want to reduce the bandwidth through the filters (if not using this already)

# sets video filter for all 3 channels
# dc=250mv, 9MHZ
VFILTER = 0, 0, 3

Re: "Replay_VideoConverter" added to support library

I just tried that. With CODER_PAL I get nothing on any output. I tried with 'PAL' and it runs, but nothing on composite. I'll check with my scope and see if I'm getting anything at all on composite.