-
Notifications
You must be signed in to change notification settings - Fork 11
2. First Steps
M2M offers a fully-featured example design including a demo-core to experiment with. This allows you to get started and learn more about M2M without the need of a MiSTer core.
The demo-core outputs a 4:3 720x576 @ 50 Hz (aka PAL) video signal via the VGA port of the MEGA65 and a 16:9 1280x720 @ 50 Hz (aka 720p) video signal via HDMI. Audio output works via the 3.5mm audio-out and via HDMI as well. On HDMI, the signal can be changed to 60 Hz if there are compatibility issues with the 50 Hz.
Have a look at the following screenshot. This is what the demo-core looks like on HDMI while the on-screen-menu is open because the Help key was pressed:
[@lydon: Please use your HDMI grabber to make a screenshot of the M2M democore while it runs "breakout" and while the Help menu is open (topmost item selected) and send it to me via Skype, so that I can add it here.]
Let's get started and build this demo core, so that we can learn more about how M2M works and what services it provides to you.
Clone the M2M GitHub repository and rename it. For a real project you would fork it, but for the purpose of getting started: Let's make it nice and easy.
MiSTer2MEGA65 contains sub-modules, so make sure that you do not "just" clone but also initialize the submodules afterwards:
git clone https://github.com/sy2002/MiSTer2MEGA65.git
mv MiSTer2MEGA65 MyFirstM2M
cd MyFirstM2M
git submodule update --init --recursive
Make sure that the QNICE development framework and the QNICE's "operating system" called "Monitor" is available to MiSTer2MEGA65. You can build it using the following commands:
cd M2M/QNICE/tools/
./make-toolchain.sh
Answer all questions that you are being asked while the QNICE tool chain
is being built by pressing Enter. You can check the success of
the process by checking if the Monitor is available as .rom
file:
ls -l ../monitor/monitor.rom
-
Go to the folder
MEGA65/m2m-rom
and build the M2M firmware:cd ../../../MEGA65/m2m-rom ./make_rom.sh
-
Go to the folder
MEGA65
and open Vivado there. This makes sure that the project-specific subfolders that Vivado will create are located in the right M2M subfolder.
cd ..
vivado
-
Chose the right project file for your MEGA65 revision. M2M strives to support
R2
andR3
(and newer), but at the time of writing this onlyR3
(and newer) are supported:Open
MEGA65-R3.xpr
in Vivado. -
Create the bitstream.
While doing so, Vivado will create multiple folders following the pattern
MEGA65-R3.*
inside yourMEGA65
folder. This is OK, you can ignore them and.gitignore
is also set-up to ignore them.The bitstream file will be located in
MEGA65/MEGA65-R3.runs/impl_1/MEGA65_R3.bit
.
-
If you have a JTAG connector installed in your MEGA65, you can now either use Vivado's hardware manager directly after the bitstream has been built or the "M65 tool" to run the bitstream on your MEGA65.
-
Using Vivado's hardware manager is highly recommended while doing this tutorial, because it is the fastest and easiest way to move forward. Later, you might prefer command line tools such as the "M65 tool".
-
Without a JTAG connector, you need to convert the bitstream, which is a
.bit
file, into a.cor
file and use MEGA65's No Scroll boot menu to flash the core.
@TODO: Describe how to get and how to build the m65 and the bit2core tool.
The demo-core is provided by M2M so that you can play with M2M, experiment and
learn without the need of a MiSTer core. It is not meant to be understood how
it works. Of course you can go to the folder M2M/vhdl/democore
and read
through the source code. But the idea is that you treat the demo-core as a
black-box, just like you (in most cases) would treat the MiSTer core as a
black-box and then start working with it inside M2M's defined structure of
files that are accessible to you in MEGA65/vhdl
.
After the core starts, you will see a welcome screen. Read it and then press Space to continue. Now you will hear a siren via the 3.5mm audio-out and via HDMI audio. And you will see a "BreakOut" set-up on your screen, i.e. a "ball", a "paddle" and something to hit.
One of the basic ideas of M2M video output is: Output a truly "retro" signal on the VGA. That means use the original core's aspect ratio (very often this is 4:3) and go as close to the original core's resolution as you can without sacrificing support on VGA displays. It might be that you need to use M2M's built-in scan-doubler or other mechanisms to actually achieve this, but this is for a later stage. Our demo-core outputs PAL, so this is a nice example of such a "retro" resolution on VGA. On HDMI, on the other hand, M2M outputs a standardized 720p 16:9 image that is a pixel-perfect scaled representation of the original core's output.
So we are catching two birds with one stone: Convenience on modern HDMI displays while still offering a "retro experience" via VGA.
Use the arrow keys and/or a joystick in port #1 to control the paddle. M2M debounces the joystick ports for you and provides an easy to use keyboard abstraction.
Play BreakOut! :-)
Press the Help key while the core is running to open the On-Screen-Menu (aka OSM and also dubbed "Help menu" or "Options menu"). You can close the menu while it is open by either pressing Help again or by choosing the menu item "Close Menu".
Play around with the menu a bit. Use Return to select menu items. Use Space to unmount a drive that has been mounted before. You will notice that the M2M framework is providing some interesting features:
-
Multi-select and single-select menu items: Multi-select in the M2M context means that you can select one option out of multiple options. The example in the demo-core is called "Item A.1", "Item, A.2", ... And "single-select" in the M2M context means that these are menu-items that are either ON or OFF. An example in the demo-core is the menu item "HDMI: CRT emulation". (We are aware that in other frameworks or contexts outside of M2M multi-select and single-select might mean something else.)
-
Make sure that at least one FAT32 formatted SD card is in your MEGA65 and then choose any of the three "Drive X", "Drive Y" or "Drive Z" virtual drive mounting menu items. You can now browse the SD card and "mount" any file as a "disk image". (Obviously, you are not mounting anything; this is just a demo of the file browser and virtual drive mounting system.)
-
Switching HDMI output between 50 Hz and 60 Hz
-
Play with the CRT emulation (video filter), audio improvements (audio filters) and the Zoom-in feature.
Now that you have gotton a first glimpse of what M2M can do, it's time to
go one level deeper and to understand the basic structure. There are two
basic "realms" or "spaces": The framework space (M2M space) and the core
space ("your" space). The M2M space is located in the folder M2M
and the
core space is split into two folders:
-
The folder you chose to add the original MiSTer core to (as a Git submodule). In this "First Steps" tutorial, there is no MiSTer core but a demo core, which is part of the framework.
-
User space main folder:
MEGA65
As a rule of thumb: Do not modify anything in the framework space, only
modify what is really needed to make it run when it comes to the original
MiSTer core and actually do your work in the core space's MEGA65
folder.
Let's have a look at the hierarchical structure now. The following is a
screenshot from Vivado's source explorer. Unfortunatelly the source explorer
cannot display the framework space and the user space separately, so please
focus your attention on the following files, which are located in the
user space folder MEGA65/vhdl
:
- top_mega65-r3.vhd: mega65_r3
- config.vhd: shell_cfg
- mega65.vhd: MEGA65
- clk.vhd: clk_gen
- main.vhd: i_main
- keyboard.vhd: i_keyboard
Another important file, that is not visible in this screenshot is
MEGA65/vhdl/globals.vhd
.
As a user of M2M, you can and should ignore all files other than the ones mentioned in the user space list above: You would normally never touch them.
The next sections walk you quickly through the user space files and explain how they interact. For a more thorough description please have a look at the Reference Guide: Each of the following user space files has its own chapter there.
Top file of the whole machine.
M2M supports multiple MEGA65 machine architectures. Right now R2
machines (pre-series models), R3
machines ("DevKits") and R3A
machines
(first commercially available machines) are supported. Since R3
and R3A
are
nearly identical, M2M just denotes them as R3
.
For each architecture, M2M provides three files in user space:
-
Vivado project: In our case this is
MEGA65/MEGA65-R3.xpr
. The project file contains all references necessary to work with M2M and/or the core in the Vivado IDE and everything necessary to make a bitstream. In particular, it links to the two other files that are machine architecture dependent. -
Constraints file: For our demo/walkthrough this is
MEGA65/MEGA65-R3.xdc
. The constraints file is highly machine dependent and contains all the I/O mappings as well as definitions for successful timing closure. -
Top file: For
R3
this isMEGA65/vhdl/top_mega65-r3.vhd
. The top file instantiates the whole machine and contains machine architecture dependent settings and modules.
The main module that the top file is instantiating is M2M
. This module
instantiates everything that the framework needs to operate, including QNICE,
the analog and digital rendering pipeline and the HyperRAM controller. The
M2M module also contains glue logic and instantiates mega65.vhd
.
It is fair to say that mega65.vhd
is the "top file of the user space", as
the following things are happening here:
- Instantiation of the wrapper of the MiSTer core
main.vhd
- Instantiation of all clock-domain-crossing hardware such as core-specific RAMs, ROMs and other devices
- Implementation of device-specific logic
- Implementation of the logic that reacts to on-screen-menu items, such as the real-time configuration of audio and video settings
In our first steps demo/example, not a lot of sophisticated stuff is
happening: main.vhd
is instantiated and there is no core-specific RAM, ROM
or device (other than i_vdrives
). As we will cover the implementation of
the logic that reacts to on-screen-menu items during the
"Hello World" Tutorial,
we will not go deeper here.
The topic of virtual drives is quite complex, which is why i_vdrives
is
not covered here, too, but in its own chapter Virtual Drives.
The MiSTer core you are porting has very specific clocking needs. Some cores
are happy with one clock, some cores need multiple clocks. Put all of them
in MEGA65/vhdl/clk.vhd
and make sure that you also implement the neccessary
clock-domain-crossing for each clock when it comes to reset generation.
The standard version of clk.vhd
supports one clock, and therefore also
one reset. Feel free to add more output signals.
We are wrapping the MiSTer core in main.vhd
. The power of the M2M
framework becomes visible, when you look at the output ports of main.vhd
:
The core just needs to output some retro video signal and signed 16-bit
PCM audio and the framework does all the magic necessary to transform this
into HDMI (incl. an 48 kHz sampled audio stream) and to a pulse density
modulated stream for the 3.5mm audio out.
If you look at how everything is structured in main.vhd
, then you will
quickly notice, that the MiSTer core can peacefully live in its own little
bubble and clocking domain and whatnot without ever knowing anything about
the MEGA65 it is running on and without ever knowing about screen overlays
(for example for the on-screen-menu), SD cards and so on.
At least two modules need to be instantiated in main.vhd
:
- MiSTer core: In our case, this is
i_democore
- Keyboard:
i_keyboard
inkeyboard.vhd
In practice, you will very likely instantiate more modules (for example
additional glue-logic for the MiSTer core) and you will also add more
input/output ports to main.vhd
. But this is absolutely OK and meant to
be like this.
M2M provides you with a very simple interface to the MEGA65 keyboard so that
you are able to implement whatever mapping and logic the core needs.
keyboard.vhd
runs in the same clock-domain as the core, so that you an
directly wire the output of your own keyboard mapper to MiSTer's keyboard
input.
In our example, the demo core expects a low-active std_logic_vector
that
has one bit per key on the MEGA65's keyboard:
keyboard_n_i : in std_logic_vector(79 downto 0);
Therefore the whole logic of keyboard.vhd
boils down to creating 80
flip-flops (i.e. a 80-bit register) and keeping them updated:
example_n_o <= key_pressed_n;
keyboard_state : process(clk_main_i)
begin
if rising_edge(clk_main_i) then
key_pressed_n(key_num_i) <= key_pressed_n_i;
end if;
end process;
The
Shell
is highly versatile and a lot of details of how it behaves and what services
it shall offer to the users can be configured. You are doing this in
config.vhd
.
Vivado will synthesize config.vhd
into a ROM that can be read by the
QNICE firmware and by the Shell. As long as you "just" would like to use the
Shell (instead of writing your own firmware from scratch), you do not need
to understand how the underlying mechanisms work. In this case just stick
with the comments in config.vhd
and do not touch any part of the file
that is marked with "DO NOT TOUCH".
The "Hello World" Tutorial will - among other
things - show you how you can use config.vhd
to create new menu items for
the on-screen-menu (Help menu) and how to change the Welcome
Screen's standard behavior.
The things that you will need to change in globals.vhd
are these:
- Precise speed of your MiSTer core's clock(s) in Hertz
- The DX and DY "retro" resolution of the core (remember: this is what will be output on the VGA port; HDMI will always be auto-scaled to 720p)
- Virtual drives and/or ROMs
- Audio filters (if any)
All of this is beyond the scope of our small first demo tour through M2M.
We highly encourage you to follow the track and continue with the "Hello World" Tutorial from here.