├── .gitignore ├── README.md ├── STV.qpf ├── STV.qsf ├── STV.srf ├── STV_DS.qpf ├── STV_DS.qsf ├── STV_DS.srf ├── Saturn.qpf ├── Saturn.qsf ├── Saturn.sdc ├── Saturn.srf ├── Saturn.sv ├── Saturn_DS.qpf ├── Saturn_DS.qsf ├── Saturn_DS.srf ├── Saturn_Q13.qpf ├── Saturn_Q13.qsf ├── Saturn_Q13.srf ├── clean.bat ├── files.qip ├── pll.qip ├── pll.v ├── releases ├── Saturn_20231010.rbf ├── Saturn_20231018.rbf ├── Saturn_20240323.rbf ├── Saturn_20240628.rbf └── Saturn_20250113.rbf ├── rtl ├── ADSP_21XX_mem.sv ├── ADSP_21xx │ ├── ADSP_2181.qip │ ├── ADSP_2181.sv │ ├── ADSP_21XX_core.sv │ └── ADSP_21XX_pkg.sv ├── CEGen.vhd ├── FX68K │ ├── fx68k.qip │ ├── fx68k.sdc │ ├── fx68k.sv │ ├── fx68k.txt │ ├── fx68kAlu.sv │ ├── microrom.mem │ ├── nanorom.mem │ └── uaddrPla.sv ├── SH │ ├── SH opcodes.xlsx │ ├── SH7034 │ │ ├── BSC.sv │ │ ├── DMAC.sv │ │ ├── INTC.sv │ │ ├── ITU.sv │ │ ├── MULT.sv │ │ ├── PFC.sv │ │ ├── RAM.sv │ │ ├── ROM.sv │ │ ├── SCI.sv │ │ ├── SH7034.qip │ │ ├── SH7034.sv │ │ ├── SH7034_mem.sv │ │ ├── SH7034_pkg.sv │ │ ├── UBC.sv │ │ └── WDT.sv │ ├── SH7604 │ │ ├── BSC.sv │ │ ├── CACHE.sv │ │ ├── DIVU.sv │ │ ├── DMAC.sv │ │ ├── FRT.sv │ │ ├── INTC.sv │ │ ├── MSBY.sv │ │ ├── MULT.sv │ │ ├── SCI.sv │ │ ├── SH7604.qip │ │ ├── SH7604.sv │ │ ├── SH7604_mem.sv │ │ ├── SH7604_pkg.sv │ │ ├── UBC.sv │ │ └── WDT.sv │ └── core │ │ ├── SH_core.sv │ │ ├── SH_mem.sv │ │ ├── SH_pkg.sv │ │ └── SH_regfile.sv ├── SH7604_mem.sv ├── SH_mem.sv ├── Saturn │ ├── B-Bus.xlsx │ ├── CART.sv │ ├── CD │ │ ├── CD.sv │ │ ├── SH1.sv │ │ ├── YGR019.sv │ │ ├── YGR019_PKG.sv │ │ └── sh7034.mif │ ├── DCC.sv │ ├── SCSP │ │ ├── SCSP.sv │ │ └── SCSP_pkg.sv │ ├── SCU │ │ ├── DSP.sv │ │ ├── DSP_PKG.sv │ │ ├── RAM.sv │ │ ├── SCU DSP.xlsx │ │ ├── SCU.sv │ │ └── SCU_PKG.sv │ ├── SMPC.sv │ ├── STV │ │ ├── 5838.sv │ │ ├── 5881.sv │ │ ├── 93C45.sv │ │ ├── RAX.sv │ │ ├── STVIO.sv │ │ └── STV_CART.sv │ ├── Saturn.qip │ ├── Saturn.sv │ ├── VDP1 │ │ ├── VDP1.sv │ │ └── VDP1_pkg.sv │ └── VDP2 │ │ ├── VDP2.sv │ │ ├── VDP2.xlsx │ │ ├── VDP2_mem.sv │ │ └── VDP2_pkg.sv ├── bram.vhd ├── cdb105.mif ├── cdb105m.mif ├── cdb106.mif ├── cdb106m.mif ├── cofi.sv ├── ddram.sv ├── hps2cdd.sv ├── hps2pad.sv ├── hps_ext.v ├── jtframe_resync.v ├── lightgun.sv ├── mlab.vhd ├── pll.qip ├── pll.v ├── pll │ ├── pll.mif │ ├── pll_0002.qip │ ├── pll_0002.v │ └── pll_0002_q13.qip ├── ps2mouse.sv ├── sdr.xlsx ├── sdram1.sv ├── sdram2.sv ├── stv_eeprom.mif └── vdp1_fb.sv └── sys ├── alsa.sv ├── arcade_video.v ├── ascal.vhd ├── audio_out.v ├── build_id.tcl ├── ddr_svc.sv ├── f2sdram_safe_terminator.sv ├── gamma_corr.sv ├── hps_io.sv ├── hq2x.sv ├── i2c.v ├── i2s.v ├── iir_filter.v ├── ltc2308.sv ├── math.sv ├── mcp23009.sv ├── mt32pi.sv ├── osd.v ├── pll.13.qip ├── pll_audio.13.qip ├── pll_audio.qip ├── pll_audio.v ├── pll_audio ├── pll_audio_0002.qip └── pll_audio_0002.v ├── pll_cfg.qip ├── pll_cfg ├── altera_pll_reconfig_core.v ├── altera_pll_reconfig_top.v ├── pll_cfg.v └── pll_cfg_hdmi.v ├── pll_hdmi.13.qip ├── pll_hdmi.qip ├── pll_hdmi.v ├── pll_hdmi ├── pll_hdmi_0002.qip └── pll_hdmi_0002.v ├── pll_hdmi_adj.vhd ├── pll_q13.qip ├── pll_q17.qip ├── scandoubler.v ├── scanlines.v ├── sd_card.sv ├── shadowmask.sv ├── sigma_delta_dac.v ├── spdif.v ├── sys.qip ├── sys.tcl ├── sys_analog.tcl ├── sys_dual_sdram.tcl ├── sys_top.sdc ├── sys_top.v ├── sysmem.sv ├── vga_out.sv ├── video_cleaner.sv ├── video_freak.sv ├── video_freezer.sv ├── video_mixer.sv └── yc_out.sv /.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | greybox_tmp 3 | incremental_db 4 | output_files 5 | simulation 6 | hc_output 7 | scaler 8 | hps_isw_handoff 9 | vip 10 | *_sim 11 | .qsys_edit 12 | PLLJ_PLLSPE_INFO.txt 13 | *.bak 14 | *.orig 15 | *.rej 16 | *.qdf 17 | *.rpt 18 | *.smsg 19 | *.summary 20 | *.done 21 | *.jdi 22 | *.pin 23 | *.sof 24 | *.qws 25 | *.ppf 26 | *.ddb 27 | build_id.v 28 | c5_pin_model_dump.txt 29 | *.sopcinfo 30 | *.csv 31 | *.f 32 | *.cmp 33 | *.sip 34 | *.spd 35 | *.bsf 36 | *~ 37 | *.xml 38 | *_netlist 39 | *.cdf 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Sega Saturn](https://en.wikipedia.org/wiki/Sega_Saturn) for MiSTer 2 | 3 | ## Hardware Requirements 4 | 5 | - 128 MB SDRAM Module (Primary) 6 | - SDRAM Module of any size (32MB-128MB) (Secondary) 7 | 8 | > **Note:** Dual SDRAM modules is recommended for better compatibility. 9 | 10 | ## Status 11 | 12 | Current status is WIP/Beta 13 | 14 | Known issues: 15 | 16 | -------------------------------------------------------------------------------- /STV.qpf: -------------------------------------------------------------------------------- 1 | QUARTUS_VERSION = "17.0" 2 | PROJECT_REVISION = "STV" 3 | -------------------------------------------------------------------------------- /STV.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # 3 | # MiSTer project 4 | # 5 | # WARNING WARNING WARNING: 6 | # Do not add files to project in Quartus IDE! It will mess this file! 7 | # Add the files manually to files.qip file. 8 | # 9 | # -------------------------------------------------------------------------- 10 | 11 | set_global_assignment -name TOP_LEVEL_ENTITY sys_top 12 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 13 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 14 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 15 | 16 | set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition" 17 | 18 | set_global_assignment -name GENERATE_RBF_FILE ON 19 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 20 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 21 | set_global_assignment -name SAVE_DISK_SPACE OFF 22 | set_global_assignment -name SMART_RECOMPILE ON 23 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" 24 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 25 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 26 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 27 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF 28 | set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF 29 | set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS 30 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 31 | set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" 32 | set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON 33 | set_global_assignment -name QII_AUTO_PACKED_REGISTERS NORMAL 34 | set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON 35 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 36 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 37 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 38 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 39 | set_global_assignment -name MUX_RESTRUCTURE ON 40 | set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON 41 | set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON 42 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON 43 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 44 | set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON 45 | set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON 46 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 47 | set_global_assignment -name ECO_OPTIMIZE_TIMING ON 48 | set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON 49 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 50 | set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW 51 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.0 52 | set_global_assignment -name SEED 1 53 | 54 | set_global_assignment -name VERILOG_MACRO "MISTER_DISABLE_ALSA=1" 55 | set_global_assignment -name VERILOG_MACRO "STV_BUILD=1" 56 | 57 | source sys/sys.tcl 58 | source sys/sys_analog.tcl 59 | source files.qip 60 | -------------------------------------------------------------------------------- /STV.srf: -------------------------------------------------------------------------------- 1 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_kbd_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 2 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_mouse_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 3 | { "" "" "" "Synthesized away node \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|outclk_wire\[2\]\"" { } { } 0 14320 "" 0 0 "Design Software" 0 -1 0 ""} 4 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 5 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 6 | { "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Design Software" 0 -1 0 ""} 7 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 8 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(129): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 9 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(134): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 10 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(97): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 11 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(102): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 12 | { "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Design Software" 0 -1 0 ""} 13 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"pll_hdmi:pll_hdmi\|pll_hdmi_0002:pll_hdmi_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 14 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 15 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 16 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(594): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 17 | { "" "" "" "Ignored filter at sys_top.sdc(17): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 18 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(16): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Design Software" 0 -1 0 ""} 19 | { "" "" "" "Ignored filter at sys_top.sdc(37): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 20 | { "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""} 21 | { "" "" "" "*" { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 22 | { "" "" "" "*" { } { } 0 276027 "" 0 0 "Design Software" 0 -1 0 ""} 23 | { "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 24 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 25 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 26 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 27 | { "" "" "" "cyclonev_pll" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 28 | -------------------------------------------------------------------------------- /STV_DS.qpf: -------------------------------------------------------------------------------- 1 | QUARTUS_VERSION = "17.0" 2 | PROJECT_REVISION = "STV_DS" 3 | -------------------------------------------------------------------------------- /STV_DS.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # 3 | # MiSTer project 4 | # 5 | # WARNING WARNING WARNING: 6 | # Do not add files to project in Quartus IDE! It will mess this file! 7 | # Add the files manually to files.qip file. 8 | # 9 | # -------------------------------------------------------------------------- 10 | 11 | set_global_assignment -name TOP_LEVEL_ENTITY sys_top 12 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 13 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 14 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 15 | 16 | set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition" 17 | 18 | set_global_assignment -name GENERATE_RBF_FILE ON 19 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 20 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 21 | set_global_assignment -name SAVE_DISK_SPACE OFF 22 | set_global_assignment -name SMART_RECOMPILE ON 23 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" 24 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 25 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 26 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 27 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF 28 | set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF 29 | set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS 30 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 31 | set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" 32 | set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON 33 | set_global_assignment -name QII_AUTO_PACKED_REGISTERS NORMAL 34 | set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON 35 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 36 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 37 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 38 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 39 | set_global_assignment -name MUX_RESTRUCTURE ON 40 | set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON 41 | set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON 42 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON 43 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 44 | set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON 45 | set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON 46 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 47 | set_global_assignment -name ECO_OPTIMIZE_TIMING ON 48 | set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON 49 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 50 | set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW 51 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.0 52 | set_global_assignment -name SEED 1 53 | 54 | set_global_assignment -name VERILOG_MACRO "MISTER_DISABLE_ALSA=1" 55 | set_global_assignment -name VERILOG_MACRO "STV_BUILD=1" 56 | 57 | source sys/sys.tcl 58 | source sys/sys_dual_sdram.tcl 59 | source files.qip 60 | -------------------------------------------------------------------------------- /STV_DS.srf: -------------------------------------------------------------------------------- 1 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_kbd_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 2 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_mouse_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 3 | { "" "" "" "Synthesized away node \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|outclk_wire\[2\]\"" { } { } 0 14320 "" 0 0 "Design Software" 0 -1 0 ""} 4 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 5 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 6 | { "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Design Software" 0 -1 0 ""} 7 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 8 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(129): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 9 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(134): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 10 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(97): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 11 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(102): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 12 | { "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Design Software" 0 -1 0 ""} 13 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"pll_hdmi:pll_hdmi\|pll_hdmi_0002:pll_hdmi_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 14 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 15 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 16 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(594): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 17 | { "" "" "" "Ignored filter at sys_top.sdc(17): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 18 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(16): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Design Software" 0 -1 0 ""} 19 | { "" "" "" "Ignored filter at sys_top.sdc(37): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 20 | { "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""} 21 | { "" "" "" "*" { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 22 | { "" "" "" "*" { } { } 0 276027 "" 0 0 "Design Software" 0 -1 0 ""} 23 | { "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 24 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 25 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 26 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 27 | { "" "" "" "cyclonev_pll" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 28 | -------------------------------------------------------------------------------- /Saturn.qpf: -------------------------------------------------------------------------------- 1 | QUARTUS_VERSION = "17.0" 2 | PROJECT_REVISION = "Saturn" 3 | -------------------------------------------------------------------------------- /Saturn.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # 3 | # MiSTer project 4 | # 5 | # WARNING WARNING WARNING: 6 | # Do not add files to project in Quartus IDE! It will mess this file! 7 | # Add the files manually to files.qip file. 8 | # 9 | # -------------------------------------------------------------------------- 10 | 11 | set_global_assignment -name TOP_LEVEL_ENTITY sys_top 12 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 13 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 14 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 15 | 16 | set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition" 17 | 18 | set_global_assignment -name GENERATE_RBF_FILE ON 19 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 20 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 21 | set_global_assignment -name SAVE_DISK_SPACE OFF 22 | set_global_assignment -name SMART_RECOMPILE ON 23 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" 24 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 25 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 26 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 27 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF 28 | set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF 29 | set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS 30 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 31 | set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" 32 | set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON 33 | set_global_assignment -name QII_AUTO_PACKED_REGISTERS NORMAL 34 | set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON 35 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 36 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 37 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 38 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 39 | set_global_assignment -name MUX_RESTRUCTURE ON 40 | set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON 41 | set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON 42 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON 43 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 44 | set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON 45 | set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON 46 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 47 | set_global_assignment -name ECO_OPTIMIZE_TIMING ON 48 | set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON 49 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 50 | set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW 51 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.0 52 | set_global_assignment -name SEED 1 53 | 54 | set_global_assignment -name VERILOG_MACRO "MISTER_DISABLE_ALSA=1" 55 | 56 | source sys/sys.tcl 57 | source sys/sys_analog.tcl 58 | source files.qip 59 | 60 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /Saturn.sdc: -------------------------------------------------------------------------------- 1 | derive_pll_clocks 2 | derive_clock_uncertainty 3 | 4 | set_multicycle_path -to {*Hq2x*} -setup 4 5 | set_multicycle_path -to {*Hq2x*} -hold 3 6 | 7 | set_multicycle_path -from [get_clocks { *|pll|pll_inst|altera_pll_i|*[1].*|divclk}] -to {ascal|*} -setup 4 8 | set_multicycle_path -from [get_clocks { *|pll|pll_inst|altera_pll_i|*[1].*|divclk}] -to {ascal|*} -hold 3 9 | 10 | set_false_path -to [get_registers {emu:emu|Saturn:saturn|VDP1:VDP1|GRD_CALC_STEP*[*]}] -------------------------------------------------------------------------------- /Saturn.srf: -------------------------------------------------------------------------------- 1 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_kbd_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 2 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_mouse_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 3 | { "" "" "" "Synthesized away node \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|outclk_wire\[2\]\"" { } { } 0 14320 "" 0 0 "Design Software" 0 -1 0 ""} 4 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 5 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 6 | { "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Design Software" 0 -1 0 ""} 7 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 8 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(129): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 9 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(134): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 10 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(97): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 11 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(102): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 12 | { "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Design Software" 0 -1 0 ""} 13 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"pll_hdmi:pll_hdmi\|pll_hdmi_0002:pll_hdmi_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 14 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 15 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 16 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(594): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 17 | { "" "" "" "Ignored filter at sys_top.sdc(17): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 18 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(16): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Design Software" 0 -1 0 ""} 19 | { "" "" "" "Ignored filter at sys_top.sdc(37): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 20 | { "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""} 21 | { "" "" "" "*" { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 22 | { "" "" "" "*" { } { } 0 276027 "" 0 0 "Design Software" 0 -1 0 ""} 23 | { "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 24 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 25 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 26 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 27 | { "" "" "" "cyclonev_pll" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 28 | -------------------------------------------------------------------------------- /Saturn_DS.qpf: -------------------------------------------------------------------------------- 1 | QUARTUS_VERSION = "17.0" 2 | PROJECT_REVISION = "Saturn_DS" 3 | -------------------------------------------------------------------------------- /Saturn_DS.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # 3 | # MiSTer project 4 | # 5 | # WARNING WARNING WARNING: 6 | # Do not add files to project in Quartus IDE! It will mess this file! 7 | # Add the files manually to files.qip file. 8 | # 9 | # -------------------------------------------------------------------------- 10 | 11 | set_global_assignment -name TOP_LEVEL_ENTITY sys_top 12 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 13 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 14 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 15 | 16 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.1 Standard Edition" 17 | 18 | set_global_assignment -name GENERATE_RBF_FILE ON 19 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 20 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 21 | set_global_assignment -name SAVE_DISK_SPACE OFF 22 | set_global_assignment -name SMART_RECOMPILE ON 23 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" 24 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 25 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 26 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 27 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF 28 | set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF 29 | set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS 30 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 31 | set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" 32 | set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON 33 | set_global_assignment -name QII_AUTO_PACKED_REGISTERS NORMAL 34 | set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON 35 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 36 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 37 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 38 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 39 | set_global_assignment -name MUX_RESTRUCTURE ON 40 | set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON 41 | set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON 42 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON 43 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 44 | set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON 45 | set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON 46 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 47 | set_global_assignment -name ECO_OPTIMIZE_TIMING ON 48 | set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON 49 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 50 | set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW 51 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.0 52 | set_global_assignment -name SEED 1 53 | 54 | set_global_assignment -name VERILOG_MACRO "MISTER_DISABLE_ALSA=1" 55 | 56 | source sys/sys.tcl 57 | source sys/sys_dual_sdram.tcl 58 | source files.qip -------------------------------------------------------------------------------- /Saturn_DS.srf: -------------------------------------------------------------------------------- 1 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_kbd_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 2 | { "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_mouse_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 3 | { "" "" "" "Synthesized away node \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|outclk_wire\[2\]\"" { } { } 0 14320 "" 0 0 "Design Software" 0 -1 0 ""} 4 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 5 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 6 | { "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Design Software" 0 -1 0 ""} 7 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} 8 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(129): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 9 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(134): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 10 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(97): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 11 | { "" "" "" "Verilog HDL or VHDL warning at de10_top.v(102): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 12 | { "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Design Software" 0 -1 0 ""} 13 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"pll_hdmi:pll_hdmi\|pll_hdmi_0002:pll_hdmi_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 14 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} 15 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 16 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(594): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} 17 | { "" "" "" "Ignored filter at sys_top.sdc(17): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 18 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(16): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Design Software" 0 -1 0 ""} 19 | { "" "" "" "Ignored filter at sys_top.sdc(37): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Design Software" 0 -1 0 ""} 20 | { "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""} 21 | { "" "" "" "*" { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} 22 | { "" "" "" "*" { } { } 0 276027 "" 0 0 "Design Software" 0 -1 0 ""} 23 | { "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 24 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 25 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 26 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 27 | { "" "" "" "cyclonev_pll" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} 28 | -------------------------------------------------------------------------------- /Saturn_Q13.qpf: -------------------------------------------------------------------------------- 1 | QUARTUS_VERSION = "13.1" 2 | PROJECT_REVISION = "Saturn_Q13" 3 | -------------------------------------------------------------------------------- /Saturn_Q13.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # 3 | # MiSTer project 4 | # 5 | # WARNING WARNING WARNING: 6 | # Do not add files to project in Quartus IDE! It will mess this file! 7 | # Add the files manually to files.qip file. 8 | # 9 | # -------------------------------------------------------------------------- 10 | 11 | set_global_assignment -name TOP_LEVEL_ENTITY sys_top 12 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 13 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 14 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 15 | 16 | set_global_assignment -name LAST_QUARTUS_VERSION 13.1 17 | 18 | set_global_assignment -name GENERATE_RBF_FILE ON 19 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 20 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 21 | set_global_assignment -name SAVE_DISK_SPACE OFF 22 | set_global_assignment -name SMART_RECOMPILE ON 23 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" 24 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 25 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 26 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 27 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF 28 | set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF 29 | set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS 30 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 31 | set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON 32 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 33 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.0 34 | set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON 35 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 36 | set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF 37 | set_global_assignment -name OPTIMIZE_POWER_DURING_SYNTHESIS "NORMAL COMPILATION" 38 | set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" 39 | set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON 40 | set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW 41 | set_global_assignment -name SEED 1 42 | 43 | set_global_assignment -name VERILOG_MACRO "DEBUG=1" 44 | 45 | source sys/sys.tcl 46 | source sys/sys_dual_sdram.tcl 47 | set_global_assignment -name QIP_FILE files.qip 48 | -------------------------------------------------------------------------------- /Saturn_Q13.srf: -------------------------------------------------------------------------------- 1 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Quartus II" 0 -1 0 ""} 2 | { "" "" "" "Verilog HDL information at MC6845.v(280): always construct contains both blocking and non-blocking assignments" { } { } 0 10268 "" 0 0 "Quartus II" 0 -1 0 ""} 3 | { "" "" "" "Verilog HDL or VHDL warning at sys_top.v(601): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Quartus II" 0 -1 0 ""} 4 | { "" "" "" "Port \"extclk\" on the entity instantiation of \"cyclonev_pll\" is connected to a signal of width 1. The formal width of the signal in the module is 2. The extra bits will be left dangling without any fan-out logic." { } { } 0 12030 "" 0 0 "Quartus II" 0 -1 0 ""} 5 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Quartus II" 0 -1 0 ""} 6 | { "" "" "" "Dummy RLC values generated in IBIS model files for device 5CSEBA6 with package UFBGA and pin count 672" { } { } 0 205009 "" 0 0 "Quartus II" 0 -1 0 ""} 7 | { "" "" "" "Ignored filter at sys_top.sdc(10): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Quartus II" 0 -1 0 ""} 8 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(9): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Quartus II" 0 -1 0 ""} 9 | { "" "" "" "Ignored filter at sys_top.sdc(29): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Quartus II" 0 -1 0 ""} 10 | { "" "" "" "Timing characteristics of device 5CSEBA6U23I7 are preliminary" { } { } 0 334000 "" 0 0 "Quartus II" 0 -1 0 ""} 11 | { "" "" "" "Inferred RAM node \"emu:emu\|rom_map_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Quartus II" 0 -1 0 ""} 12 | { "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Quartus II" 0 -1 0 ""} 13 | { "" "" "" "Ignored filter at sys_top.sdc(17): vip\|output_inst\|vid_clk could not be matched with a net" { } { } 0 332174 "" 0 0 "Quartus II" 0 -1 0 ""} 14 | { "" "" "" "Ignored create_generated_clock at sys_top.sdc(16): Argument is an empty collection" { } { } 0 332049 "" 0 0 "Quartus II" 0 -1 0 ""} 15 | { "" "" "" "Ignored filter at sys_top.sdc(37): VID_CLK could not be matched with a clock" { } { } 0 332174 "" 0 0 "Quartus II" 0 -1 0 ""} 16 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Quartus II" 0 -1 0 ""} 17 | { "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Quartus II" 0 -1 0 ""} 18 | { "" "" "" "Ignoring invalid fast I/O register assignments. See the Ignored Assignments panel in the Fitter Compilation Report for more information." { } { } 0 176250 "" 0 0 "Quartus II" 0 -1 0 ""} 19 | { "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Quartus II" 0 -1 0 ""} 20 | { "" "" "" "*" { } { } 0 10268 "" 0 0 "Quartus II" 0 -1 0 ""} 21 | { "" "" "" "*" { } { } 0 276027 "" 0 0 "Quartus II" 0 -1 0 ""} 22 | { "" "" "" "*" { } { } 0 276020 "" 0 0 "Quartus II" 0 -1 0 ""} 23 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} 24 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} 25 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} 26 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del /s *.bak 3 | del /s *.orig 4 | del /s *.rej 5 | del /s *~ 6 | rmdir /s /q db 7 | rmdir /s /q incremental_db 8 | rmdir /s /q output_files 9 | rmdir /s /q simulation 10 | rmdir /s /q greybox_tmp 11 | rmdir /s /q hc_output 12 | rmdir /s /q .qsys_edit 13 | rmdir /s /q hps_isw_handoff 14 | rmdir /s /q sys\.qsys_edit 15 | rmdir /s /q sys\vip 16 | for /d %%i in (sys\*_sim) do rmdir /s /q "%%i" 17 | for /d %%i in (rtl\*_sim) do rmdir /s /q "%%i" 18 | del build_id.v 19 | del c5_pin_model_dump.txt 20 | del PLLJ_PLLSPE_INFO.txt 21 | del /s *.qws 22 | del /s *.ppf 23 | del /s *.ddb 24 | del /s *.csv 25 | del /s *.cmp 26 | del /s *.sip 27 | del /s *.spd 28 | del /s *.bsf 29 | del /s *.f 30 | del /s *.sopcinfo 31 | del /s *.xml 32 | del *.cdf 33 | del *.rpt 34 | del /s new_rtl_netlist 35 | del /s old_rtl_netlist 36 | pause 37 | -------------------------------------------------------------------------------- /files.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name QIP_FILE rtl/FX68K/fx68k.qip 2 | set_global_assignment -name QIP_FILE rtl/SH/SH7604/SH7604.qip 3 | set_global_assignment -name QIP_FILE rtl/SH/SH7034/SH7034.qip 4 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/SH_mem.sv 5 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/SH7604_mem.sv 6 | set_global_assignment -name QIP_FILE rtl/ADSP_21xx/ADSP_2181.qip 7 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/ADSP_21XX_mem.sv 8 | set_global_assignment -name QIP_FILE rtl/Saturn/Saturn.qip 9 | set_global_assignment -name VHDL_FILE rtl/CEGen.vhd 10 | set_global_assignment -name VHDL_FILE rtl/bram.vhd 11 | set_global_assignment -name VHDL_FILE rtl/mlab.vhd 12 | set_global_assignment -name VERILOG_FILE rtl/hps_ext.v 13 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram1.sv 14 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram2.sv 15 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/ddram.sv 16 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/vdp1_fb.sv 17 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/hps2pad.sv 18 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/ps2mouse.sv 19 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/lightgun.sv 20 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/cofi.sv 21 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/jtframe_resync.v 22 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/hps2cdd.sv 23 | set_global_assignment -name SDC_FILE Saturn.sdc 24 | set_global_assignment -name SYSTEMVERILOG_FILE Saturn.sv 25 | -------------------------------------------------------------------------------- /releases/Saturn_20231010.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/releases/Saturn_20231010.rbf -------------------------------------------------------------------------------- /releases/Saturn_20231018.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/releases/Saturn_20231018.rbf -------------------------------------------------------------------------------- /releases/Saturn_20240323.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/releases/Saturn_20240323.rbf -------------------------------------------------------------------------------- /releases/Saturn_20240628.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/releases/Saturn_20240628.rbf -------------------------------------------------------------------------------- /releases/Saturn_20250113.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/releases/Saturn_20250113.rbf -------------------------------------------------------------------------------- /rtl/ADSP_21xx/ADSP_2181.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ADSP_21XX_pkg.sv ] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ADSP_21XX_core.sv ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ADSP_2181.sv ] 4 | -------------------------------------------------------------------------------- /rtl/CEGen.vhd: -------------------------------------------------------------------------------- 1 | LIBRARY ieee; 2 | USE ieee.std_logic_1164.all; 3 | 4 | ENTITY CEGen IS 5 | PORT 6 | ( 7 | CLK : in STD_LOGIC; 8 | RST_N : in STD_LOGIC; 9 | 10 | IN_CLK : in integer; 11 | OUT_CLK : in integer; 12 | 13 | CE : out STD_LOGIC 14 | ); 15 | END CEGen; 16 | 17 | ARCHITECTURE SYN OF CEGen IS 18 | BEGIN 19 | process( RST_N, CLK ) 20 | variable CLK_SUM : integer; 21 | begin 22 | if RST_N = '0' then 23 | CLK_SUM := 0; 24 | CE <= '0'; 25 | elsif falling_edge(CLK) then 26 | CE <= '0'; 27 | CLK_SUM := CLK_SUM + OUT_CLK; 28 | if CLK_SUM >= IN_CLK then 29 | CLK_SUM := CLK_SUM - IN_CLK; 30 | CE <= '1'; 31 | end if; 32 | end if; 33 | end process; 34 | END SYN; 35 | -------------------------------------------------------------------------------- /rtl/FX68K/fx68k.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) fx68k.sv ] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) fx68kAlu.sv ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) uaddrPla.sv ] 4 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) fx68k.sdc ] -------------------------------------------------------------------------------- /rtl/FX68K/fx68k.sdc: -------------------------------------------------------------------------------- 1 | set_multicycle_path -start -setup -from [get_keepers *fx68k:*|Ir[*]] -to [get_keepers *fx68k:*|microAddr[*]] 2 2 | set_multicycle_path -start -hold -from [get_keepers *fx68k:*|Ir[*]] -to [get_keepers *fx68k:*|microAddr[*]] 1 3 | set_multicycle_path -start -setup -from [get_keepers *fx68k:*|Ir[*]] -to [get_keepers *fx68k:*|nanoAddr[*]] 2 4 | set_multicycle_path -start -hold -from [get_keepers *fx68k:*|Ir[*]] -to [get_keepers *fx68k:*|nanoAddr[*]] 1 5 | 6 | set_multicycle_path -start -setup -from {*|nanoLatch[*]} -to {*|excUnit|alu|pswCcr[*]} 2 7 | set_multicycle_path -start -hold -from {*|nanoLatch[*]} -to {*|excUnit|alu|pswCcr[*]} 1 8 | set_multicycle_path -start -setup -from {*|excUnit|alu|oper[*]} -to {*|excUnit|alu|pswCcr[*]} 2 9 | set_multicycle_path -start -hold -from {*|excUnit|alu|oper[*]} -to {*|excUnit|alu|pswCcr[*]} 1 -------------------------------------------------------------------------------- /rtl/SH/SH opcodes.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/rtl/SH/SH opcodes.xlsx -------------------------------------------------------------------------------- /rtl/SH/SH7034/MULT.sv: -------------------------------------------------------------------------------- 1 | module SH7034_MULT ( 2 | input CLK, 3 | input RST_N, 4 | input CE_R, 5 | input CE_F, 6 | 7 | input RES_N, 8 | 9 | input [27:0] CBUS_A, 10 | input [31:0] CBUS_DI, 11 | output [31:0] CBUS_DO, 12 | input CBUS_WR, 13 | input [3:0] CBUS_BA, 14 | input CBUS_REQ, 15 | output CBUS_BUSY, 16 | 17 | input [1:0] MAC_SEL, 18 | input [3:0] MAC_OP, 19 | input MAC_S, 20 | input MAC_WE 21 | ); 22 | 23 | import SH7034_PKG::*; 24 | 25 | bit [31:0] MACL; 26 | bit [9:0] MACH; 27 | bit [15:0] MA; 28 | bit [15:0] MB; 29 | 30 | wire [31:0] SRES = $signed(MA) * $signed(MB); 31 | wire [31:0] URES = $unsigned(MA) * $unsigned(MB); 32 | wire [41:0] ACC = {MACH,MACL} + {{10{SRES[31]}},SRES}; 33 | 34 | always @(posedge CLK or negedge RST_N) begin 35 | bit MUL_EXEC; 36 | bit MACW_EXEC; 37 | // bit SAT; 38 | bit SIGNED; 39 | bit [15:0] DW; 40 | 41 | if (!RST_N) begin 42 | MACL <= '0; 43 | MACH <= '0; 44 | MA <= '0; 45 | MB <= '0; 46 | MUL_EXEC <= 0; 47 | MACW_EXEC <= 0; 48 | SIGNED <= 0; 49 | // synopsys translate_off 50 | MACL <= 32'h01234567; 51 | MACH <= 10'h0EF; 52 | // synopsys translate_on 53 | end 54 | else begin 55 | if (MAC_SEL && MAC_WE && CE_R) begin 56 | case (MAC_OP) 57 | 4'b0100, //LDS Rm,MACx 58 | 4'b1000: begin //LDS @Rm+,MACx 59 | if (MAC_SEL[0]) MACL <= CBUS_DI; 60 | if (MAC_SEL[1]) MACH <= CBUS_DI[9:0]; 61 | end 62 | 4'b0001, //MUL.L 63 | 4'b0010, //DMULU.L 64 | 4'b0011: begin //DMULS.L 65 | end 66 | 4'b0110, //MULU.W 67 | 4'b0111: begin //MULS.W 68 | MA <= CBUS_DI[15:0]; 69 | MB <= CBUS_DI[31:16]; 70 | MUL_EXEC <= MAC_SEL[1]; 71 | SIGNED <= MAC_OP[0]; 72 | end 73 | 4'b1001: begin //MAC.L 74 | end 75 | 4'b1011: begin //MAC.W 76 | DW = !CBUS_A[1] ? CBUS_DI[31:16] : CBUS_DI[15:0]; 77 | if (MAC_SEL[0]) MA <= DW; 78 | if (MAC_SEL[1]) MB <= DW; 79 | MACW_EXEC <= MAC_SEL[1]; 80 | SIGNED <= MAC_OP[0]; 81 | // SAT <= MAC_S; 82 | end 83 | 4'b1111: {MACH,MACL} <= '0; 84 | endcase 85 | end 86 | 87 | if (MUL_EXEC) begin 88 | if (SIGNED) MACL <= SRES[31:0]; 89 | else MACL <= URES[31:0]; 90 | MUL_EXEC <= 0; 91 | end 92 | 93 | if (MACW_EXEC) begin 94 | {MACH,MACL} <= ACC; 95 | MACW_EXEC <= 0; 96 | end 97 | end 98 | end 99 | 100 | assign CBUS_DO = MAC_SEL[1] ? {{22{MACH[9]}},MACH} : MACL; 101 | assign CBUS_BUSY = 0; 102 | 103 | endmodule 104 | -------------------------------------------------------------------------------- /rtl/SH/SH7034/RAM.sv: -------------------------------------------------------------------------------- 1 | module SH7034_RAM 2 | ( 3 | input CLK, 4 | input RST_N, 5 | input CE_R, 6 | input CE_F, 7 | 8 | input [27:0] IBUS_A, 9 | input [31:0] IBUS_DI, 10 | output [31:0] IBUS_DO, 11 | input [3:0] IBUS_BA, 12 | input IBUS_WE, 13 | input IBUS_REQ, 14 | output IBUS_BUSY, 15 | output IBUS_ACT, 16 | 17 | 18 | output [7:0] DBG_CD_STATE, 19 | output [7:0] DBG_CD_FLAGS, 20 | output [7:0] DBG_CD_STATUS, 21 | output [7:0] DBG_CDD_RX_STAT, 22 | output [7:0] DBG_CDD_COMM0, 23 | output [7:0] DBG_CDD_COMM1, 24 | output [7:0] DBG_CDD_COMM11, 25 | output [7:0] DBG_7B0 26 | ); 27 | 28 | wire RAM_SEL = (IBUS_A[27:24] == 4'hF); 29 | 30 | bit [31:0] RAM_Q; 31 | wire [31:0] RAM_D = {IBUS_BA[3] ? IBUS_DI[31:24] : RAM_Q[31:24], 32 | IBUS_BA[2] ? IBUS_DI[23:16] : RAM_Q[23:16], 33 | IBUS_BA[1] ? IBUS_DI[15: 8] : RAM_Q[15: 8], 34 | IBUS_BA[0] ? IBUS_DI[ 7: 0] : RAM_Q[ 7: 0]}; 35 | CPU_RAM cpu_ram 36 | ( 37 | .clock(CLK), 38 | .wraddress(IBUS_A[11:2]), 39 | .data(RAM_D), 40 | .wren(IBUS_WE & RAM_SEL & CE_R), 41 | .rdaddress(IBUS_A[11:2]), 42 | .q(RAM_Q) 43 | ); 44 | 45 | assign IBUS_DO = RAM_Q; 46 | assign IBUS_BUSY = 0; 47 | assign IBUS_ACT = RAM_SEL; 48 | 49 | always @(posedge CLK or negedge RST_N) begin 50 | if (!RST_N) begin 51 | 52 | end else begin 53 | if (IBUS_WE & RAM_SEL & CE_R) begin 54 | case ({IBUS_A[11:2],2'b00}) 55 | 12'h288: begin 56 | if (IBUS_BA[1]) DBG_CD_STATUS <= IBUS_DI[15: 8]; 57 | end 58 | 12'h2A4: begin 59 | if (IBUS_BA[2]) DBG_CD_STATE <= IBUS_DI[23:16]; 60 | if (IBUS_BA[1]) DBG_CD_FLAGS <= IBUS_DI[15:8]; 61 | end 62 | 12'h2C4: begin 63 | if (IBUS_BA[3]) DBG_CDD_COMM0 <= IBUS_DI[31:24]; 64 | if (IBUS_BA[2]) DBG_CDD_COMM1 <= IBUS_DI[23:16]; 65 | end 66 | 12'h2CC: begin 67 | if (IBUS_BA[0]) DBG_CDD_COMM11 <= IBUS_DI[7:0]; 68 | end 69 | 12'h2D0: begin 70 | if (IBUS_BA[3]) DBG_CDD_RX_STAT <= IBUS_DI[31:24]; 71 | end 72 | 12'h7b0: begin 73 | if (IBUS_BA[3]) DBG_7B0 <= IBUS_DI[31:24]; 74 | end 75 | default; 76 | endcase 77 | end 78 | end 79 | end 80 | 81 | endmodule 82 | -------------------------------------------------------------------------------- /rtl/SH/SH7034/ROM.sv: -------------------------------------------------------------------------------- 1 | module SH7034_ROM 2 | #( 3 | parameter rom_file = "" 4 | ) 5 | ( 6 | input CLK, 7 | input RST_N, 8 | input CE_R, 9 | input CE_F, 10 | 11 | input [27:0] IBUS_A, 12 | input [31:0] IBUS_DI, 13 | output [31:0] IBUS_DO, 14 | input [3:0] IBUS_BA, 15 | input IBUS_WE, 16 | input IBUS_REQ, 17 | output IBUS_BUSY, 18 | output IBUS_ACT 19 | ); 20 | 21 | wire ROM_SEL = (IBUS_A[26:24] == 3'h0); 22 | bit [31:0] ROM_Q; 23 | CPU_ROM #(rom_file) cpu_rom 24 | ( 25 | .clock(CLK), 26 | .address(IBUS_A[15:2]), 27 | .q(ROM_Q) 28 | ); 29 | 30 | assign IBUS_DO = ROM_Q; 31 | assign IBUS_BUSY = 0; 32 | assign IBUS_ACT = ROM_SEL; 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /rtl/SH/SH7034/SH7034.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_pkg.sv ] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_regfile.sv ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_core.sv ] 4 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SH7034_pkg.sv ] 5 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SH7034_mem.sv ] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) MULT.sv ] 7 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) INTC.sv ] 8 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) BSC.sv ] 9 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) DMAC.sv ] 10 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) UBC.sv ] 11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ITU.sv ] 12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) WDT.sv ] 13 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCI.sv ] 14 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) PFC.sv ] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) RAM.sv ] 16 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ROM.sv ] 17 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SH7034.sv ] -------------------------------------------------------------------------------- /rtl/SH/SH7034/SH7034_mem.sv: -------------------------------------------------------------------------------- 1 | // synopsys translate_off 2 | `timescale 1 ps / 1 ps 3 | // synopsys translate_on 4 | 5 | // synopsys translate_off 6 | `define SIM 7 | // synopsys translate_on 8 | 9 | 10 | module CPU_RAM ( 11 | data, 12 | rdaddress, 13 | clock, 14 | wraddress, 15 | wren, 16 | q); 17 | 18 | input [31:0] data; 19 | input [9:0] rdaddress; 20 | input clock; 21 | input [9:0] wraddress; 22 | input wren; 23 | output [31:0] q; 24 | `ifndef ALTERA_RESERVED_QIS 25 | // synopsys translate_off 26 | `endif 27 | tri1 clock; 28 | tri0 wren; 29 | `ifndef ALTERA_RESERVED_QIS 30 | // synopsys translate_on 31 | `endif 32 | 33 | `ifdef SIM 34 | reg [31:0] MEM [1024]; 35 | 36 | initial begin 37 | MEM = '{1024{'0}}; 38 | end 39 | 40 | always @(posedge clock) begin 41 | if (wren) begin 42 | MEM[wraddress] <= data; 43 | end 44 | end 45 | 46 | wire [31:0] q = MEM[rdaddress]; 47 | `else 48 | wire [31:0] sub_wire0; 49 | wire [31:0] q = sub_wire0; 50 | 51 | altsyncram altsyncram_component ( 52 | .address_a (wraddress), 53 | .address_b (rdaddress), 54 | .clock0 (clock), 55 | .clock1 (clock), 56 | .data_a (data), 57 | .wren_a (wren), 58 | .q_b (sub_wire0), 59 | .aclr0 (1'b0), 60 | .aclr1 (1'b0), 61 | .addressstall_a (1'b0), 62 | .addressstall_b (1'b0), 63 | .byteena_a (1'b1), 64 | .byteena_b (1'b1), 65 | .clocken0 (1'b1), 66 | .clocken1 (1'b1), 67 | .clocken2 (1'b1), 68 | .clocken3 (1'b1), 69 | .data_b ({32{1'b1}}), 70 | .eccstatus (), 71 | .q_a (), 72 | .rden_a (1'b1), 73 | .rden_b (1'b1), 74 | .wren_b (1'b0)); 75 | defparam 76 | altsyncram_component.address_aclr_b = "NONE", 77 | altsyncram_component.address_reg_b = "CLOCK1", 78 | altsyncram_component.clock_enable_input_a = "BYPASS", 79 | altsyncram_component.clock_enable_input_b = "BYPASS", 80 | altsyncram_component.clock_enable_output_b = "BYPASS", 81 | altsyncram_component.intended_device_family = "Cyclone V", 82 | altsyncram_component.lpm_type = "altsyncram", 83 | altsyncram_component.numwords_a = 1024, 84 | altsyncram_component.numwords_b = 1024, 85 | altsyncram_component.operation_mode = "DUAL_PORT", 86 | altsyncram_component.outdata_aclr_b = "NONE", 87 | altsyncram_component.outdata_reg_b = "UNREGISTERED", 88 | altsyncram_component.power_up_uninitialized = "FALSE", 89 | altsyncram_component.widthad_a = 10, 90 | altsyncram_component.widthad_b = 10, 91 | altsyncram_component.width_a = 32, 92 | altsyncram_component.width_b = 32, 93 | altsyncram_component.width_byteena_a = 1; 94 | `endif 95 | 96 | endmodule 97 | 98 | 99 | module CPU_ROM #(parameter rom_file = "") 100 | ( 101 | address, 102 | clock, 103 | q); 104 | 105 | input [13:0] address; 106 | input clock; 107 | output [31:0] q; 108 | `ifndef ALTERA_RESERVED_QIS 109 | // synopsys translate_off 110 | `endif 111 | tri1 clock; 112 | `ifndef ALTERA_RESERVED_QIS 113 | // synopsys translate_on 114 | `endif 115 | 116 | `ifdef SIM 117 | reg [31:0] MEM [16*1024]; 118 | 119 | initial begin 120 | MEM = '{16*1024{'0}}; 121 | $readmemh(rom_file, MEM); 122 | 123 | end 124 | 125 | wire [31:0] q = MEM[address]; 126 | `else 127 | wire [31:0] sub_wire0; 128 | wire [31:0] q = sub_wire0[31:0]; 129 | 130 | altsyncram altsyncram_component ( 131 | .address_a (address), 132 | .clock0 (clock), 133 | .q_a (sub_wire0), 134 | .aclr0 (1'b0), 135 | .aclr1 (1'b0), 136 | .address_b (1'b1), 137 | .addressstall_a (1'b0), 138 | .addressstall_b (1'b0), 139 | .byteena_a (1'b1), 140 | .byteena_b (1'b1), 141 | .clock1 (1'b1), 142 | .clocken0 (1'b1), 143 | .clocken1 (1'b1), 144 | .clocken2 (1'b1), 145 | .clocken3 (1'b1), 146 | .data_a ({32{1'b1}}), 147 | .data_b (1'b1), 148 | .eccstatus (), 149 | .q_b (), 150 | .rden_a (1'b1), 151 | .rden_b (1'b1), 152 | .wren_a (1'b0), 153 | .wren_b (1'b0)); 154 | defparam 155 | altsyncram_component.address_aclr_a = "NONE", 156 | altsyncram_component.clock_enable_input_a = "BYPASS", 157 | altsyncram_component.clock_enable_output_a = "BYPASS", 158 | altsyncram_component.init_file = rom_file, 159 | altsyncram_component.intended_device_family = "Cyclone V", 160 | altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", 161 | altsyncram_component.lpm_type = "altsyncram", 162 | altsyncram_component.numwords_a = 16384, 163 | altsyncram_component.operation_mode = "ROM", 164 | altsyncram_component.outdata_aclr_a = "NONE", 165 | altsyncram_component.outdata_reg_a = "UNREGISTERED", 166 | altsyncram_component.widthad_a = 14, 167 | altsyncram_component.width_a = 32, 168 | altsyncram_component.width_byteena_a = 1; 169 | `endif 170 | 171 | endmodule 172 | 173 | -------------------------------------------------------------------------------- /rtl/SH/SH7034/UBC.sv: -------------------------------------------------------------------------------- 1 | module SH7034_UBC 2 | #(parameter bit DISABLE=0) 3 | ( 4 | input CLK, 5 | input RST_N, 6 | input CE_R, 7 | input CE_F, 8 | 9 | input RES_N, 10 | 11 | input [27:0] IBUS_A, 12 | input [31:0] IBUS_DI, 13 | output [31:0] IBUS_DO, 14 | input [3:0] IBUS_BA, 15 | input IBUS_WE, 16 | input IBUS_REQ, 17 | output IBUS_BUSY, 18 | output IBUS_ACT, 19 | 20 | output IRQ 21 | ); 22 | 23 | import SH7034_PKG::*; 24 | 25 | BAR_t BARH; 26 | BAR_t BARL; 27 | BAMR_t BAMRL; 28 | BAMR_t BAMRH; 29 | BBR_t BBR; 30 | 31 | wire REG_SEL = (IBUS_A >= 28'h5FFFF90 && IBUS_A <= 28'h5FFFF99); 32 | 33 | //Registers 34 | always @(posedge CLK or negedge RST_N) begin 35 | if (!RST_N) begin 36 | // synopsys translate_off 37 | BARH <= BAR_INIT; 38 | BARL <= BAR_INIT; 39 | BAMRL <= BAMR_INIT; 40 | BAMRH <= BAMR_INIT; 41 | BBR <= BBR_INIT; 42 | // synopsys translate_on 43 | end 44 | else begin 45 | if (!RES_N) begin 46 | BARH <= BAR_INIT; 47 | BARL <= BAR_INIT; 48 | BAMRL <= BAMR_INIT; 49 | BAMRH <= BAMR_INIT; 50 | BBR <= BBR_INIT; 51 | end else if (CE_R && !DISABLE) begin 52 | if (REG_SEL && IBUS_WE && IBUS_REQ) begin 53 | case ({IBUS_A[3:2],2'b00}) 54 | 4'h0: begin 55 | if (IBUS_BA[3]) BARH <= IBUS_DI[31:24] & BAR_WMASK[15: 8]; 56 | if (IBUS_BA[2]) BARH <= IBUS_DI[23:16] & BAR_WMASK[ 7: 0]; 57 | if (IBUS_BA[1]) BARL <= IBUS_DI[15: 8] & BAR_WMASK[15: 8]; 58 | if (IBUS_BA[0]) BARL <= IBUS_DI[ 7: 0] & BAR_WMASK[ 7: 0]; 59 | end 60 | 4'h4: begin 61 | if (IBUS_BA[3]) BAMRH <= IBUS_DI[31:24] & BAMR_WMASK[15: 8]; 62 | if (IBUS_BA[2]) BAMRH <= IBUS_DI[23:16] & BAMR_WMASK[ 7: 0]; 63 | if (IBUS_BA[1]) BAMRL <= IBUS_DI[15: 8] & BAMR_WMASK[15: 8]; 64 | if (IBUS_BA[0]) BAMRL <= IBUS_DI[ 7: 0] & BAMR_WMASK[ 7: 0]; 65 | end 66 | 4'h8: begin 67 | if (IBUS_BA[3]) BBR <= IBUS_DI[31:24] & BBR_WMASK[15: 8]; 68 | if (IBUS_BA[2]) BBR <= IBUS_DI[23:16] & BBR_WMASK[ 7: 0]; 69 | end 70 | default:; 71 | endcase 72 | end 73 | end 74 | end 75 | end 76 | 77 | assign IRQ = 0; 78 | 79 | 80 | bit [31:0] REG_DO; 81 | always @(posedge CLK or negedge RST_N) begin 82 | if (!RST_N) begin 83 | // synopsys translate_off 84 | REG_DO <= '0; 85 | // synopsys translate_on 86 | end 87 | else begin 88 | if (!RES_N) begin 89 | REG_DO <= '0; 90 | end else if (CE_F && !DISABLE) begin 91 | if (REG_SEL && !IBUS_WE && IBUS_REQ) begin 92 | case ({IBUS_A[3:2],2'b00}) 93 | 4'h0: REG_DO <= {BARH,BARL} & {BAR_RMASK,BAR_RMASK}; 94 | 4'h4: REG_DO <= {BAMRH,BAMRL} & {BAMR_RMASK,BAMR_RMASK}; 95 | 4'h8: REG_DO <= {BBR,16'h0000} & {BBR_RMASK,16'h0000}; 96 | default:REG_DO <= '0; 97 | endcase 98 | end 99 | end 100 | end 101 | end 102 | 103 | assign IBUS_DO = REG_SEL ? REG_DO : '0; 104 | assign IBUS_BUSY = 0; 105 | assign IBUS_ACT = REG_SEL; 106 | 107 | endmodule 108 | -------------------------------------------------------------------------------- /rtl/SH/SH7034/WDT.sv: -------------------------------------------------------------------------------- 1 | module SH7034_WDT 2 | #(parameter bit DISABLE=0) 3 | ( 4 | input CLK, 5 | input RST_N, 6 | input CE_R, 7 | input CE_F, 8 | 9 | input RES_N, 10 | 11 | output reg WDTOVF_N, 12 | 13 | input CLK2_CE, 14 | input CLK64_CE, 15 | input CLK128_CE, 16 | input CLK256_CE, 17 | input CLK512_CE, 18 | input CLK1024_CE, 19 | input CLK4096_CE, 20 | input CLK8192_CE, 21 | 22 | input [27:0] IBUS_A, 23 | input [31:0] IBUS_DI, 24 | output [31:0] IBUS_DO, 25 | input [3:0] IBUS_BA, 26 | input IBUS_WE, 27 | input IBUS_REQ, 28 | output IBUS_BUSY, 29 | output IBUS_ACT, 30 | 31 | output ITI_IRQ, 32 | output PRES, 33 | output MRES 34 | ); 35 | 36 | import SH7034_PKG::*; 37 | 38 | WTCNT_t WTCNT; 39 | WTCSR_t WTCSR; 40 | RSTCSR_t RSTCSR; 41 | bit WRES; 42 | 43 | //Clock selector 44 | bit WT_CE; 45 | always @(posedge CLK or negedge RST_N) begin 46 | if (!RST_N) begin 47 | // synopsys translate_off 48 | WT_CE <= 0; 49 | // synopsys translate_on 50 | end 51 | else begin 52 | if (!RES_N) begin 53 | WT_CE <= 0; 54 | end else if (CE_R && !DISABLE) begin 55 | case (WTCSR.CKS) 56 | 3'b000: WT_CE <= CLK2_CE; 57 | 3'b001: WT_CE <= CLK64_CE; 58 | 3'b010: WT_CE <= CLK128_CE; 59 | 3'b011: WT_CE <= CLK256_CE; 60 | 3'b100: WT_CE <= CLK512_CE; 61 | 3'b101: WT_CE <= CLK1024_CE; 62 | 3'b110: WT_CE <= CLK4096_CE; 63 | 3'b111: WT_CE <= CLK8192_CE; 64 | endcase 65 | end 66 | end 67 | end 68 | 69 | always @(posedge CLK or negedge RST_N) begin 70 | if (!RST_N) begin 71 | // synopsys translate_off 72 | WDTOVF_N <= 1; 73 | WRES <= 0; 74 | // synopsys translate_on 75 | end 76 | else begin 77 | if (!RES_N) begin 78 | WDTOVF_N <= 1; 79 | WRES <= 0; 80 | end else if (CE_R && !DISABLE) begin 81 | if (WT_CE) begin 82 | if (WTCNT == 8'hFF && WTCSR.WTIT) begin 83 | WDTOVF_N <= 0; 84 | WRES = RSTCSR.RSTE & ~RSTCSR.RSTS; 85 | end 86 | end 87 | 88 | if (!WDTOVF_N && CLK128_CE) WDTOVF_N <= 1; 89 | if (WRES && CLK512_CE) WRES <= 0; 90 | end 91 | end 92 | end 93 | 94 | assign ITI_IRQ = WTCSR.OVF; 95 | assign PRES = WRES & ~RSTCSR.RSTS; 96 | assign MRES = WRES & RSTCSR.RSTS; 97 | 98 | 99 | wire REG_SEL = (IBUS_A >= 28'h5FFFFB8 && IBUS_A <= 28'h5FFFFBB); 100 | 101 | //Registers 102 | always @(posedge CLK or negedge RST_N) begin 103 | if (!RST_N) begin 104 | // synopsys translate_off 105 | WTCNT <= WTCNT_INIT; 106 | WTCSR <= WTCSR_INIT; 107 | RSTCSR <= RSTCSR_INIT; 108 | // synopsys translate_on 109 | end 110 | else begin 111 | if (!RES_N) begin 112 | WTCNT <= WTCNT_INIT; 113 | WTCSR <= WTCSR_INIT; 114 | RSTCSR <= RSTCSR_INIT; 115 | end else if (CE_R && !DISABLE) begin 116 | if (WT_CE) begin 117 | if (WTCSR.TME) begin 118 | WTCNT <= WTCNT + 8'd1; 119 | end 120 | else begin 121 | WTCNT <= 8'h00; 122 | end 123 | 124 | if (WTCNT == 8'hFF) begin 125 | if (!WTCSR.WTIT) begin 126 | WTCSR.OVF <= 1; 127 | end 128 | else begin 129 | RSTCSR.WOVF <= 1; 130 | WTCSR <= 8'h18; 131 | end 132 | end 133 | end 134 | 135 | if (REG_SEL && IBUS_WE && IBUS_REQ) begin 136 | case (IBUS_A[1:0]) 137 | 2'h0: begin 138 | if (IBUS_DI[15:8] == 8'h5A) WTCNT <= IBUS_DI[7:0] & WTCNT_WMASK; 139 | else if (IBUS_DI[15:8] == 8'hA5) begin 140 | WTCSR[6:0] <= IBUS_DI[6:0] & WTCSR_WMASK[6:0]; 141 | if (!IBUS_DI[7]) WTCSR[7] <= 0; 142 | end 143 | end 144 | 2'h2: begin 145 | if (IBUS_DI[15:8] == 8'h5A) RSTCSR[6:0] <= IBUS_DI[6:0] & RSTCSR_WMASK[6:0]; 146 | else if (IBUS_DI[15:8] == 8'hA5 && !IBUS_DI[7]) RSTCSR[7] <= 0; 147 | end 148 | default:; 149 | endcase 150 | end 151 | end 152 | end 153 | end 154 | 155 | bit [31:0] REG_DO; 156 | always @(posedge CLK or negedge RST_N) begin 157 | if (!RST_N) begin 158 | // synopsys translate_off 159 | REG_DO <= '0; 160 | // synopsys translate_on 161 | end 162 | else begin 163 | if (!RES_N) begin 164 | REG_DO <= '0; 165 | end else if (CE_F && !DISABLE) begin 166 | if (REG_SEL && !IBUS_WE && IBUS_REQ) begin 167 | case (IBUS_A[1:0]) 168 | 2'h0: REG_DO <= {4{WTCSR & WTCSR_RMASK}}; 169 | 2'h1: REG_DO <= {4{WTCNT & WTCNT_RMASK}}; 170 | 2'h2: REG_DO <= '0; 171 | 2'h3: REG_DO <= {4{RSTCSR & RSTCSR_RMASK}}; 172 | default:; 173 | endcase 174 | end 175 | end 176 | end 177 | end 178 | 179 | assign IBUS_DO = REG_SEL ? REG_DO : 8'h00; 180 | assign IBUS_BUSY = 0; 181 | assign IBUS_ACT = REG_SEL; 182 | 183 | endmodule 184 | -------------------------------------------------------------------------------- /rtl/SH/SH7604/MSBY.sv: -------------------------------------------------------------------------------- 1 | module SH7604_MSBY ( 2 | input CLK, 3 | input RST_N, 4 | input CE_R, 5 | input CE_F, 6 | input EN, 7 | 8 | input RES_N, 9 | 10 | input [31:0] IBUS_A, 11 | input [31:0] IBUS_DI, 12 | output [31:0] IBUS_DO, 13 | input [3:0] IBUS_BA, 14 | input IBUS_WE, 15 | input IBUS_REQ, 16 | output IBUS_BUSY, 17 | output IBUS_ACT, 18 | 19 | output SBY 20 | ); 21 | 22 | import SH7604_PKG::*; 23 | 24 | SBYCR_t SBYCR; 25 | 26 | wire REG_SEL = (IBUS_A == 32'hFFFFFE91); 27 | always @(posedge CLK or negedge RST_N) begin 28 | if (!RST_N) begin 29 | SBYCR <= SBYCR_INIT; 30 | // synopsys translate_off 31 | // synopsys translate_on 32 | end 33 | else if (EN && CE_R) begin 34 | if (REG_SEL && IBUS_WE && IBUS_REQ) begin 35 | SBYCR <= IBUS_DI[23:16] & SBYCR_WMASK; 36 | end 37 | end 38 | end 39 | 40 | assign SBY = SBYCR.SBY; 41 | 42 | bit [31:0] REG_DO; 43 | always @(posedge CLK or negedge RST_N) begin 44 | if (!RST_N) begin 45 | REG_DO <= '0; 46 | end 47 | else if (CE_F) begin 48 | if (REG_SEL && !IBUS_WE && IBUS_REQ) begin 49 | REG_DO <= {4{SBYCR & SBYCR_RMASK}}; 50 | end 51 | end 52 | end 53 | 54 | assign IBUS_DO = REG_SEL ? REG_DO : 8'h00; 55 | assign IBUS_BUSY = 0; 56 | assign IBUS_ACT = REG_SEL; 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /rtl/SH/SH7604/MULT.sv: -------------------------------------------------------------------------------- 1 | module SH7604_MULT ( 2 | input CLK, 3 | input RST_N, 4 | input CE_R, 5 | input CE_F, 6 | input EN, 7 | 8 | input RES_N, 9 | 10 | input [31:0] CBUS_A, 11 | input [31:0] CBUS_DI, 12 | output [31:0] CBUS_DO, 13 | input CBUS_WR, 14 | input [3:0] CBUS_BA, 15 | input CBUS_REQ, 16 | output CBUS_BUSY, 17 | 18 | input [1:0] MAC_SEL, 19 | input [3:0] MAC_OP, 20 | input MAC_S, 21 | input MAC_WE 22 | ); 23 | 24 | import SH7604_PKG::*; 25 | 26 | bit [31:0] MACL; 27 | bit [31:0] MACH; 28 | bit [31:0] MA; 29 | bit [31:0] MB; 30 | bit MM_DONE; 31 | 32 | wire [63:0] SRES = $signed(MA) * $signed(MB); 33 | wire [63:0] URES = $unsigned(MA) * $unsigned(MB); 34 | wire [63:0] ACC64 = $signed({MACH,MACL}) + $signed(SRES); 35 | wire [32:0] ACC32 = $signed({MACL[31],MACL}) + $signed(SRES[32:0]); 36 | 37 | always @(posedge CLK or negedge RST_N) begin 38 | bit [ 1: 0] MM_CYC; 39 | bit MUL_EXEC; 40 | bit DMUL_EXEC; 41 | bit MACW_EXEC; 42 | bit MACL_EXEC; 43 | bit SAT; 44 | bit SIGNED; 45 | bit [15: 0] DW; 46 | 47 | if (!RST_N) begin 48 | MACL <= '0; 49 | MACH <= '0; 50 | MA <= '0; 51 | MB <= '0; 52 | MM_DONE <= 1; 53 | MM_CYC <= '0; 54 | MUL_EXEC <= 0; 55 | DMUL_EXEC <= 0; 56 | MACW_EXEC <= 0; 57 | MACL_EXEC <= 0; 58 | SIGNED <= 0; 59 | // synopsys translate_off 60 | MACL <= 32'h01234567; 61 | MACH <= 32'h89ABCDEF; 62 | // synopsys translate_on 63 | end 64 | else begin 65 | if (MAC_SEL && MAC_WE && EN && CE_R) begin 66 | MM_DONE <= 1; 67 | case (MAC_OP) 68 | 4'b0100, //LDS Rm,MACx 69 | 4'b1000: begin //LDS @Rm+,MACx 70 | if (MAC_SEL[0]) MACL <= CBUS_DI; 71 | if (MAC_SEL[1]) MACH <= CBUS_DI; 72 | end 73 | 4'b0001, //MUL.L 74 | 4'b0010, //DMULU.L 75 | 4'b0011: begin //DMULS.L 76 | if (MAC_SEL[0]) MA <= CBUS_DI; 77 | if (MAC_SEL[1]) begin 78 | MB <= CBUS_DI; 79 | MUL_EXEC <= ~MAC_OP[1]; 80 | DMUL_EXEC <= MAC_OP[1]; 81 | SIGNED <= MAC_OP[0] & MAC_OP[1]; 82 | MM_CYC <= 2'd3; 83 | MM_DONE <= 0; 84 | end 85 | end 86 | 4'b0110, //MULU.W 87 | 4'b0111: begin //MULS.W 88 | MA <= {{16{CBUS_DI[15]&MAC_OP[0]}},CBUS_DI[15:0]}; 89 | MB <= {{16{CBUS_DI[31]&MAC_OP[0]}},CBUS_DI[31:16]}; 90 | MUL_EXEC <= MAC_SEL[1]; 91 | SIGNED <= MAC_OP[0]; 92 | MM_CYC <= 2'd1; 93 | MM_DONE <= 0; 94 | end 95 | 4'b1001: begin //MAC.L @Rm+,@Rn+ 96 | if (MAC_SEL[0]) MA <= CBUS_DI; 97 | if (MAC_SEL[1]) begin 98 | MB <= CBUS_DI; 99 | MACL_EXEC <= 1; 100 | SIGNED <= MAC_OP[0]; 101 | SAT <= MAC_S; 102 | MM_CYC <= 2'd3; 103 | MM_DONE <= 0; 104 | end 105 | end 106 | 4'b1011: begin //MAC.W @Rm+,@Rn+ 107 | DW = !CBUS_A[1] ? CBUS_DI[31:16] : CBUS_DI[15:0]; 108 | if (MAC_SEL[0]) MA <= {{16{DW[15]&MAC_OP[0]}},DW}; 109 | if (MAC_SEL[1]) begin 110 | MB <= {{16{DW[15]&MAC_OP[0]}},DW}; 111 | MACW_EXEC <= 1; 112 | SIGNED <= MAC_OP[0]; 113 | SAT <= MAC_S; 114 | MM_CYC <= 2'd1; 115 | MM_DONE <= 0; 116 | end 117 | end 118 | 4'b1111: {MACH,MACL} <= '0; 119 | endcase 120 | end 121 | 122 | if (!MM_DONE && CE_R) begin 123 | if (MM_CYC) MM_CYC <= MM_CYC - 2'd1; 124 | if (MM_CYC == 2'd1) MM_DONE <= 1; 125 | end 126 | 127 | if (MUL_EXEC) begin 128 | if (SIGNED) MACL <= SRES[31:0]; 129 | else MACL <= URES[31:0]; 130 | MUL_EXEC <= 0; 131 | end 132 | 133 | if (DMUL_EXEC) begin 134 | if (SIGNED) {MACH,MACL} <= SRES; 135 | else {MACH,MACL} <= URES; 136 | DMUL_EXEC <= 0; 137 | end 138 | 139 | if (MACW_EXEC) begin 140 | if (!SAT) begin 141 | {MACH,MACL} <= ACC64; 142 | end else begin 143 | if (ACC32[32] != ACC32[31]) begin 144 | MACL <= {ACC32[32],{31{~ACC32[32]}}}; 145 | MACH <= 32'h00000001; 146 | end else begin 147 | MACL <= ACC32[31:0]; 148 | // MACH <= 32'h00000000;//?? 149 | end 150 | end 151 | MACW_EXEC <= 0; 152 | end 153 | 154 | if (MACL_EXEC) begin 155 | if (!SAT) begin 156 | {MACH,MACL} <= ACC64; 157 | end else begin 158 | {MACH,MACL} <= {{16{ACC64[63]}},ACC64[47:0]}; 159 | end 160 | MACL_EXEC <= 0; 161 | end 162 | end 163 | end 164 | 165 | assign CBUS_DO = MAC_SEL[1] ? MACH : MACL; 166 | assign CBUS_BUSY = ~MM_DONE && |MAC_SEL; 167 | 168 | endmodule 169 | -------------------------------------------------------------------------------- /rtl/SH/SH7604/SH7604.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_pkg.sv ] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_regfile.sv ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../core/SH_core.sv ] 4 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SH7604_pkg.sv ] 5 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) CACHE.sv ] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) BSC.sv ] 7 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) DMAC.sv ] 8 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) UBC.sv ] 9 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) INTC.sv ] 10 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) FRT.sv ] 11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) WDT.sv ] 12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCI.sv ] 13 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) DIVU.sv ] 14 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) MULT.sv ] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) MSBY.sv ] 16 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SH7604.sv ] 17 | -------------------------------------------------------------------------------- /rtl/SH/SH7604/UBC.sv: -------------------------------------------------------------------------------- 1 | module SH7604_UBC 2 | #(parameter bit DISABLE=0) 3 | ( 4 | input CLK, 5 | input RST_N, 6 | input CE_R, 7 | input CE_F, 8 | input EN, 9 | 10 | input RES_N, 11 | 12 | input [31:0] IBUS_A, 13 | input [31:0] IBUS_DI, 14 | output [31:0] IBUS_DO, 15 | input [3:0] IBUS_BA, 16 | input IBUS_WE, 17 | input IBUS_REQ, 18 | output IBUS_BUSY, 19 | output IBUS_ACT, 20 | 21 | output IRQ 22 | ); 23 | 24 | import SH7604_PKG::*; 25 | 26 | BARx_t BARAH; 27 | BARx_t BARAL; 28 | BAMRx_t BAMRAL; 29 | BAMRx_t BAMRAH; 30 | BBRx_t BBRA; 31 | BARx_t BARBH; 32 | BARx_t BARBL; 33 | BAMRx_t BAMRBL; 34 | BAMRx_t BAMRBH; 35 | BDRB_t BDRBH; 36 | BDRB_t BDRBL; 37 | BDMRB_t BDMRBL; 38 | BDMRB_t BDMRBH; 39 | BBRx_t BBRB; 40 | BRCR_t BRCR; 41 | 42 | wire REG_SEL = (IBUS_A >= 32'hFFFFFF40 && IBUS_A <= 32'hFFFFFF7C); 43 | 44 | //Registers 45 | always @(posedge CLK or negedge RST_N) begin 46 | if (!RST_N) begin 47 | // synopsys translate_off 48 | BARAH <= BARx_INIT; 49 | BARAL <= BARx_INIT; 50 | BAMRAL <= BAMRx_INIT; 51 | BAMRAH <= BAMRx_INIT; 52 | BBRA <= BBRx_INIT; 53 | BARBH <= BARx_INIT; 54 | BARBL <= BARx_INIT; 55 | BAMRBL <= BAMRx_INIT; 56 | BAMRBH <= BAMRx_INIT; 57 | BDRBH <= BDRB_INIT; 58 | BDRBL <= BDRB_INIT; 59 | BDMRBL <= BDMRB_INIT; 60 | BDMRBH <= BDMRB_INIT; 61 | BBRB <= BBRx_INIT; 62 | BRCR <= BRCR_INIT; 63 | // synopsys translate_on 64 | end 65 | else if (EN && CE_R && !DISABLE) begin 66 | if (!RES_N) begin 67 | BARAH <= BARx_INIT; 68 | BARAL <= BARx_INIT; 69 | BAMRAL <= BAMRx_INIT; 70 | BAMRAH <= BAMRx_INIT; 71 | BBRA <= BBRx_INIT; 72 | BARBH <= BARx_INIT; 73 | BARBL <= BARx_INIT; 74 | BAMRBL <= BAMRx_INIT; 75 | BAMRBH <= BAMRx_INIT; 76 | BDRBH <= BDRB_INIT; 77 | BDRBL <= BDRB_INIT; 78 | BDMRBL <= BDMRB_INIT; 79 | BDMRBH <= BDMRB_INIT; 80 | BBRB <= BBRx_INIT; 81 | BRCR <= BRCR_INIT; 82 | end 83 | else if (REG_SEL && IBUS_WE && IBUS_REQ) begin 84 | case ({IBUS_A[5:2],2'b00}) 85 | 6'h00: begin 86 | if (IBUS_BA[3:2]) BARAH <= IBUS_DI[31:16] & BARx_WMASK; 87 | if (IBUS_BA[1:0]) BARAL <= IBUS_DI[15:0] & BARx_WMASK; 88 | end 89 | 6'h04: begin 90 | if (IBUS_BA[3:2]) BAMRAH <= IBUS_DI[31:16] & BAMRx_WMASK; 91 | if (IBUS_BA[1:0]) BAMRAL <= IBUS_DI[15:0] & BAMRx_WMASK; 92 | end 93 | 6'h08: begin 94 | if (IBUS_BA[3:2]) BBRA <= IBUS_DI[31:16] & BBRx_WMASK; 95 | end 96 | 6'h20: begin 97 | if (IBUS_BA[3:2]) BARBH <= IBUS_DI[31:16] & BARx_WMASK; 98 | if (IBUS_BA[1:0]) BARBL <= IBUS_DI[15:0] & BARx_WMASK; 99 | end 100 | 6'h24: begin 101 | if (IBUS_BA[3:2]) BAMRBH <= IBUS_DI[31:16] & BAMRx_WMASK; 102 | if (IBUS_BA[1:0]) BAMRBL <= IBUS_DI[15:0] & BAMRx_WMASK; 103 | end 104 | 6'h28: begin 105 | if (IBUS_BA[3:2]) BBRB <= IBUS_DI[31:16] & BBRx_WMASK; 106 | end 107 | 6'h30: begin 108 | if (IBUS_BA[3:2]) BDRBH <= IBUS_DI[31:16] & BDRB_WMASK; 109 | if (IBUS_BA[1:0]) BDRBL <= IBUS_DI[15:0] & BDRB_WMASK; 110 | end 111 | 6'h34: begin 112 | if (IBUS_BA[3:2]) BDMRBH <= IBUS_DI[31:16] & BDMRB_WMASK; 113 | if (IBUS_BA[1:0]) BDMRBL <= IBUS_DI[15:0] & BDMRB_WMASK; 114 | end 115 | 6'h38: begin 116 | if (IBUS_BA[3:2]) BRCR <= IBUS_DI[31:16] & BRCR_WMASK; 117 | end 118 | default:; 119 | endcase 120 | end 121 | end 122 | end 123 | 124 | assign IRQ = 0; 125 | 126 | 127 | bit [31:0] REG_DO; 128 | always @(posedge CLK or negedge RST_N) begin 129 | if (!RST_N) begin 130 | // synopsys translate_off 131 | REG_DO <= '0; 132 | // synopsys translate_on 133 | end 134 | else begin 135 | if (!RES_N) begin 136 | REG_DO <= '0; 137 | end else if (CE_F && !DISABLE) begin 138 | if (REG_SEL && !IBUS_WE && IBUS_REQ) begin 139 | case ({IBUS_A[5:2],2'b00}) 140 | 6'h00: REG_DO <= {BARAH,BARAL} & {BARx_RMASK,BARx_RMASK}; 141 | 6'h04: REG_DO <= {BAMRAH,BAMRAL} & {BAMRx_RMASK,BAMRx_RMASK}; 142 | 6'h08: REG_DO <= {BBRA,BBRA} & {BBRx_RMASK,BBRx_RMASK}; 143 | 6'h20: REG_DO <= {BARBH,BARBL} & {BARx_RMASK,BARx_RMASK}; 144 | 6'h24: REG_DO <= {BAMRBH,BAMRBL} & {BAMRx_RMASK,BAMRx_RMASK}; 145 | 6'h28: REG_DO <= {BBRB,BBRB} & {BBRx_RMASK,BBRx_RMASK}; 146 | 6'h30: REG_DO <= {BDRBH,BDRBL} & {BDRB_RMASK,BDRB_RMASK}; 147 | 6'h34: REG_DO <= {BDMRBH,BDMRBL} & {BDMRB_RMASK,BDMRB_RMASK}; 148 | 6'h38: REG_DO <= {BRCR,BRCR} & {BRCR_RMASK,BRCR_RMASK}; 149 | default:REG_DO <= '0; 150 | endcase 151 | end 152 | end 153 | end 154 | end 155 | 156 | assign IBUS_DO = REG_SEL ? REG_DO : '0; 157 | assign IBUS_BUSY = 0; 158 | assign IBUS_ACT = REG_SEL; 159 | 160 | endmodule 161 | -------------------------------------------------------------------------------- /rtl/SH/SH7604/WDT.sv: -------------------------------------------------------------------------------- 1 | module SH7604_WDT 2 | #(parameter bit DISABLE=0) 3 | ( 4 | input CLK, 5 | input RST_N, 6 | input CE_R, 7 | input CE_F, 8 | input EN, 9 | 10 | input RES_N, 11 | input SBY, 12 | 13 | output reg WDTOVF_N, 14 | 15 | input CLK2_CE, 16 | input CLK64_CE, 17 | input CLK128_CE, 18 | input CLK256_CE, 19 | input CLK512_CE, 20 | input CLK1024_CE, 21 | input CLK4096_CE, 22 | input CLK8192_CE, 23 | 24 | input [31:0] IBUS_A, 25 | input [31:0] IBUS_DI, 26 | output [31:0] IBUS_DO, 27 | input [3:0] IBUS_BA, 28 | input IBUS_WE, 29 | input IBUS_REQ, 30 | output IBUS_BUSY, 31 | output IBUS_ACT, 32 | 33 | output ITI_IRQ, 34 | output PRES, 35 | output MRES 36 | ); 37 | 38 | import SH7604_PKG::*; 39 | 40 | WTCNT_t WTCNT; 41 | WTCSR_t WTCSR; 42 | RSTCSR_t RSTCSR; 43 | bit WRES; 44 | 45 | //Clock selector 46 | bit WT_CE; 47 | always_comb begin 48 | case (WTCSR.CKS) 49 | 3'b000: WT_CE = CLK2_CE; 50 | 3'b001: WT_CE = CLK64_CE; 51 | 3'b010: WT_CE = CLK128_CE; 52 | 3'b011: WT_CE = CLK256_CE; 53 | 3'b100: WT_CE = CLK512_CE; 54 | 3'b101: WT_CE = CLK1024_CE; 55 | 3'b110: WT_CE = CLK4096_CE; 56 | 3'b111: WT_CE = CLK8192_CE; 57 | endcase 58 | end 59 | 60 | always @(posedge CLK or negedge RST_N) begin 61 | if (!RST_N) begin 62 | // synopsys translate_off 63 | WDTOVF_N <= 1; 64 | WRES <= 0; 65 | // synopsys translate_onn 66 | end 67 | else begin 68 | if (!RES_N) begin 69 | WDTOVF_N <= 1; 70 | WRES <= 0; 71 | end else if (EN && CE_R && !DISABLE) begin 72 | if (WT_CE) begin 73 | if (WTCNT == 8'hFF && WTCSR.WTIT) begin 74 | WDTOVF_N <= 0; 75 | WRES <= RSTCSR.RSTE & ~RSTCSR.RSTS; 76 | end 77 | end 78 | 79 | if (!WDTOVF_N && CLK128_CE) WDTOVF_N <= 1; 80 | if (WRES && CLK512_CE) WRES <= 0; 81 | end 82 | end 83 | end 84 | 85 | assign PRES = WRES & ~RSTCSR.RSTS; 86 | assign MRES = WRES & RSTCSR.RSTS; 87 | 88 | 89 | //Registers 90 | wire REG_SEL = (IBUS_A >= 32'hFFFFFE80 && IBUS_A <= 32'hFFFFFE8F); 91 | always @(posedge CLK or negedge RST_N) begin 92 | if (!RST_N) begin 93 | // synopsys translate_off 94 | WTCNT <= WTCNT_INIT; 95 | WTCSR <= WTCSR_INIT; 96 | RSTCSR <= RSTCSR_INIT; 97 | // synopsys translate_on 98 | end 99 | else begin 100 | if (!RES_N) begin 101 | WTCNT <= WTCNT_INIT; 102 | WTCSR <= WTCSR_INIT; 103 | RSTCSR <= RSTCSR_INIT; 104 | end else if (EN && CE_R && !DISABLE) begin 105 | if (WT_CE) begin 106 | if (WTCSR.TME) begin 107 | WTCNT <= WTCNT + 8'd1; 108 | end 109 | 110 | if (WTCNT == 8'hFF) begin 111 | if (!WTCSR.WTIT) begin 112 | WTCSR.OVF <= 1; 113 | end 114 | else begin 115 | RSTCSR.WOVF <= 1; 116 | WTCSR <= 8'h18; 117 | end 118 | end 119 | end 120 | 121 | if (!RES_N) begin 122 | WTCNT <= WTCNT_INIT; 123 | WTCSR <= WTCSR_INIT; 124 | RSTCSR <= RSTCSR_INIT; 125 | end else if (SBY) begin 126 | WTCNT <= WTCNT_INIT;//? 127 | WTCSR[7:3] <= WTCSR_INIT[7:3]; 128 | RSTCSR <= RSTCSR_INIT; 129 | end else if (REG_SEL && IBUS_WE && IBUS_REQ) begin 130 | case (IBUS_A[3:0]) 131 | 4'h0, 132 | 4'h8: begin 133 | if (IBUS_DI[15:8] == 8'h5A) WTCNT <= IBUS_DI[7:0] & WTCNT_WMASK; 134 | else if (IBUS_DI[15:8] == 8'hA5) begin 135 | WTCSR[6:0] <= IBUS_DI[6:0] & WTCSR_WMASK[6:0]; 136 | if (!IBUS_DI[7]) WTCSR[7] <= 0; 137 | if (!IBUS_DI[5]) begin WTCNT <= 8'h00; WTCSR[7] <= 0; end//? 138 | end 139 | end 140 | 4'h2, 141 | 4'hA: begin 142 | if (IBUS_DI[15:8] == 8'h5A) RSTCSR[6:0] <= IBUS_DI[6:0] & RSTCSR_WMASK[6:0]; 143 | else if (IBUS_DI[15:8] == 8'hA5 && !IBUS_DI[7]) RSTCSR[7] <= 0; 144 | end 145 | default:; 146 | endcase 147 | end 148 | end 149 | end 150 | end 151 | 152 | assign ITI_IRQ = WTCSR.OVF; 153 | 154 | 155 | bit [31:0] REG_DO; 156 | always @(posedge CLK or negedge RST_N) begin 157 | if (!RST_N) begin 158 | REG_DO <= '0; 159 | end 160 | else begin 161 | if (!RES_N) begin 162 | REG_DO <= '0; 163 | end else if (CE_F && !DISABLE) begin 164 | if (REG_SEL && !IBUS_WE && IBUS_REQ) begin 165 | case (IBUS_A[3:0]) 166 | 4'h0, 167 | 4'h8: REG_DO <= {4{WTCSR & WTCSR_RMASK}}; 168 | 4'h1, 169 | 4'h9: REG_DO <= {4{WTCNT & WTCNT_RMASK}}; 170 | 4'h2, 171 | 4'hA: REG_DO <= '0; 172 | 4'h3, 173 | 4'hB: REG_DO <= {4{RSTCSR & RSTCSR_RMASK}}; 174 | default:; 175 | endcase 176 | end 177 | end 178 | end 179 | end 180 | 181 | assign IBUS_DO = REG_SEL ? REG_DO : '0; 182 | assign IBUS_BUSY = 0; 183 | assign IBUS_ACT = REG_SEL; 184 | 185 | endmodule 186 | -------------------------------------------------------------------------------- /rtl/SH/core/SH_mem.sv: -------------------------------------------------------------------------------- 1 | // synopsys translate_off 2 | `timescale 1 ps / 1 ps 3 | // synopsys translate_on 4 | 5 | module SH_regram ( 6 | clock, 7 | data, 8 | rdaddress, 9 | wraddress, 10 | wren, 11 | q); 12 | 13 | input clock; 14 | input [31:0] data; 15 | input [4:0] rdaddress; 16 | input [4:0] wraddress; 17 | input wren; 18 | output [31:0] q; 19 | `ifndef ALTERA_RESERVED_QIS 20 | // synopsys translate_off 21 | `endif 22 | tri0 wren; 23 | `ifndef ALTERA_RESERVED_QIS 24 | // synopsys translate_on 25 | `endif 26 | 27 | wire [31:0] sub_wire0; 28 | wire [31:0] q = sub_wire0[31:0]; 29 | 30 | // altsyncram altsyncram_component ( 31 | // .address_a (wraddress), 32 | // .address_b (rdaddress), 33 | // .clock0 (clock), 34 | // .clock1 (~clock), 35 | // .data_a (data), 36 | // .wren_a (wren), 37 | // .q_b (sub_wire0), 38 | // .aclr0 (1'b0), 39 | // .aclr1 (1'b0), 40 | // .addressstall_a (1'b0), 41 | // .addressstall_b (1'b0), 42 | // .byteena_a (1'b1), 43 | // .byteena_b (1'b1), 44 | // .clocken0 (1'b1), 45 | // .clocken1 (1'b1), 46 | // .clocken2 (1'b1), 47 | // .clocken3 (1'b1), 48 | // .data_b ({32{1'b1}}), 49 | // .eccstatus (), 50 | // .q_a (), 51 | // .rden_a (1'b1), 52 | // .rden_b (1'b1), 53 | // .wren_b (1'b0)); 54 | // defparam 55 | // altsyncram_component.address_aclr_b = "NONE", 56 | // altsyncram_component.address_reg_b = "CLOCK1", 57 | // altsyncram_component.clock_enable_input_a = "BYPASS", 58 | // altsyncram_component.clock_enable_input_b = "BYPASS", 59 | // altsyncram_component.clock_enable_output_b = "BYPASS", 60 | // altsyncram_component.intended_device_family = "Cyclone V", 61 | // altsyncram_component.lpm_type = "altsyncram", 62 | // altsyncram_component.numwords_a = 32, 63 | // altsyncram_component.numwords_b = 32, 64 | // altsyncram_component.operation_mode = "DUAL_PORT", 65 | // altsyncram_component.outdata_aclr_b = "NONE", 66 | // altsyncram_component.outdata_reg_b = "UNREGISTERED", 67 | // altsyncram_component.power_up_uninitialized = "FALSE", 68 | // altsyncram_component.widthad_a = 5, 69 | // altsyncram_component.widthad_b = 5, 70 | // altsyncram_component.width_a = 32, 71 | // altsyncram_component.width_b = 32, 72 | // altsyncram_component.width_byteena_a = 1; 73 | 74 | altdpram altdpram_component ( 75 | .data (data), 76 | .inclock (clock), 77 | .outclock (clock), 78 | .rdaddress (rdaddress), 79 | .wraddress (wraddress), 80 | .wren (wren), 81 | .q (sub_wire0), 82 | .aclr (1'b0), 83 | .byteena (1'b1), 84 | .inclocken (1'b1), 85 | .outclocken (1'b1), 86 | .rdaddressstall (1'b0), 87 | .rden (1'b1), 88 | // .sclr (1'b0), 89 | .wraddressstall (1'b0)); 90 | defparam 91 | altdpram_component.indata_aclr = "OFF", 92 | altdpram_component.indata_reg = "INCLOCK", 93 | altdpram_component.intended_device_family = "Cyclone V", 94 | altdpram_component.lpm_type = "altdpram", 95 | altdpram_component.outdata_aclr = "OFF", 96 | altdpram_component.outdata_reg = "UNREGISTERED", 97 | altdpram_component.ram_block_type = "MLAB", 98 | altdpram_component.rdaddress_aclr = "OFF", 99 | altdpram_component.rdaddress_reg = "UNREGISTERED", 100 | altdpram_component.rdcontrol_aclr = "OFF", 101 | altdpram_component.rdcontrol_reg = "UNREGISTERED", 102 | altdpram_component.read_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE", 103 | altdpram_component.width = 32, 104 | altdpram_component.widthad = 5, 105 | altdpram_component.width_byteena = 1, 106 | altdpram_component.wraddress_aclr = "OFF", 107 | altdpram_component.wraddress_reg = "INCLOCK", 108 | altdpram_component.wrcontrol_aclr = "OFF", 109 | altdpram_component.wrcontrol_reg = "INCLOCK"; 110 | 111 | endmodule 112 | -------------------------------------------------------------------------------- /rtl/SH/core/SH_regfile.sv: -------------------------------------------------------------------------------- 1 | module SH2_regfile ( 2 | input CLK, 3 | input RST_N, 4 | input CE, 5 | input EN, 6 | 7 | input [4:0] WA_ADDR, 8 | input [31:0] WA_D, 9 | input WAE, 10 | input [4:0] WB_ADDR, 11 | input [31:0] WB_D, 12 | input WBE, 13 | 14 | input [4:0] RA_ADDR, 15 | output [31:0] RA_Q, 16 | input [4:0] RB_ADDR, 17 | output [31:0] RB_Q, 18 | output [31:0] R0_Q 19 | 20 | `ifdef DEBUG 21 | , 22 | output [31:0] R0, 23 | output [31:0] R1, 24 | output [31:0] R2, 25 | output [31:0] R3, 26 | output [31:0] R4, 27 | output [31:0] R5, 28 | output [31:0] R6, 29 | output [31:0] R7, 30 | output [31:0] R8, 31 | output [31:0] R9, 32 | output [31:0] R10, 33 | output [31:0] R11, 34 | output [31:0] R12, 35 | output [31:0] R13, 36 | output [31:0] R14, 37 | output [31:0] R15, 38 | output [31:0] PR_ 39 | `endif 40 | ); 41 | 42 | // synopsys translate_off 43 | `define SIM 44 | // synopsys translate_on 45 | 46 | `ifdef SIM 47 | 48 | reg [31:0] GR[16+1]; 49 | 50 | bit [4:0] WB_ADDR_LATCH; 51 | bit [31:0] WB_D_LATCH; 52 | bit WBE_LATCH; 53 | always @(posedge CLK or negedge RST_N) begin 54 | if (!RST_N) begin 55 | WB_ADDR_LATCH <= '0; 56 | WB_D_LATCH <= '0; 57 | WBE_LATCH <= 0; 58 | end 59 | else begin 60 | WBE_LATCH <= 0; 61 | if (CE) begin 62 | WB_ADDR_LATCH <= WB_ADDR; 63 | WB_D_LATCH <= WB_D; 64 | WBE_LATCH <= WBE; 65 | end 66 | end 67 | end 68 | 69 | always @(posedge CLK or negedge RST_N) begin 70 | if (!RST_N) begin 71 | GR <= '{'h01234567,'h11111111,'h89ABCDEF,'h11111111,'0,'0,'0,'0,'0,'0,'0,'0,'0,'0,'0,'0,'0}; 72 | end 73 | else if (EN) begin 74 | if (WAE && CE) begin 75 | GR[WA_ADDR] <= WA_D; 76 | end 77 | if (WBE_SAVE) begin 78 | GR[WB_ADDR_LATCH] <= WB_D_LATCH; 79 | end 80 | end 81 | end 82 | 83 | assign RA_Q = GR[RA_ADDR]; 84 | assign RB_Q = GR[RB_ADDR]; 85 | 86 | reg [31:0] GR0; 87 | always @(posedge CLK or negedge RST_N) begin 88 | if (!RST_N) begin 89 | GR0 <= '0; 90 | end 91 | else if (EN) begin 92 | if (WAE && !WA_ADDR && CE) begin 93 | GR0 <= WA_D; 94 | end 95 | if (WBE_LATCH && !WB_ADDR_LATCH) begin 96 | GR0 <= WB_D_LATCH; 97 | end 98 | end 99 | end 100 | 101 | assign R0_Q = GR0; 102 | 103 | `else 104 | 105 | bit [4:0] WB_ADDR_LATCH; 106 | bit [31:0] WB_D_LATCH; 107 | bit WBE_LATCH; 108 | always @(posedge CLK or negedge RST_N) begin 109 | if (!RST_N) begin 110 | WB_ADDR_LATCH <= '0; 111 | WB_D_LATCH <= '0; 112 | WBE_LATCH <= 0; 113 | end 114 | else begin 115 | WBE_LATCH <= 0; 116 | if (CE) begin 117 | WB_ADDR_LATCH <= WB_ADDR; 118 | WB_D_LATCH <= WB_D; 119 | WBE_LATCH <= WBE; 120 | end 121 | end 122 | end 123 | 124 | wire [4:0] W_ADDR = CE ? WA_ADDR : WB_ADDR_LATCH; 125 | wire [31:0] REG_D = CE ? WA_D : WB_D_LATCH; 126 | wire REG_WE = (WAE & ~WA_ADDR[4] & CE) | (WBE_LATCH & ~WB_ADDR_LATCH[4]); 127 | bit [31:0] RAMA_Q, RAMB_Q; 128 | SH_regram regramA(.clock(CLK), .wraddress(W_ADDR[3:0]), .data(REG_D), .wren(REG_WE & EN), .rdaddress(RA_ADDR[3:0]), .q(RAMA_Q)); 129 | SH_regram regramB(.clock(CLK), .wraddress(W_ADDR[3:0]), .data(REG_D), .wren(REG_WE & EN), .rdaddress(RB_ADDR[3:0]), .q(RAMB_Q)); 130 | 131 | bit [31:0] PR; 132 | always @(posedge CLK or negedge RST_N) begin 133 | if (!RST_N) begin 134 | PR <= '0; 135 | end 136 | else if (EN) begin 137 | if (WAE && WA_ADDR[4] && CE) begin 138 | PR <= WA_D; 139 | end 140 | if (WBE_LATCH && WB_ADDR_LATCH[4]) begin 141 | PR <= WB_D_LATCH; 142 | end 143 | end 144 | end 145 | assign RA_Q = RA_ADDR[4] ? PR : RAMA_Q; 146 | assign RB_Q = RB_ADDR[4] ? PR : RAMB_Q; 147 | 148 | bit [31:0] GR0; 149 | always @(posedge CLK or negedge RST_N) begin 150 | if (!RST_N) begin 151 | GR0 <= '0; 152 | end 153 | else if (EN) begin 154 | if (WAE && !WA_ADDR && CE) begin 155 | GR0 <= WA_D; 156 | end 157 | if (WBE_LATCH && !WB_ADDR_LATCH) begin 158 | GR0 <= WB_D_LATCH; 159 | end 160 | end 161 | end 162 | assign R0_Q = GR0; 163 | `endif 164 | 165 | `ifdef DEBUG 166 | reg [31:0] DBG_GR[17]; 167 | always @(posedge CLK or negedge RST_N) begin 168 | if (!RST_N) begin 169 | DBG_GR <= '{17{'0}}; 170 | end 171 | else if (EN) begin 172 | if (WAE && CE) begin 173 | DBG_GR[WA_ADDR] <= WA_D; 174 | end 175 | if (WBE_LATCH) begin 176 | DBG_GR[WB_ADDR_LATCH] <= WB_D_LATCH; 177 | end 178 | end 179 | end 180 | 181 | assign R0 = DBG_GR[0]; 182 | assign R1 = DBG_GR[1]; 183 | assign R2 = DBG_GR[2]; 184 | assign R3 = DBG_GR[3]; 185 | assign R4 = DBG_GR[4]; 186 | assign R5 = DBG_GR[5]; 187 | assign R6 = DBG_GR[6]; 188 | assign R7 = DBG_GR[7]; 189 | assign R8 = DBG_GR[8]; 190 | assign R9 = DBG_GR[9]; 191 | assign R10 = DBG_GR[10]; 192 | assign R11 = DBG_GR[11]; 193 | assign R12 = DBG_GR[12]; 194 | assign R13 = DBG_GR[13]; 195 | assign R14 = DBG_GR[14]; 196 | assign R15 = DBG_GR[15]; 197 | assign PR_ = DBG_GR[16]; 198 | `endif 199 | 200 | endmodule 201 | -------------------------------------------------------------------------------- /rtl/SH_mem.sv: -------------------------------------------------------------------------------- 1 | // synopsys translate_off 2 | `timescale 1 ps / 1 ps 3 | // synopsys translate_on 4 | 5 | module SH_regram ( 6 | clock, 7 | data, 8 | rdaddress, 9 | wraddress, 10 | wren, 11 | q); 12 | 13 | input clock; 14 | input [31:0] data; 15 | input [3:0] rdaddress; 16 | input [3:0] wraddress; 17 | input wren; 18 | output [31:0] q; 19 | `ifndef ALTERA_RESERVED_QIS 20 | // synopsys translate_off 21 | `endif 22 | tri0 wren; 23 | `ifndef ALTERA_RESERVED_QIS 24 | // synopsys translate_on 25 | `endif 26 | 27 | wire [31:0] sub_wire0; 28 | wire [31:0] q = sub_wire0[31:0]; 29 | 30 | altdpram altdpram_component ( 31 | .data (data), 32 | .inclock (clock), 33 | .rdaddress (rdaddress), 34 | .wraddress (wraddress), 35 | .wren (wren), 36 | .q (sub_wire0), 37 | .aclr (1'b0), 38 | .byteena (1'b1), 39 | .inclocken (1'b1), 40 | .rdaddressstall (1'b0), 41 | .rden (1'b1), 42 | // .sclr (1'b0), 43 | .wraddressstall (1'b0)); 44 | defparam 45 | altdpram_component.indata_aclr = "OFF", 46 | altdpram_component.indata_reg = "INCLOCK", 47 | altdpram_component.intended_device_family = "Cyclone V", 48 | altdpram_component.lpm_type = "altdpram", 49 | altdpram_component.outdata_aclr = "OFF", 50 | altdpram_component.outdata_reg = "UNREGISTERED", 51 | altdpram_component.ram_block_type = "MLAB", 52 | altdpram_component.rdaddress_aclr = "OFF", 53 | altdpram_component.rdaddress_reg = "UNREGISTERED", 54 | altdpram_component.rdcontrol_aclr = "OFF", 55 | altdpram_component.rdcontrol_reg = "UNREGISTERED", 56 | altdpram_component.read_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE", 57 | altdpram_component.width = 32, 58 | altdpram_component.widthad = 4, 59 | altdpram_component.width_byteena = 1, 60 | altdpram_component.wraddress_aclr = "OFF", 61 | altdpram_component.wraddress_reg = "INCLOCK", 62 | altdpram_component.wrcontrol_aclr = "OFF", 63 | altdpram_component.wrcontrol_reg = "INCLOCK"; 64 | 65 | endmodule 66 | -------------------------------------------------------------------------------- /rtl/Saturn/B-Bus.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/rtl/Saturn/B-Bus.xlsx -------------------------------------------------------------------------------- /rtl/Saturn/CART.sv: -------------------------------------------------------------------------------- 1 | module CART ( 2 | input CLK, 3 | input RST_N, 4 | 5 | input [2:0] MODE, //0-none, 1-ROM 2M, 2-DRAM 1M, 3-DRAM 4M, 4-DRAM 6M, 5-BACKUP 6 | 7 | input RES_N, 8 | 9 | input CE_R, 10 | input CE_F, 11 | input [25:0] AA, 12 | input [15:0] ADI, 13 | output [15:0] ADO, 14 | input [1:0] AFC, 15 | input ACS0_N, 16 | input ACS1_N, 17 | input ACS2_N, 18 | input ARD_N, 19 | input AWRL_N, 20 | input AWRU_N, 21 | input ATIM0_N, 22 | input ATIM2_N, 23 | output AWAIT_N, 24 | output ARQT_N, 25 | 26 | output [25:1] MEM_A, 27 | input [15:0] MEM_DI, 28 | output [15:0] MEM_DO, 29 | output [ 1:0] MEM_WE, 30 | output MEM_RD, 31 | input MEM_RDY 32 | ); 33 | 34 | wire [25:1] DRAM1M_ADDR = {6'b000000,AA[21],AA[18:1]}; 35 | wire [25:1] DRAM4M_ADDR = {4'b0000,AA[21:1]}; 36 | wire [25:1] DRAM6M_ADDR = {3'b000,AA[22:1]}; 37 | wire [25:1] ROM2M_ADDR = {5'b00000,AA[20:1]}; 38 | wire [25:1] BACKUP_ADDR = {6'b000000,AA[19:1]}; 39 | 40 | wire CART_ID_SEL = (AA[23:1] == 24'hFFFFFF>>1) && ~ACS1_N; 41 | wire CART_MEM_SEL = (~ACS0_N && MODE < 3'h4) || (~ACS1_N && MODE == 3'h4); 42 | wire BACKUP_MEM_SEL = ~ACS1_N; 43 | 44 | bit AWR_N_OLD; 45 | bit ARD_N_OLD; 46 | always @(posedge CLK) begin 47 | AWR_N_OLD <= AWRL_N & AWRU_N; 48 | ARD_N_OLD <= ARD_N; 49 | end 50 | 51 | bit [15:0] ABUS_DO; 52 | bit ABUS_WAIT; 53 | always @(posedge CLK or negedge RST_N) begin 54 | if (!RST_N) begin 55 | ABUS_WAIT <= 0; 56 | end else begin 57 | if (!RES_N) begin 58 | ABUS_WAIT <= 0; 59 | end else begin 60 | if ((!AWRL_N || !AWRU_N) && AWR_N_OLD) begin 61 | if (CART_ID_SEL) begin 62 | 63 | end 64 | else if (CART_MEM_SEL || BACKUP_MEM_SEL) begin 65 | case (MODE) 66 | 3'h2: MEM_A <= DRAM1M_ADDR; 67 | 3'h3: MEM_A <= DRAM4M_ADDR; 68 | 3'h4: MEM_A <= DRAM6M_ADDR; 69 | 3'h5: MEM_A <= BACKUP_ADDR; 70 | default: MEM_A <= '1; 71 | endcase 72 | MEM_DO <= ADI; 73 | case (MODE) 74 | 3'h2, 75 | 3'h3, 76 | 3'h4, 77 | 3'h5: MEM_WE <= ~{AWRU_N,AWRL_N}; 78 | default: MEM_WE <= '0; 79 | endcase 80 | ABUS_WAIT <= (MODE == 3'h2 || MODE == 3'h3 || MODE == 3'h4 || MODE == 3'h5); 81 | end 82 | end else if (!ARD_N && ARD_N_OLD) begin 83 | if (CART_ID_SEL) begin 84 | case (MODE) 85 | 3'h1: ABUS_DO <= 16'hFFFF; 86 | 3'h2: ABUS_DO <= 16'hFF5A; 87 | 3'h3: ABUS_DO <= 16'hFF5C; 88 | 3'h4: ABUS_DO <= 16'hFF5C; 89 | 3'h5: ABUS_DO <= 16'hFF21; 90 | default: ABUS_DO <= 16'hFFFF; 91 | endcase 92 | end 93 | else if (CART_MEM_SEL || BACKUP_MEM_SEL) begin 94 | case (MODE) 95 | 3'h1: MEM_A <= ROM2M_ADDR; 96 | 3'h2: MEM_A <= DRAM1M_ADDR; 97 | 3'h3: MEM_A <= DRAM4M_ADDR; 98 | 3'h4: MEM_A <= DRAM6M_ADDR; 99 | 3'h5: MEM_A <= BACKUP_ADDR; 100 | default: MEM_A <= '1; 101 | endcase 102 | MEM_RD <= 1; 103 | ABUS_WAIT <= 1; 104 | end 105 | end 106 | 107 | if (ABUS_WAIT && MEM_RDY) begin 108 | case (MODE) 109 | 3'h0: ABUS_DO <= 16'hFFFF; 110 | default: ABUS_DO <= MEM_DI; 111 | endcase 112 | MEM_WE <= '0; 113 | MEM_RD <= 0; 114 | ABUS_WAIT <= 0; 115 | end 116 | end 117 | end 118 | end 119 | 120 | assign ADO = ABUS_DO; 121 | assign AWAIT_N = ~(ABUS_WAIT); 122 | assign ARQT_N = 1; 123 | 124 | endmodule 125 | -------------------------------------------------------------------------------- /rtl/Saturn/CD/CD.sv: -------------------------------------------------------------------------------- 1 | module CD 2 | #( 3 | parameter rom_file = "sh7034.mif" 4 | ) 5 | ( 6 | input CLK, 7 | input RST_N, 8 | input CE, 9 | 10 | input RES_N, 11 | 12 | input CE_R, 13 | input CE_F, 14 | input [14:1] AA, 15 | input [15:0] ADI, 16 | output [15:0] ADO, 17 | input [1:0] AFC, 18 | input ACS2_N, 19 | input ARD_N, 20 | input AWRL_N, 21 | input AWRU_N, 22 | input ATIM0_N, 23 | input ATIM2_N, 24 | output AWAIT_N, 25 | output ARQT_N, 26 | 27 | input CDATA, 28 | output HDATA, 29 | output COMCLK, 30 | input COMREQ_N, 31 | input COMSYNC_N, 32 | output DEMP, 33 | 34 | output [18:1] RAM_A, 35 | output [15:0] RAM_D, 36 | input [15:0] RAM_Q, 37 | output RAM_CS, 38 | output [1:0] RAM_WE, 39 | output RAM_RD, 40 | input RAM_RDY, 41 | 42 | input [15:0] CD_D, 43 | input CD_CK 44 | ); 45 | 46 | bit [21:0] SA; 47 | bit [15:0] SDI; 48 | bit [15:0] SDO; 49 | bit SWRL_N; 50 | bit SWRH_N; 51 | bit SRD_N; 52 | bit SCS1_N; 53 | bit SCS2_N; 54 | bit SCS6_N; 55 | bit SWAIT_N; 56 | bit DACK0; 57 | bit DACK1; 58 | bit DREQ0_N; 59 | bit DREQ1_N; 60 | bit SIRQL_N; 61 | bit SIRQH_N; 62 | 63 | bit [15:0] YGR019_DO; 64 | 65 | bit SHCLK; 66 | bit SHCE_R, SHCE_F; 67 | always @(posedge CLK) begin 68 | if (CE) SHCLK <= ~SHCLK; 69 | end 70 | assign SHCE_R = SHCLK & CE; 71 | assign SHCE_F = ~SHCLK & CE; 72 | 73 | SH1 #(rom_file) sh1 74 | ( 75 | .CLK(CLK), 76 | .RST_N(RST_N), 77 | .CE_R(SHCE_R), 78 | .CE_F(SHCE_F), 79 | 80 | .RES_N(RES_N), 81 | 82 | .A(SA), 83 | .DI(SDI), 84 | .DO(SDO), 85 | 86 | .CS1N_CASHN(SCS1_N),//in original CASH_N 87 | .CS2N(SCS2_N), 88 | .CS6N(SCS6_N), 89 | .WRLN(SWRL_N), 90 | .WRHN(SWRH_N), 91 | .RDN(SRD_N), 92 | .WAITN(SWAIT_N), 93 | 94 | .IRQ6N(SIRQL_N), 95 | .IRQ7N(SIRQH_N), 96 | 97 | .DACK0(DACK0), 98 | .DACK1(DACK1), 99 | .DREQ0N(DREQ0_N), 100 | .DREQ1N(DREQ1_N), 101 | 102 | .RXD0(CDATA), 103 | .TXD0(HDATA), 104 | .SCK0O(COMCLK), 105 | .PB2I(COMSYNC_N), 106 | .TIOCB3(COMREQ_N), 107 | .PB6O(DEMP), 108 | 109 | .TIOCA0(1'b0),//MPEG 110 | .TIOCA1(1'b0),//MPEG 111 | .TIOCA2(1'b1),//MPEGA_IRQ_N 112 | .TIOCB2(1'b1)//MPEGV_IRQ_N 113 | ); 114 | 115 | assign SDI = !SCS1_N ? RAM_Q : YGR019_DO; 116 | 117 | YGR019 ygr 118 | ( 119 | .CLK(CLK), 120 | .RST_N(RST_N), 121 | 122 | .RES_N(RES_N), 123 | 124 | .CE_R(CE_R), 125 | .CE_F(CE_F), 126 | .AA(AA), 127 | .ADI(ADI), 128 | .ADO(ADO), 129 | .AFC(AFC), 130 | .ACS2_N(ACS2_N), 131 | .ARD_N(ARD_N), 132 | .AWRL_N(AWRL_N), 133 | .AWRU_N(AWRU_N), 134 | .ATIM0_N(ATIM0_N), 135 | .ATIM2_N(ATIM2_N), 136 | .AWAIT_N(AWAIT_N), 137 | .ARQT_N(ARQT_N), 138 | 139 | .SHCE_R(SHCE_R), 140 | .SHCE_F(SHCE_F), 141 | .SA(SA[21:1]), 142 | .SDI(SDO), 143 | .BDI(SDI), 144 | .SDO(YGR019_DO), 145 | .SWRL_N(SWRL_N), 146 | .SWRH_N(SWRH_N), 147 | .SRD_N(SRD_N), 148 | .SCS2_N(SCS2_N), 149 | .SCS6_N(SCS6_N), 150 | .SIRQL_N(SIRQL_N), 151 | .SIRQH_N(SIRQH_N), 152 | 153 | .DACK0(DACK0), 154 | .DACK1(DACK1), 155 | .DREQ0_N(DREQ0_N), 156 | .DREQ1_N(DREQ1_N), 157 | 158 | .CD_D(CD_D), 159 | .CD_CK(CD_CK) 160 | ); 161 | 162 | assign SWAIT_N = RAM_RDY; 163 | 164 | assign RAM_A = SA[18:1]; 165 | assign RAM_D = SDO; 166 | assign RAM_CS = ~SCS1_N; 167 | assign RAM_WE = ~{SWRH_N,SWRL_N}; 168 | assign RAM_RD = ~SRD_N; 169 | 170 | 171 | endmodule 172 | -------------------------------------------------------------------------------- /rtl/Saturn/CD/SH1.sv: -------------------------------------------------------------------------------- 1 | module SH1 2 | #( 3 | parameter rom_file = " " 4 | ) 5 | ( 6 | input CLK, 7 | input RST_N, 8 | input CE_R, 9 | input CE_F, 10 | input EN, 11 | 12 | input RES_N, 13 | 14 | output [21:0] A, 15 | input [15:0] DI, 16 | output [15:0] DO, 17 | 18 | //PA in 19 | input TIOCA0, 20 | input TIOCA1, 21 | input DREQ0N, 22 | input DREQ1N, 23 | //PA out 24 | output RASN, 25 | output CS6N, 26 | output WRLN, 27 | output WRHN, 28 | output RDN, 29 | output DACK0, 30 | output DACK1, 31 | 32 | //PB in 33 | input TIOCA2, 34 | input TIOCB2, 35 | input PB2I, 36 | input TIOCB3, 37 | input RXD0, 38 | input IRQ6N, 39 | input IRQ7N, 40 | //PB out 41 | output PB6O, 42 | output TXD0, 43 | output SCK0O, 44 | 45 | output CS1N_CASHN, 46 | output CS2N, 47 | output CASLN, 48 | input WAITN 49 | ); 50 | 51 | SH7034 #(.rom_file(rom_file), .UBC_DISABLE(1), .SCI0_DISABLE(0), .SCI1_DISABLE(1), .WDT_DISABLE(1)) sh7034 52 | ( 53 | .CLK(CLK), 54 | .RST_N(RST_N), 55 | .CE_R(CE_R), 56 | .CE_F(CE_F), 57 | .EN(EN), 58 | 59 | .RES_N(RES_N), 60 | .NMI_N(1'b1), 61 | 62 | .A(A), 63 | .DI(DI), 64 | .DO(DO), 65 | 66 | .PA0I_TIOCA0(TIOCA0), 67 | .PA1I(1'b0), 68 | .PA2I_TIOCB0(1'b0), 69 | .PA3I_WAITN(WAITN), 70 | .PA4I(1'b0), 71 | .PA5I(1'b0), 72 | .PA6I(1'b0), 73 | .PA7I(1'b0), 74 | .PA8I_BREQN(1'b0), 75 | .PA9I_ADTRGN(1'b0), 76 | .PA10I_DPL_TIOCA1(TIOCA1), 77 | .PA11I_DPH_TIOCB1(1'b0), 78 | .PA12I_IRQ0N_TCLKA(1'b0), 79 | .PA13I_IRQ1N_TCLKB_DREQ0N(DREQ0N), 80 | .PA14I_IRQ2N(1'b0), 81 | .PA15I_IRQ3N_DREQ1N(DREQ1N), 82 | 83 | .PB0I_TIOCA2(TIOCA2), 84 | .PB1I_TIOCB2(TIOCB2), 85 | .PB2I_TIOCA3(PB2I), 86 | .PB3I_TIOCB3(TIOCB3), 87 | .PB4I_TIOCA4(1'b0), 88 | .PB5I_TIOCB4(1'b0), 89 | .PB6I_TCLKC(1'b0), 90 | .PB7I_TCLKD(1'b0), 91 | .PB8I_RXD0(RXD0), 92 | .PB9I(1'b0), 93 | .PB10I_RXD1(1'b1), 94 | .PB11I(1'b0), 95 | .PB12I_IRQ4N_SCK0I(1'b0), 96 | .PB13I_IRQ5N_SCK1I(1'b0), 97 | .PB14I_IRQ6N(IRQ6N), 98 | .PB15I_IRQ7N(IRQ7N), 99 | 100 | .PC0I(1'b0), 101 | .PC1I(1'b0), 102 | .PC2I(1'b0), 103 | .PC3I(1'b0), 104 | .PC4I(1'b0), 105 | .PC5I(1'b0), 106 | .PC6I(1'b0), 107 | .PC7I(1'b0), 108 | 109 | .PA0O_CS4N_TIOCA0(), 110 | .PA1O_CS5N_RASN(RASN), 111 | .PA2O_CS6N_TIOCB0(CS6N), 112 | .PA3O_CS7N(), 113 | .PA4O_WRLN(WRLN), 114 | .PA5O_WRHN(WRHN), 115 | .PA6O_RDN(RDN), 116 | .PA7O_BACKN(), 117 | .PA8O(), 118 | .PA9O_AHN_IRQOUTN(), 119 | .PA10O_DPL_TIOCA1(), 120 | .PA11O_DPH_TIOCB1(), 121 | .PA12O_DACK0(DACK0), 122 | .PA13O(), 123 | .PA14O_DACK1(DACK1), 124 | .PA15O(), 125 | 126 | .PB0O_TIOCA2_TP0(), 127 | .PB1O_TIOCB2_TP1(), 128 | .PB2O_TIOCA3_TP2(), 129 | .PB3O_TIOCB3_TP3(), 130 | .PB4O_TIOCA4_TP4(), 131 | .PB5O_TIOCB4_TP5(), 132 | .PB6O_TOCXA4_TP6(PB6O), 133 | .PB7O_TOCXB4_TP7(), 134 | .PB8O_TP8(), 135 | .PB9O_TXD0_TP9(TXD0), 136 | .PB10O_TP10(), 137 | .PB11O_TXD1_TP11(), 138 | .PB12O_SCK0O_TP12(SCK0O), 139 | .PB13O_SCK1O_TP13(), 140 | .PB14O_TP14(), 141 | .PB15O_TP15(), 142 | 143 | .CS0N(), 144 | .CS1N_CASHN(CS1N_CASHN), 145 | .CS2N(CS2N), 146 | .CS3N_CASLN(CASLN), 147 | 148 | .WDTOVF_N(), 149 | 150 | .MD(3'b010) 151 | ); 152 | 153 | 154 | endmodule 155 | -------------------------------------------------------------------------------- /rtl/Saturn/CD/YGR019_PKG.sv: -------------------------------------------------------------------------------- 1 | package YGR019_PKG; 2 | 3 | typedef bit [15:0] DATATRNS_t; //R/W;258XXX00,258XXX02 4 | parameter bit [15:0] DATATRNS_WMASK = 16'hFFFF; 5 | parameter bit [15:0] DATATRNS_RMASK = 16'hFFFF; 6 | parameter bit [15:0] DATATRNS_INIT = 16'hFFFF; 7 | 8 | typedef struct packed //R;258XXX04,258XXX06 9 | { 10 | bit [12: 0] UNUSED; 11 | bit DIR; //R 12 | bit FUL; //R 13 | bit EMP; //R 14 | } DATASTAT_t; 15 | parameter bit [15:0] DATASTAT_WMASK = 16'h0007; 16 | parameter bit [15:0] DATASTAT_RMASK = 16'h0007; 17 | parameter bit [15:0] DATASTAT_INIT = 16'h0000; 18 | 19 | typedef struct packed //R/W;258XXX08,258XXX0A 20 | { 21 | bit [ 1: 0] UNUSED; 22 | bit MPST; //R/W0 23 | bit MPCM; //R/W0 24 | bit MPED; //R/W0 25 | bit SCDQ; //R/W0 26 | bit EFLS; //R/W0 27 | bit ECPY; //R/W0 28 | bit EHST; //R/W0 29 | bit ESEL; //R/W0 30 | bit DCHG; //R/W0 31 | bit PEND; //R/W0 32 | bit BFUL; //R/W0 33 | bit CSCT; //R/W0 34 | bit DRDY; //R/W0 35 | bit CMOK; //R/W0 36 | } HIRQREQ_t; 37 | parameter bit [15:0] HIRQREQ_WMASK = 16'h3FFF; 38 | parameter bit [15:0] HIRQREQ_RMASK = 16'h3FFF; 39 | parameter bit [15:0] HIRQREQ_INIT = 16'h0000; 40 | 41 | typedef struct packed //R/W;258XXX0C,258XXX0E 42 | { 43 | bit [ 1: 0] UNUSED; 44 | bit MPST; //R/W 45 | bit MPCM; //R/W 46 | bit MPED; //R/W 47 | bit SCDQ; //R/W 48 | bit EFLS; //R/W 49 | bit ECPY; //R/W 50 | bit EHST; //R/W 51 | bit ESEL; //R/W 52 | bit DCHG; //R/W 53 | bit PEND; //R/W 54 | bit BFUL; //R/W 55 | bit CSCT; //R/W 56 | bit DRDY; //R/W 57 | bit CMOK; //R/W 58 | } HIRQMSK_t; 59 | parameter bit [15:0] HIRQMSK_WMASK = 16'h3FFF; 60 | parameter bit [15:0] HIRQMSK_RMASK = 16'h3FFF; 61 | parameter bit [15:0] HIRQMSK_INIT = 16'hFFFF; 62 | 63 | typedef bit [15:0] CR_t; //R/W;258XXX18-258XXX26 64 | parameter bit [15:0] CR_WMASK = 16'hFFFF; 65 | parameter bit [15:0] CR_RMASK = 16'hFFFF; 66 | parameter bit [15:0] CR_INIT = 16'h0000; 67 | 68 | typedef bit [15:0] MPEGRGB_t; //R;258XXX28,258XXX2A 69 | parameter bit [15:0] MPEGRGB_WMASK = 16'hFFFF; 70 | parameter bit [15:0] MPEGRGB_RMASK = 16'hFFFF; 71 | parameter bit [15:0] MPEGRGB_INIT = 16'h0000; 72 | 73 | typedef bit [15:0] TRCTL_t; //R/W;0A000002 74 | parameter bit [15:0] TRCTL_WMASK = 16'h000F; 75 | parameter bit [15:0] TRCTL_RMASK = 16'h000F; 76 | parameter bit [15:0] TRCTL_INIT = 16'h0000; 77 | 78 | typedef bit [15:0] CDIRQL_t; //R/W;0A000004 79 | parameter bit [15:0] CDIRQL_WMASK = 16'h0003; 80 | parameter bit [15:0] CDIRQL_RMASK = 16'h0003; 81 | parameter bit [15:0] CDIRQL_INIT = 16'h0000; 82 | 83 | typedef bit [15:0] CDIRQU_t; //R/W;0A000006 84 | parameter bit [15:0] CDIRQU_WMASK = 16'h0070; 85 | parameter bit [15:0] CDIRQU_RMASK = 16'h0070; 86 | parameter bit [15:0] CDIRQU_INIT = 16'h0000; 87 | 88 | typedef bit [15:0] CDMASKL_t; //R/W;0A000008 89 | parameter bit [15:0] CDMASKL_WMASK = 16'h0003; 90 | parameter bit [15:0] CDMASKL_RMASK = 16'h0003; 91 | parameter bit [15:0] CDMASKL_INIT = 16'h0000; 92 | 93 | typedef bit [15:0] CDMASKU_t; //R/W;0A00000A 94 | parameter bit [15:0] CDMASKU_WMASK = 16'h0070; 95 | parameter bit [15:0] CDMASKU_RMASK = 16'h0070; 96 | parameter bit [15:0] CDMASKU_INIT = 16'h0000; 97 | 98 | typedef bit [15:0] REG1A_t; //R/W;0A00001A 99 | parameter bit [15:0] REG1A_WMASK = 16'h00FF; 100 | parameter bit [15:0] REG1A_RMASK = 16'h00FF; 101 | parameter bit [15:0] REG1A_INIT = 16'h0000; 102 | 103 | endpackage 104 | -------------------------------------------------------------------------------- /rtl/Saturn/DCC.sv: -------------------------------------------------------------------------------- 1 | module DCC 2 | ( 3 | input CLK, 4 | input RST_N, 5 | input CE_R, 6 | input CE_F, 7 | 8 | input RES_N, 9 | 10 | input [24:1] A, 11 | input BS_N, 12 | input CS0_N, 13 | input CS1_N, 14 | input CS2_N, 15 | input RD_WR_N, 16 | input [1:0] WE_N, 17 | input RD_N, 18 | output WAIT_N, 19 | 20 | output BRLS_N, 21 | input BGR_N, 22 | input BREQ_N, 23 | output BACK_N, 24 | input EXBREQ_N, 25 | output EXBACK_N, 26 | 27 | input WTIN_N, 28 | input IVECF_N, 29 | 30 | input HINT_N, 31 | input VINT_N, 32 | output [2:1] IREQ_N, 33 | 34 | output reg MFTI, 35 | output reg SFTI, 36 | 37 | output DCE_N, 38 | output DOE_N, 39 | output [1:0] DWE_N, 40 | input DWAIT_N,//not present in original 41 | 42 | output ROMCE_N, 43 | output SRAMCE_N, 44 | output SMPCCE_N, 45 | output MOE_N, 46 | output MWR_N, 47 | 48 | input FAST 49 | ); 50 | 51 | const bit [3:0] DRAM_CYC = 4'd7; 52 | const bit [3:0] ROM_SRAM_SMPC_CYC = 4'd8; 53 | 54 | //SCU bus arbitration 55 | bit SSH_ACTIVE; 56 | bit SCU_ACTIVE; 57 | always @(posedge CLK or negedge RST_N) begin 58 | if (!RST_N) begin 59 | SSH_ACTIVE <= '0; 60 | SCU_ACTIVE <= 0; 61 | end else if (CE_R) begin 62 | if (!BREQ_N && !SSH_ACTIVE && !SCU_ACTIVE) SSH_ACTIVE <= 1; 63 | else if (BREQ_N && SSH_ACTIVE) SSH_ACTIVE <= 0; 64 | 65 | if (!EXBREQ_N && BREQ_N && !SCU_ACTIVE && !SSH_ACTIVE) SCU_ACTIVE <= 1; 66 | else if (EXBREQ_N && SCU_ACTIVE) SCU_ACTIVE <= 0; 67 | end 68 | end 69 | assign BRLS_N = BREQ_N & EXBREQ_N; 70 | assign BACK_N = BGR_N | ~SSH_ACTIVE; 71 | assign EXBACK_N = BGR_N | ~SCU_ACTIVE; 72 | 73 | //ROM (BIOS) 74 | assign ROMCE_N = ~(A[24:20] == 5'b00000) | CS0_N; 75 | //SMPC 76 | assign SMPCCE_N = ~(A[24:19] == 6'b000010) | CS0_N; 77 | //SRAM (backup) 78 | assign SRAMCE_N = ~(A[24:19] == 6'b000011) | CS0_N; 79 | 80 | assign MOE_N = RD_N; 81 | assign MWR_N = WE_N[0]; 82 | 83 | //DRAM (LWRAM) 84 | assign DCE_N = ~(A[24:21] == 4'b0001) | CS0_N; 85 | assign DOE_N = RD_N; 86 | assign DWE_N = WE_N; 87 | bit MEM_WAIT; 88 | always @(posedge CLK or negedge RST_N) begin 89 | bit [ 3: 0] CYC_NUM; 90 | bit RD_N_OLD; 91 | bit WE_N_OLD; 92 | bit [ 3: 0] WAIT_CNT; 93 | bit [ 7: 0] FAULT_CNT; 94 | 95 | if (!RST_N) begin 96 | MEM_WAIT <= 0; 97 | WAIT_CNT <= '0; 98 | end else begin 99 | CYC_NUM = (!DCE_N ? DRAM_CYC : ROM_SRAM_SMPC_CYC) - 4'd2; 100 | 101 | RD_N_OLD <= RD_N; 102 | WE_N_OLD <= &WE_N; 103 | if ((!RD_N && RD_N_OLD && !CS0_N) || (!(&WE_N) && WE_N_OLD && !CS0_N)) begin 104 | MEM_WAIT <= 1; 105 | if (FAST) begin 106 | MEM_WAIT <= 0; 107 | WAIT_CNT <= '0; 108 | end else if (!FAULT_CNT) begin 109 | WAIT_CNT <= CYC_NUM; 110 | end else if (FAULT_CNT >= 8'd4) begin 111 | WAIT_CNT <= '0; 112 | FAULT_CNT <= FAULT_CNT - 8'd4; 113 | end else begin 114 | WAIT_CNT <= CYC_NUM - FAULT_CNT[3:0]; 115 | FAULT_CNT <= '0; 116 | end 117 | end else if (WAIT_CNT && CE_R) begin 118 | WAIT_CNT <= WAIT_CNT - 4'd1; 119 | end else if (!WAIT_CNT && CE_F) begin 120 | MEM_WAIT <= 0; 121 | if (!RD_N && !DCE_N && !DWAIT_N) begin 122 | FAULT_CNT <= FAULT_CNT + 8'd1; 123 | end 124 | end 125 | end 126 | end 127 | 128 | //MINIT/SINIT 129 | wire MINIT_SEL = (A[24:23] == 2'b10) & ~CS0_N; 130 | wire SINIT_SEL = (A[24:23] == 2'b11) & ~CS0_N; 131 | always @(posedge CLK or negedge RST_N) begin 132 | bit WE_N_OLD; 133 | 134 | if (!RST_N) begin 135 | MFTI = 1; 136 | SFTI = 1; 137 | end else if (!RES_N) begin 138 | MFTI = 1; 139 | SFTI = 1; 140 | end else if (CE_R) begin 141 | MFTI = 1; 142 | SFTI = 1; 143 | 144 | WE_N_OLD <= &WE_N; 145 | if (!(&WE_N) && WE_N_OLD) begin 146 | if (SINIT_SEL) MFTI <= 0; 147 | if (MINIT_SEL) SFTI <= 0; 148 | end 149 | end 150 | end 151 | 152 | assign WAIT_N = WTIN_N & ~MEM_WAIT; 153 | 154 | assign IREQ_N = {VINT_N,VINT_N&HINT_N}; 155 | 156 | endmodule 157 | -------------------------------------------------------------------------------- /rtl/Saturn/SCU/SCU DSP.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/rtl/Saturn/SCU/SCU DSP.xlsx -------------------------------------------------------------------------------- /rtl/Saturn/STV/93C45.sv: -------------------------------------------------------------------------------- 1 | module E93C45 2 | #(parameter init_file = " ") 3 | ( 4 | input CLK, 5 | input RST_N, 6 | 7 | input DI, 8 | output DO, 9 | input CS, 10 | input SK, 11 | 12 | input [ 5: 0] MEM_A, 13 | input [15: 0] MEM_DI, 14 | input MEM_WREN, 15 | output [15: 0] MEM_DO 16 | ); 17 | 18 | bit SK_OLD,CS_OLD; 19 | always @(posedge CLK) begin 20 | SK_OLD <= SK; 21 | CS_OLD <= CS; 22 | end 23 | wire SK_FALL = !SK & SK_OLD; 24 | wire SK_RISE = SK & !SK_OLD; 25 | wire CS_FALL = !CS & CS_OLD; 26 | wire CS_RISE = CS & !CS_OLD; 27 | 28 | bit [ 2: 0] STATE; 29 | bit [ 1: 0] OPCODE; 30 | bit WEN; 31 | bit [ 5: 0] ADDRESS; 32 | bit [15: 0] DATA; 33 | bit WRITE; 34 | always @(posedge CLK or negedge RST_N) begin 35 | bit [ 3: 0] BIT_CNT; 36 | 37 | if (!RST_N) begin 38 | STATE <= '0; 39 | BIT_CNT <= '0; 40 | OPCODE <= '0; 41 | ADDRESS <= '0; 42 | DATA <= '0; 43 | WRITE <= 0; 44 | end else begin 45 | WRITE <= 0; 46 | case (STATE) 47 | 3'd0: begin 48 | if (CS_RISE) begin 49 | STATE <= 3'd1; 50 | end 51 | end 52 | 53 | 3'd1: begin //start 54 | if (DI && SK_RISE) begin 55 | DO <= 0; 56 | BIT_CNT <= '0; 57 | STATE <= 3'd2; 58 | end 59 | if (CS_FALL) begin 60 | DO <= 1; 61 | STATE <= 3'd0; 62 | end 63 | end 64 | 65 | 3'd2: begin //opcode 66 | if (SK_RISE) begin 67 | BIT_CNT <= BIT_CNT + 4'd1; 68 | case (BIT_CNT) 69 | 4'd0: begin OPCODE[1] <= DI; end 70 | 4'd1: begin OPCODE[0] <= DI; BIT_CNT <= '0; STATE <= 3'd3; end 71 | endcase 72 | end 73 | if (CS_FALL) begin 74 | DO <= 1; 75 | STATE <= 3'd0; 76 | end 77 | end 78 | 79 | 3'd3: begin //address 80 | if (SK_RISE) begin 81 | BIT_CNT <= BIT_CNT + 4'd1; 82 | case (BIT_CNT) 83 | 4'd0: begin ADDRESS[5] <= DI; end 84 | 4'd1: begin ADDRESS[4] <= DI; end 85 | 4'd2: begin ADDRESS[3] <= DI; end 86 | 4'd3: begin ADDRESS[2] <= DI; end 87 | 4'd4: begin ADDRESS[1] <= DI; end 88 | 4'd5: begin ADDRESS[0] <= DI; DO <= 0; BIT_CNT <= '0; STATE <= 3'd4; end 89 | endcase 90 | end 91 | if (CS_FALL) begin 92 | DO <= 1; 93 | STATE <= 3'd0; 94 | end 95 | end 96 | 97 | 3'd4: begin //read/ewen/ewds 98 | case (OPCODE) 99 | 2'b00: begin 100 | if (ADDRESS[5:4] == 2'b11) WEN <= 1; 101 | if (ADDRESS[5:4] == 2'b00) WEN <= 0; 102 | //if (ADDRESS[5:4] == 2'b01) WEN <= 1; 103 | STATE <= 3'd7; 104 | end 105 | 2'b01: begin 106 | STATE <= 3'd6; 107 | end 108 | 2'b10: begin 109 | STATE <= 3'd5; 110 | end 111 | 2'b11: begin 112 | STATE <= 3'd7; 113 | end 114 | endcase 115 | end 116 | 117 | 3'd5: begin //read to buf 118 | DATA <= EEPROM_Q; 119 | STATE <= 3'd6; 120 | end 121 | 122 | 3'd6: begin //data in/out 123 | if (SK_RISE) begin 124 | {DO,DATA} <= {DATA,DI}; 125 | BIT_CNT <= BIT_CNT + 4'd1; 126 | if (BIT_CNT == 4'd15) begin 127 | if (OPCODE == 2'b10) begin 128 | ADDRESS <= ADDRESS + 6'd1; 129 | STATE <= 3'd4; 130 | end else begin 131 | STATE <= 3'd7; 132 | end 133 | end 134 | end 135 | if (CS_FALL) begin 136 | DO <= 1; 137 | STATE <= 3'd0; 138 | end 139 | end 140 | 141 | 3'd7: begin //write 142 | if (CS_FALL) begin 143 | DO <= 1; 144 | WRITE <= (OPCODE == 2'b01 && WEN); 145 | STATE <= 3'd0; 146 | end 147 | end 148 | 149 | default:; 150 | endcase 151 | end 152 | end 153 | 154 | bit [15: 0] EEPROM_Q; 155 | dpram #(6,16,init_file) eeprom 156 | ( 157 | .clock(CLK), 158 | 159 | .address_a(ADDRESS), 160 | .data_a(DATA), 161 | .wren_a(WRITE), 162 | .q_a(EEPROM_Q), 163 | 164 | .address_b(MEM_A), 165 | .data_b(MEM_DI), 166 | .wren_b(MEM_WREN), 167 | .q_b(MEM_DO) 168 | ); 169 | 170 | 171 | endmodule 172 | -------------------------------------------------------------------------------- /rtl/Saturn/STV/STVIO.sv: -------------------------------------------------------------------------------- 1 | module STVIO ( 2 | input CLK, 3 | input RST_N, 4 | input CE_R, 5 | input CE_F, 6 | 7 | input RES_N, 8 | 9 | input [ 6: 1] A, 10 | input [ 7: 0] DI, 11 | output [ 7: 0] DO, 12 | input CS_N, 13 | input RW_N, 14 | 15 | input [13: 0] JOY1, 16 | input [13: 0] JOY2, 17 | 18 | input [ 7: 0] MODE 19 | ); 20 | 21 | bit [ 3: 0] J1UDLR,J2UDLR; 22 | bit J1B1,J1B2,J1B3,J1B4,J1B5,J1B6,J2B1,J2B2,J2B3,J2B4,J2B5,J2B6; 23 | bit J1START,J2START,J1COIN,J2COIN,J1SERVICE,J2SERVICE,J1TEST,J2TEST; 24 | assign {J1TEST,J1SERVICE,J1COIN,J1START,J1B6,J1B5,J1B4,J1B3,J1B2,J1B1,J1UDLR} = JOY1; 25 | assign {J2TEST,J2SERVICE,J2COIN,J2START,J2B6,J2B5,J2B4,J2B3,J2B2,J2B1,J2UDLR} = JOY2; 26 | 27 | bit [ 7: 0] IN[8]; 28 | bit [ 7: 0] OUT[8]; 29 | bit [ 7: 0] DIR; 30 | always_comb begin 31 | // 0x0001 PORT-A (P1) JAMMA (56P) 32 | // 0x0003 PORT-B (P2) JAMMA (56P) 33 | // 0x0005 PORT-C (SYSTEM) JAMMA (56P) 34 | // 0x0007 PORT-D (OUTPUT) JAMMA (56P) + CN25 (JST NH 5P) RESERVED OUTPUT 4bit. (?) 35 | // 0x0009 PORT-E (P3) CN32 (JST NH 9P) EXTENSION I/O 8bit. 36 | // 0x000b PORT-F (P4 / Extra 6B layout) CN21 (JST NH 11P) EXTENSION I/O 8bit. 37 | // 0x000d PORT-G CN20 (JST HN 10P) EXTENSION INPUT 8bit. (?) 38 | // 0x000f unused 39 | // 0x0011 PORT_DIR 40 | // 41 | // (each bit of PORT_DIR configures the DIRection of each 8-bit IO port. 1=input, 0=output.) 42 | // 43 | // eg. PORT_DIR[0]=1=PORTA pins are all INPUTs. 44 | // eg. PORT_DIR[1]=1=PORTB pins are all INPUTs. 45 | // eg. PORT_DIR[2]=1=PORTC pins are all INPUTs. 46 | // eg. PORT_DIR[3]=0=PORTD pins are all OUTPUTs. 47 | 48 | 49 | // PORTs A, B, E, F. (Player 1, 2, 3, 4)... 50 | // 51 | // b7 = Left 52 | // b6 = Right 53 | // b5 = Up 54 | // b4 = Down 55 | // b3 = Button 4 (P3/P4 use this for Start) 56 | // b2 = Button 3 57 | // b1 = Button 2 58 | // b0 = Button 1 59 | // 60 | IN[0][7:4] = {J1UDLR[1],J1UDLR[0],J1UDLR[3],J1UDLR[2]}; 61 | IN[1][7:4] = {J2UDLR[1],J2UDLR[0],J2UDLR[3],J2UDLR[2]}; 62 | if (MODE[3:0] == 4'h3) begin //batmanfr 63 | IN[0][3:0] = {J1B3,J1B2,J1B1,1'b1}; 64 | IN[1][3:0] = {J2B3,J2B2,J2B1,1'b1}; 65 | end else begin 66 | IN[0][3:0] = {1'b1,J1B3,J1B2,J1B1}; 67 | IN[1][3:0] = {1'b1,J2B3,J2B2,J2B1}; 68 | end 69 | 70 | // PORTC (System) inputs... 71 | // 72 | // b7 = Pause (if the game supports it) 73 | // b6 = Multi-Cart Select. 74 | // b5 = Start 2 ? 75 | // b4 = Start 1 ? 76 | // b3 = Service 1. 77 | // b2 = Test ? 78 | // b1 = Coin 2 79 | // b0 = Coin 1 80 | // 81 | // Button inputs to core are Active-LOW ! 82 | // 83 | IN[2] = {1'b1,1'b1,J2START,J1START,J1SERVICE,J1TEST,J2COIN,J1COIN}; 84 | IN[3] = 8'h00; 85 | IN[4] = 8'hFF; 86 | IN[5] = {1'b1,J2B6,J2B5,J2B4,1'b1,J1B6,J1B5,J1B4}; 87 | IN[6] = 8'hFF; 88 | IN[7] = 8'hFF; 89 | end 90 | 91 | bit [ 7: 0] REG_DO; 92 | always @(posedge CLK or negedge RST_N) begin 93 | bit RW_N_OLD; 94 | bit CS_N_OLD; 95 | 96 | if (!RST_N) begin 97 | OUT <= '{8{'1}}; 98 | DIR <= '1; 99 | end 100 | else if (!RES_N) begin 101 | 102 | end else begin 103 | RW_N_OLD <= RW_N; 104 | if (!RW_N && RW_N_OLD && !CS_N) begin 105 | case ({A,1'b1}) 106 | 7'h01: OUT[0] <= DI; 107 | 7'h03: OUT[1] <= DI; 108 | 7'h05: OUT[2] <= DI; 109 | 7'h07: OUT[3] <= DI; 110 | 7'h09: OUT[4] <= DI; 111 | 7'h0B: OUT[5] <= DI; 112 | 7'h0D: OUT[6] <= DI; 113 | 7'h0F: OUT[7] <= DI; 114 | 7'h11: DIR <= DI; 115 | default:; 116 | endcase 117 | end 118 | 119 | CS_N_OLD <= CS_N; 120 | if (!CS_N && CS_N_OLD && RW_N) begin 121 | case ({A,1'b1}) 122 | 7'h01: REG_DO <= IN[0] & (OUT[0]|{8{DIR[0]}}); 123 | 7'h03: REG_DO <= IN[1] & (OUT[1]|{8{DIR[1]}}); 124 | 7'h05: REG_DO <= IN[2] & (OUT[2]|{8{DIR[2]}}); 125 | 7'h07: REG_DO <= IN[3] & (OUT[3]|{8{DIR[3]}}); 126 | 7'h09: REG_DO <= IN[4] & (OUT[4]|{8{DIR[4]}}); 127 | 7'h0B: REG_DO <= IN[5] & (OUT[5]|{8{DIR[5]}}); 128 | 7'h0D: REG_DO <= IN[6] & (OUT[6]|{8{DIR[6]}}); 129 | 7'h0F: REG_DO <= IN[7] & (OUT[7]|{8{DIR[7]}}); 130 | 7'h11: REG_DO <= DIR; 131 | 132 | 7'h17: REG_DO <= '0; 133 | 7'h19: REG_DO <= '0; 134 | default: REG_DO <= '1; 135 | endcase 136 | end 137 | end 138 | end 139 | assign DO = REG_DO; 140 | 141 | endmodule 142 | -------------------------------------------------------------------------------- /rtl/Saturn/Saturn.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) Saturn.sv ] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SMPC.sv ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) DCC.sv ] 4 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCU/DSP_PKG.sv ] 5 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCU/RAM.sv ] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCU/DSP.sv ] 7 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCU/SCU_PKG.sv ] 8 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCU/SCU.sv ] 9 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) VDP1/VDP1_pkg.sv ] 10 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) VDP1/VDP1.sv ] 11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) VDP2/VDP2_pkg.sv ] 12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) VDP2/VDP2.sv ] 13 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) VDP2/VDP2_mem.sv] 14 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCSP/SCSP_pkg.sv ] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) SCSP/SCSP.sv ] 16 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) CD/YGR019.sv ] 17 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) CD/YGR019_PKG.sv ] 18 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) CD/SH1.sv ] 19 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) CART.sv ] 20 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/5838.sv ] 21 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/5881.sv ] 22 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/RAX.sv ] 23 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/STV_CART.sv ] 24 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/STVIO.sv ] 25 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) STV/93C45.sv ] 26 | -------------------------------------------------------------------------------- /rtl/Saturn/VDP2/VDP2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/rtl/Saturn/VDP2/VDP2.xlsx -------------------------------------------------------------------------------- /rtl/Saturn/VDP2/VDP2_mem.sv: -------------------------------------------------------------------------------- 1 | module VDP2_PAL_RAM ( 2 | input CLK, 3 | 4 | input [ 9:0] ADDR_A, 5 | input [15:0] DATA_A, 6 | input [ 1:0] WREN_A, 7 | output [15:0] Q_A, 8 | 9 | input [ 9:0] ADDR_B, 10 | input [15:0] DATA_B, 11 | input [ 1:0] WREN_B, 12 | output [15:0] Q_B 13 | ); 14 | 15 | wire [15:0] sub_wire0; 16 | wire [15:0] sub_wire1; 17 | 18 | altsyncram altsyncram_component ( 19 | .clock0 (CLK), 20 | .wren_a (|WREN_A), 21 | .address_b (ADDR_B), 22 | .data_b (DATA_B), 23 | .wren_b (|WREN_B), 24 | .address_a (ADDR_A), 25 | .data_a (DATA_A), 26 | .q_a (sub_wire0), 27 | .q_b (sub_wire1), 28 | .aclr0 (1'b0), 29 | .aclr1 (1'b0), 30 | .addressstall_a (1'b0), 31 | .addressstall_b (1'b0), 32 | .byteena_a (WREN_A), 33 | .byteena_b (WREN_B), 34 | .clock1 (1'b1), 35 | .clocken0 (1'b1), 36 | .clocken1 (1'b1), 37 | .clocken2 (1'b1), 38 | .clocken3 (1'b1), 39 | .eccstatus (), 40 | .rden_a (1'b1), 41 | .rden_b (1'b1)); 42 | defparam 43 | altsyncram_component.address_reg_b = "CLOCK0", 44 | altsyncram_component.byteena_reg_b = "CLOCK0", 45 | altsyncram_component.byte_size = 8, 46 | altsyncram_component.clock_enable_input_a = "BYPASS", 47 | altsyncram_component.clock_enable_input_b = "BYPASS", 48 | altsyncram_component.clock_enable_output_a = "BYPASS", 49 | altsyncram_component.clock_enable_output_b = "BYPASS", 50 | altsyncram_component.indata_reg_b = "CLOCK0", 51 | altsyncram_component.intended_device_family = "Cyclone V", 52 | altsyncram_component.lpm_type = "altsyncram", 53 | altsyncram_component.numwords_a = 1024, 54 | altsyncram_component.numwords_b = 1024, 55 | altsyncram_component.operation_mode = "BIDIR_DUAL_PORT", 56 | altsyncram_component.outdata_aclr_a = "NONE", 57 | altsyncram_component.outdata_aclr_b = "NONE", 58 | altsyncram_component.outdata_reg_a = "UNREGISTERED", 59 | altsyncram_component.outdata_reg_b = "UNREGISTERED", 60 | altsyncram_component.power_up_uninitialized = "FALSE", 61 | altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", 62 | altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ", 63 | altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ", 64 | altsyncram_component.widthad_a = 10, 65 | altsyncram_component.widthad_b = 10, 66 | altsyncram_component.width_a = 16, 67 | altsyncram_component.width_b = 16, 68 | altsyncram_component.width_byteena_a = 2, 69 | altsyncram_component.width_byteena_b = 2, 70 | altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0"; 71 | 72 | assign Q_A = sub_wire0; 73 | assign Q_B = sub_wire1; 74 | 75 | endmodule 76 | 77 | module VDP2_WRITE_FIFO ( 78 | input CLK, 79 | input RST_N, 80 | 81 | input [35:0] DATA, 82 | input WRREQ, 83 | input RDREQ, 84 | output [35:0] Q, 85 | output EMPTY, 86 | output FULL, 87 | output LAST 88 | ); 89 | 90 | wire [35: 0] sub_wire0; 91 | bit [ 2: 0] RADDR; 92 | bit [ 2: 0] WADDR; 93 | bit [ 3: 0] AMOUNT; 94 | 95 | always @(posedge CLK or negedge RST_N) begin 96 | if (!RST_N) begin 97 | AMOUNT <= '0; 98 | RADDR <= '0; 99 | WADDR <= '0; 100 | end 101 | else begin 102 | if (WRREQ && !AMOUNT[3]) begin 103 | WADDR <= WADDR + 3'd1; 104 | end 105 | if (RDREQ && AMOUNT) begin 106 | RADDR <= RADDR + 3'd1; 107 | end 108 | 109 | if (WRREQ && !RDREQ && !AMOUNT[3]) begin 110 | AMOUNT <= AMOUNT + 4'd1; 111 | end else if (!WRREQ && RDREQ && AMOUNT) begin 112 | AMOUNT <= AMOUNT - 4'd1; 113 | end 114 | end 115 | end 116 | assign EMPTY = ~|AMOUNT; 117 | assign FULL = AMOUNT[3]; 118 | assign LAST = (AMOUNT == 4'd1); 119 | 120 | altdpram altdpram_component ( 121 | .data (DATA), 122 | .inclock (CLK), 123 | .rdaddress (RADDR), 124 | .wraddress (WADDR), 125 | .wren (WRREQ), 126 | .q (sub_wire0), 127 | .aclr (1'b0), 128 | .byteena (1'b1), 129 | .inclocken (1'b1), 130 | .rdaddressstall (1'b0), 131 | .rden (1'b1), 132 | // .sclr (1'b0), 133 | .wraddressstall (1'b0)); 134 | defparam 135 | altdpram_component.indata_aclr = "OFF", 136 | altdpram_component.indata_reg = "INCLOCK", 137 | altdpram_component.intended_device_family = "Cyclone V", 138 | altdpram_component.lpm_type = "altdpram", 139 | altdpram_component.outdata_aclr = "OFF", 140 | altdpram_component.outdata_reg = "UNREGISTERED", 141 | altdpram_component.ram_block_type = "MLAB", 142 | altdpram_component.rdaddress_aclr = "OFF", 143 | altdpram_component.rdaddress_reg = "UNREGISTERED", 144 | altdpram_component.rdcontrol_aclr = "OFF", 145 | altdpram_component.rdcontrol_reg = "UNREGISTERED", 146 | altdpram_component.read_during_write_mode_mixed_ports = "CONSTRAINED_DONT_CARE", 147 | altdpram_component.width = 36, 148 | altdpram_component.widthad = 3, 149 | altdpram_component.width_byteena = 1, 150 | altdpram_component.wraddress_aclr = "OFF", 151 | altdpram_component.wraddress_reg = "INCLOCK", 152 | altdpram_component.wrcontrol_aclr = "OFF", 153 | altdpram_component.wrcontrol_reg = "INCLOCK"; 154 | 155 | assign Q = sub_wire0; 156 | 157 | endmodule 158 | -------------------------------------------------------------------------------- /rtl/cofi.sv: -------------------------------------------------------------------------------- 1 | // Composite-like horizontal blending by Kitrinx 2 | 3 | module cofi ( 4 | input clk, 5 | input pix_ce, 6 | input enable, 7 | 8 | input hblank, 9 | input vblank, 10 | input hs, 11 | input vs, 12 | input [7:0] red, 13 | input [7:0] green, 14 | input [7:0] blue, 15 | 16 | output reg hblank_out, 17 | output reg vblank_out, 18 | output reg hs_out, 19 | output reg vs_out, 20 | output reg [7:0] red_out, 21 | output reg [7:0] green_out, 22 | output reg [7:0] blue_out 23 | ); 24 | 25 | function bit [7:0] color_blend ( 26 | input [7:0] color_prev, 27 | input [7:0] color_curr, 28 | input blank_last 29 | ); 30 | begin 31 | color_blend = blank_last ? color_curr : (color_prev >> 1) + (color_curr >> 1); 32 | end 33 | endfunction 34 | 35 | reg [7:0] red_last; 36 | reg [7:0] green_last; 37 | reg [7:0] blue_last; 38 | 39 | always @(posedge clk) if (pix_ce) begin 40 | 41 | hblank_out <= hblank; 42 | vblank_out <= vblank; 43 | vs_out <= vs; 44 | hs_out <= hs; 45 | 46 | red_last <= red; 47 | blue_last <= blue; 48 | green_last <= green; 49 | 50 | red_out <= enable ? color_blend(red_last, red, hblank_out) : red; 51 | blue_out <= enable ? color_blend(blue_last, blue, hblank_out) : blue; 52 | green_out <= enable ? color_blend(green_last, green, hblank_out) : green; 53 | 54 | end 55 | 56 | endmodule 57 | -------------------------------------------------------------------------------- /rtl/hps_ext.v: -------------------------------------------------------------------------------- 1 | // 2 | // hps_ext for Saturn 3 | // 4 | // Copyright (c) 2020 Alexey Melnikov 5 | // 6 | // This source file is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published 8 | // by the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This source file is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | // 19 | /////////////////////////////////////////////////////////////////////// 20 | 21 | module hps_ext 22 | ( 23 | input clk_sys, 24 | inout [35:0] EXT_BUS, 25 | 26 | // CD interface 27 | input [96:0] cd_in, 28 | output reg [96:0] cd_out 29 | ); 30 | 31 | assign EXT_BUS[15:0] = io_dout; 32 | wire [15:0] io_din = EXT_BUS[31:16]; 33 | assign EXT_BUS[32] = dout_en; 34 | wire io_strobe = EXT_BUS[33]; 35 | wire io_enable = EXT_BUS[34]; 36 | 37 | localparam EXT_CMD_MIN = CD_GET; 38 | localparam EXT_CMD_MAX = CD_SET; 39 | 40 | localparam CD_GET = 'h34; 41 | localparam CD_SET = 'h35; 42 | 43 | reg [15:0] io_dout; 44 | reg dout_en = 0; 45 | reg [9:0] byte_cnt; 46 | 47 | always@(posedge clk_sys) begin 48 | reg [15:0] cmd; 49 | reg [7:0] cd_req = 0; 50 | reg old_cd = 0; 51 | reg old_io_enable = 0; 52 | 53 | old_cd <= cd_in[96]; 54 | if(old_cd ^ cd_in[96]) cd_req <= cd_req + 1'd1; 55 | 56 | old_io_enable <= io_enable; 57 | if(~io_enable) begin 58 | dout_en <= 0; 59 | io_dout <= 0; 60 | byte_cnt <= 0; 61 | if(cmd == 'h35 && old_io_enable) cd_out[96] <= ~cd_out[96]; 62 | end 63 | else if(io_strobe) begin 64 | 65 | io_dout <= 0; 66 | if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1; 67 | 68 | if(byte_cnt == 0) begin 69 | cmd <= io_din; 70 | dout_en <= (io_din >= EXT_CMD_MIN && io_din <= EXT_CMD_MAX); 71 | if(io_din == CD_GET) io_dout <= cd_req; 72 | end else begin 73 | case(cmd) 74 | CD_GET: 75 | if(!byte_cnt[9:3]) begin 76 | case(byte_cnt[2:0]) 77 | 1: io_dout <= cd_in[15:0]; 78 | 2: io_dout <= cd_in[31:16]; 79 | 3: io_dout <= cd_in[47:32]; 80 | 4: io_dout <= cd_in[63:48]; 81 | 5: io_dout <= cd_in[79:64]; 82 | 6: io_dout <= cd_in[95:80]; 83 | endcase 84 | end 85 | 86 | CD_SET: 87 | if(!byte_cnt[9:3]) begin 88 | case(byte_cnt[2:0]) 89 | 1: cd_out[15:0] <= io_din; 90 | 2: cd_out[31:16] <= io_din; 91 | 3: cd_out[47:32] <= io_din; 92 | 4: cd_out[63:48] <= io_din; 93 | 5: cd_out[79:64] <= io_din; 94 | 6: cd_out[95:80] <= io_din; 95 | endcase 96 | end 97 | endcase 98 | end 99 | end 100 | end 101 | 102 | endmodule 103 | -------------------------------------------------------------------------------- /rtl/jtframe_resync.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT_FRAME. 2 | JTFRAME program is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | JTFRAME program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with JTFRAME. If not, see . 14 | 15 | Author: Jose Tejada Gomez. Twitter: @topapate 16 | Version: 1.0 17 | Date: 25-9-2019 */ 18 | 19 | module jtframe_resync #(parameter BITS=4)( 20 | input clk, 21 | input pxl_cen, 22 | input hs_in, 23 | input vs_in, 24 | input LVBL, 25 | input LHBL, 26 | input [BITS - 1:0] hoffset, 27 | input [BITS - 1:0] voffset, 28 | input hres_mode, 29 | output reg hs_out, 30 | output reg vs_out 31 | ); 32 | 33 | parameter CNTW = 10; // max 1024 pixels/lines 34 | 35 | reg [CNTW-1:0] hs_pos[0:1], vs_hpos[0:1], vs_vpos[0:1],// relative positions of the original sync pulses 36 | hs_len[0:1], vs_len[0:1], // count the length of the original sync pulses 37 | hs_cnt, vs_cnt, // count the position of the original sync pulses 38 | hs_hold, vs_hold; 39 | reg last_LHBL, last_LVBL, last_hsin, last_vsin; 40 | 41 | wire hb_edge, hs_edge, hs_n_edge, vb_edge, vs_edge, vs_n_edge; 42 | reg field; 43 | 44 | wire [CNTW-1:0] hpos_off = hres_mode ? 45 | { {CNTW-BITS-1{hoffset[BITS-1]}}, hoffset, 1'b0 } : 46 | { {CNTW-BITS{hoffset[BITS-1]}}, hoffset }; 47 | wire [CNTW-1:0] htrip = hs_pos[field] + hpos_off; 48 | wire [CNTW-1:0] vs_htrip = vs_hpos[field] + hpos_off; 49 | wire [CNTW-1:0] vs_vtrip = vs_vpos[field] + { {CNTW-BITS{voffset[BITS-1]}}, voffset[(BITS-1):0] }; 50 | 51 | assign hb_edge = LHBL && !last_LHBL; 52 | assign hs_edge = hs_in && !last_hsin; 53 | assign hs_n_edge = !hs_in && last_hsin; 54 | assign vb_edge = LVBL && !last_LVBL; 55 | assign vs_edge = vs_in && !last_vsin; 56 | assign vs_n_edge = !vs_in && last_vsin; 57 | 58 | always @(posedge clk) if(pxl_cen) begin 59 | last_LHBL <= LHBL; 60 | last_LVBL <= LVBL; 61 | last_hsin <= hs_in; 62 | last_vsin <= vs_in; 63 | 64 | hs_cnt <= hb_edge ? {CNTW{1'b0}} : hs_cnt+1'b1; 65 | if( vb_edge ) begin 66 | vs_cnt <= {CNTW{1'b0}}; 67 | field <= ~field; 68 | end else if(hb_edge) 69 | vs_cnt <= vs_cnt+1'b1; 70 | 71 | // Horizontal 72 | if( hs_edge ) hs_pos[field] <= hs_cnt; 73 | if( hs_n_edge ) hs_len[field] <= hs_cnt - hs_pos[field]; 74 | 75 | if( hs_cnt == htrip ) begin 76 | hs_out <= 1; 77 | hs_hold <= hs_len[field] - 1'b1; 78 | end else begin 79 | if( |hs_hold ) hs_hold <= hs_hold - 1'b1; 80 | if( hs_hold == 0 ) hs_out <= 0; 81 | end 82 | 83 | // Vertical 84 | if( vs_edge ) begin 85 | vs_hpos[field] <= hs_cnt; 86 | vs_vpos[field] <= vs_cnt; 87 | end 88 | if( vs_n_edge ) vs_len[field] <= vs_cnt - vs_vpos[field]; 89 | 90 | if( hs_cnt == vs_htrip ) begin 91 | if( vs_cnt == vs_vtrip ) begin 92 | vs_hold <= vs_len[field] - 1'b1; 93 | vs_out <= 1; 94 | end else begin 95 | if( |vs_hold ) vs_hold <= vs_hold - 1'b1; 96 | if( vs_hold == 0 ) vs_out <= 0; 97 | end 98 | end 99 | 100 | end 101 | 102 | `ifdef SIMULATION 103 | initial begin 104 | hs_cnt = {CNTW{1'b0}}; 105 | vs_cnt = {CNTW{1'b0}}; 106 | hs_out = 0; 107 | vs_out = 0; 108 | end 109 | `endif 110 | 111 | endmodule 112 | -------------------------------------------------------------------------------- /rtl/mlab.vhd: -------------------------------------------------------------------------------- 1 | LIBRARY ieee; 2 | USE ieee.std_logic_1164.all; 3 | 4 | LIBRARY altera_mf; 5 | USE altera_mf.altera_mf_components.all; 6 | 7 | ENTITY mlab IS 8 | generic ( 9 | addr_width : integer := 8; 10 | data_width : integer := 8 11 | ); 12 | PORT 13 | ( 14 | clock : in STD_LOGIC; 15 | rdaddress : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); 16 | wraddress : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); 17 | data : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); 18 | wren : in STD_LOGIC := '0'; 19 | q : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); 20 | cs : in std_logic := '1' 21 | ); 22 | END ENTITY; 23 | 24 | ARCHITECTURE SYN OF mlab IS 25 | signal q0 : std_logic_vector((data_width - 1) downto 0); 26 | BEGIN 27 | q<= q0 when cs = '1' else (others => '1'); 28 | 29 | altdpram_component : altdpram 30 | GENERIC MAP ( 31 | indata_aclr => "OFF", 32 | indata_reg => "INCLOCK", 33 | intended_device_family => "Cyclone V", 34 | lpm_type => "altdpram", 35 | outdata_aclr => "OFF", 36 | outdata_reg => "UNREGISTERED", 37 | ram_block_type => "MLAB", 38 | rdaddress_aclr => "OFF", 39 | rdaddress_reg => "UNREGISTERED", 40 | rdcontrol_aclr => "OFF", 41 | rdcontrol_reg => "UNREGISTERED", 42 | read_during_write_mode_mixed_ports => "CONSTRAINED_DONT_CARE", 43 | width => data_width, 44 | widthad => addr_width, 45 | width_byteena => 1, 46 | wraddress_aclr => "OFF", 47 | wraddress_reg => "INCLOCK", 48 | wrcontrol_aclr => "OFF", 49 | wrcontrol_reg => "INCLOCK" 50 | ) 51 | PORT MAP ( 52 | data => data, 53 | outclock => clock, 54 | rdaddress => rdaddress, 55 | wren => wren, 56 | inclock => clock, 57 | wraddress => wraddress, 58 | q => q0 59 | ); 60 | 61 | END SYN; -------------------------------------------------------------------------------- /rtl/pll/pll_0002.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*" 2 | set_instance_assignment -name UNFORCE_MERGE_PLL_OUTPUT_COUNTER ON -to "*pll_0002*|altera_pll:altera_pll_i*|*" 3 | -------------------------------------------------------------------------------- /rtl/pll/pll_0002_q13.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*" 2 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*" 3 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*" 4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*" 5 | -------------------------------------------------------------------------------- /rtl/ps2mouse.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | 3 | /* 4 | * PS2 mouse protocol 5 | * Bit 7 6 5 4 3 2 1 0 6 | * Byte 0: YOVR XOVR YSGN XSGN 1 MBUT RBUT LBUT 7 | * Byte 1: XMOVE 8 | * Byte 2: YMOVE 9 | */ 10 | 11 | module ps2_mouse 12 | ( 13 | input clk, 14 | input ce, 15 | 16 | input reset, 17 | input reset_acc, 18 | 19 | input [24:0] ps2_mouse, 20 | input [15:0] ps2_mouse_ext, 21 | 22 | output reg [3:0] flags, 23 | output reg [3:0] buttons, 24 | output reg [7:0] x, 25 | output reg [7:0] y 26 | ); 27 | 28 | 29 | reg [10:0] curdx; 30 | reg [10:0] curdy; 31 | wire [10:0] newdx = curdx + {{3{ps2_mouse[4]}},ps2_mouse[15:8]}; 32 | wire [10:0] newdy = curdy + {{3{ps2_mouse[5]}},ps2_mouse[23:16]}; 33 | wire [7:0] dx = curdx[7:0]; 34 | wire [7:0] dy = curdy[7:0]; 35 | 36 | /* flags bits */ 37 | wire x_ov_p = ($signed(newdx) > $signed( 10'd255)); 38 | wire x_ov_n = ($signed(newdx) < $signed(-10'd256)); 39 | wire x_ov = x_ov_p | x_ov_n; 40 | wire y_ov_p = ($signed(newdy) > $signed( 10'd255)); 41 | wire y_ov_n = ($signed(newdy) < $signed(-10'd256)); 42 | wire y_ov = y_ov_p | y_ov_n; 43 | wire sdx = newdx[10]; 44 | wire sdy = newdy[10]; 45 | 46 | wire strobe = (old_stb != ps2_mouse[24]); 47 | reg old_stb = 0; 48 | always @(posedge clk) old_stb <= ps2_mouse[24]; 49 | 50 | /* Capture flags state */ 51 | always@(posedge clk or posedge reset or posedge reset_acc) begin 52 | if (reset || reset_acc) flags[3:0] <= 4'b0; 53 | else if (strobe) begin 54 | flags <= {y_ov,x_ov,sdy,sdx}; 55 | end 56 | end 57 | 58 | /* Clip x accumulator */ 59 | always@(posedge clk or posedge reset or posedge reset_acc) begin 60 | if (reset || reset_acc) curdx <= 0; 61 | else if (strobe) begin 62 | if(x_ov_p) curdx <= 10'd255; 63 | else if(x_ov_n) curdx <= -10'd256; 64 | else curdx <= newdx; 65 | end 66 | end 67 | 68 | /* Clip y accumulator */ 69 | always@(posedge clk or posedge reset or posedge reset_acc) begin 70 | if (reset || reset_acc) curdy <= 0; 71 | else if (strobe) begin 72 | if(y_ov_p) curdy <= 10'd255; 73 | else if(y_ov_n) curdy <= -10'd256; 74 | else curdy <= newdy; 75 | end 76 | end 77 | 78 | /* Capture button state */ 79 | always@(posedge clk or posedge reset) 80 | if (reset) buttons[3:0] <= 4'b0; 81 | else if (strobe) buttons[3:0] <= {|ps2_mouse_ext[15:8],ps2_mouse[2:0]}; 82 | 83 | always@(posedge clk or posedge reset) begin 84 | if (reset) x <= 0; 85 | else x <= dx; 86 | end 87 | 88 | always@(posedge clk or posedge reset) begin 89 | if (reset) y <= 0; 90 | else y <= dy; 91 | end 92 | 93 | endmodule 94 | -------------------------------------------------------------------------------- /rtl/sdr.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTer-devel/Saturn_MiSTer/fc4593ef37f40661c07d513ffbef2d01cbb277eb/rtl/sdr.xlsx -------------------------------------------------------------------------------- /rtl/stv_eeprom.mif: -------------------------------------------------------------------------------- 1 | WIDTH=16; 2 | DEPTH=64; 3 | 4 | ADDRESS_RADIX=HEX; 5 | DATA_RADIX=HEX; 6 | 7 | CONTENT BEGIN 8 | 0000 : 5345; 9 | 0001 : 4741; 10 | 0002 : FFFF; 11 | 0003 : FFFF; 12 | 0004 : 9015; 13 | 0005 : FFFF; 14 | 0006 : 0000; 15 | 0007 : 0001; 16 | 0008 : 0100; 17 | 0009 : 0101; 18 | 000A : 0000; 19 | 000B : 0000; 20 | 000C : 0008; 21 | 000D : 08FD; 22 | 000E : 1D01; 23 | 000F : 0203; 24 | 0010 : 0300; 25 | 0011 : 0000; 26 | 0012 : 0000; 27 | 0013 : FFFF; 28 | 0014 : FFFF; 29 | 0015 : FFFF; 30 | 0016 : FFFF; 31 | 0017 : FFFF; 32 | 0018 : FFFF; 33 | 0019 : FFFF; 34 | 001A : FFFF; 35 | 001B : FFFF; 36 | 001C : FFFF; 37 | 001D : FFFF; 38 | 001E : FFFF; 39 | 001F : FFFF; 40 | 0020 : FFFF; 41 | 0021 : FFFF; 42 | 0022 : 9015; 43 | 0023 : FFFF; 44 | 0024 : 0000; 45 | 0025 : 0001; 46 | 0026 : 0100; 47 | 0027 : 0101; 48 | 0028 : 0000; 49 | 0029 : 0000; 50 | 002A : 0008; 51 | 002B : 08FD; 52 | 002C : 1D01; 53 | 002D : 0203; 54 | 002E : 0300; 55 | 002F : 0000; 56 | 0030 : 0000; 57 | 0031 : FFFF; 58 | 0032 : FFFF; 59 | 0033 : FFFF; 60 | 0034 : FFFF; 61 | 0035 : FFFF; 62 | 0036 : FFFF; 63 | 0037 : FFFF; 64 | 0038 : FFFF; 65 | 0039 : FFFF; 66 | 003A : FFFF; 67 | 003B : FFFF; 68 | 003C : FFFF; 69 | 003D : FFFF; 70 | 003E : FFFF; 71 | 003F : FFFF; 72 | 73 | END; 74 | -------------------------------------------------------------------------------- /rtl/vdp1_fb.sv: -------------------------------------------------------------------------------- 1 | module vdp1_fb_352x256x16 2 | ( 3 | input clock, 4 | input [16:0] address, 5 | input [15:0] data, 6 | input [1:0] wren, 7 | output [15:0] q 8 | ); 9 | 10 | wire [15:0] ram64Kx16_q,ram16Kx16_q,ram8Kx16_q; 11 | spram #(16,8) ram64Kx16l 12 | ( 13 | .clock(clock), 14 | .address(address[15:0]), 15 | .data(data[7:0]), 16 | .wren(wren[0] & ~address[16]), 17 | .q(ram64Kx16_q[7:0]) 18 | ); 19 | spram #(16,8) ram64Kx16h 20 | ( 21 | .clock(clock), 22 | .address(address[15:0]), 23 | .data(data[15:8]), 24 | .wren(wren[1] & ~address[16]), 25 | .q(ram64Kx16_q[15:8]) 26 | ); 27 | 28 | spram #(14,8) ram16Kx16l 29 | ( 30 | .clock(clock), 31 | .address(address[13:0]), 32 | .data(data[7:0]), 33 | .wren(wren[0] & address[16] & ~address[15] & ~address[14]), 34 | .q(ram16Kx16_q[7:0]) 35 | ); 36 | spram #(14,8) ram16Kx16h 37 | ( 38 | .clock(clock), 39 | .address(address[13:0]), 40 | .data(data[15:8]), 41 | .wren(wren[1] & address[16] & ~address[15] & ~address[14]), 42 | .q(ram16Kx16_q[15:8]) 43 | ); 44 | 45 | spram #(13,8) ram8Kx16l 46 | ( 47 | .clock(clock), 48 | .address(address[12:0]), 49 | .data(data[7:0]), 50 | .wren(wren[0] & address[16] & ~address[15] & address[14] & ~address[13]), 51 | .q(ram8Kx16_q[7:0]) 52 | ); 53 | spram #(13,8) ram8Kx16h 54 | ( 55 | .clock(clock), 56 | .address(address[12:0]), 57 | .data(data[15:8]), 58 | .wren(wren[1] & address[16] & ~address[15] & address[14] & ~address[13]), 59 | .q(ram8Kx16_q[15:8]) 60 | ); 61 | assign q = !address[16] ? ram64Kx16_q : 62 | !address[15] && !address[14] ? ram16Kx16_q : 63 | ram8Kx16_q; 64 | 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /sys/alsa.sv: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // 3 | // ALSA sound support for MiSTer 4 | // (c)2019,2020 Alexey Melnikov 5 | // 6 | // This program is free software; you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License as published by the Free 8 | // Software Foundation; either version 2 of the License, or (at your option) 9 | // any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, but WITHOUT 12 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | // more details. 15 | // 16 | // You should have received a copy of the GNU General Public License along 17 | // with this program; if not, write to the Free Software Foundation, Inc., 18 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | // 20 | //============================================================================ 21 | 22 | module alsa 23 | #( 24 | parameter CLK_RATE = 24576000 25 | ) 26 | ( 27 | input reset, 28 | input clk, 29 | 30 | output reg [31:3] ram_address, 31 | input [63:0] ram_data, 32 | output reg ram_req = 0, 33 | input ram_ready, 34 | 35 | input spi_ss, 36 | input spi_sck, 37 | input spi_mosi, 38 | output spi_miso, 39 | 40 | output reg [15:0] pcm_l, 41 | output reg [15:0] pcm_r 42 | ); 43 | 44 | reg [60:0] buf_info; 45 | reg [6:0] spicnt = 0; 46 | always @(posedge spi_sck, posedge spi_ss) begin 47 | reg [95:0] spi_data; 48 | 49 | if(spi_ss) spicnt <= 0; 50 | else begin 51 | spi_data[{spicnt[6:3],~spicnt[2:0]}] <= spi_mosi; 52 | if(&spicnt) buf_info <= {spi_data[82:67],spi_data[50:35],spi_data[31:3]}; 53 | spicnt <= spicnt + 1'd1; 54 | end 55 | end 56 | 57 | assign spi_miso = spi_out[{spicnt[4:3],~spicnt[2:0]}]; 58 | 59 | reg [31:0] spi_out = 0; 60 | always @(posedge clk) if(spi_ss) spi_out <= {buf_rptr, hurryup, 8'h00}; 61 | 62 | 63 | reg [31:3] buf_addr; 64 | reg [18:3] buf_len; 65 | reg [18:3] buf_wptr = 0; 66 | 67 | always @(posedge clk) begin 68 | reg [60:0] data1,data2; 69 | 70 | data1 <= buf_info; 71 | data2 <= data1; 72 | if(data2 == data1) {buf_wptr,buf_len,buf_addr} <= data2; 73 | end 74 | 75 | reg [2:0] hurryup = 0; 76 | reg [18:3] buf_rptr = 0; 77 | 78 | always @(posedge clk) begin 79 | reg [18:3] len = 0; 80 | reg [1:0] ready = 0; 81 | reg [63:0] readdata; 82 | reg got_first = 0; 83 | reg [7:0] ce_cnt = 0; 84 | reg [1:0] state = 0; 85 | 86 | if(reset) begin 87 | ready <= 0; 88 | ce_cnt <= 0; 89 | state <= 0; 90 | got_first <= 0; 91 | len <= 0; 92 | end 93 | else begin 94 | 95 | //ramp up 96 | if(len[18:14] && (hurryup < 1)) hurryup <= 1; 97 | if(len[18:16] && (hurryup < 2)) hurryup <= 2; 98 | if(len[18:17] && (hurryup < 4)) hurryup <= 4; 99 | 100 | //ramp down 101 | if(!len[18:15] && (hurryup > 2)) hurryup <= 2; 102 | if(!len[18:13] && (hurryup > 1)) hurryup <= 1; 103 | if(!len[18:10]) hurryup <= 0; 104 | 105 | if(ce_sample && ~&ce_cnt) ce_cnt <= ce_cnt + 1'd1; 106 | 107 | case(state) 108 | 0: if(!ce_sample) begin 109 | if(ready) begin 110 | if(ce_cnt) begin 111 | {readdata[31:0],pcm_r,pcm_l} <= readdata; 112 | ready <= ready - 1'd1; 113 | ce_cnt <= ce_cnt - 1'd1; 114 | end 115 | end 116 | else if(buf_rptr != buf_wptr) begin 117 | if(~got_first) begin 118 | buf_rptr <= buf_wptr; 119 | got_first <= 1; 120 | end 121 | else begin 122 | ram_address <= buf_addr + buf_rptr; 123 | ram_req <= ~ram_req; 124 | buf_rptr <= buf_rptr + 1'd1; 125 | len <= (buf_wptr < buf_rptr) ? (buf_len + buf_wptr - buf_rptr) : (buf_wptr - buf_rptr); 126 | state <= 1; 127 | end 128 | end 129 | else begin 130 | len <= 0; 131 | ce_cnt <= 0; 132 | hurryup <= 0; 133 | end 134 | end 135 | 1: if(ram_ready) begin 136 | ready <= 2; 137 | readdata <= ram_data; 138 | if(buf_rptr >= buf_len) buf_rptr <= buf_rptr - buf_len; 139 | state <= 0; 140 | end 141 | endcase 142 | end 143 | end 144 | 145 | reg ce_sample; 146 | always @(posedge clk) begin 147 | reg [31:0] acc = 0; 148 | 149 | ce_sample <= 0; 150 | acc <= acc + 48000 + {hurryup,6'd0}; 151 | if(acc >= CLK_RATE) begin 152 | acc <= acc - CLK_RATE; 153 | ce_sample <= 1; 154 | end 155 | end 156 | 157 | endmodule 158 | -------------------------------------------------------------------------------- /sys/build_id.tcl: -------------------------------------------------------------------------------- 1 | 2 | # Build TimeStamp Verilog Module 3 | # Jeff Wiencrot - 8/1/2011 4 | # Sorgelig - 02/11/2019 5 | proc generateBuildID_Verilog {} { 6 | 7 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) 8 | set buildDate "`define BUILD_DATE \"[clock format [ clock seconds ] -format %y%m%d]\"" 9 | 10 | # Create a Verilog file for output 11 | set outputFileName "build_id.v" 12 | 13 | set fileData "" 14 | if { [file exists $outputFileName]} { 15 | set outputFile [open $outputFileName "r"] 16 | set fileData [read $outputFile] 17 | close $outputFile 18 | } 19 | 20 | if {$buildDate ne $fileData} { 21 | set outputFile [open $outputFileName "w"] 22 | puts -nonewline $outputFile $buildDate 23 | close $outputFile 24 | # Send confirmation message to the Messages window 25 | post_message "Generated: [pwd]/$outputFileName: $buildDate" 26 | } 27 | } 28 | 29 | # Build CDF file 30 | # Sorgelig - 17/2/2018 31 | proc generateCDF {revision device outpath} { 32 | 33 | set outputFileName "jtag.cdf" 34 | set outputFile [open $outputFileName "w"] 35 | 36 | puts $outputFile "JedecChain;" 37 | puts $outputFile " FileRevision(JESD32A);" 38 | puts $outputFile " DefaultMfr(6E);" 39 | puts $outputFile "" 40 | puts $outputFile " P ActionCode(Ign)" 41 | puts $outputFile " Device PartName(SOCVHPS) MfrSpec(OpMask(0));" 42 | puts $outputFile " P ActionCode(Cfg)" 43 | puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));" 44 | puts $outputFile "ChainEnd;" 45 | puts $outputFile "" 46 | puts $outputFile "AlteraBegin;" 47 | puts $outputFile " ChainType(JTAG);" 48 | puts $outputFile "AlteraEnd;" 49 | } 50 | 51 | set project_name [lindex $quartus(args) 1] 52 | set revision [lindex $quartus(args) 2] 53 | 54 | if {[project_exists $project_name]} { 55 | if {[string equal "" $revision]} { 56 | project_open $project_name -revision [get_current_revision $project_name] 57 | } else { 58 | project_open $project_name -revision $revision 59 | } 60 | } else { 61 | post_message -type error "Project $project_name does not exist" 62 | exit 63 | } 64 | 65 | set device [get_global_assignment -name DEVICE] 66 | set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY] 67 | 68 | if [is_project_open] { 69 | project_close 70 | } 71 | 72 | generateBuildID_Verilog 73 | generateCDF $revision $device $outpath 74 | -------------------------------------------------------------------------------- /sys/ddr_svc.sv: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2020 Alexey Melnikov 3 | // 4 | // 5 | // This source file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published 7 | // by the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This source file is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | // 18 | // ------------------------------------------ 19 | // 20 | 21 | // 16-bit version 22 | 23 | module ddr_svc 24 | ( 25 | input clk, 26 | 27 | input ram_waitrequest, 28 | output [7:0] ram_burstcnt, 29 | output [28:0] ram_addr, 30 | input [63:0] ram_readdata, 31 | input ram_read_ready, 32 | output reg ram_read, 33 | output [63:0] ram_writedata, 34 | output [7:0] ram_byteenable, 35 | output reg ram_write, 36 | 37 | output [7:0] ram_bcnt, 38 | 39 | input [31:3] ch0_addr, 40 | input [7:0] ch0_burst, 41 | output [63:0] ch0_data, 42 | input ch0_req, 43 | output ch0_ready, 44 | 45 | input [31:3] ch1_addr, 46 | input [7:0] ch1_burst, 47 | output [63:0] ch1_data, 48 | input ch1_req, 49 | output ch1_ready 50 | ); 51 | 52 | assign ram_burstcnt = ram_burst; 53 | assign ram_byteenable = 8'hFF; 54 | assign ram_addr = ram_address; 55 | assign ram_writedata = 0; 56 | 57 | assign ch0_data = ram_q[0]; 58 | assign ch1_data = ram_q[1]; 59 | assign ch0_ready = ready[0]; 60 | assign ch1_ready = ready[1]; 61 | 62 | reg [7:0] ram_burst; 63 | reg [63:0] ram_q[2]; 64 | reg [31:3] ram_address; 65 | reg [1:0] ack = 0; 66 | reg [1:0] ready; 67 | reg state = 0; 68 | reg ch = 0; 69 | 70 | always @(posedge clk) begin 71 | ready <= 0; 72 | 73 | if(!ram_waitrequest) begin 74 | ram_read <= 0; 75 | ram_write <= 0; 76 | 77 | case(state) 78 | 0: if(ch0_req != ack[0]) begin 79 | ack[0] <= ch0_req; 80 | ram_address <= ch0_addr; 81 | ram_burst <= ch0_burst; 82 | ram_read <= 1; 83 | ch <= 0; 84 | ram_bcnt <= 8'hFF; 85 | state <= 1; 86 | end 87 | else if(ch1_req != ack[1]) begin 88 | ack[1] <= ch1_req; 89 | ram_address <= ch1_addr; 90 | ram_burst <= ch1_burst; 91 | ram_read <= 1; 92 | ch <= 1; 93 | ram_bcnt <= 8'hFF; 94 | state <= 1; 95 | end 96 | 1: begin 97 | if(ram_read_ready) begin 98 | ram_bcnt <= ram_bcnt + 1'd1; 99 | ram_q[ch] <= ram_readdata; 100 | ready[ch] <= 1; 101 | if ((ram_bcnt+2'd2) == ram_burst) state <= 0; 102 | end 103 | end 104 | endcase 105 | end 106 | end 107 | 108 | endmodule 109 | -------------------------------------------------------------------------------- /sys/gamma_corr.sv: -------------------------------------------------------------------------------- 1 | module gamma_corr 2 | ( 3 | input clk_sys, 4 | input clk_vid, 5 | input ce_pix, 6 | input gamma_en, 7 | input gamma_wr, 8 | input [9:0] gamma_wr_addr, 9 | input [7:0] gamma_value, 10 | input HSync, 11 | input VSync, 12 | input HBlank, 13 | input VBlank, 14 | input [23:0] RGB_in, 15 | output reg HSync_out, 16 | output reg VSync_out, 17 | output reg HBlank_out, 18 | output reg VBlank_out, 19 | output reg [23:0] RGB_out 20 | ); 21 | 22 | (* ramstyle="no_rw_check" *) reg [7:0] gamma_curve[768]; 23 | 24 | always @(posedge clk_sys) if (gamma_wr) gamma_curve[gamma_wr_addr] <= gamma_value; 25 | always @(posedge clk_vid) gamma <= gamma_curve[gamma_index]; 26 | 27 | reg [9:0] gamma_index; 28 | reg [7:0] gamma; 29 | 30 | always @(posedge clk_vid) begin 31 | reg [7:0] R_in, G_in, B_in; 32 | reg [7:0] R_gamma, G_gamma; 33 | reg hs,vs,hb,vb; 34 | reg [1:0] ctr = 0; 35 | reg old_ce; 36 | 37 | old_ce <= ce_pix; 38 | if(~old_ce & ce_pix) begin 39 | {R_in,G_in,B_in} <= RGB_in; 40 | hs <= HSync; vs <= VSync; 41 | hb <= HBlank; vb <= VBlank; 42 | 43 | RGB_out <= gamma_en ? {R_gamma,G_gamma,gamma} : {R_in,G_in,B_in}; 44 | HSync_out <= hs; VSync_out <= vs; 45 | HBlank_out <= hb; VBlank_out <= vb; 46 | 47 | ctr <= 1; 48 | gamma_index <= {2'b00,RGB_in[23:16]}; 49 | end 50 | 51 | if (|ctr) ctr <= ctr + 1'd1; 52 | 53 | case(ctr) 54 | 1: begin gamma_index <= {2'b01,G_in}; end 55 | 2: begin R_gamma <= gamma; gamma_index <= {2'b10,B_in}; end 56 | 3: begin G_gamma <= gamma; end 57 | endcase 58 | end 59 | 60 | endmodule 61 | 62 | module gamma_fast 63 | ( 64 | input clk_vid, 65 | input ce_pix, 66 | 67 | inout [21:0] gamma_bus, 68 | 69 | input HSync, 70 | input VSync, 71 | input HBlank, 72 | input VBlank, 73 | input DE, 74 | input [23:0] RGB_in, 75 | 76 | output reg HSync_out, 77 | output reg VSync_out, 78 | output reg HBlank_out, 79 | output reg VBlank_out, 80 | output reg DE_out, 81 | output reg [23:0] RGB_out 82 | ); 83 | 84 | (* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_r[256]; 85 | (* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_g[256]; 86 | (* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_b[256]; 87 | 88 | assign gamma_bus[21] = 1; 89 | wire clk_sys = gamma_bus[20]; 90 | wire gamma_en = gamma_bus[19]; 91 | wire gamma_wr = gamma_bus[18]; 92 | wire [9:0] gamma_wr_addr = gamma_bus[17:8]; 93 | wire [7:0] gamma_value = gamma_bus[7:0]; 94 | 95 | always @(posedge clk_sys) if (gamma_wr) begin 96 | case(gamma_wr_addr[9:8]) 97 | 0: gamma_curve_r[gamma_wr_addr[7:0]] <= gamma_value; 98 | 1: gamma_curve_g[gamma_wr_addr[7:0]] <= gamma_value; 99 | 2: gamma_curve_b[gamma_wr_addr[7:0]] <= gamma_value; 100 | endcase 101 | end 102 | 103 | reg [7:0] gamma_index_r,gamma_index_g,gamma_index_b; 104 | 105 | always @(posedge clk_vid) begin 106 | reg [7:0] R_in, G_in, B_in; 107 | reg [7:0] R_gamma, G_gamma; 108 | reg hs,vs,hb,vb,de; 109 | 110 | if(ce_pix) begin 111 | {gamma_index_r,gamma_index_g,gamma_index_b} <= RGB_in; 112 | hs <= HSync; vs <= VSync; 113 | hb <= HBlank; vb <= VBlank; 114 | de <= DE; 115 | 116 | RGB_out <= gamma_en ? {gamma_curve_r[gamma_index_r],gamma_curve_g[gamma_index_g],gamma_curve_b[gamma_index_b]} 117 | : {gamma_index_r,gamma_index_g,gamma_index_b}; 118 | HSync_out <= hs; VSync_out <= vs; 119 | HBlank_out <= hb; VBlank_out <= vb; 120 | DE_out <= de; 121 | end 122 | end 123 | 124 | endmodule 125 | -------------------------------------------------------------------------------- /sys/i2c.v: -------------------------------------------------------------------------------- 1 | 2 | module i2c 3 | ( 4 | input CLK, 5 | 6 | input START, 7 | input READ, 8 | input [6:0] I2C_ADDR, 9 | input I2C_WLEN, // 0 - one byte, 1 - two bytes 10 | input [7:0] I2C_WDATA1, 11 | input [7:0] I2C_WDATA2, 12 | output [7:0] I2C_RDATA, 13 | output reg END = 1, 14 | output reg ACK = 0, 15 | 16 | //I2C bus 17 | output I2C_SCL, 18 | inout I2C_SDA 19 | ); 20 | 21 | 22 | // Clock Setting 23 | parameter CLK_Freq = 50_000_000; // 50 MHz 24 | parameter I2C_Freq = 400_000; // 400 KHz 25 | 26 | localparam I2C_FreqX2 = I2C_Freq*2; 27 | 28 | reg I2C_CLOCK; 29 | reg [31:0] cnt; 30 | wire [31:0] cnt_next = cnt + I2C_FreqX2; 31 | 32 | always @(posedge CLK) begin 33 | cnt <= cnt_next; 34 | if(cnt_next >= CLK_Freq) begin 35 | cnt <= cnt_next - CLK_Freq; 36 | I2C_CLOCK <= ~I2C_CLOCK; 37 | end 38 | end 39 | 40 | assign I2C_SCL = (SCLK | I2C_CLOCK) ? 1'bZ : 1'b0; 41 | assign I2C_SDA = SDO[3] ? 1'bz : 1'b0; 42 | 43 | reg SCLK; 44 | reg [3:0] SDO; 45 | reg [0:7] rdata; 46 | 47 | reg [5:0] SD_COUNTER; 48 | reg [0:31] SD; 49 | 50 | initial begin 51 | SD_COUNTER = 'b111111; 52 | SD = 'hFFFF; 53 | SCLK = 1; 54 | SDO = 4'b1111; 55 | end 56 | 57 | assign I2C_RDATA = rdata; 58 | 59 | always @(posedge CLK) begin 60 | reg old_clk; 61 | reg old_st; 62 | reg rd,len; 63 | 64 | old_clk <= I2C_CLOCK; 65 | old_st <= START; 66 | 67 | // delay to make sure SDA changed while SCL is stabilized at low 68 | if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[5]) SDO[0] <= SD[SD_COUNTER[4:0]]; 69 | SDO[3:1] <= SDO[2:0]; 70 | 71 | if(~old_st && START) begin 72 | SCLK <= 1; 73 | SDO <= 4'b1111; 74 | ACK <= 0; 75 | END <= 0; 76 | rd <= READ; 77 | len <= I2C_WLEN; 78 | if(READ) SD <= {2'b10, I2C_ADDR, 1'b1, 1'b1, 8'b11111111, 1'b1, 3'b011, 9'b111111111}; 79 | else SD <= {2'b10, I2C_ADDR, 1'b0, 1'b1, I2C_WDATA1, 1'b1, I2C_WDATA2, 4'b1011}; 80 | SD_COUNTER <= 0; 81 | end else begin 82 | if(~old_clk && I2C_CLOCK && ~&SD_COUNTER) begin 83 | SD_COUNTER <= SD_COUNTER + 6'd1; 84 | case(SD_COUNTER) 85 | 01: SCLK <= 0; 86 | 10: ACK <= ACK | I2C_SDA; 87 | 19: if(~rd) begin 88 | ACK <= ACK | I2C_SDA; 89 | if(~len) SD_COUNTER <= 29; 90 | end 91 | 20: if(rd) SCLK <= 1; 92 | 23: if(rd) END <= 1; 93 | 28: if(~rd) ACK <= ACK | I2C_SDA; 94 | 29: if(~rd) SCLK <= 1; 95 | 32: if(~rd) END <= 1; 96 | endcase 97 | 98 | if(SD_COUNTER >= 11 && SD_COUNTER <= 18) rdata[SD_COUNTER[4:0]-11] <= I2C_SDA; 99 | end 100 | end 101 | end 102 | 103 | endmodule 104 | -------------------------------------------------------------------------------- /sys/i2s.v: -------------------------------------------------------------------------------- 1 | 2 | module i2s 3 | #( 4 | parameter AUDIO_DW = 16 5 | ) 6 | ( 7 | input reset, 8 | input clk, 9 | input ce, 10 | 11 | output reg sclk, 12 | output reg lrclk, 13 | output reg sdata, 14 | 15 | input [AUDIO_DW-1:0] left_chan, 16 | input [AUDIO_DW-1:0] right_chan 17 | ); 18 | 19 | always @(posedge clk) begin 20 | reg [7:0] bit_cnt; 21 | reg msclk; 22 | 23 | reg [AUDIO_DW-1:0] left; 24 | reg [AUDIO_DW-1:0] right; 25 | 26 | if (reset) begin 27 | bit_cnt <= 1; 28 | lrclk <= 1; 29 | sclk <= 1; 30 | msclk <= 1; 31 | end 32 | else begin 33 | sclk <= msclk; 34 | if(ce) begin 35 | msclk <= ~msclk; 36 | if(msclk) begin 37 | if(bit_cnt >= AUDIO_DW) begin 38 | bit_cnt <= 1; 39 | lrclk <= ~lrclk; 40 | if(lrclk) begin 41 | left <= left_chan; 42 | right <= right_chan; 43 | end 44 | end 45 | else begin 46 | bit_cnt <= bit_cnt + 1'd1; 47 | end 48 | sdata <= lrclk ? right[AUDIO_DW - bit_cnt] : left[AUDIO_DW - bit_cnt]; 49 | end 50 | end 51 | end 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /sys/ltc2308.sv: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // 3 | // LTC2308 controller 4 | // Copyright (C) 2019 Sorgelig 5 | // 6 | // 7 | // This program is free software; you can redistribute it and/or modify it 8 | // under the terms of the GNU General Public License as published by the Free 9 | // Software Foundation; either version 2 of the License, or (at your option) 10 | // any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, but WITHOUT 13 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 | // more details. 16 | // 17 | // You should have received a copy of the GNU General Public License along 18 | // with this program; if not, write to the Free Software Foundation, Inc., 19 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | // 21 | //============================================================================ 22 | 23 | 24 | // NUM_CH 1..8 25 | // Sampling rate = ADC_RATE/NUM_CH 26 | // ADC_RATE max is ~500KHz 27 | // CLK_RATE max is ~80MHz 28 | module ltc2308 #(parameter NUM_CH = 2, ADC_RATE = 96000, CLK_RATE = 50000000) 29 | ( 30 | input reset, 31 | input clk, 32 | 33 | inout [3:0] ADC_BUS, 34 | 35 | output reg dout_sync, // toggle with every ADC round 36 | output reg [(NUM_CH*12)-1:0] dout // 12 bits per channel (unsigned) 37 | ); 38 | 39 | localparam TCONV = CLK_RATE/625000; 40 | 41 | reg sck; 42 | wire sdo = cfg[5]; 43 | 44 | assign ADC_BUS[3] = sck; 45 | wire sdi = ADC_BUS[2]; 46 | assign ADC_BUS[1] = sdo; 47 | assign ADC_BUS[0] = convst; 48 | 49 | reg convst; 50 | reg [5:0] cfg; 51 | 52 | reg [31:0] sum; 53 | wire [31:0] next_sum = sum + ADC_RATE; 54 | 55 | reg [2:0] pin; 56 | wire [2:0] next_pin = (pin == (NUM_CH-1)) ? 3'd0 : (pin + 1'd1); 57 | 58 | always @(posedge clk) begin 59 | reg [7:0] tconv; 60 | reg [3:0] bitcnt; 61 | reg [10:0] adcin; 62 | 63 | convst <= 0; 64 | 65 | if(reset) begin 66 | sum <= 0; 67 | tconv <= 0; 68 | bitcnt <= 0; 69 | sck <= 0; 70 | cfg <= 0; 71 | dout <= 0; 72 | pin <= NUM_CH[2:0]-1'd1; 73 | end 74 | else begin 75 | sum <= next_sum; 76 | if(next_sum >= CLK_RATE) begin 77 | sum <= next_sum - CLK_RATE; 78 | tconv <= TCONV[7:0]; 79 | convst <= 1; 80 | bitcnt <= 12; 81 | cfg <= {1'b1, next_pin[0], next_pin[2:1], 1'b1, 1'b0}; 82 | if(!next_pin) dout_sync <= ~dout_sync; 83 | end 84 | 85 | if(tconv) tconv <= tconv - 1'd1; 86 | else if(bitcnt) begin 87 | sck <= ~sck; 88 | 89 | if(sck) cfg <= cfg<<1; 90 | else begin 91 | adcin <= {adcin[9:0],sdi}; 92 | bitcnt <= bitcnt - 1'd1; 93 | if(bitcnt == 1) begin 94 | dout[pin*12 +:12] <= {adcin,sdi}; 95 | pin <= next_pin; 96 | end 97 | end 98 | end 99 | else sck <= 0; 100 | end 101 | end 102 | 103 | endmodule 104 | 105 | module ltc2308_tape #(parameter HIST_LOW = 16, HIST_HIGH = 64, ADC_RATE = 48000, CLK_RATE = 50000000, NUM_CH = 1) 106 | ( 107 | input reset, 108 | input clk, 109 | 110 | inout [3:0] ADC_BUS, 111 | output reg dout, 112 | output active, 113 | output adc_sync, 114 | output [(NUM_CH*12)-1:0] adc_data 115 | ); 116 | 117 | ltc2308 #(NUM_CH, ADC_RATE, CLK_RATE) adc 118 | ( 119 | .reset(reset), 120 | .clk(clk), 121 | 122 | .ADC_BUS(ADC_BUS), 123 | .dout(adc_data), 124 | .dout_sync(adc_sync) 125 | ); 126 | 127 | always @(posedge clk) begin 128 | reg [13:0] data1,data2,data3,data4, sum; 129 | reg adc_sync_d; 130 | 131 | adc_sync_d<=adc_sync; 132 | if(adc_sync_d ^ adc_sync) begin 133 | data1 <= data2; 134 | data2 <= data3; 135 | data3 <= data4; 136 | data4 <= adc_data[11:0]; 137 | 138 | sum <= data1+data2+data3+data4; 139 | 140 | if(sum[13:2]HIST_HIGH) dout <= 1; 142 | end 143 | end 144 | 145 | assign active = |act; 146 | 147 | reg [1:0] act; 148 | always @(posedge clk) begin 149 | reg [31:0] onesec; 150 | reg old_dout; 151 | 152 | onesec <= onesec + 1; 153 | if(onesec>CLK_RATE) begin 154 | onesec <= 0; 155 | if(act) act <= act - 1'd1; 156 | end 157 | 158 | old_dout <= dout; 159 | if(old_dout ^ dout) act <= 2; 160 | end 161 | 162 | endmodule 163 | -------------------------------------------------------------------------------- /sys/math.sv: -------------------------------------------------------------------------------- 1 | 2 | // result = num/div 3 | module sys_udiv 4 | #( 5 | parameter NB_NUM, 6 | parameter NB_DIV 7 | ) 8 | ( 9 | input clk, 10 | input start, 11 | output busy, 12 | 13 | input [NB_NUM-1:0] num, 14 | input [NB_DIV-1:0] div, 15 | output reg [NB_NUM-1:0] result, 16 | output reg [NB_DIV-1:0] remainder 17 | ); 18 | 19 | reg run; 20 | assign busy = run; 21 | 22 | always @(posedge clk) begin 23 | reg [5:0] cpt; 24 | reg [NB_NUM+NB_DIV+1:0] rem; 25 | 26 | if (start) begin 27 | cpt <= 0; 28 | run <= 1; 29 | rem <= num; 30 | end 31 | else if (run) begin 32 | cpt <= cpt + 1'd1; 33 | run <= (cpt != NB_NUM + 1'd1); 34 | remainder <= rem[NB_NUM+NB_DIV:NB_NUM+1]; 35 | if (!rem[NB_DIV + NB_NUM + 1'd1]) 36 | rem <= {rem[NB_DIV+NB_NUM:0] - (div << NB_NUM),1'b0}; 37 | else 38 | rem <= {rem[NB_DIV+NB_NUM:0] + (div << NB_NUM),1'b0}; 39 | result <= {result[NB_NUM-2:0], !rem[NB_DIV + NB_NUM + 1'd1]}; 40 | end 41 | end 42 | 43 | endmodule 44 | 45 | // result = mul1*mul2 46 | module sys_umul 47 | #( 48 | parameter NB_MUL1, 49 | parameter NB_MUL2 50 | ) 51 | ( 52 | input clk, 53 | input start, 54 | output busy, 55 | 56 | input [NB_MUL1-1:0] mul1, 57 | input [NB_MUL2-1:0] mul2, 58 | output reg [NB_MUL1+NB_MUL2-1:0] result 59 | ); 60 | 61 | reg run; 62 | assign busy = run; 63 | 64 | always @(posedge clk) begin 65 | reg [NB_MUL1+NB_MUL2-1:0] add; 66 | reg [NB_MUL2-1:0] map; 67 | 68 | if (start) begin 69 | run <= 1; 70 | result <= 0; 71 | add <= mul1; 72 | map <= mul2; 73 | end 74 | else if (run) begin 75 | if(!map) run <= 0; 76 | if(map[0]) result <= result + add; 77 | add <= add << 1; 78 | map <= map >> 1; 79 | end 80 | end 81 | 82 | endmodule 83 | 84 | // result = (mul1*mul2)/div 85 | module sys_umuldiv 86 | #( 87 | parameter NB_MUL1, 88 | parameter NB_MUL2, 89 | parameter NB_DIV 90 | ) 91 | ( 92 | input clk, 93 | input start, 94 | output busy, 95 | 96 | input [NB_MUL1-1:0] mul1, 97 | input [NB_MUL2-1:0] mul2, 98 | input [NB_DIV-1:0] div, 99 | output [NB_MUL1+NB_MUL2-1:0] result, 100 | output [NB_DIV-1:0] remainder 101 | ); 102 | 103 | wire mul_run; 104 | wire [NB_MUL1+NB_MUL2-1:0] mul_res; 105 | sys_umul #(NB_MUL1,NB_MUL2) umul(clk,start,mul_run,mul1,mul2,mul_res); 106 | 107 | sys_udiv #(NB_MUL1+NB_MUL2,NB_DIV) udiv(clk,start|mul_run,busy,mul_res,div,result,remainder); 108 | 109 | endmodule 110 | -------------------------------------------------------------------------------- /sys/mcp23009.sv: -------------------------------------------------------------------------------- 1 | // 2 | // MCP23009 3 | // (C) 2019 Alexey Melnikov 4 | // 5 | module mcp23009 6 | ( 7 | input clk, 8 | 9 | output reg [2:0] btn, 10 | input [2:0] led, 11 | output reg flg_sd_cd, 12 | output reg flg_present, 13 | output reg flg_mode, 14 | 15 | output scl, 16 | inout sda 17 | ); 18 | 19 | 20 | reg start = 0; 21 | wire ready; 22 | wire error; 23 | reg rw; 24 | wire [7:0] dout; 25 | reg [15:0] din; 26 | 27 | i2c #(50_000_000, 500_000) i2c 28 | ( 29 | .CLK(clk), 30 | .START(start), 31 | .READ(rw), 32 | .I2C_ADDR('h20), 33 | .I2C_WLEN(1), 34 | .I2C_WDATA1(din[15:8]), 35 | .I2C_WDATA2(din[7:0]), 36 | .I2C_RDATA(dout), 37 | .END(ready), 38 | .ACK(error), 39 | .I2C_SCL(scl), 40 | .I2C_SDA(sda) 41 | ); 42 | 43 | always@(posedge clk) begin 44 | reg [3:0] idx = 0; 45 | reg [1:0] state = 0; 46 | reg [15:0] timeout = 0; 47 | 48 | if(~&timeout) begin 49 | timeout <= timeout + 1'd1; 50 | start <= 0; 51 | state <= 0; 52 | idx <= 0; 53 | btn <= 0; 54 | rw <= 0; 55 | flg_sd_cd <= 1; 56 | flg_present <= 0; 57 | flg_mode <= 1; 58 | end 59 | else begin 60 | if(~&init_data[idx]) begin 61 | case(state) 62 | 0: begin 63 | start <= 1; 64 | state <= 1; 65 | din <= init_data[idx]; 66 | end 67 | 1: if(~ready) state <= 2; 68 | 2: begin 69 | start <= 0; 70 | if(ready) begin 71 | state <= 0; 72 | if(!error) idx <= idx + 1'd1; 73 | end 74 | end 75 | endcase 76 | end 77 | else begin 78 | case(state) 79 | 0: begin 80 | start <= 1; 81 | state <= 1; 82 | din <= {8'h09,5'b00000,led}; 83 | end 84 | 1: if(~ready) state <= 2; 85 | 2: begin 86 | start <= 0; 87 | if(ready) begin 88 | state <= 0; 89 | rw <= 0; 90 | if(!error) begin 91 | if(rw) begin 92 | {flg_sd_cd, flg_mode, btn} <= {dout[7:3]}; 93 | flg_present <= 1; 94 | end 95 | rw <= ~rw; 96 | end 97 | end 98 | end 99 | endcase 100 | end 101 | end 102 | end 103 | 104 | wire [15:0] init_data[12] = 105 | '{ 106 | 16'h00F8, 107 | 16'h0138, 108 | 16'h0200, 109 | 16'h0300, 110 | 16'h0400, 111 | 16'h0524, 112 | 16'h06FF, 113 | 16'h0700, 114 | 16'h0800, 115 | 16'h0900, 116 | 16'h0A00, 117 | 16'hFFFF 118 | }; 119 | 120 | endmodule 121 | -------------------------------------------------------------------------------- /sys/pll.13.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_NAME "altera_pll" 2 | set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_ENV "mwpim" 4 | set_global_assignment -library "pll" -name MISC_FILE [file join $::quartus(qip_path) "pll.cmp"] 5 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON 6 | 7 | set_global_assignment -library "pll" -name VERILOG_FILE rtl/pll.v 8 | set_global_assignment -library "pll" -name VERILOG_FILE rtl/pll/pll_0002.v 9 | 10 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*" 11 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*" 12 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*" 13 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*" 14 | 15 | set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_NAME "altera_pll" 16 | set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_VERSION "13.1" 17 | set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_ENV "mwpim" 18 | -------------------------------------------------------------------------------- /sys/pll_audio.13.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -entity "pll_audio" -library "pll_audio" -name IP_TOOL_NAME "altera_pll" 2 | set_global_assignment -entity "pll_audio" -library "pll_audio" -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -entity "pll_audio" -library "pll_audio" -name IP_TOOL_ENV "mwpim" 4 | set_global_assignment -library "pll_audio" -name MISC_FILE [file join $::quartus(qip_path) "pll_audio.cmp"] 5 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON 6 | 7 | set_global_assignment -library "pll_audio" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_audio.v"] 8 | set_global_assignment -library "pll_audio" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_audio/pll_audio_0002.v"] 9 | 10 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 11 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 12 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 13 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 14 | 15 | set_global_assignment -entity "pll_audio_0002" -library "pll_audio" -name IP_TOOL_NAME "altera_pll" 16 | set_global_assignment -entity "pll_audio_0002" -library "pll_audio" -name IP_TOOL_VERSION "13.1" 17 | set_global_assignment -entity "pll_audio_0002" -library "pll_audio" -name IP_TOOL_ENV "mwpim" 18 | -------------------------------------------------------------------------------- /sys/pll_audio/pll_audio_0002.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 2 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 3 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_audio_0002*|altera_pll:altera_pll_i*|*" 5 | -------------------------------------------------------------------------------- /sys/pll_audio/pll_audio_0002.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/10ps 2 | module pll_audio_0002( 3 | 4 | // interface 'refclk' 5 | input wire refclk, 6 | 7 | // interface 'reset' 8 | input wire rst, 9 | 10 | // interface 'outclk0' 11 | output wire outclk_0, 12 | 13 | // interface 'locked' 14 | output wire locked 15 | ); 16 | 17 | altera_pll #( 18 | .fractional_vco_multiplier("true"), 19 | .reference_clock_frequency("50.0 MHz"), 20 | .operation_mode("direct"), 21 | .number_of_clocks(1), 22 | .output_clock_frequency0("24.576000 MHz"), 23 | .phase_shift0("0 ps"), 24 | .duty_cycle0(50), 25 | .output_clock_frequency1("0 MHz"), 26 | .phase_shift1("0 ps"), 27 | .duty_cycle1(50), 28 | .output_clock_frequency2("0 MHz"), 29 | .phase_shift2("0 ps"), 30 | .duty_cycle2(50), 31 | .output_clock_frequency3("0 MHz"), 32 | .phase_shift3("0 ps"), 33 | .duty_cycle3(50), 34 | .output_clock_frequency4("0 MHz"), 35 | .phase_shift4("0 ps"), 36 | .duty_cycle4(50), 37 | .output_clock_frequency5("0 MHz"), 38 | .phase_shift5("0 ps"), 39 | .duty_cycle5(50), 40 | .output_clock_frequency6("0 MHz"), 41 | .phase_shift6("0 ps"), 42 | .duty_cycle6(50), 43 | .output_clock_frequency7("0 MHz"), 44 | .phase_shift7("0 ps"), 45 | .duty_cycle7(50), 46 | .output_clock_frequency8("0 MHz"), 47 | .phase_shift8("0 ps"), 48 | .duty_cycle8(50), 49 | .output_clock_frequency9("0 MHz"), 50 | .phase_shift9("0 ps"), 51 | .duty_cycle9(50), 52 | .output_clock_frequency10("0 MHz"), 53 | .phase_shift10("0 ps"), 54 | .duty_cycle10(50), 55 | .output_clock_frequency11("0 MHz"), 56 | .phase_shift11("0 ps"), 57 | .duty_cycle11(50), 58 | .output_clock_frequency12("0 MHz"), 59 | .phase_shift12("0 ps"), 60 | .duty_cycle12(50), 61 | .output_clock_frequency13("0 MHz"), 62 | .phase_shift13("0 ps"), 63 | .duty_cycle13(50), 64 | .output_clock_frequency14("0 MHz"), 65 | .phase_shift14("0 ps"), 66 | .duty_cycle14(50), 67 | .output_clock_frequency15("0 MHz"), 68 | .phase_shift15("0 ps"), 69 | .duty_cycle15(50), 70 | .output_clock_frequency16("0 MHz"), 71 | .phase_shift16("0 ps"), 72 | .duty_cycle16(50), 73 | .output_clock_frequency17("0 MHz"), 74 | .phase_shift17("0 ps"), 75 | .duty_cycle17(50), 76 | .pll_type("General"), 77 | .pll_subtype("General") 78 | ) altera_pll_i ( 79 | .rst (rst), 80 | .outclk ({outclk_0}), 81 | .locked (locked), 82 | .fboutclk ( ), 83 | .fbclk (1'b0), 84 | .refclk (refclk) 85 | ); 86 | endmodule 87 | 88 | -------------------------------------------------------------------------------- /sys/pll_cfg.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON 2 | set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/pll_cfg.v"] 3 | set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/pll_cfg_hdmi.v"] 4 | set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/altera_pll_reconfig_top.v"] 5 | set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/altera_pll_reconfig_core.v"] 6 | -------------------------------------------------------------------------------- /sys/pll_cfg/pll_cfg.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %Altera PLL Reconfig v17.0% 2 | // GENERATION: XML 3 | // pll_cfg.v 4 | 5 | // Generated using ACDS version 17.0 598 6 | 7 | `timescale 1 ps / 1 ps 8 | module pll_cfg #( 9 | parameter ENABLE_BYTEENABLE = 0, 10 | parameter BYTEENABLE_WIDTH = 4, 11 | parameter RECONFIG_ADDR_WIDTH = 6, 12 | parameter RECONFIG_DATA_WIDTH = 32, 13 | parameter reconf_width = 64, 14 | parameter WAIT_FOR_LOCK = 1 15 | ) ( 16 | input wire mgmt_clk, // mgmt_clk.clk 17 | input wire mgmt_reset, // mgmt_reset.reset 18 | output wire mgmt_waitrequest, // mgmt_avalon_slave.waitrequest 19 | input wire mgmt_read, // .read 20 | input wire mgmt_write, // .write 21 | output wire [31:0] mgmt_readdata, // .readdata 22 | input wire [5:0] mgmt_address, // .address 23 | input wire [31:0] mgmt_writedata, // .writedata 24 | output wire [63:0] reconfig_to_pll, // reconfig_to_pll.reconfig_to_pll 25 | input wire [63:0] reconfig_from_pll // reconfig_from_pll.reconfig_from_pll 26 | ); 27 | 28 | altera_pll_reconfig_top #( 29 | .device_family ("Cyclone V"), 30 | .ENABLE_MIF (0), 31 | .MIF_FILE_NAME ("sys/pll_cfg.mif"), 32 | .ENABLE_BYTEENABLE (ENABLE_BYTEENABLE), 33 | .BYTEENABLE_WIDTH (BYTEENABLE_WIDTH), 34 | .RECONFIG_ADDR_WIDTH (RECONFIG_ADDR_WIDTH), 35 | .RECONFIG_DATA_WIDTH (RECONFIG_DATA_WIDTH), 36 | .reconf_width (reconf_width), 37 | .WAIT_FOR_LOCK (WAIT_FOR_LOCK) 38 | ) pll_cfg_inst ( 39 | .mgmt_clk (mgmt_clk), // mgmt_clk.clk 40 | .mgmt_reset (mgmt_reset), // mgmt_reset.reset 41 | .mgmt_waitrequest (mgmt_waitrequest), // mgmt_avalon_slave.waitrequest 42 | .mgmt_read (mgmt_read), // .read 43 | .mgmt_write (mgmt_write), // .write 44 | .mgmt_readdata (mgmt_readdata), // .readdata 45 | .mgmt_address (mgmt_address), // .address 46 | .mgmt_writedata (mgmt_writedata), // .writedata 47 | .reconfig_to_pll (reconfig_to_pll), // reconfig_to_pll.reconfig_to_pll 48 | .reconfig_from_pll (reconfig_from_pll), // reconfig_from_pll.reconfig_from_pll 49 | .mgmt_byteenable (4'b0000) // (terminated) 50 | ); 51 | 52 | endmodule 53 | // Retrieval info: 54 | // 79 | // Retrieval info: 80 | // Retrieval info: 81 | // Retrieval info: 82 | // Retrieval info: 83 | // Retrieval info: 84 | // Retrieval info: 85 | // IPFS_FILES : pll_cfg.vo 86 | // RELATED_FILES: pll_cfg.v, altera_pll_reconfig_top.v, altera_pll_reconfig_core.v, altera_std_synchronizer.v 87 | -------------------------------------------------------------------------------- /sys/pll_hdmi.13.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll" 2 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim" 4 | set_global_assignment -library "pll_hdmi" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi.cmp"] 5 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON 6 | 7 | set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi.v"] 8 | set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002.v"] 9 | 10 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 11 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 12 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 13 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 14 | 15 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll" 16 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1" 17 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim" 18 | -------------------------------------------------------------------------------- /sys/pll_hdmi/pll_hdmi_0002.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 2 | set_instance_assignment -name UNFORCE_MERGE_PLL_OUTPUT_COUNTER ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" 3 | -------------------------------------------------------------------------------- /sys/pll_q13.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.13.qip ] 2 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.13.qip ] 3 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_audio.13.qip ] 4 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_cfg.qip ] 5 | -------------------------------------------------------------------------------- /sys/pll_q17.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name QIP_FILE rtl/pll.qip 2 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ] 3 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_audio.qip ] 4 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_cfg.qip ] 5 | -------------------------------------------------------------------------------- /sys/scanlines.v: -------------------------------------------------------------------------------- 1 | module scanlines #(parameter v2=0) 2 | ( 3 | input clk, 4 | 5 | input [1:0] scanlines, 6 | input [23:0] din, 7 | input hs_in,vs_in, 8 | input de_in,ce_in, 9 | 10 | output reg [23:0] dout, 11 | output reg hs_out,vs_out, 12 | output reg de_out,ce_out 13 | ); 14 | 15 | reg [1:0] scanline; 16 | always @(posedge clk) begin 17 | reg old_hs, old_vs; 18 | 19 | old_hs <= hs_in; 20 | old_vs <= vs_in; 21 | 22 | if(old_hs && ~hs_in) begin 23 | if(v2) begin 24 | scanline <= scanline + 1'd1; 25 | if (scanline == scanlines) scanline <= 0; 26 | end 27 | else scanline <= scanline ^ scanlines; 28 | end 29 | if(old_vs && ~vs_in) scanline <= 0; 30 | end 31 | 32 | wire [7:0] r,g,b; 33 | assign {r,g,b} = din; 34 | 35 | reg [23:0] d; 36 | always @(*) begin 37 | case(scanline) 38 | 1: // reduce 25% = 1/2 + 1/4 39 | d = {{1'b0, r[7:1]} + {2'b00, r[7:2]}, 40 | {1'b0, g[7:1]} + {2'b00, g[7:2]}, 41 | {1'b0, b[7:1]} + {2'b00, b[7:2]}}; 42 | 43 | 2: // reduce 50% = 1/2 44 | d = {{1'b0, r[7:1]}, 45 | {1'b0, g[7:1]}, 46 | {1'b0, b[7:1]}}; 47 | 48 | 3: // reduce 75% = 1/4 49 | d = {{2'b00, r[7:2]}, 50 | {2'b00, g[7:2]}, 51 | {2'b00, b[7:2]}}; 52 | 53 | default: d = {r,g,b}; 54 | endcase 55 | end 56 | 57 | always @(posedge clk) begin 58 | reg [23:0] dout1, dout2; 59 | reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2; 60 | 61 | dout <= dout2; dout2 <= dout1; dout1 <= d; 62 | vs_out <= vs2; vs2 <= vs1; vs1 <= vs_in; 63 | hs_out <= hs2; hs2 <= hs1; hs1 <= hs_in; 64 | de_out <= de2; de2 <= de1; de1 <= de_in; 65 | ce_out <= ce2; ce2 <= ce1; ce1 <= ce_in; 66 | end 67 | 68 | endmodule 69 | -------------------------------------------------------------------------------- /sys/shadowmask.sv: -------------------------------------------------------------------------------- 1 | module shadowmask 2 | ( 3 | input clk, 4 | input clk_sys, 5 | 6 | input cmd_wr, 7 | input [15:0] cmd_in, 8 | 9 | input [23:0] din, 10 | input hs_in,vs_in, 11 | input de_in, 12 | input brd_in, 13 | input enable, 14 | 15 | output reg [23:0] dout, 16 | output reg hs_out,vs_out, 17 | output reg de_out 18 | ); 19 | 20 | 21 | reg [4:0] hmax; 22 | reg [4:0] vmax; 23 | reg [7:0] mask_idx; 24 | reg mask_2x; 25 | reg mask_rotate; 26 | reg mask_enable; 27 | reg [10:0] mask_lut[256]; 28 | 29 | always @(posedge clk) begin 30 | reg [4:0] hcount; 31 | reg [4:0] vcount; 32 | reg [3:0] hindex; 33 | reg [3:0] vindex; 34 | reg [4:0] hmax2; 35 | reg [4:0] vmax2; 36 | reg [11:0] pcnt,pde; 37 | reg old_hs, old_vs, old_brd; 38 | reg next_v; 39 | 40 | old_hs <= hs_in; 41 | old_vs <= vs_in; 42 | old_brd<= brd_in; 43 | 44 | // hcount and vcount counts pixel rows and columns 45 | // hindex and vindex half the value of the counters for double size patterns 46 | // hindex2, vindex2 swap the h and v counters for drawing rotated masks 47 | hindex <= mask_2x ? hcount[4:1] : hcount[3:0]; 48 | vindex <= mask_2x ? vcount[4:1] : vcount[3:0]; 49 | mask_idx <= mask_rotate ? {hindex,vindex} : {vindex,hindex}; 50 | 51 | // hmax and vmax store these sizes 52 | // hmax2 and vmax2 swap the values to handle rotation 53 | hmax2 <= ((mask_rotate ? vmax : hmax) << mask_2x) | mask_2x; 54 | vmax2 <= ((mask_rotate ? hmax : vmax) << mask_2x) | mask_2x; 55 | 56 | pcnt <= pcnt+1'd1; 57 | if(old_brd && ~brd_in) pde <= pcnt-4'd3; 58 | 59 | hcount <= hcount+1'b1; 60 | if(hcount == hmax2 || pde == pcnt) hcount <= 0; 61 | 62 | if(~old_brd && brd_in) next_v <= 1; 63 | if(old_vs && ~vs_in) vcount <= 0; 64 | if(old_hs && ~hs_in) begin 65 | vcount <= vcount + next_v; 66 | next_v <= 0; 67 | pcnt <= 0; 68 | if (vcount == vmax2) vcount <= 0; 69 | end 70 | end 71 | 72 | reg [4:0] r_mul, g_mul, b_mul; // 1.4 fixed point multipliers 73 | always @(posedge clk) begin 74 | reg [10:0] lut; 75 | 76 | lut <= mask_lut[mask_idx]; 77 | 78 | r_mul <= 5'b10000; g_mul <= 5'b10000; b_mul <= 5'b10000; // default 100% to all channels 79 | if (mask_enable) begin 80 | r_mul <= lut[10] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; 81 | g_mul <= lut[9] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; 82 | b_mul <= lut[8] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; 83 | end 84 | end 85 | 86 | always @(posedge clk) begin 87 | reg [11:0] vid; 88 | reg [7:0] r1, g1, b1; 89 | reg [7:0] r2, g2, b2; 90 | reg [7:0] r3_x, g3_x, b3_x; // 6.25% + 12.5% 91 | reg [8:0] r3_y, g3_y, b3_y; // 25% + 50% + 100% 92 | reg [8:0] r4, g4, b4; 93 | 94 | // C1 - data input 95 | {r1,g1,b1} <= din; 96 | vid <= {vid[8:0],vs_in, hs_in, de_in}; 97 | 98 | // C2 - relax timings 99 | {r2,g2,b2} <= {r1,g1,b1}; 100 | 101 | // C3 - perform multiplications 102 | r3_x <= ({4{r_mul[0]}} & r2[7:4]) + ({8{r_mul[1]}} & r2[7:3]); 103 | r3_y <= ({6{r_mul[2]}} & r2[7:2]) + ({7{r_mul[3]}} & r2[7:1]) + ({9{r_mul[4]}} & r2[7:0]); 104 | g3_x <= ({4{g_mul[0]}} & g2[7:4]) + ({8{g_mul[1]}} & g2[7:3]); 105 | g3_y <= ({6{g_mul[2]}} & g2[7:2]) + ({7{g_mul[3]}} & g2[7:1]) + ({9{g_mul[4]}} & g2[7:0]); 106 | b3_x <= ({4{b_mul[0]}} & b2[7:4]) + ({8{b_mul[1]}} & b2[7:3]); 107 | b3_y <= ({6{b_mul[2]}} & b2[7:2]) + ({7{b_mul[3]}} & b2[7:1]) + ({9{b_mul[4]}} & b2[7:0]); 108 | 109 | // C4 - combine results 110 | r4 <= r3_x + r3_y; 111 | g4 <= g3_x + g3_y; 112 | b4 <= b3_x + b3_y; 113 | 114 | // C5 - clamp and output 115 | dout <= {{8{r4[8]}} | r4[7:0], {8{g4[8]}} | g4[7:0], {8{b4[8]}} | b4[7:0]}; 116 | {vs_out,hs_out,de_out} <= vid[11:9]; 117 | end 118 | 119 | // clock in mask commands 120 | always @(posedge clk_sys) begin 121 | reg m_enable; 122 | reg [7:0] idx; 123 | 124 | if (cmd_wr) begin 125 | case(cmd_in[15:13]) 126 | 3'b000: begin {m_enable, mask_rotate, mask_2x} <= cmd_in[3:1]; idx <= 0; end 127 | 3'b001: vmax <= cmd_in[3:0]; 128 | 3'b010: hmax <= cmd_in[3:0]; 129 | 3'b011: begin mask_lut[idx] <= cmd_in[10:0]; idx <= idx + 1'd1; end 130 | endcase 131 | end 132 | 133 | mask_enable <= m_enable & enable; 134 | end 135 | 136 | endmodule 137 | -------------------------------------------------------------------------------- /sys/sigma_delta_dac.v: -------------------------------------------------------------------------------- 1 | // 2 | // PWM DAC 3 | // 4 | // MSBI is the highest bit number. NOT amount of bits! 5 | // 6 | module sigma_delta_dac #(parameter MSBI=7, parameter INV=1'b1) 7 | ( 8 | output reg DACout, //Average Output feeding analog lowpass 9 | input [MSBI:0] DACin, //DAC input (excess 2**MSBI) 10 | input CLK, 11 | input RESET 12 | ); 13 | 14 | reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder 15 | reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder 16 | reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder 17 | reg [MSBI+2:0] DeltaB; //B input of Delta Adder 18 | 19 | always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1); 20 | always @(*) DeltaAdder = DACin + DeltaB; 21 | always @(*) SigmaAdder = DeltaAdder + SigmaLatch; 22 | 23 | always @(posedge CLK or posedge RESET) begin 24 | if(RESET) begin 25 | SigmaLatch <= 1'b1 << (MSBI+1); 26 | DACout <= INV; 27 | end else begin 28 | SigmaLatch <= SigmaAdder; 29 | DACout <= SigmaLatch[MSBI+2] ^ INV; 30 | end 31 | end 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /sys/sys.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name QIP_FILE [join [list $::quartus(qip_path) pll_q [regexp -inline {[0-9]+} $quartus(version)] .qip] {}] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ] 3 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] 5 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) math.sv ] 7 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] 10 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) shadowmask.sv ] 11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ] 12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) gamma_corr.sv ] 13 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ] 14 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_freak.sv ] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_freezer.sv ] 16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ] 17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ] 18 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ] 19 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) yc_out.sv ] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ] 21 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ] 22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ] 23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ] 24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) audio_out.v ] 25 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) iir_filter.v ] 26 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ] 27 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ] 28 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mt32pi.sv ] 29 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mcp23009.sv ] 30 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) f2sdram_safe_terminator.sv ] 31 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ddr_svc.sv ] 32 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ] 33 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sd_card.sv ] 34 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hps_io.sv ] 35 | -------------------------------------------------------------------------------- /sys/sys_analog.tcl: -------------------------------------------------------------------------------- 1 | #============================================================ 2 | # SDIO 3 | #============================================================ 4 | set_location_assignment PIN_AF25 -to SDIO_DAT[0] 5 | set_location_assignment PIN_AF23 -to SDIO_DAT[1] 6 | set_location_assignment PIN_AD26 -to SDIO_DAT[2] 7 | set_location_assignment PIN_AF28 -to SDIO_DAT[3] 8 | set_location_assignment PIN_AF27 -to SDIO_CMD 9 | set_location_assignment PIN_AH26 -to SDIO_CLK 10 | set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDIO_* 11 | 12 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDIO_* 13 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_DAT[*] 14 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_CMD 15 | 16 | #============================================================ 17 | # VGA 18 | #============================================================ 19 | set_location_assignment PIN_AE17 -to VGA_R[0] 20 | set_location_assignment PIN_AE20 -to VGA_R[1] 21 | set_location_assignment PIN_AF20 -to VGA_R[2] 22 | set_location_assignment PIN_AH18 -to VGA_R[3] 23 | set_location_assignment PIN_AH19 -to VGA_R[4] 24 | set_location_assignment PIN_AF21 -to VGA_R[5] 25 | 26 | set_location_assignment PIN_AE19 -to VGA_G[0] 27 | set_location_assignment PIN_AG15 -to VGA_G[1] 28 | set_location_assignment PIN_AF18 -to VGA_G[2] 29 | set_location_assignment PIN_AG18 -to VGA_G[3] 30 | set_location_assignment PIN_AG19 -to VGA_G[4] 31 | set_location_assignment PIN_AG20 -to VGA_G[5] 32 | 33 | set_location_assignment PIN_AG21 -to VGA_B[0] 34 | set_location_assignment PIN_AA20 -to VGA_B[1] 35 | set_location_assignment PIN_AE22 -to VGA_B[2] 36 | set_location_assignment PIN_AF22 -to VGA_B[3] 37 | set_location_assignment PIN_AH23 -to VGA_B[4] 38 | set_location_assignment PIN_AH21 -to VGA_B[5] 39 | 40 | set_location_assignment PIN_AH22 -to VGA_HS 41 | set_location_assignment PIN_AG24 -to VGA_VS 42 | 43 | set_location_assignment PIN_AH27 -to VGA_EN 44 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to VGA_EN 45 | 46 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_* 47 | set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_* 48 | 49 | #============================================================ 50 | # AUDIO 51 | #============================================================ 52 | set_location_assignment PIN_AC24 -to AUDIO_L 53 | set_location_assignment PIN_AE25 -to AUDIO_R 54 | set_location_assignment PIN_AG26 -to AUDIO_SPDIF 55 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to AUDIO_* 56 | set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to AUDIO_* 57 | 58 | #============================================================ 59 | # I/O #1 60 | #============================================================ 61 | set_location_assignment PIN_Y15 -to LED_USER 62 | set_location_assignment PIN_AA15 -to LED_HDD 63 | set_location_assignment PIN_AG28 -to LED_POWER 64 | 65 | set_location_assignment PIN_AH24 -to BTN_USER 66 | set_location_assignment PIN_AG25 -to BTN_OSD 67 | set_location_assignment PIN_AG23 -to BTN_RESET 68 | 69 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED_* 70 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to BTN_* 71 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to BTN_* 72 | -------------------------------------------------------------------------------- /sys/sys_dual_sdram.tcl: -------------------------------------------------------------------------------- 1 | #============================================================ 2 | # Secondary SDRAM 3 | #============================================================ 4 | set_location_assignment PIN_Y15 -to SDRAM2_DQ[0] 5 | set_location_assignment PIN_AC24 -to SDRAM2_DQ[1] 6 | set_location_assignment PIN_AA15 -to SDRAM2_DQ[2] 7 | set_location_assignment PIN_AD26 -to SDRAM2_DQ[3] 8 | set_location_assignment PIN_AG28 -to SDRAM2_DQ[4] 9 | set_location_assignment PIN_AF28 -to SDRAM2_DQ[5] 10 | set_location_assignment PIN_AE25 -to SDRAM2_DQ[6] 11 | set_location_assignment PIN_AF27 -to SDRAM2_DQ[7] 12 | set_location_assignment PIN_AG26 -to SDRAM2_DQ[14] 13 | set_location_assignment PIN_AH27 -to SDRAM2_DQ[15] 14 | 15 | set_location_assignment PIN_AG25 -to SDRAM2_DQ[13] 16 | set_location_assignment PIN_AH26 -to SDRAM2_DQ[12] 17 | set_location_assignment PIN_AH24 -to SDRAM2_DQ[11] 18 | set_location_assignment PIN_AF25 -to SDRAM2_DQ[10] 19 | set_location_assignment PIN_AG23 -to SDRAM2_DQ[9] 20 | set_location_assignment PIN_AF23 -to SDRAM2_DQ[8] 21 | set_location_assignment PIN_AG24 -to SDRAM2_A[12] 22 | set_location_assignment PIN_AH22 -to SDRAM2_CLK 23 | set_location_assignment PIN_AH21 -to SDRAM2_A[9] 24 | set_location_assignment PIN_AG21 -to SDRAM2_A[11] 25 | set_location_assignment PIN_AH23 -to SDRAM2_A[7] 26 | set_location_assignment PIN_AA20 -to SDRAM2_A[8] 27 | set_location_assignment PIN_AF22 -to SDRAM2_A[5] 28 | set_location_assignment PIN_AE22 -to SDRAM2_A[6] 29 | set_location_assignment PIN_AG20 -to SDRAM2_nWE 30 | set_location_assignment PIN_AF21 -to SDRAM2_A[4] 31 | 32 | set_location_assignment PIN_AG19 -to SDRAM2_nCAS 33 | set_location_assignment PIN_AH19 -to SDRAM2_nRAS 34 | set_location_assignment PIN_AG18 -to SDRAM2_nCS 35 | set_location_assignment PIN_AH18 -to SDRAM2_BA[0] 36 | set_location_assignment PIN_AF18 -to SDRAM2_BA[1] 37 | set_location_assignment PIN_AF20 -to SDRAM2_A[10] 38 | set_location_assignment PIN_AG15 -to SDRAM2_A[0] 39 | set_location_assignment PIN_AE20 -to SDRAM2_A[1] 40 | set_location_assignment PIN_AE19 -to SDRAM2_A[2] 41 | set_location_assignment PIN_AE17 -to SDRAM2_A[3] 42 | 43 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM2_* 44 | set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM2_* 45 | set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_* 46 | set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM2_DQ[*] 47 | set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM2_DQ[*] 48 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDRAM2_DQ[*] 49 | set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM2_* 50 | 51 | set_global_assignment -name VERILOG_MACRO "MISTER_DUAL_SDRAM=1" 52 | -------------------------------------------------------------------------------- /sys/sys_top.sdc: -------------------------------------------------------------------------------- 1 | # Specify root clocks 2 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK1_50] 3 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK2_50] 4 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK3_50] 5 | create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk] 6 | create_clock -period "100.0 MHz" [get_pins -compatibility_mode spi|sclk_out] -name spi_sck 7 | create_clock -period "10.0 MHz" [get_pins -compatibility_mode hdmi_i2c|out_clk] -name hdmi_sck 8 | 9 | derive_pll_clocks 10 | derive_clock_uncertainty 11 | 12 | # Decouple different clock groups (to simplify routing) 13 | set_clock_groups -exclusive \ 14 | -group [get_clocks { *|pll|pll_inst|altera_pll_i|*[*].*|divclk}] \ 15 | -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \ 16 | -group [get_clocks { pll_audio|pll_audio_inst|altera_pll_i|*[0].*|divclk}] \ 17 | -group [get_clocks { spi_sck}] \ 18 | -group [get_clocks { hdmi_sck}] \ 19 | -group [get_clocks { *|h2f_user0_clk}] \ 20 | -group [get_clocks { FPGA_CLK1_50 }] \ 21 | -group [get_clocks { FPGA_CLK2_50 }] \ 22 | -group [get_clocks { FPGA_CLK3_50 }] 23 | 24 | set_false_path -from [get_ports {KEY*}] 25 | set_false_path -from [get_ports {BTN_*}] 26 | set_false_path -to [get_ports {LED_*}] 27 | set_false_path -to [get_ports {VGA_*}] 28 | set_false_path -from [get_ports {VGA_EN}] 29 | set_false_path -to [get_ports {AUDIO_SPDIF}] 30 | set_false_path -to [get_ports {AUDIO_L}] 31 | set_false_path -to [get_ports {AUDIO_R}] 32 | set_false_path -from {get_ports {SW[*]}} 33 | set_false_path -to {cfg[*]} 34 | set_false_path -from {cfg[*]} 35 | set_false_path -from {VSET[*]} 36 | set_false_path -to {wcalc[*] hcalc[*]} 37 | set_false_path -to {hdmi_width[*] hdmi_height[*]} 38 | set_false_path -to {deb_* btn_en btn_up} 39 | 40 | set_multicycle_path -to {*_osd|osd_vcnt*} -setup 2 41 | set_multicycle_path -to {*_osd|osd_vcnt*} -hold 1 42 | 43 | set_false_path -to {*_osd|v_cnt*} 44 | set_false_path -to {*_osd|v_osd_start*} 45 | set_false_path -to {*_osd|v_info_start*} 46 | set_false_path -to {*_osd|h_osd_start*} 47 | set_false_path -from {*_osd|v_osd_start*} 48 | set_false_path -from {*_osd|v_info_start*} 49 | set_false_path -from {*_osd|h_osd_start*} 50 | set_false_path -from {*_osd|rot*} 51 | set_false_path -from {*_osd|dsp_width*} 52 | set_false_path -to {*_osd|half} 53 | 54 | set_false_path -to {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]} 55 | set_false_path -from {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]} 56 | set_false_path -to {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]} 57 | set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]} 58 | set_false_path -to {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]} 59 | set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]} 60 | set_false_path -from {aflt_* acx* acy* areset* arc*} 61 | set_false_path -from {arx* ary*} 62 | set_false_path -from {vs_line*} 63 | set_false_path -from {ColorBurst_Range* PhaseInc* pal_en cvbs yc_en} 64 | 65 | set_false_path -from {ascal|o_ihsize*} 66 | set_false_path -from {ascal|o_ivsize*} 67 | set_false_path -from {ascal|o_format*} 68 | set_false_path -from {ascal|o_hdown} 69 | set_false_path -from {ascal|o_vdown} 70 | set_false_path -from {ascal|o_hmin* ascal|o_hmax* ascal|o_vmin* ascal|o_vmax* ascal|o_vrrmax* ascal|o_vrr} 71 | set_false_path -from {ascal|o_hdisp* ascal|o_vdisp*} 72 | set_false_path -from {ascal|o_htotal* ascal|o_vtotal*} 73 | set_false_path -from {ascal|o_hsstart* ascal|o_vsstart* ascal|o_hsend* ascal|o_vsend*} 74 | set_false_path -from {ascal|o_hsize* ascal|o_vsize*} 75 | 76 | set_false_path -from {mcp23009|flg_*} 77 | set_false_path -to {sysmem|fpga_interfaces|clocks_resets*} 78 | -------------------------------------------------------------------------------- /sys/vga_out.sv: -------------------------------------------------------------------------------- 1 | 2 | module vga_out 3 | ( 4 | input clk, 5 | input ypbpr_en, 6 | 7 | input hsync, 8 | input vsync, 9 | input csync, 10 | input de, 11 | 12 | input [23:0] din, 13 | output [23:0] dout, 14 | 15 | output reg hsync_o, 16 | output reg vsync_o, 17 | output reg csync_o, 18 | output reg de_o 19 | ); 20 | 21 | wire [7:0] red = din[23:16]; 22 | wire [7:0] green = din[15:8]; 23 | wire [7:0] blue = din[7:0]; 24 | 25 | // http://marsee101.blog19.fc2.com/blog-entry-2311.html 26 | 27 | 28 | // Y = 0.301*R + 0.586*G + 0.113*B (Y = 0.299*R + 0.587*G + 0.114*B) 29 | // Pb = 128 - 0.168*R - 0.332*G + 0.500*B (Pb = -0.169*R - 0.331*G + 0.500*B) 30 | // Pr = 128 + 0.500*R - 0.418*G - 0.082*B (Pr = 0.500*R - 0.419*G - 0.081*B) 31 | 32 | reg [7:0] y, pb, pr; 33 | reg [23:0] rgb; 34 | always @(posedge clk) begin 35 | reg [18:0] y_1r, pb_1r, pr_1r; 36 | reg [18:0] y_1g, pb_1g, pr_1g; 37 | reg [18:0] y_1b, pb_1b, pr_1b; 38 | reg [18:0] y_2, pb_2, pr_2; 39 | reg [23:0] din1, din2; 40 | reg hsync2, vsync2, csync2, de2; 41 | reg hsync1, vsync1, csync1, de1; 42 | 43 | y_1r <= {red, 6'd0} + {red, 3'd0} + {red, 2'd0} + red; 44 | pb_1r <= 19'd32768 - ({red, 5'd0} + {red, 3'd0} + {red, 1'd0}); 45 | pr_1r <= 19'd32768 + {red, 7'd0}; 46 | 47 | y_1g <= {green, 7'd0} + {green, 4'd0} + {green, 2'd0} + {green, 1'd0}; 48 | pb_1g <= {green, 6'd0} + {green, 4'd0} + {green, 2'd0} + green; 49 | pr_1g <= {green, 6'd0} + {green, 5'd0} + {green, 3'd0} + {green, 1'd0}; 50 | 51 | y_1b <= {blue, 4'd0} + {blue, 3'd0} + {blue, 2'd0} + blue; 52 | pb_1b <= {blue, 7'd0}; 53 | pr_1b <= {blue, 4'd0} + {blue, 2'd0} + blue; 54 | 55 | y_2 <= y_1r + y_1g + y_1b; 56 | pb_2 <= pb_1r - pb_1g + pb_1b; 57 | pr_2 <= pr_1r - pr_1g - pr_1b; 58 | 59 | y <= y_2[18] ? 8'd0 : y_2[16] ? 8'd255 : y_2[15:8]; 60 | pb <= pb_2[18] ? 8'd0 : pb_2[16] ? 8'd255 : pb_2[15:8]; 61 | pr <= pr_2[18] ? 8'd0 : pr_2[16] ? 8'd255 : pr_2[15:8]; 62 | 63 | hsync_o <= hsync2; hsync2 <= hsync1; hsync1 <= hsync; 64 | vsync_o <= vsync2; vsync2 <= vsync1; vsync1 <= vsync; 65 | csync_o <= csync2; csync2 <= csync1; csync1 <= csync; 66 | de_o <= de2; de2 <= de1; de1 <= de; 67 | 68 | rgb <= din2; din2 <= din1; din1 <= din; 69 | end 70 | 71 | assign dout = ypbpr_en ? {pr, y, pb} : rgb; 72 | 73 | endmodule 74 | -------------------------------------------------------------------------------- /sys/video_cleaner.sv: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2018 Sorgelig 4 | // 5 | // This program is GPL Licensed. See COPYING for the full license. 6 | // 7 | // 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 9 | 10 | `timescale 1ns / 1ps 11 | 12 | module video_cleaner 13 | ( 14 | input clk_vid, 15 | input ce_pix, 16 | 17 | input [7:0] R, 18 | input [7:0] G, 19 | input [7:0] B, 20 | 21 | input HSync, 22 | input VSync, 23 | input HBlank, 24 | input VBlank, 25 | 26 | //optional de 27 | input DE_in, 28 | 29 | //optional interlace support 30 | input interlace, 31 | input f1, 32 | 33 | // video output signals 34 | output reg [7:0] VGA_R, 35 | output reg [7:0] VGA_G, 36 | output reg [7:0] VGA_B, 37 | output reg VGA_VS, 38 | output reg VGA_HS, 39 | output VGA_DE, 40 | 41 | // optional aligned blank 42 | output reg HBlank_out, 43 | output reg VBlank_out, 44 | 45 | // optional aligned de 46 | output reg DE_out 47 | ); 48 | 49 | wire hs, vs; 50 | s_fix sync_v(clk_vid, HSync, hs); 51 | s_fix sync_h(clk_vid, VSync, vs); 52 | 53 | wire hbl = hs | HBlank; 54 | wire vbl = vs | VBlank; 55 | 56 | assign VGA_DE = ~(HBlank_out | VBlank_out); 57 | 58 | always @(posedge clk_vid) begin 59 | if(ce_pix) begin 60 | HBlank_out <= hbl; 61 | 62 | VGA_HS <= hs; 63 | 64 | VGA_R <= R; 65 | VGA_G <= G; 66 | VGA_B <= B; 67 | DE_out <= DE_in; 68 | 69 | if (interlace & f1) begin 70 | VGA_VS <= vs; 71 | VBlank_out <= vbl; 72 | end else begin 73 | if(~VGA_HS & hs) VGA_VS <= vs; 74 | if(HBlank_out & ~hbl) VBlank_out <= vbl; 75 | end 76 | end 77 | end 78 | 79 | endmodule 80 | 81 | module s_fix 82 | ( 83 | input clk, 84 | 85 | input sync_in, 86 | output sync_out 87 | ); 88 | 89 | assign sync_out = sync_in ^ pol; 90 | 91 | reg pol; 92 | always @(posedge clk) begin 93 | integer pos = 0, neg = 0, cnt = 0; 94 | reg s1,s2; 95 | 96 | s1 <= sync_in; 97 | s2 <= s1; 98 | 99 | if(~s2 & s1) neg <= cnt; 100 | if(s2 & ~s1) pos <= cnt; 101 | 102 | cnt <= cnt + 1; 103 | if(s2 != s1) cnt <= 0; 104 | 105 | pol <= pos > neg; 106 | end 107 | 108 | endmodule 109 | -------------------------------------------------------------------------------- /sys/video_freezer.sv: -------------------------------------------------------------------------------- 1 | // 2 | // video freeze with sync 3 | // (C) Alexey Melnikov 4 | // 5 | // 6 | // This program is free software; you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License as published by the Free 8 | // Software Foundation; either version 2 of the License, or (at your option) 9 | // any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, but WITHOUT 12 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | // more details. 15 | // 16 | // You should have received a copy of the GNU General Public License along 17 | // with this program; if not, write to the Free Software Foundation, Inc., 18 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | 21 | module video_freezer 22 | ( 23 | input clk, 24 | 25 | output sync, 26 | input freeze, 27 | 28 | input hs_in, 29 | input vs_in, 30 | input hbl_in, 31 | input vbl_in, 32 | 33 | output hs_out, 34 | output vs_out, 35 | output hbl_out, 36 | output vbl_out 37 | ); 38 | 39 | sync_lock #(33) vs_lock 40 | ( 41 | .clk(clk), 42 | .sync_in(vs_in), 43 | .sync_out(vs_out), 44 | .de_in(vbl_in), 45 | .de_out(vbl_out), 46 | .freeze(freeze) 47 | ); 48 | 49 | wire sync_pt; 50 | sync_lock #(21) hs_lock 51 | ( 52 | .clk(clk), 53 | .sync_in(hs_in), 54 | .sync_out(hs_out), 55 | .de_in(hbl_in), 56 | .de_out(hbl_out), 57 | .freeze(freeze), 58 | .sync_pt(sync_pt) 59 | ); 60 | 61 | reg sync_o; 62 | always @(posedge clk) begin 63 | reg old_hs, old_vs; 64 | reg vs_sync; 65 | 66 | old_vs <= vs_out; 67 | 68 | if(~old_vs & vs_out) vs_sync <= 1; 69 | if(sync_pt & vs_sync) begin 70 | vs_sync <= 0; 71 | sync_o <= ~sync_o; 72 | end 73 | end 74 | 75 | assign sync = sync_o; 76 | 77 | endmodule 78 | 79 | 80 | module sync_lock #(parameter WIDTH) 81 | ( 82 | input clk, 83 | 84 | input sync_in, 85 | input de_in, 86 | 87 | output sync_out, 88 | output de_out, 89 | 90 | input freeze, 91 | output sync_pt, 92 | output valid 93 | ); 94 | 95 | reg [WIDTH-1:0] f_len, s_len, de_start, de_end; 96 | reg sync_valid; 97 | 98 | reg old_sync; 99 | always @(posedge clk) old_sync <= sync_in; 100 | 101 | always @(posedge clk) begin 102 | reg [WIDTH-1:0] cnti; 103 | reg f_valid; 104 | reg old_de; 105 | 106 | cnti <= cnti + 1'd1; 107 | if(~old_sync & sync_in) begin 108 | if(sync_valid) f_len <= cnti; 109 | f_valid <= 1; 110 | sync_valid <= f_valid; 111 | cnti <= 0; 112 | end 113 | 114 | if(old_sync & ~sync_in & sync_valid) s_len <= cnti; 115 | 116 | old_de <= de_in; 117 | if(~old_de & de_in & sync_valid) de_start <= cnti; 118 | if(old_de & ~de_in & sync_valid) de_end <= cnti; 119 | 120 | if(freeze) {f_valid, sync_valid} <= 0; 121 | end 122 | 123 | reg sync_o, de_o, sync_o_pre; 124 | always @(posedge clk) begin 125 | reg [WIDTH-1:0] cnto; 126 | 127 | cnto <= cnto + 1'd1; 128 | if(old_sync & ~sync_in & sync_valid) cnto <= s_len + 2'd2; 129 | if(cnto == f_len) cnto <= 0; 130 | 131 | sync_o_pre <= (cnto == (s_len>>1)); // middle in sync 132 | if(cnto == f_len) sync_o <= 1; 133 | if(cnto == s_len) sync_o <= 0; 134 | if(cnto == de_start) de_o <= 1; 135 | if(cnto == de_end) de_o <= 0; 136 | end 137 | 138 | assign sync_out = freeze ? sync_o : sync_in; 139 | assign valid = sync_valid; 140 | assign sync_pt = sync_o_pre; 141 | assign de_out = freeze ? de_o : de_in; 142 | 143 | endmodule 144 | --------------------------------------------------------------------------------