Framework Overview

If you’re as new to VHDL as I was, you may be wondering what exactly Core_Pack is or how does Core_Top and Example_Audio_Top fit into the framework?

A complete breakdown of the framework is way beyond the scope of this guide, but a high level overview will hopefully provide enough context to understand where the boundary is between the User Core and Framework.

FPGA Replay Framework

FPGA Replay Framework

Framework

When you build a project for the FPGA Replay, everything begins with the Replay_Top entity in “hw/replay/cores/replay_lib/common/”.

This entity acts as a bridge and brings together the user core via Core_Top as well as the Library via Replay_Lib_Wrap.

It does this by creating an instance of a Core_Top entity expected to be defined with that exact name in the User Core (shown in blue in the image above)

 u_core : entity work.Core_Top
  port map (
    ...

as well as a instance of the Replay_Lib_Wrap entity

  u_Lib : entity work.Replay_Lib_Wrap
  generic map (

Replay_Top is able to access any of the named pins in the constraints file and map those either to the user core or to the library.

For example, it exposes the three clock lines i_clk_a, b and c to the Library which eventually bubble back out from the library via o_ctrl (of type r_Ctrl_to_core) which is mapped to the ctrl_to_core signal which in turn is mapped to i_ctrl on the User core. This provides the User Core with access to numerous clock and control signals

The types used by the Framework (and user core) are defined in the Package Replay_Lib_Wrap_Pack, for example part of the r_Ctrl_to_core record is:

  type r_Ctrl_to_core is record
    -- System clock, enable and reset, generated from Clk A
    clk_sys                 : bit1;
    ena_sys                 : bit1;
    cph_sys                 : word(3 downto 0); -- four phased enables. (3) = ena_sys
    rst_sys                 : bit1;
    -- Aux Clock, generated from Clk B. Can be used for Audio
    clk_aux                 : bit1;
    rst_aux                 : bit1;
    --
    clk_ram                 : bit1;
    rst_ram                 : bit1;

    ...

This allows the framework to make use of the three physical clocks and derive additional clocks which can be packaged up and exposed to the User Core along with additional control signals.

Similar happens from the user core to the lib. For example, Replay_Top takes a r_Ctrl_fm_core type via o_ctrl and passes this into the Library via u_Lib’s i_ctrl (the mapping uses ctrl_fm_core as a go between signal). This record is smaller that the r_Ctrl_to_core record and allows the User core to enable/disable the audio or video clocks as well as provide a clock to be used by the audio section of the framework. A clock that is likely derived from one of the clocks the framework exposed via Replay_Top to the User core above.

  type r_Ctrl_fm_core is record
    ena_vid                 : bit1;  -- optional, tie high if not neeed
    --
    clk_aud                 : bit1;  -- clock   -- 49.152MHz gives 192KHz
    ena_aud                 : bit1;  -- enable  -- one in four enable gives 48KHz
    rst_aud                 : bit1;  -- reset
    --
    rst_soft                : bit1;
  end record;

The intention of this Replay_Top bridge is (at least as far as possible) to insulate the User core from changes within the framework.

Configuration

The Framework also makes use of a handful of configuration constants which are specified on the User core side in Core_Pack.

Package Core_Pack is
  constant c_clk_sys_divider      : natural := 28;   -- divide clk_sys down to 1MHz
  constant c_clk_ctl_for_video    : boolean := false;
  constant c_use_dram             : boolean := true; -- enabled DRAM block
  constant c_use_fileio           : boolean := true; -- enabled FILEIO block

  ...

Some of these values will be covered later in the guide.

As with Core_Top, the name of this package file in the user core must be Core_Pack.

RTL

Replay_Lib_Wrap instantiates various entities from the Replay RTL which all provide support related to parts of the replay board hardware itself.

A selection of these are shown in Green in the RTL section of the image above which are entities that nearly (all?) cores making use of the framework would expect to be available. For example ensuring video and audio signals are generated, the joystick port read and interfacing with the ARM via SysCON.

Additional RTL components are available which cover RAM access, mouse and keyboard access etc. See “hw/replay/cores/replay_lib/rtl/”.

Library

Finally the framework provides a more general Library of entities that are not specific to the functioning of the replay hardware, this includes the Z80 processor used by several existing cores and custom chips such as the namco and konami’s.

These can all be found in the “hw/replay/cores/lib/” directory and will usually be instantiated on the User Core side for example within Example_Audio_Top or within other custom user entities you may create.

User Core

In general and certainly for the purposes of this guide, new vhdl code will be added in the “User Core” side. Although if you’re creating a new entity for a generally available part that may be used by many cores, it may be a good candidate to add to the replay Library itself.

The User core must have an entity with the exact name “Core_Top”. The framework will create an instance of this (u_core) and make suitable connections to the underlying framework library via u_Lib.

The User core must also have a package with the name Core_Pack, this is also used by the framework to access various configuration constants which will be covered later in the guide.

Core_Top can be seen as a way to insulate the real user core from changes within the framework and in turn creates the actual core entity Example_Audio_Top. This is where everything that makes your core unique will reside. Whether that’s making instances of entities from the Library such as the Z80 cpu, or perhaps from the RTL itself (as the Example_Audio_Top does in this example to make use of the Generic FileIO), or perhaps custom entities specific to your core that may or may not in turn make use of the Library/RTL.

Note, both the framework and Core_Top use the name u_core for the entity they create. Do not confuse the two.

Not shown in the image above are the various _tb files which are related to the test bench and not covered by this guide.

Summary

The main points to keep in mind are:

  • Nearly all Core code will be added in the User Core section.
  • Cores must have a Core_Top and Core_Pack
  • Further wrapping such as using Example_Audio_Top is optional but useful.
  • User cores may make use of components from with the RTL or Library.

With all that out of the way, lets get started making some noise.

Next section Audio Clock and Data

Back to index