Skip to content

The framework is still under development

The documentation in this section refers to the Game Bub Core Framework as of v1.1-beta. The framework is not finalized, and may change based on developer feedback.

Reference: Interfaces

As described in Core Structure, cores select from and configure a variety of interfaces to interact with the hardware via the framework.

import chisel3._
import net.gamebub.framework.Core
import net.gamebub.framework.interface._

class MyCore extends Module with Core {
  val io = IO(new Bundle {
    // Hardware interfaces are declared as elements of this Bundle
  })
}
Port Name Interface Class Required
clocks ClocksV0 Yes
video VideoV0 Yes
host HostV0 Yes
audio AudioV0 No
input InputV0 No
vibrate VibrateV0 No
cartridge CartridgePortV0 No
link LinkPortV0 No
pmod PmodV0 No
sram SramV0 No
sdram SdramV0 No
videoFilter VideoFilterBasicV0 No

Clocks (clocks: ClocksV0)

Required. This interface provides the root 50 MHz clock to the core, and allows the core to provide necessary clocks to the framework (system clock, display clock, SPI clock).

The system clock, generated by the core, is the clock used with all interfaces, unless otherwise specified.

Parameters

  • clockSystemHz: Frequency in Hz of the system clock.
  • clockDisplayHz: Frequency in Hz of the LCD interface clock. Must fall within the range returned by ClocksV0.getClockDisplayHz(...).
  • clockSpiHz: Frequency in Hz of the clock used to sample the MCU SPI bus. Must be at least 160 MHz.

Helpers

  • ClocksV0.getClockDisplayHz: (Double) => (Int, Int): provides a tuple of the minimum and maximum allowable display clock frequencies (in Hz), based on the given frame period in seconds (e.g. 1.0 / 60.0).

Port Signals

Signal Direction Type Description
clockIn50M Input Clock 50 MHz reference clock input
clockOutSystem Output Clock System clock
clockOutDisplay Output Clock Display clock
clockOutSpi Output Clock Host MCU SPI clock
locked Output Bool High when the core's clocks are stable and locked (i.e. PLL output)

Video (video: VideoV0)

Required. This interface allows the core to produce video output. The signals are referenced to the system clock.

Parameters

  • videoWidth: Width of the active video signal (in pixels)
  • videoHeight: Height of the active video signal (in pixels)
  • colorDepthR: Bit-depth of the red channel
  • colorDepthG: Bit-depth of the green channel
  • colorDepthB: Bit-depth of the blue channel
  • framePeriod: Video frame period (in seconds), e.g. 1.0 / 60.0

Port Signals

Signal Direction Type Description
data.r Output UInt Video data: red channel
data.g Output UInt Video data: green channel
data.b Output UInt Video data: blue channel
dataEnable Output Bool High during video output
vblank Output Bool Pulse high at the end of each frame
hblank Output Bool Pulse high at the end of each line

Host (host: HostV0)

Required. This interface allows the host MCU to communicate with the core. There are two main interfaces: the memory interface, and the command interface. Both interfaces use the system clock.

The memory interface is a simple memory interface (no pipelining or bursting), where a single 32-bit address is transmitted, along with a 32-bit data word read or write. enable goes high to indicate a new request is starting, with the given address, and whether it is a read (write low) or write (write high). Writes also come with dataWrite. When the core has completed the request, it must raise done. If the request was a read, dataRead must also be valid.

All memory accesses take at least two cycles: the first cycle starts when enable goes high, and the earliest it can end is on the second cycle (when done goes high). However, if the core needs additional time to handle the request, it can delay raising done until the third, fourth, or a later cycle.

The next transaction can start immediately on the cycle after done goes high.

Addresses beginning with 0xFxxxxxxx are reserved for use by the framework. Except as explicitly specified (e.g. for the command interface), the core must not map its own registers or memory at these addresses.

There are two command interfaces: commandHost (for Host -> Core commands), and commandCore (for Core -> Host) commands. Each provides a separate request / response channel.

The command interfaces are described in a later section.

Port Signals

Signal Direction Type Description
mem.enable Input Bool High when a transaction is going on
mem.write Input Bool High if the transaction is a write, low if it is a read
mem.address Input UInt(32.W) The 32-bit byte address
mem.dataWrite Input UInt(32.W) 32-bit data written by the host
mem.dataRead Output UInt(32.W) 32-bit data read by the host, valid when done goes high
mem.done Output Bool High for one cycle when the transaction is completed
commandHost.request Input Bool High during a host-initiated request
commandHost.busy Output Bool Set high when the core acknowledges the request
commandHost.done Output Bool Set high when the core completes the request
commandHost.error Output Bool Set high if the request completes in an error
commandCore.request Output Bool High during a core-initiated request
commandCore.busy Input Bool High when the host acknowledges the request
commandCore.done Input Bool High when the host completes the request
commandCore.error Input Bool High if the requested completed in an error

Audio (audio: AudioV0)

Optional. This interface allows the core to produce audio output. The signals are referenced to the system clock.

The sample rate is always 48000 Hz, so the core should update left and right at 48 kHz.

Port Signals

Signal Direction Type Description
left Output SInt(16.W) 16-bit signed PCM audio sample for the left channel
right Output SInt(16.W) 16-bit signed PCM audio sample for the right channel

Input (input: InputV0)

Optional. This interface allows the core to receive button input. Each button signal is active-high and synchronized into the system clock domain.

Port Signals

Signal Direction Type Description
buttons.a Input Bool Action button 'A'
buttons.b Input Bool Action button 'B'
buttons.x Input Bool Action button 'X'
buttons.y Input Bool Action button 'Y'
buttons.up Input Bool D-Pad button 'Up'
buttons.down Input Bool D-Pad button 'Down'
buttons.left Input Bool D-Pad button 'Left'
buttons.right Input Bool D-Pad button 'Right'
buttons.l Input Bool Shoulder button 'L'
buttons.r Input Bool Shoulder button 'R'
buttons.start Input Bool Menu button 'Start'
buttons.select Input Bool Menu button 'Select'

Vibrate (vibrate: VibrateV0)

Optional. This interface allows the core to produce haptic feedback (vibration).

The mode can be either:

  • Off (0b00)
  • On (0b01)
  • Brake (0b10)

Port Signals

Signal Direction Type Description
mode Output VibrateV0.Mode() Output to the vibration motor

Cartridge Port (cartridge: CartridgePortV0)

Optional. This interface allows the core to access the cartridge slot. Note that cartridge power must be enabled in the core.json metadata file.

Cartridge pins go through level shifters, and the I/O voltage is controlled automatically by the hardware based on a shape-detecting switch in the cartridge slot.

For each direction signal, high (1) indicates output from FPGA to cartridge, 0 indicates input from cartridge to FPGA.

Port Signals

Signal Direction Type Description
enabled Output Bool High to enable cartridge level shifters.
switch Input Bool High when a DMG/CGB cartridge is inserted (5 V), low otherwise (3.3 V)
bank0In / bank0Out In / Out UInt(8.W) Address bus lines A16 through A23.
bank0Dir Output Bool Direction for Bank 0
bank1In / bank1Out In / Out UInt(8.W) Address/Data bus lines AD8 through AD15.
bank1Dir Output Bool Direction for Bank 1
bank2In / bank2Out In / Out UInt(8.W) Address/Data bus lines AD0 through AD7.
bank2Dir Output Bool Direction for Bank 2
bank3In / bank3Out In / Out UInt(4.W) Control pins: bit 0 = nCS1, 1 = nRD, 2 = nWR, 3 = PHI
bank3Dir Output Bool Direction for Bank 3 control pins
pin30In / pin30Out In / Out Bool Pin 30: nRST / nCS2
pin30Dir Output Bool Direction for Pin 30
pin31In / pin31Out In / Out Bool Pin 31: VIN / nIRQ
pin31Dir Output Bool Direction for Pin 31

Optional. This interface allows the core to access the link port. The voltage is automatically controlled by the cartridge shape-detector switch.

For each direction signal, high (1) indicates output, 0 indicates input.

Port Signals

Signal Direction Type Description
soIn, soOut, soDir In / Out / Out Bool SO pin
siIn, siOut, siDir In / Out / Out Bool SI pin
sdIn, sdOut, sdDir In / Out / Out Bool SD pin
scIn, scOut, scDir In / Out / Out Bool SC pin

PMOD (pmod: PmodV0)

Optional. This interface allows the core to access the PMOD connector at the top of the device. All I/Os are 3.3 V and unbuffered.

For each direction signal, high (1) indicates output, 0 indicates input.

Port Signals

Signal Direction Type Description
in Input UInt(4.W) Input from PMOD header
out Output UInt(4.W) Output to PMOD header
dir Output UInt(4.W) Pin direction mask

SDRAM (sdram: SdramV0)

Optional. This interface allows the core to access SDRAM memory chips.

For each direction signal, high (1) indicates output, 0 indicates input.

Game Bub Rev4 has 2x 32 MiB SDRAM chips with a 16-bit data bus.

Parameters

  • addressWidth: Row/column address bus width (default: 13)
  • dataWidth: Data bus width (default: 16)
  • bankWidth: Bank addres width (default: 2)
  • chips: Number of parallel chips / chip-select lines (default: 1)

Helpers

  • SdramV0.numChips: Int: exposes the number of SDRAM chips available on the target

Port Signals

Signal Direction Type Description
clock Output Clock SDRAM clock
cke Output Bool Clock enable
cs Output UInt Active-low chip select
ras, cas, we Output Bool Active-low command strobe lines
dqm Output UInt Active-high data byte mask
bank Output UInt Bank address
address Output UInt Address bus
dataIn Input UInt Data bus input
dataOut Output UInt Data bus output
dataDir Output Bool Data bus direction

SRAM (sram: SramV0)

Optional. This interface allows the core to access asynchronous SRAM memory chips.

For each direction signal, high (1) indicates output, 0 indicates input.

Game Bub Rev4 has a 512 KiB, 16-bit data bus asynchronous SRAM chip.

Parameters

  • addressWidth: Address bus width (default: 18)
  • dataWidth: Data bus width (default: 16)

Port Signals

Signal Direction Type Description
ceN Output Bool Active-low chip enable
weN Output Bool Active-low write enable
oeN Output Bool Active-low output enable
writeMaskN Output UInt Active-low byte write masks
address Output UInt Address bus
dataIn Input UInt Data bus input
dataOut Output UInt Data bus output
dataDir Output Bool Data bus direction

Video Filter (videoFilter: VideoFilterBasicV0)

Optional. This interface allows the core to apply filter effects to video output after scaling.

These signals are in the display clock domain, not the system clock domain.

Parameters

  • colorInDepthR: Bit-depth of the red channel (must match video)
  • colorInDepthG: Bit-depth of the green channel (must match video)
  • colorInDepthB: Bit-depth of the blue channel (must match video)
  • latency: Latency from filter input to output (in clock cycles)

Port Signals

Signal Direction Type Description
clock Input Clock Display clock
reset Input Reset Filter reset signal (active-high)
dataIn.r Input UInt Input color data (red channel)
dataIn.g Input UInt Input color data (green channel)
dataIn.b Input UInt Input color data (blue channel)
dataOut.r Output UInt(8.W) Output color data (red channel)
dataOut.g Output UInt(8.W) Output color data (green channel)
dataOut.b Output UInt(8.W) Output color data (blue channel)

Host/Core Commands

To begin a request, the initiator raises request high, and holds it high for the duration of the request. The receiver then raises the busy signal, to indicate it is working on the request. When the receiver is finished, it raises the done signal (and the error signal, if the command completed in an error).

After the initiator is done handling the response, they must lower request. Then, they may raise request again to send a new request, and the whole process repeats.

Parameters and Results

Request parameters and results are transmitted using the memory bus, in the regions 0xF000_0000 (Host -> Core) and 0xF000_1000 (Core -> Host). Each parameter and result is 32 bits.

Before raising request, the host writes its command opcode to 0xF000_0000, its first parameter (if there is one) to 0xF000_0004, its second parameter (if there is one) to 0xF000_0008, etc.

Upon request completion (when done goes high), the host will read the first result word from 0xF000_0000, the second result word from 0xF000_0004, etc.

For Core -> Host commands, the same interface holds true, but in reverse, at starting at 0xF000_1000. That is, when request is raised by the core, the host will read the opcode from 0xF000_1000, the first parameter from 0xF000_1004, etc. And similarly, before it raises done, it will write the first result word to 0xF000_1000, the second to 0xF000_1004, etc.

Host -> Core commands

GetStatus (0x0000)

Called by the host to request the status of the core. No parameters. The result is a single value, indicating the status:

  • StatusUnknown = 0: unknown status
  • StatusInitialize = 1: the core is initializing itself
  • StatusSetup = 2: the core has initialized, and is ready for the host to transmit commands and memory accesses
  • StatusCoreHalt = 3: the core has been set up, and is halted in reset
  • StatusCoreRun = 4: the core is actively running

CoreRun (0x0100)

Called by the host to start core execution (taking it out of reset).

No parameters or results.

The core should transition to StatusCoreRun.

CoreHalt (0x0101)

Called by the host to halt core execution (putting it into reset).

No parameters or results.

The core should transition to StatusCoreHalt.

SetupComplete (0x0102)

Called by the host to indicate that it is done setting up the core (files and settings have been transmitted).

No parameters or results.

The core should finalize its setup and transition to StatusCoreHalt.

NotifyFocus (0x0200)

Called by the host to indicate that the core gained or lost UI focus. When not focused, video may be obscured by a menu, audio may be silenced, and the core will not receive any input.

The core may choose to (but does not have to) pause itself.

One parameter: 1 if the core has gained focus, 0 if the core has lost focus. No results.

FileWriteStart (0x0300)

Called by the host before it starts writing a file to the core via the host memory interface.

One parameter: the file ID, defined in files.json. No results.

FileWriteEnd (0x0301)

Called by the host when it has finished writing the file.

Three parameters: 1. The file ID 2. The total size of the file transferred, in bytes 3. Reserved (0)

No results.

FileReadStart (0x0302)

Called by the host before it starts reading a file from the core via the host memory interface.

One parameter: the file ID. One result: the file size in bytes.

FileReadEnd (0x0303)

Called by the host when it has finished reading the file.

One parameter: the file ID. No results.

Core -> Host commands

There are no core initiated commands yet.