Skip to content

Latest commit

 

History

History
81 lines (55 loc) · 4.97 KB

clocks.md

File metadata and controls

81 lines (55 loc) · 4.97 KB

Game clocks

Games are expected to operate on a 48MHz clock using clock enable signals. There is an optional 6MHz that can be enabled with the macro JTFRAME_CLK6. This clock goes in the game module through a clk6 port which is only connected to when that macro is defined. jtbtiger is an example of game using this feature.

clock input Macro Needed
clk 48MHz unless JTFRAME_SDRAM96 is defined, then 96MHz
clk96 JTFRAME_CLK96
clk48 JTFRAME_CLK48
clk24 JTFRAME_CLK24
clk6 JTFRAME_CLK6

Note that although clk6 and clk24 are obtained without affecting the main clock input, if JTFRAME_SDRAM96 is defined, the main clock input moves up from 48MHz to 96MHz. The 48MHz clock can the be obtained from clk48 if JTFRAME_CLK48 is defined too. This implies that the SDRAM will be clocked at 96MHz instead of 48MHz. The constraints in the SDC files have to match this clock variation.

If STA was to be run on these pins, the SDRAM clock would have to be assigned the correct PLL output in the SDC file but this is hard to do because the TCL language subset used by Quartus seems to lack control flow statements. So we are required to do another text edit hack on the fly, which is not nice. Apart from changing the PLL output, when using 96MHz clock the input data should have a multicycle path constraint as it takes an extra clock cycle for the data to be ready. If you just change the PLL clock then you'll find plenty of timing problems unless you define the multicycle path constraint.

This is the code needed:

create_generated_clock -name SDRAM_CLK -source \
    [get_pins {emu|pll|pll_inst|altera_pll_i|general[5].gpll~PLL_OUTPUT_COUNTER|divclk}] \
    -divide_by 1 \
    [get_ports SDRAM_CLK]

set_multicycle_path -from [get_ports {SDRAM_DQ[*]}] -to [get_clocks {emu|pll|pll_inst|altera_pll_i|general[4].gpll~PLL_OUTPUT_COUNTER|divclk}] -setup -end 2

set_multicycle_path -from [get_ports {SDRAM_DQ[*]}] -to [get_clocks {emu|pll|pll_inst|altera_pll_i|general[4].gpll~PLL_OUTPUT_COUNTER|divclk}] -hold -end 2

This only applies to MiSTer. For MiST the approach is different and there are two different PLL modules which produce the SDRAM clock at the same pin. So a single create_generated_clock applies to both. Due to different SDRAM shifts used, the multicycle path constraint does not seem needed in MiST.

The script jtcore handles this process transparently.

By default unless JTFRAME_MR_FASTIO is already defined, JTFRAME_CLK96 will define it to 1. This enables fast ROM download in MiSTer using 16-bit mode in hps_io.

Internal JTFRAME clocks

The clocks passed to the target subsystem (jtframe_mist, jtframe_mister or jtframe_neptuno) are three:

clock Use Frequency
clk_sys Video & general purpose same as game clock clk
clk_rom SDRAM access same as clk_sys or higher
clk_pico picoBlaze clock 48MHz

clk_rom is controlled by the macros JTFRAME_SDRAM96 clk_sys is normally 48MHz, even if clk_rom is 96MHz. It can be set to 96MHz with JTFRAME_CLK96.

Games can move these frequencies by replacing the PLL (using the JTFRAME_PLL macro) but the changes should be within ±10% of the expected values.

JTFRAME_PLL Base clock Pixel clocks Used on
jtframe_pll6000 48/96 8 and 6 MHz Most JT cores. Used by default
jtframe_pll6144 49.152 6.144 JTKICKER, JTTWIN16
jtframe_pll6293 50.3496 6.2937 JTS16
jtframe_pll6671 53.372 6.671 JTRASTAN

For example, to use a 6.144 MHz pixel clock use JTFRAME_PLL=jtframe_pll6144 in the .def file.

The game module input clocks are multiples of the base clock:

clock input Default jtframe_pll6144
clk 48 49.152
clk96 96 98.304
clk48 48 49.152
clk24 24 24.576
clk6 6 6.144

Pixel Clock

All cores must define two clock enable signals based on clk_rom:

  • pxl_cen is the pixel clock. A typical value is 6MHz
  • pxl2_cen runs at twice the frequency of pxl_cen

As clock enable signals, these should not be high for more than one clock cycle. Some modules may expect an idle cycle after the active one.

Most core define these two signals as output ports. But it is possible to have them as input ports and leave JTFRAME to handle them by defining JTFRAME_PXLCLK to be either 6 or 8. JTFRAME will generate them correctly provided regardless of whether the SDRAM is set to 48 or 96MHz.

JTFRAME_PXLCLK will divide clk_rom by 6 or 8 (for a 48MHz reference). If JTFRAME_PLL is used, note that those two are the only valid values. Because of the PLL, the actual frequency will be off 6MHz, which is the intention of using JTFRAME_PLL in the first place.