├── .gitignore ├── LICENSE ├── README.md ├── clean.bat ├── dev └── stp1.stp ├── doc ├── Artwork - Dipswitch Info │ ├── hellfire-dip.png │ ├── hellfire-jp101.jpg │ ├── hellfire-jp102.jpg │ ├── out-zone-dip.png │ ├── out-zone-jp101.jpg │ ├── out-zone-jp102.jpg │ ├── tatsujin-dip.png │ ├── tatsujin101.jpg │ ├── tatsujin102.jpg │ ├── zero-wing-dip.png │ ├── zero-wing-jp101.jpg │ └── zero-wing-jp102.jpg ├── Out Zone (TP-015C) │ ├── Out Zone (TCP-015C) │ │ └── PXL_20220131_034746408.jpg │ ├── Zero Wing │ │ ├── 1 - CG0hSFG.jpg │ │ ├── 2 - QHaxXRl.jpg │ │ ├── 3 - rFlWtWq.jpg │ │ ├── 4 - XhrRfrr.jpg │ │ ├── 5 - ycb8UDb.jpg │ │ ├── 6 - WFY0QAw.jpg │ │ ├── 7 - BjNSo7Z.jpg │ │ └── 8 - QDJ8zqu.jpg │ ├── outzone_50MHz.sr │ ├── outzone_Hz.png │ └── outzone_KHz.png ├── Schematics │ └── Out Zone Schematics.pdf └── Tatsujin (TP-013B) │ ├── tatsujin_50MHz.pvs │ ├── tatsujin_50MHz.sr │ ├── tatsujin_Hz.png │ ├── tatsujin_KHz.png │ ├── tatsujin_sync.png │ ├── tatsujin_sync.pvs │ └── tatsujin_sync.sr ├── files.qip ├── releases ├── Hellfire (2P Set).mra ├── Out Zone.mra ├── Truxton - Tatsujin.mra ├── Zero Wing (2P Set).mra ├── _alternatives │ ├── _Hellfire │ │ ├── Hellfire (1P Set).mra │ │ ├── Hellfire (1P Set, Older).mra │ │ └── Hellfire (2P Set, Older).mra │ ├── _Out Zone │ │ ├── Out Zone (Harder).mra │ │ ├── Out Zone (Old Set).mra │ │ ├── Out Zone (Older Set).mra │ │ └── Out Zone (Zero Wing TP-015 PCB Conversion).mra │ └── _Zero Wing │ │ ├── Zero Wing (1P Set).mra │ │ ├── Zero Wing (2P Set, No Flash).mra │ │ └── Zero Wing (2P Set, Williams License).mra ├── zerowing_20230521.rbf ├── zerowing_20230604.rbf └── zerowing_20230606.rbf ├── rtl ├── chip_select.v ├── fx68k │ ├── fx68k.qip │ ├── fx68k.sdc │ ├── fx68k.sv │ ├── fx68k.txt │ ├── fx68kAlu.sv │ ├── microrom.mem │ ├── nanorom.mem │ └── uaddrPla.sv ├── jtframe_fir_mono.v ├── jtframe_mixer.v ├── mem │ ├── cache.v │ ├── download_buffer.vhd │ ├── dual_port_ram.vhd │ ├── math.vhd │ ├── rom_controller.v │ ├── sdram.vhd │ ├── segment.vhd │ ├── single_port_ram.vhd │ ├── single_port_rom.vhd │ ├── tile_cache.v │ └── true_dual_port_ram.vhd ├── opl2_fpga_MiSTer │ ├── COPYING.LESSER │ ├── README.md │ ├── opl2_fpga.qip │ └── src │ │ ├── afifo.v │ │ ├── calc_envelope_shift.sv │ │ ├── calc_phase_inc.sv │ │ ├── calc_rhythm_phase.sv │ │ ├── cdc_vector_handshake_continuous.sv │ │ ├── channels.sv │ │ ├── clk_div.sv │ │ ├── control_operators.sv │ │ ├── dac_prep.sv │ │ ├── edge_detector.sv │ │ ├── envelope_generator.sv │ │ ├── host_if.sv │ │ ├── ksl_add_rom.sv │ │ ├── leds.sv │ │ ├── mem_simple_dual_port.sv │ │ ├── mem_simple_dual_port_async_read.sv │ │ ├── mem_single_bank.sv │ │ ├── mem_single_bank_reset.sv │ │ ├── operator.sv │ │ ├── opl2_exp_lut.sv │ │ ├── opl2_fpga.sv │ │ ├── opl2_log_sine_lut.sv │ │ ├── opl2_pkg.sv │ │ ├── phase_generator.sv │ │ ├── pipeline_sr.sv │ │ ├── reset_sync.sv │ │ ├── synchronizer.sv │ │ ├── timer.sv │ │ ├── timers.sv │ │ ├── tremolo.sv │ │ ├── trick_sw_detection.sv │ │ └── vibrato.sv ├── pause.v ├── pll.qip ├── pll.v ├── pll │ ├── pll_0002.qip │ ├── pll_0002.v │ └── pll_0002_q13.qip ├── t80 │ ├── T80.qip │ ├── T80.vhd │ ├── T80_ALU.vhd │ ├── T80_MCode.vhd │ ├── T80_Pack.vhd │ ├── T80_Reg.vhd │ ├── T80pa.vhd │ └── T80s.vhd └── video_timing.v ├── sys ├── alsa.sv ├── arcade_video.v ├── ascal.vhd ├── audio_out.v ├── build_id.tcl ├── ddr_svc.sv ├── f2sdram_safe_terminator.sv ├── gamma_corr.sv ├── hdmi_config.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.v ├── pll_cfg │ ├── altera_pll_reconfig_core.v │ ├── altera_pll_reconfig_top.v │ └── altera_std_synchronizer.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 ├── pll_q20.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 ├── zerowing.qpf ├── zerowing.qsf ├── zerowing.sdc └── zerowing.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 | **/.DS_Store -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/hellfire-dip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/hellfire-dip.png -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/hellfire-jp101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/hellfire-jp101.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/hellfire-jp102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/hellfire-jp102.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/out-zone-dip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/out-zone-dip.png -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/out-zone-jp101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/out-zone-jp101.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/out-zone-jp102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/out-zone-jp102.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/tatsujin-dip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/tatsujin-dip.png -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/tatsujin101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/tatsujin101.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/tatsujin102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/tatsujin102.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/zero-wing-dip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/zero-wing-dip.png -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/zero-wing-jp101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/zero-wing-jp101.jpg -------------------------------------------------------------------------------- /doc/Artwork - Dipswitch Info/zero-wing-jp102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Artwork - Dipswitch Info/zero-wing-jp102.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Out Zone (TCP-015C)/PXL_20220131_034746408.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Out Zone (TCP-015C)/PXL_20220131_034746408.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/1 - CG0hSFG.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/1 - CG0hSFG.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/2 - QHaxXRl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/2 - QHaxXRl.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/3 - rFlWtWq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/3 - rFlWtWq.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/4 - XhrRfrr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/4 - XhrRfrr.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/5 - ycb8UDb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/5 - ycb8UDb.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/6 - WFY0QAw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/6 - WFY0QAw.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/7 - BjNSo7Z.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/7 - BjNSo7Z.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/Zero Wing/8 - QDJ8zqu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/Zero Wing/8 - QDJ8zqu.jpg -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/outzone_50MHz.sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/outzone_50MHz.sr -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/outzone_Hz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/outzone_Hz.png -------------------------------------------------------------------------------- /doc/Out Zone (TP-015C)/outzone_KHz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Out Zone (TP-015C)/outzone_KHz.png -------------------------------------------------------------------------------- /doc/Schematics/Out Zone Schematics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Schematics/Out Zone Schematics.pdf -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_50MHz.pvs: -------------------------------------------------------------------------------- 1 | [0] 2 | name=IPL2_PIN_23_68K 3 | enabled=true 4 | color=4279638298 5 | conversion_type=0 6 | conv_options=0 7 | 8 | [1] 9 | name=HS_PIN_3_74LS04 10 | enabled=true 11 | color=4287582722 12 | conversion_type=0 13 | conv_options=0 14 | 15 | [2] 16 | name=DVBLK_PIN_5_74LS04 17 | enabled=true 18 | color=4291559424 19 | conversion_type=0 20 | conv_options=0 21 | 22 | [3] 23 | name=GND 24 | enabled=true 25 | color=4294277376 26 | conversion_type=0 27 | conv_options=0 28 | 29 | [4] 30 | name=VBLK_PIN_2_74LS08 31 | enabled=true 32 | color=4293776384 33 | conversion_type=0 34 | conv_options=0 35 | 36 | [5] 37 | name=VS_PIN_3_74LS08 38 | enabled=true 39 | color=4285780502 40 | conversion_type=0 41 | conv_options=0 42 | 43 | [6] 44 | name=HBLK_PIN_4_74LS08 45 | enabled=true 46 | color=4281623972 47 | conversion_type=0 48 | conv_options=0 49 | 50 | [7] 51 | name=VS_PIN_10_74LS08 52 | enabled=true 53 | color=4285878395 54 | conversion_type=0 55 | conv_options=0 56 | 57 | [8] 58 | name=8 59 | enabled=true 60 | color=4287138437 61 | conversion_type=0 62 | conv_options=0 63 | 64 | [9] 65 | name=9 66 | enabled=true 67 | color=4293848812 68 | conversion_type=0 69 | conv_options=0 70 | 71 | [10] 72 | name=10 73 | enabled=true 74 | color=4279638298 75 | conversion_type=0 76 | conv_options=0 77 | 78 | [11] 79 | name=11 80 | enabled=true 81 | color=4287582722 82 | conversion_type=0 83 | conv_options=0 84 | 85 | [12] 86 | name=12 87 | enabled=true 88 | color=4291559424 89 | conversion_type=0 90 | conv_options=0 91 | 92 | [13] 93 | name=13 94 | enabled=true 95 | color=4294277376 96 | conversion_type=0 97 | conv_options=0 98 | 99 | [14] 100 | name=14 101 | enabled=true 102 | color=4293776384 103 | conversion_type=0 104 | conv_options=0 105 | 106 | [15] 107 | name=15 108 | enabled=true 109 | color=4285780502 110 | conversion_type=0 111 | conv_options=0 112 | 113 | [General] 114 | decode_signals=0 115 | views=2 116 | meta_objs=0 117 | 118 | [view0] 119 | scale=1.620745542949757e-5 120 | v_offset=20 121 | splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\x9c\0\0\x4S\x1\0\0\0\x1\x1\0\0\0\x1\0) 122 | segment_display_mode=1 123 | offset=22 serialization::archive 14 0 0 0 0 216840 43449710 8867769 22596398 0 0 -24 1 0 6 124 | zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 125 | 0\trace_height=26 126 | 1\trace_height=26 127 | 2\trace_height=26 128 | 3\trace_height=26 129 | 4\trace_height=26 130 | 5\trace_height=26 131 | 6\trace_height=26 132 | 7\trace_height=26 133 | 8\trace_height=26 134 | 9\trace_height=26 135 | 10\trace_height=26 136 | 11\trace_height=26 137 | 12\trace_height=26 138 | 13\trace_height=26 139 | 14\trace_height=26 140 | 15\trace_height=26 141 | 142 | [view1] 143 | type=0 144 | scale=0.001 145 | v_offset=20 146 | splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\x9c\0\0\0\x46\x1\0\0\0\x1\x1\0\0\0\x1\0) 147 | segment_display_mode=1 148 | offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 149 | 0\trace_height=26 150 | 1\trace_height=26 151 | 2\trace_height=26 152 | 3\trace_height=26 153 | 4\trace_height=26 154 | 5\trace_height=26 155 | 6\trace_height=26 156 | 7\trace_height=26 157 | 8\trace_height=26 158 | 9\trace_height=26 159 | 10\trace_height=26 160 | 11\trace_height=26 161 | 12\trace_height=26 162 | 13\trace_height=26 163 | 14\trace_height=26 164 | 15\trace_height=26 165 | -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_50MHz.sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Tatsujin (TP-013B)/tatsujin_50MHz.sr -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_Hz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Tatsujin (TP-013B)/tatsujin_Hz.png -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_KHz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Tatsujin (TP-013B)/tatsujin_KHz.png -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Tatsujin (TP-013B)/tatsujin_sync.png -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_sync.pvs: -------------------------------------------------------------------------------- 1 | [0] 2 | name=IPL2_PIN_23_68K 3 | enabled=true 4 | color=4279638298 5 | conversion_type=0 6 | conv_options=0 7 | 8 | [1] 9 | name=HS_PIN_3_74LS04 10 | enabled=true 11 | color=4287582722 12 | conversion_type=0 13 | conv_options=0 14 | 15 | [2] 16 | name=DVBLK_PIN_5_74LS04 17 | enabled=true 18 | color=4291559424 19 | conversion_type=0 20 | conv_options=0 21 | 22 | [3] 23 | name=GND 24 | enabled=true 25 | color=4294277376 26 | conversion_type=0 27 | conv_options=0 28 | 29 | [4] 30 | name=VBLK_PIN_2_74LS08 31 | enabled=true 32 | color=4293776384 33 | conversion_type=0 34 | conv_options=0 35 | 36 | [5] 37 | name=VS_PIN_3_74LS08 38 | enabled=true 39 | color=4285780502 40 | conversion_type=0 41 | conv_options=0 42 | 43 | [6] 44 | name=HBLK_PIN_4_74LS08 45 | enabled=true 46 | color=4281623972 47 | conversion_type=0 48 | conv_options=0 49 | 50 | [7] 51 | name=VS_PIN_10_74LS08 52 | enabled=true 53 | color=4285878395 54 | conversion_type=0 55 | conv_options=0 56 | 57 | [8] 58 | name=8 59 | enabled=true 60 | color=4287138437 61 | conversion_type=0 62 | conv_options=0 63 | 64 | [9] 65 | name=9 66 | enabled=true 67 | color=4293848812 68 | conversion_type=0 69 | conv_options=0 70 | 71 | [10] 72 | name=10 73 | enabled=true 74 | color=4279638298 75 | conversion_type=0 76 | conv_options=0 77 | 78 | [11] 79 | name=11 80 | enabled=true 81 | color=4287582722 82 | conversion_type=0 83 | conv_options=0 84 | 85 | [12] 86 | name=12 87 | enabled=true 88 | color=4291559424 89 | conversion_type=0 90 | conv_options=0 91 | 92 | [13] 93 | name=13 94 | enabled=true 95 | color=4294277376 96 | conversion_type=0 97 | conv_options=0 98 | 99 | [14] 100 | name=14 101 | enabled=true 102 | color=4293776384 103 | conversion_type=0 104 | conv_options=0 105 | 106 | [15] 107 | name=15 108 | enabled=true 109 | color=4285780502 110 | conversion_type=0 111 | conv_options=0 112 | 113 | [General] 114 | decode_signals=0 115 | views=1 116 | meta_objs=0 117 | 118 | [view0] 119 | scale=0.0001620745542949757 120 | v_offset=20 121 | splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\x9c\0\0\x4S\x1\0\0\0\x1\x1\0\0\0\x1\0) 122 | segment_display_mode=1 123 | offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 124 | zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 125 | 0\trace_height=26 126 | 1\trace_height=26 127 | 2\trace_height=26 128 | 3\trace_height=26 129 | 4\trace_height=26 130 | 5\trace_height=26 131 | 6\trace_height=26 132 | 7\trace_height=26 133 | 8\trace_height=26 134 | 9\trace_height=26 135 | 10\trace_height=26 136 | 11\trace_height=26 137 | 12\trace_height=26 138 | 13\trace_height=26 139 | 14\trace_height=26 140 | 15\trace_height=26 141 | -------------------------------------------------------------------------------- /doc/Tatsujin (TP-013B)/tatsujin_sync.sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/doc/Tatsujin (TP-013B)/tatsujin_sync.sr -------------------------------------------------------------------------------- /files.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SDC_FILE zerowing.sdc 2 | set_global_assignment -name SYSTEMVERILOG_FILE zerowing.sv 3 | set_global_assignment -name QIP_FILE rtl/t80/T80.qip 4 | set_global_assignment -name QIP_FILE rtl/fx68k/fx68k.qip 5 | set_global_assignment -name QIP_FILE rtl/opl2_fpga_MiSTer/opl2_fpga.qip 6 | set_global_assignment -name VERILOG_FILE rtl/video_timing.v 7 | set_global_assignment -name QIP_FILE sys/pll_q17.qip 8 | set_global_assignment -name QIP_FILE sys/pll_hdmi.qip 9 | set_global_assignment -name QIP_FILE sys/pll_cfg.qip 10 | set_global_assignment -name QIP_FILE sys/pll_audio.qip 11 | set_global_assignment -name CDF_FILE jtag.cdf 12 | set_global_assignment -name QIP_FILE sys/sys.qip 13 | set_global_assignment -name VERILOG_FILE rtl/pause.v 14 | set_global_assignment -name VERILOG_FILE rtl/mem/rom_controller.v 15 | set_global_assignment -name VERILOG_FILE rtl/mem/tile_cache.v 16 | set_global_assignment -name VERILOG_FILE rtl/mem/cache.v 17 | set_global_assignment -name SYSTEMVERILOG_FILE rtl/chip_select.v 18 | set_global_assignment -name VHDL_FILE rtl/mem/math.vhd 19 | set_global_assignment -name VHDL_FILE rtl/mem/segment.vhd 20 | set_global_assignment -name VHDL_FILE rtl/mem/download_buffer.vhd 21 | set_global_assignment -name VHDL_FILE rtl/mem/sdram.vhd 22 | set_global_assignment -name VHDL_FILE rtl/mem/dual_port_ram.vhd 23 | set_global_assignment -name VERILOG_FILE rtl/jtframe_mixer.v 24 | set_global_assignment -name VERILOG_FILE rtl/jtframe_fir_mono.v 25 | -------------------------------------------------------------------------------- /releases/Hellfire (2P Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Hellfire (2P Set) 3 | hellfire 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan (Taito License) 8 | 2 9 | 8-way 10 | Horizontal 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 03 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | FF 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /releases/Out Zone.mra: -------------------------------------------------------------------------------- 1 | 2 | Out Zone 3 | outzone 4 | zerowing 5 | 0254 6 | 1990 7 | Toaplan 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 02 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /releases/Truxton - Tatsujin.mra: -------------------------------------------------------------------------------- 1 | 2 | Truxton / Tatsujin 3 | truxton 4 | zerowing 5 | 0254 6 | 1988 7 | Toaplan / Taito Corporation 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 04 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | FF 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | FF 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /releases/Zero Wing (2P Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Zero Wing (2P Set) 3 | zerowing 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan 8 | 2 9 | 8-way 10 | Horizontal 11 | USA 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 00 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | FF 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /releases/_alternatives/_Hellfire/Hellfire (1P Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Hellfire (1P Set) 3 | hellfire1 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan (Taito License) 8 | 2 9 | 8-way 10 | Horizontal 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 03 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | FF 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | FF 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /releases/_alternatives/_Hellfire/Hellfire (1P Set, Older).mra: -------------------------------------------------------------------------------- 1 | 2 | Hellfire (1P Set, Older) 3 | hellfire1a 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan (Taito License) 8 | 2 9 | 8-way 10 | Horizontal 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 03 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | FF 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | FF 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /releases/_alternatives/_Hellfire/Hellfire (2P Set, Older).mra: -------------------------------------------------------------------------------- 1 | 2 | Hellfire (2P Set, Older) 3 | hellfire2a 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan (Taito License) 8 | 2 9 | 8-way 10 | Horizontal 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 03 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | FF 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /releases/_alternatives/_Out Zone/Out Zone (Harder).mra: -------------------------------------------------------------------------------- 1 | 2 | Out Zone (Harder) 3 | outzoneh 4 | zerowing 5 | 0254 6 | 1990 7 | Toaplan 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 02 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /releases/_alternatives/_Out Zone/Out Zone (Old Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Out Zone (Old Set) 3 | outzonea 4 | zerowing 5 | 0254 6 | 1990 7 | Toaplan 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 02 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /releases/_alternatives/_Out Zone/Out Zone (Older Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Out Zone (Older Set) 3 | outzoneb 4 | zerowing 5 | 0254 6 | 1990 7 | Toaplan 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | World 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 02 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | FF 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /releases/_alternatives/_Out Zone/Out Zone (Zero Wing TP-015 PCB Conversion).mra: -------------------------------------------------------------------------------- 1 | 2 | Out Zone (Zero Wing TP-015 PCB Conversion) 3 | outzonecv 4 | zerowing 5 | 0254 6 | 1990 7 | Toaplan 8 | 2 9 | 8-way 10 | Vertical (CW) 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 00 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 01 61 | 62 | 63 | -------------------------------------------------------------------------------- /releases/_alternatives/_Zero Wing/Zero Wing (1P Set).mra: -------------------------------------------------------------------------------- 1 | 2 | Zero Wing (1P Set) 3 | zerowing1 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan 8 | 2 9 | 8-way 10 | Horizontal 11 | Japan 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 00 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | FF 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | FF 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /releases/_alternatives/_Zero Wing/Zero Wing (2P Set, No Flash).mra: -------------------------------------------------------------------------------- 1 | 2 | Zero Wing (2P Set) 3 | zerowing 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan 8 | 2 9 | 8-way 10 | Horizontal 11 | USA 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 00 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | FF 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 60 10 68 | 4E 71 69 | 4E 71 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /releases/_alternatives/_Zero Wing/Zero Wing (2P Set, Williams License).mra: -------------------------------------------------------------------------------- 1 | 2 | Zero Wing (2P set, Williams license) 3 | zerowingw 4 | zerowing 5 | 0254 6 | 1989 7 | Toaplan 8 | 2 9 | 8-way 10 | Horizontal 11 | USA 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 00 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | FF 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | FF 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /releases/zerowing_20230521.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/releases/zerowing_20230521.rbf -------------------------------------------------------------------------------- /releases/zerowing_20230604.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/releases/zerowing_20230604.rbf -------------------------------------------------------------------------------- /releases/zerowing_20230606.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/va7deo/zerowing/cb3a5537d97cf78859e35421894d1259147a13dd/releases/zerowing_20230606.rbf -------------------------------------------------------------------------------- /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 10 | -------------------------------------------------------------------------------- /rtl/jtframe_fir_mono.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JTFRAME. 2 | 3 | 4 | JTFRAME program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | JTFRAME program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with JTFRAME. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 12-1-2021 20 | 21 | */ 22 | 23 | // Generic FIR filter for mono signals 24 | // Max 255 coefficients 25 | 26 | // Parameters 27 | // KMAX = number of coefficients (8 bit value) 28 | // COEFFS = hex file with filter coefficients 29 | 30 | module jtframe_fir_mono( 31 | input rst, 32 | input clk, 33 | input sample, 34 | input signed [15:0] din, 35 | output reg signed [15:0] dout 36 | ); 37 | 38 | parameter [7:0] KMAX = 8'd68; 39 | parameter COEFFS = "filter.hex"; 40 | 41 | reg [ 7:0] pt_wr, pt_rd, cnt; 42 | reg [ 8:0] rd_addr; 43 | reg st, wt_ram; 44 | reg signed [35:0] acc; 45 | reg signed [15:0] coeff; 46 | reg signed [31:0] p; 47 | wire signed [15:0] ram_dout; 48 | 49 | function signed [35:0] ext; 50 | input signed [31:0] p; 51 | ext = { {4{p[31]}}, p }; 52 | endfunction 53 | 54 | function [7:0] loop_inc; 55 | input [7:0] s; 56 | loop_inc = s == KMAX-8'd1 ? 8'd0 : s+8'd1; 57 | endfunction 58 | 59 | function signed [15:0] sat; 60 | input [35:0] a; 61 | sat = a[35:30] == {6{a[29]}} ? a[29:14] : { a[35], {15{~a[35]}} }; 62 | endfunction 63 | 64 | always @(*) begin 65 | rd_addr = st==0 ? {1'd0, cnt} : {1'd1, pt_rd}; 66 | end 67 | 68 | // dual port RAM 69 | // the first half contains the coefficients 70 | // the second half, contains the signal 71 | 72 | jtframe_dual_ram #(.dw(16), .aw(9), .synfile(COEFFS)) u_ram( 73 | .clk0 ( clk ), 74 | .clk1 ( clk ), 75 | // Port 0: write 76 | .data0 ( din ), 77 | .addr0 ( {1'd1, pt_wr} ), 78 | .we0 ( sample ), 79 | .q0 ( ), 80 | // Port 1: read 81 | .data1 ( 16'd0 ), 82 | .addr1 ( rd_addr ), 83 | .we1 ( 1'd0 ), 84 | .q1 ( ram_dout ) 85 | ); 86 | 87 | always@(posedge clk, posedge rst) begin 88 | if( rst ) begin 89 | dout <= 16'd0; 90 | pt_rd <= 8'd0; 91 | pt_wr <= 8'd0; 92 | cnt <= 8'd0; 93 | acc <= 36'd0; 94 | p <= 32'd0; 95 | coeff <= 16'd0; 96 | end else begin 97 | if( sample ) begin 98 | pt_rd <= pt_wr; 99 | cnt <= 0; 100 | // ram[ { 1'd1, pt_wr } ] <= din; 101 | pt_wr <= loop_inc( pt_wr ); 102 | acc <= 36'd0; 103 | p <= 32'd0; 104 | st <= 0; 105 | wt_ram<= 1; 106 | end else begin 107 | wt_ram <= ~wt_ram; 108 | if( !wt_ram ) begin 109 | if( cnt < KMAX ) begin 110 | st <= ~st; 111 | if( st == 0 ) begin 112 | coeff <= ram_dout; 113 | end else begin 114 | p <= ram_dout * coeff; 115 | acc <= acc + ext(p); 116 | cnt <= cnt+7'd1; 117 | pt_rd <= loop_inc( pt_rd ); 118 | end 119 | end else begin 120 | dout <= sat(acc); 121 | end 122 | end 123 | end 124 | end 125 | end 126 | 127 | endmodule 128 | 129 | -------------------------------------------------------------------------------- /rtl/mem/cache.v: -------------------------------------------------------------------------------- 1 | ///---------------------------------------------------------------------------- 2 | // 3 | // Copyright 2022 Darren Olafson 4 | // 5 | // MiSTer Copyright (C) 2017 Sorgelig 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 | // simple read-only cache 25 | // specificly for 68k program rom. todo - parameterize 26 | module cache 27 | ( 28 | input reset, 29 | input clk, 30 | 31 | input cache_req, 32 | input [22:0] cache_addr, 33 | 34 | output reg cache_valid, 35 | output [15:0] cache_data, 36 | 37 | input [15:0] rom_data, 38 | input rom_valid, 39 | 40 | output reg rom_req, 41 | output reg [22:0] rom_addr 42 | ); 43 | 44 | 45 | reg [22:10] tag [1023:0]; 46 | reg [1023:0] valid ; 47 | reg [1:0] state = 0; 48 | 49 | reg [9:0] idx_r; 50 | 51 | wire [9:0] idx = cache_addr[9:0]; 52 | wire hit; 53 | 54 | // if tag value matches the upper bits of the address 55 | // and valid then no need to pass request to sdram 56 | assign hit = ( tag[idx] == cache_addr[22:10] && valid[idx] == 1 && state == 1 ); 57 | 58 | 59 | assign cache_data = ( hit == 1 ) ? cache_dout : rom_data; 60 | 61 | always @ (posedge clk) begin 62 | cache_valid <= ( cache_req != 0 ) && ( hit == 1 || rom_valid == 1 ); 63 | if ( reset == 1 ) begin 64 | state <= 0; 65 | // reset bits that indicate tag is valid 66 | valid <= 0; 67 | end else begin 68 | // if no read request then do nothing 69 | if ( cache_req == 0 ) begin 70 | rom_req <= 0; 71 | state <= 1; 72 | end else begin 73 | // if there is a hit then read from cache and say we are done 74 | if ( hit == 1 ) begin 75 | rom_req <= 0; 76 | end else if ( state == 1 ) begin 77 | // read from memory 78 | 79 | idx_r <= idx; 80 | 81 | // we need to read from sdram 82 | rom_req <= 1; 83 | rom_addr <= cache_addr; 84 | 85 | // next state is wait for rom ready 86 | state <= 2; 87 | 88 | end else if ( state == 2 && rom_valid == 1 ) begin 89 | 90 | // write updated tag 91 | tag[idx_r] <= rom_addr[22:10]; 92 | // mark tag valid 93 | valid[idx_r] <= 1'b1; 94 | 95 | cache_din <= rom_data; 96 | 97 | state <= 3; 98 | end else if ( state == 3 ) begin 99 | state <= 0; 100 | end 101 | end 102 | end 103 | end 104 | 105 | reg [15:0] cache_din; 106 | wire [15:0] cache_dout; 107 | 108 | dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) cache_ram ( 109 | .clock_a ( clk ), 110 | .address_a ( idx_r ), 111 | .wren_a ( state == 3 ), 112 | .data_a ( cache_din ), 113 | .q_a ( ), 114 | 115 | .clock_b ( clk ), 116 | .address_b ( idx ), 117 | .wren_b ( 0 ), 118 | .q_b ( cache_dout ) 119 | ); 120 | 121 | 122 | endmodule 123 | 124 | -------------------------------------------------------------------------------- /rtl/mem/download_buffer.vhd: -------------------------------------------------------------------------------- 1 | -- __ __ __ __ __ __ 2 | -- /\ "-.\ \ /\ \/\ \ /\ \ /\ \ 3 | -- \ \ \-. \ \ \ \_\ \ \ \ \____ \ \ \____ 4 | -- \ \_\\"\_\ \ \_____\ \ \_____\ \ \_____\ 5 | -- \/_/ \/_/ \/_____/ \/_____/ \/_____/ 6 | -- ______ ______ __ ______ ______ ______ 7 | -- /\ __ \ /\ == \ /\ \ /\ ___\ /\ ___\ /\__ _\ 8 | -- \ \ \/\ \ \ \ __< _\_\ \ \ \ __\ \ \ \____ \/_/\ \/ 9 | -- \ \_____\ \ \_____\ /\_____\ \ \_____\ \ \_____\ \ \_\ 10 | -- \/_____/ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ 11 | -- 12 | -- https://joshbassett.info 13 | -- https://twitter.com/nullobject 14 | -- https://github.com/nullobject 15 | -- 16 | -- Copyright (c) 2020 Josh Bassett 17 | -- 18 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 19 | -- of this software and associated documentation files (the "Software"), to deal 20 | -- in the Software without restriction, including without limitation the rights 21 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | -- copies of the Software, and to permit persons to whom the Software is 23 | -- furnished to do so, subject to the following conditions: 24 | -- 25 | -- The above copyright notice and this permission notice shall be included in all 26 | -- copies or substantial portions of the Software. 27 | -- 28 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | -- SOFTWARE. 35 | 36 | library ieee; 37 | use ieee.std_logic_1164.all; 38 | use ieee.numeric_std.all; 39 | 40 | -- use work.types.all; 41 | 42 | -- The download buffer writes a stream of bytes to an internal buffer. When the 43 | -- buffer is full, it is flushed as a single word. 44 | -- 45 | -- For example, with a buffer size of four, every four bytes written will be 46 | -- flushed as a single 32-bit word. 47 | entity download_buffer is 48 | generic ( 49 | -- the size of the buffer (in bytes) 50 | SIZE : natural 51 | ); 52 | port ( 53 | -- reset 54 | reset : in std_logic := '0'; 55 | 56 | -- clock 57 | clk : in std_logic; 58 | 59 | -- data in 60 | din : in std_logic_vector(7 downto 0); 61 | 62 | -- data out 63 | dout : out std_logic_vector(SIZE*8-1 downto 0); 64 | 65 | -- write enable 66 | we : in std_logic; 67 | 68 | -- when the valid signal is asserted there is a word on the output data bus 69 | valid : out std_logic 70 | ); 71 | end download_buffer; 72 | 73 | architecture arch of download_buffer is 74 | signal counter : natural range 0 to SIZE-1; 75 | begin 76 | process (clk, reset) 77 | begin 78 | if reset = '1' then 79 | counter <= 0; 80 | valid <= '0'; 81 | elsif rising_edge(clk) then 82 | if we = '1' then 83 | -- write the word to the output data bus 84 | dout((SIZE-counter)*8-1 downto (SIZE-counter-1)*8) <= din; 85 | 86 | -- increment the counter 87 | counter <= counter + 1; 88 | 89 | -- flush the buffer if it is full 90 | if counter = SIZE-1 then 91 | valid <= '1'; 92 | else 93 | valid <= '0'; 94 | end if; 95 | end if; 96 | end if; 97 | end process; 98 | end architecture; 99 | -------------------------------------------------------------------------------- /rtl/mem/math.vhd: -------------------------------------------------------------------------------- 1 | -- __ __ __ __ __ __ 2 | -- /\ "-.\ \ /\ \/\ \ /\ \ /\ \ 3 | -- \ \ \-. \ \ \ \_\ \ \ \ \____ \ \ \____ 4 | -- \ \_\\"\_\ \ \_____\ \ \_____\ \ \_____\ 5 | -- \/_/ \/_/ \/_____/ \/_____/ \/_____/ 6 | -- ______ ______ __ ______ ______ ______ 7 | -- /\ __ \ /\ == \ /\ \ /\ ___\ /\ ___\ /\__ _\ 8 | -- \ \ \/\ \ \ \ __< _\_\ \ \ \ __\ \ \ \____ \/_/\ \/ 9 | -- \ \_____\ \ \_____\ /\_____\ \ \_____\ \ \_____\ \ \_\ 10 | -- \/_____/ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ 11 | -- 12 | -- https://joshbassett.info 13 | -- https://twitter.com/nullobject 14 | -- https://github.com/nullobject 15 | -- 16 | -- Copyright (c) 2020 Josh Bassett 17 | -- 18 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 19 | -- of this software and associated documentation files (the "Software"), to deal 20 | -- in the Software without restriction, including without limitation the rights 21 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | -- copies of the Software, and to permit persons to whom the Software is 23 | -- furnished to do so, subject to the following conditions: 24 | -- 25 | -- The above copyright notice and this permission notice shall be included in all 26 | -- copies or substantial portions of the Software. 27 | -- 28 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | -- SOFTWARE. 35 | 36 | library ieee; 37 | use ieee.std_logic_1164.all; 38 | use ieee.numeric_std.all; 39 | use ieee.math_real.all; 40 | 41 | package math is 42 | -- calculates the log2 of the given number 43 | function ilog2(n : natural) return natural; 44 | 45 | -- Masks the given range of bits for a vector. 46 | -- 47 | -- Only the bits between the MSB and LSB (inclusive) will be kept, all other 48 | -- bits will be masked out. 49 | function mask_bits(data : std_logic_vector; msb : natural; lsb : natural) return std_logic_vector; 50 | function mask_bits(data : std_logic_vector; msb : natural; lsb : natural; size : natural) return std_logic_vector; 51 | end package math; 52 | 53 | package body math is 54 | function ilog2(n : natural) return natural is 55 | begin 56 | return natural(ceil(log2(real(n)))); 57 | end ilog2; 58 | 59 | function mask_bits(data : std_logic_vector; msb : natural; lsb : natural) return std_logic_vector is 60 | variable n : natural; 61 | variable mask : std_logic_vector(data'length-1 downto 0); 62 | begin 63 | n := (2**(msb-lsb+1))-1; 64 | mask := std_logic_vector(shift_left(to_unsigned(n, mask'length), lsb)); 65 | return std_logic_vector(shift_right(unsigned(data AND mask), lsb)); 66 | end mask_bits; 67 | 68 | function mask_bits(data : std_logic_vector; msb : natural; lsb : natural; size : natural) return std_logic_vector is 69 | begin 70 | return std_logic_vector(resize(unsigned(mask_bits(data, msb, lsb)), size)); 71 | end mask_bits; 72 | end package body math; 73 | -------------------------------------------------------------------------------- /rtl/mem/single_port_ram.vhd: -------------------------------------------------------------------------------- 1 | -- __ __ __ __ __ __ 2 | -- /\ "-.\ \ /\ \/\ \ /\ \ /\ \ 3 | -- \ \ \-. \ \ \ \_\ \ \ \ \____ \ \ \____ 4 | -- \ \_\\"\_\ \ \_____\ \ \_____\ \ \_____\ 5 | -- \/_/ \/_/ \/_____/ \/_____/ \/_____/ 6 | -- ______ ______ __ ______ ______ ______ 7 | -- /\ __ \ /\ == \ /\ \ /\ ___\ /\ ___\ /\__ _\ 8 | -- \ \ \/\ \ \ \ __< _\_\ \ \ \ __\ \ \ \____ \/_/\ \/ 9 | -- \ \_____\ \ \_____\ /\_____\ \ \_____\ \ \_____\ \ \_\ 10 | -- \/_____/ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ 11 | -- 12 | -- https://joshbassett.info 13 | -- https://twitter.com/nullobject 14 | -- https://github.com/nullobject 15 | -- 16 | -- Copyright (c) 2020 Josh Bassett 17 | -- 18 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 19 | -- of this software and associated documentation files (the "Software"), to deal 20 | -- in the Software without restriction, including without limitation the rights 21 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | -- copies of the Software, and to permit persons to whom the Software is 23 | -- furnished to do so, subject to the following conditions: 24 | -- 25 | -- The above copyright notice and this permission notice shall be included in all 26 | -- copies or substantial portions of the Software. 27 | -- 28 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | -- SOFTWARE. 35 | 36 | library ieee; 37 | use ieee.std_logic_1164.all; 38 | use ieee.numeric_std.all; 39 | 40 | library altera_mf; 41 | use altera_mf.altera_mf_components.all; 42 | 43 | entity single_port_ram is 44 | generic ( 45 | ADDR_WIDTH : natural := 8; 46 | DATA_WIDTH : natural := 8 47 | ); 48 | port ( 49 | -- clock 50 | clk : in std_logic; 51 | 52 | -- chip select 53 | cs : in std_logic := '1'; 54 | 55 | -- address 56 | addr : in unsigned(ADDR_WIDTH-1 downto 0); 57 | 58 | -- data in 59 | din : in std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0'); 60 | 61 | -- data out 62 | dout : out std_logic_vector(DATA_WIDTH-1 downto 0); 63 | 64 | -- write enable 65 | we : in std_logic := '0' 66 | ); 67 | end single_port_ram; 68 | 69 | architecture arch of single_port_ram is 70 | signal q : std_logic_vector(DATA_WIDTH-1 downto 0); 71 | begin 72 | altsyncram_component : altsyncram 73 | generic map ( 74 | clock_enable_input_a => "BYPASS", 75 | clock_enable_output_a => "BYPASS", 76 | intended_device_family => "Cyclone V", 77 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 78 | lpm_type => "altsyncram", 79 | numwords_a => 2**ADDR_WIDTH, 80 | operation_mode => "SINGLE_PORT", 81 | outdata_aclr_a => "NONE", 82 | outdata_reg_a => "UNREGISTERED", 83 | power_up_uninitialized => "FALSE", 84 | read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", 85 | width_a => DATA_WIDTH, 86 | width_byteena_a => 1, 87 | widthad_a => ADDR_WIDTH 88 | ) 89 | port map ( 90 | address_a => std_logic_vector(addr), 91 | clock0 => clk, 92 | data_a => din, 93 | wren_a => cs and we, 94 | q_a => q 95 | ); 96 | 97 | dout <= q when cs = '1' else (others => '0'); 98 | end architecture arch; 99 | -------------------------------------------------------------------------------- /rtl/mem/single_port_rom.vhd: -------------------------------------------------------------------------------- 1 | -- __ __ __ __ __ __ 2 | -- /\ "-.\ \ /\ \/\ \ /\ \ /\ \ 3 | -- \ \ \-. \ \ \ \_\ \ \ \ \____ \ \ \____ 4 | -- \ \_\\"\_\ \ \_____\ \ \_____\ \ \_____\ 5 | -- \/_/ \/_/ \/_____/ \/_____/ \/_____/ 6 | -- ______ ______ __ ______ ______ ______ 7 | -- /\ __ \ /\ == \ /\ \ /\ ___\ /\ ___\ /\__ _\ 8 | -- \ \ \/\ \ \ \ __< _\_\ \ \ \ __\ \ \ \____ \/_/\ \/ 9 | -- \ \_____\ \ \_____\ /\_____\ \ \_____\ \ \_____\ \ \_\ 10 | -- \/_____/ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ 11 | -- 12 | -- https://joshbassett.info 13 | -- https://twitter.com/nullobject 14 | -- https://github.com/nullobject 15 | -- 16 | -- Copyright (c) 2020 Josh Bassett 17 | -- 18 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 19 | -- of this software and associated documentation files (the "Software"), to deal 20 | -- in the Software without restriction, including without limitation the rights 21 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | -- copies of the Software, and to permit persons to whom the Software is 23 | -- furnished to do so, subject to the following conditions: 24 | -- 25 | -- The above copyright notice and this permission notice shall be included in all 26 | -- copies or substantial portions of the Software. 27 | -- 28 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | -- SOFTWARE. 35 | 36 | library ieee; 37 | use ieee.std_logic_1164.all; 38 | use ieee.numeric_std.all; 39 | 40 | library altera_mf; 41 | use altera_mf.altera_mf_components.all; 42 | 43 | entity single_port_rom is 44 | generic ( 45 | ADDR_WIDTH : natural := 8; 46 | DATA_WIDTH : natural := 8; 47 | INIT_FILE : string := "" 48 | ); 49 | port ( 50 | -- clock 51 | clk : in std_logic; 52 | 53 | -- chip select 54 | cs : in std_logic := '1'; 55 | 56 | -- address 57 | addr : in unsigned(ADDR_WIDTH-1 downto 0); 58 | 59 | -- data out 60 | dout : out std_logic_vector(DATA_WIDTH-1 downto 0) 61 | ); 62 | end single_port_rom; 63 | 64 | architecture arch of single_port_rom is 65 | signal q : std_logic_vector(DATA_WIDTH-1 downto 0); 66 | begin 67 | altsyncram_component : altsyncram 68 | generic map ( 69 | address_aclr_a => "NONE", 70 | clock_enable_input_a => "BYPASS", 71 | clock_enable_output_a => "BYPASS", 72 | init_file => INIT_FILE, 73 | intended_device_family => "Cyclone V", 74 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 75 | lpm_type => "altsyncram", 76 | numwords_a => 2**ADDR_WIDTH, 77 | operation_mode => "ROM", 78 | outdata_aclr_a => "NONE", 79 | outdata_reg_a => "UNREGISTERED", 80 | width_a => DATA_WIDTH, 81 | width_byteena_a => 1, 82 | widthad_a => ADDR_WIDTH 83 | ) 84 | port map ( 85 | address_a => std_logic_vector(addr), 86 | clock0 => clk, 87 | q_a => q 88 | ); 89 | 90 | dout <= q when cs = '1' else (others => '0'); 91 | end architecture arch; 92 | -------------------------------------------------------------------------------- /rtl/mem/tile_cache.v: -------------------------------------------------------------------------------- 1 | ///---------------------------------------------------------------------------- 2 | // 3 | // Copyright 2022 Darren Olafson 4 | // 5 | // MiSTer Copyright (C) 2017 Sorgelig 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 | // input tile_rom_cs, 25 | // input tile_rom_oe, 26 | // input [19:0] tile_rom_addr, 27 | // output [31:0] tile_rom_data, 28 | // output tile_rom_data_valid, 29 | 30 | module tile_cache 31 | ( 32 | input reset, 33 | input clk, 34 | 35 | input cache_req, 36 | input [17:0] cache_addr, 37 | 38 | output reg cache_valid, 39 | output [31:0] cache_data, 40 | 41 | input [31:0] rom_data, 42 | input rom_valid, 43 | 44 | output reg rom_req, 45 | output reg [17:0] rom_addr 46 | ); 47 | 48 | 49 | reg [17:10] tag [1023:0]; 50 | reg [1023:0] valid ; 51 | reg [1:0] state = 0; 52 | 53 | reg [9:0] idx_r; 54 | 55 | wire [9:0] idx = cache_addr[9:0]; 56 | wire hit; 57 | 58 | // if tag value matches the upper bits of the address 59 | // and valid then no need to pass request to sdram 60 | assign hit = ( tag[idx] == cache_addr[17:10] && valid[idx] == 1 && state == 1 ); 61 | //assign cache_valid = ( cache_req != 0 ) && ( hit == 1 || rom_valid == 1 ); 62 | 63 | assign cache_data = ( hit == 1 ) ? cache_dout : rom_data; 64 | 65 | always @ (posedge clk) begin 66 | cache_valid <= ( cache_req != 0 ) && ( hit == 1 || rom_valid == 1 ); 67 | if ( reset == 1 ) begin 68 | state <= 0; 69 | // reset bits that indicate tag is valid 70 | valid <= 0; 71 | end else begin 72 | // if no read request then do nothing 73 | if ( cache_req == 0 ) begin 74 | rom_req <= 0; 75 | state <= 1; 76 | end else begin 77 | // if there is a hit then read from cache and say we are done 78 | if ( hit == 1 ) begin 79 | rom_req <= 0; 80 | end else if ( state == 1 ) begin 81 | // read from memory 82 | 83 | idx_r <= idx; 84 | 85 | // we need to read from sdram 86 | rom_req <= 1; 87 | rom_addr <= cache_addr; 88 | 89 | // next state is wait for rom ready 90 | state <= 2; 91 | 92 | end else if ( state == 2 && rom_valid == 1 ) begin 93 | 94 | // write updated tag 95 | tag[idx_r] <= rom_addr[17:10]; 96 | // mark tag valid 97 | valid[idx_r] <= 1'b1; 98 | 99 | cache_din <= rom_data; 100 | 101 | state <= 3; 102 | end else if ( state == 3 ) begin 103 | state <= 0; 104 | end 105 | end 106 | end 107 | end 108 | 109 | reg [31:0] cache_din; 110 | wire [31:0] cache_dout; 111 | 112 | dual_port_ram #(.LEN(1024), .DATA_WIDTH(32)) cache_ram ( 113 | .clock_a ( clk ), 114 | .address_a ( idx_r ), 115 | .wren_a ( state == 3 ), 116 | .data_a ( cache_din ), 117 | .q_a ( ), 118 | 119 | .clock_b ( clk ), 120 | .address_b ( idx ), 121 | .wren_b ( 0 ), 122 | .q_b ( cache_dout ) 123 | ); 124 | 125 | 126 | endmodule 127 | 128 | -------------------------------------------------------------------------------- /rtl/opl2_fpga_MiSTer/README.md: -------------------------------------------------------------------------------- 1 | opl2_fpga_MiSTER 2 | ========= 3 | ## About 4 | Port of https://github.com/gtaylormb/opl2_fpga which is an OPL3->OPL2 conversion of https://github.com/gtaylormb/opl3_fpga, 5 | which was merged into https://github.com/MiSTer-devel/ao486_MiSTer in April 2024. 6 | 7 | This is specifically targetted for easy drop-in on cores for the MiSTer platform--the parameters in opl2_pkg.sv and the top level ports in opl2_fpga.sv 8 | have been targetted to MiSTer, but this could be used anywhere. 9 | -------------------------------------------------------------------------------- /rtl/opl2_fpga_MiSTer/opl2_fpga.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/opl2_pkg.sv ] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) src/afifo.v ] 3 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/calc_envelope_shift.sv ] 4 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/calc_phase_inc.sv ] 5 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/calc_rhythm_phase.sv ] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/cdc_vector_handshake_continuous.sv ] 7 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/channels.sv ] 8 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/clk_div.sv ] 9 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/control_operators.sv ] 10 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/dac_prep.sv ] 11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/edge_detector.sv ] 12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/envelope_generator.sv ] 13 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/host_if.sv ] 14 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/ksl_add_rom.sv ] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/leds.sv ] 16 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/mem_simple_dual_port_async_read.sv ] 17 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/mem_simple_dual_port.sv ] 18 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/mem_single_bank_reset.sv ] 19 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/mem_single_bank.sv ] 20 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/operator.sv ] 21 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/opl2_exp_lut.sv ] 22 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/opl2_fpga.sv ] 23 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/opl2_log_sine_lut.sv ] 24 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/phase_generator.sv ] 25 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/pipeline_sr.sv ] 26 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/reset_sync.sv ] 27 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/synchronizer.sv ] 28 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/timer.sv ] 29 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/timers.sv ] 30 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/tremolo.sv ] 31 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/trick_sw_detection.sv ] 32 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) src/vibrato.sv ] 33 | -------------------------------------------------------------------------------- /rtl/opl2_fpga_MiSTer/src/calc_phase_inc.sv: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | # +html+
  3 | #
  4 | #   FILENAME: calc_phase_inc.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 13 Oct 2014
  6 | #
  7 | #   DESCRIPTION:
  8 | #   Prepare the phase increment for the NCO (calc multiplier and vibrato)
  9 | #
 10 | #   CHANGE HISTORY:
 11 | #   13 Oct 2014    Greg Taylor
 12 | #       Initial version
 13 | #
 14 | #   Copyright (C) 2014 Greg Taylor 
 15 | #
 16 | #   This file is part of OPL3 FPGA.
 17 | #
 18 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
 19 | #   it under the terms of the GNU Lesser General Public License as published by
 20 | #   the Free Software Foundation, either version 3 of the License, or
 21 | #   (at your option) any later version.
 22 | #
 23 | #   OPL3 FPGA is distributed in the hope that it will be useful,
 24 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 25 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 26 | #   GNU Lesser General Public License for more details.
 27 | #
 28 | #   You should have received a copy of the GNU Lesser General Public License
 29 | #   along with OPL3 FPGA.  If not, see .
 30 | #
 31 | #   Original Java Code:
 32 | #   Copyright (C) 2008 Robson Cozendey 
 33 | #
 34 | #   Original C++ Code:
 35 | #   Copyright (C) 2012  Steffen Ohrendorf 
 36 | #
 37 | #   Some code based on forum posts in:
 38 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 39 | #   Copyright (C) 2010-2013 by carbon14 and opl3
 40 | #
 41 | #******************************************************************************/
 42 | `timescale 1ns / 1ps
 43 | `default_nettype none
 44 | /* altera message_off 10230 */
 45 | 
 46 | module calc_phase_inc
 47 |     import opl2_pkg::*;
 48 | (
 49 |     input wire clk,
 50 |     input wire sample_clk_en,
 51 |     input wire [OP_NUM_WIDTH-1:0] op_num,
 52 |     input wire [REG_FNUM_WIDTH-1:0] fnum,
 53 |     input wire [REG_MULT_WIDTH-1:0] mult,
 54 |     input wire [REG_BLOCK_WIDTH-1:0] block,
 55 |     input wire vib,
 56 |     input wire dvb,
 57 |     output logic [PHASE_ACC_WIDTH-1:0] phase_inc_p2
 58 | );
 59 |     localparam PIPELINE_DELAY = 2;
 60 | 
 61 |     logic signed [REG_FNUM_WIDTH+2**REG_BLOCK_WIDTH-1-1:0] pre_mult_p0;
 62 |     logic signed [REG_FNUM_WIDTH+2**REG_BLOCK_WIDTH-1-1:0] pre_mult_p1 = 0;
 63 |     logic signed [PHASE_ACC_WIDTH-1:0] post_mult_p2 = 0;
 64 |     logic [VIB_VAL_WIDTH-1:0] vib_val_p2;
 65 |     logic [PIPELINE_DELAY:1] vib_p;
 66 |     logic [$clog2(30)-1:0] multiplier_p1 = 0;
 67 | 
 68 |     always_comb pre_mult_p0 = (fnum << block) >> 1;
 69 | 
 70 |     always_ff @(posedge clk)
 71 |         unique case (mult)
 72 |         'h0: multiplier_p1 <= 1;
 73 |         'h1: multiplier_p1 <= 2;
 74 |         'h2: multiplier_p1 <= 4;
 75 |         'h3: multiplier_p1 <= 6;
 76 |         'h4: multiplier_p1 <= 8;
 77 |         'h5: multiplier_p1 <= 10;
 78 |         'h6: multiplier_p1 <= 12;
 79 |         'h7: multiplier_p1 <= 14;
 80 |         'h8: multiplier_p1 <= 16;
 81 |         'h9: multiplier_p1 <= 18;
 82 |         'hA: multiplier_p1 <= 20;
 83 |         'hB: multiplier_p1 <= 20;
 84 |         'hC: multiplier_p1 <= 24;
 85 |         'hD: multiplier_p1 <= 24;
 86 |         'hE: multiplier_p1 <= 30;
 87 |         'hF: multiplier_p1 <= 30;
 88 |         endcase
 89 | 
 90 |     always_ff @(posedge clk) begin
 91 |         pre_mult_p1 <= pre_mult_p0;
 92 |         post_mult_p2 <= (pre_mult_p1*multiplier_p1) >> 1;
 93 |     end
 94 | 
 95 |     pipeline_sr #(
 96 |         .ENDING_CYCLE(PIPELINE_DELAY)
 97 |     ) vib_sr (
 98 |         .clk,
 99 |         .in(vib),
100 |         .out(vib_p)
101 |     );
102 | 
103 |     always_comb
104 |         if (vib_p[2])
105 |             phase_inc_p2 = post_mult_p2 + vib_val_p2;
106 |         else
107 |             phase_inc_p2 = post_mult_p2;
108 | 
109 |     /*
110 |      * Calculate vib_val
111 |      */
112 |     vibrato vibrato (
113 |         .*
114 |     );
115 | endmodule
116 | `default_nettype wire
117 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/cdc_vector_handshake_continuous.sv:
--------------------------------------------------------------------------------
 1 | /*
 2 | Can be used in place of asynchronous FIFO for applications with infrequent transitions
 3 | to pass vector across CDC. Continuously passes value across but holds current value for
 4 | single bit synchronized handshaking feedback loop. Works for both fast->slow and
 5 | slow->fast clock differences.
 6 | */
 7 | `timescale 1ns / 1ps
 8 | `default_nettype none
 9 | 
10 | module cdc_vector_handshake_continuous #(
11 |     parameter DATA_WIDTH = 0
12 | ) (
13 |     input wire clk_in,
14 |     input wire clk_out,
15 |     input wire [DATA_WIDTH-1:0] data_in,
16 |     output logic [DATA_WIDTH-1:0] data_out = 0
17 | );
18 |     logic [DATA_WIDTH-1:0] data_hold_clk_in = 0;
19 |     logic new_value_clk_in = 0;
20 |     logic new_value_clk_out;
21 |     logic ack_clk_in;
22 | 
23 |     always_ff @(posedge clk_in)
24 |         if (ack_clk_in)
25 |             new_value_clk_in <= 0;
26 |         else if (!new_value_clk_in) begin
27 |             new_value_clk_in <= 1;
28 |             data_hold_clk_in <= data_in;
29 |         end
30 | 
31 |     synchronizer new_value_sync (
32 |         .clk(clk_out),
33 |         .in(new_value_clk_in),
34 |         .out(new_value_clk_out)
35 |     );
36 | 
37 |     synchronizer ack_sync (
38 |         .clk(clk_in),
39 |         .in(new_value_clk_out),
40 |         .out(ack_clk_in)
41 |     );
42 | 
43 |     always_ff @(posedge clk_out)
44 |         if (new_value_clk_out)
45 |             data_out <= data_hold_clk_in;
46 | endmodule
47 | `default_nettype wire


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/clk_div.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: clk_div.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 13 Oct 2014
 6 | #
 7 | #   DESCRIPTION:
 8 | #   Generates a clk enable pulse based on the frequency specified by
 9 | #   OUTPUT_CLK_EN_FREQ.
10 | #
11 | #   CHANGE HISTORY:
12 | #   13 Oct 2014        Greg Taylor
13 | #       Initial version
14 | #
15 | #   Copyright (C) 2014 Greg Taylor 
16 | #
17 | #   This file is part of OPL3 FPGA.
18 | #
19 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
20 | #   it under the terms of the GNU Lesser General Public License as published by
21 | #   the Free Software Foundation, either version 3 of the License, or
22 | #   (at your option) any later version.
23 | #
24 | #   OPL3 FPGA is distributed in the hope that it will be useful,
25 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 | #   GNU Lesser General Public License for more details.
28 | #
29 | #   You should have received a copy of the GNU Lesser General Public License
30 | #   along with OPL3 FPGA.  If not, see .
31 | #
32 | #   Original Java Code:
33 | #   Copyright (C) 2008 Robson Cozendey 
34 | #
35 | #   Original C++ Code:
36 | #   Copyright (C) 2012  Steffen Ohrendorf 
37 | #
38 | #   Some code based on forum posts in:
39 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
40 | #   Copyright (C) 2010-2013 by carbon14 and opl3
41 | #
42 | #******************************************************************************/
43 | `timescale 1ns / 1ps
44 | `default_nettype none
45 | /* altera message_off 10230 */
46 | 
47 | module clk_div #(
48 |     parameter CLK_DIV_COUNT = 0
49 | )(
50 |     input wire clk,
51 |     output logic clk_en = 0
52 | );
53 |     logic [$clog2(CLK_DIV_COUNT)-1:0] counter = 0;
54 | 
55 |     always_ff @(posedge clk)
56 |         if (counter == CLK_DIV_COUNT - 1)
57 |             counter <= 0;
58 |         else
59 |             counter <= counter + 1;
60 | 
61 |     always_ff @(posedge clk)
62 |         clk_en <= (counter == CLK_DIV_COUNT - 1);
63 | 
64 | endmodule
65 | `default_nettype wire
66 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/dac_prep.sv:
--------------------------------------------------------------------------------
  1 | /*******************************************************************************
  2 | #   +html+
  3 | #
  4 | #   FILENAME: dac_prep.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 5 April 2024
  6 | #
  7 | #   DESCRIPTION: Add channels and optionally sync to host clk domain
  8 | #
  9 | #   CHANGE HISTORY:
 10 | #   5 April 2024    Greg Taylor
 11 | #       Initial version
 12 | #
 13 | #   Copyright (C) 2014 Greg Taylor 
 14 | #
 15 | #   This file is part of opl2 FPGA.
 16 | #
 17 | #   opl2 FPGA is free software: you can redistribute it and/or modify
 18 | #   it under the terms of the GNU Lesser General Public License as published by
 19 | #   the Free Software Foundation, either version 3 of the License, or
 20 | #   (at your option) any later version.
 21 | #
 22 | #   opl2 FPGA is distributed in the hope that it will be useful,
 23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25 | #   GNU Lesser General Public License for more details.
 26 | #
 27 | #   You should have received a copy of the GNU Lesser General Public License
 28 | #   along with opl2 FPGA.  If not, see .
 29 | #
 30 | #   Original Java Code:
 31 | #   Copyright (C) 2008 Robson Cozendey 
 32 | #
 33 | #   Original C++ Code:
 34 | #   Copyright (C) 2012  Steffen Ohrendorf 
 35 | #
 36 | #   Some code based on forum posts in:
 37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 38 | #   Copyright (C) 2010-2013 by carbon14 and opl2
 39 | #
 40 | #******************************************************************************/
 41 | `timescale 1ns / 1ps
 42 | `default_nettype none
 43 | 
 44 | module dac_prep
 45 |     import opl2_pkg::*;
 46 | (
 47 |     input wire clk,
 48 |     input wire clk_dac,
 49 |     input wire channel_valid,
 50 |     input wire signed [SAMPLE_WIDTH-1:0] channel,
 51 |     output logic sample_valid,
 52 |     output logic signed [DAC_OUTPUT_WIDTH-1:0] sample
 53 | );
 54 |     logic sample_valid_opl2_p1 = 0;
 55 |     logic signed [DAC_OUTPUT_WIDTH-1:0] sample_opl2_p1 = 0;
 56 | 
 57 |     always_ff @(posedge clk) begin
 58 |         sample_valid_opl2_p1 <= channel_valid;
 59 |         sample_opl2_p1 <= channel <<< DAC_LEFT_SHIFT;
 60 |     end
 61 | 
 62 |     generate
 63 |     if (INSTANTIATE_SAMPLE_DAC_CDC) begin
 64 |         logic [2:0] sample_valid_opl2_pulse_extend;
 65 |         logic sample_valid_opl2_extended_pulse = 0;
 66 |         logic sample_valid_dac_p0;
 67 |         logic sample_valid_dac_p1 = 0;
 68 | 
 69 |         /*
 70 |          * pulse extend to make it through synchronizer
 71 |          */
 72 |         always_ff @(posedge clk) begin
 73 |             sample_valid_opl2_pulse_extend <= sample_valid_opl2_pulse_extend << 1;
 74 |             sample_valid_opl2_pulse_extend[0] <= sample_valid_opl2_p1;
 75 |             sample_valid_opl2_extended_pulse <= sample_valid_opl2_pulse_extend != 0;
 76 |         end
 77 | 
 78 |         synchronizer channel_valid_sync (
 79 |             .clk(clk_dac),
 80 |             .in(sample_valid_opl2_extended_pulse),
 81 |             .out(sample_valid_dac_p0)
 82 |         );
 83 | 
 84 |         /*
 85 |         * opl2 channels are latched and held on channel_valid for a full sample period, so we only need to
 86 |         * synchronize the channel_valid bit and use to latch samples into DAC clock domain
 87 |         */
 88 |         always_ff @(posedge clk_dac) begin
 89 |             sample_valid_dac_p1 <= sample_valid_dac_p0;
 90 | 
 91 |             if (sample_valid_dac_p0)
 92 |                 sample <= sample_opl2_p1;
 93 | 
 94 |             sample_valid <= sample_valid_dac_p0 && !sample_valid_dac_p1;
 95 |         end
 96 |     end
 97 |     else
 98 |         always_comb begin
 99 |             sample_valid = sample_valid_opl2_p1;
100 |             sample = sample_opl2_p1;
101 |         end
102 |     endgenerate
103 | endmodule
104 | `default_nettype wire
105 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/edge_detector.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: edge_detector.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 1 April 2009
 6 | #
 7 | #   DESCRIPTION:
 8 | #       Detect edge on i_in. Create single pulse on o_edge_detected upon edge
 9 | #       detection. i_in must be synchronous to i_sys_clk (this is not an
10 | #       asynchronous edge detector!). Use 1 clock delay for glitch free output
11 | #       (output registered).
12 | #
13 | #   CHANGE HISTORY:
14 | #   1 April 2009        Greg Taylor
15 | #       Initial version
16 | #   14 Sept 2009        Greg Taylor
17 | #       Added clock delay configuration parameter
18 | #
19 | #   Copyright (C) 2014 Greg Taylor 
20 | #
21 | #   This file is part of OPL3 FPGA.
22 | #
23 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
24 | #   it under the terms of the GNU Lesser General Public License as published by
25 | #   the Free Software Foundation, either version 3 of the License, or
26 | #   (at your option) any later version.
27 | #
28 | #   OPL3 FPGA is distributed in the hope that it will be useful,
29 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
30 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31 | #   GNU Lesser General Public License for more details.
32 | #
33 | #   You should have received a copy of the GNU Lesser General Public License
34 | #   along with OPL3 FPGA.  If not, see .
35 | #
36 | #   Original Java Code:
37 | #   Copyright (C) 2008 Robson Cozendey 
38 | #
39 | #   Original C++ Code:
40 | #   Copyright (C) 2012  Steffen Ohrendorf 
41 | #
42 | #   Some code based on forum posts in:
43 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
44 | #   Copyright (C) 2010-2013 by carbon14 and opl3
45 | #
46 | #******************************************************************************/
47 | `timescale 1ns / 1ps
48 | `default_nettype none
49 | /* altera message_off 10230 */
50 | 
51 | module edge_detector #(
52 |     parameter EDGE_LEVEL = 1, // 1 = positive edge, 0 = negative edge
53 |     parameter CLK_DLY = 0, // 0 = no clock delay, 1 = 1 clock delay
54 |     parameter INITIAL_INPUT_LEVEL = 0
55 | ) (
56 |     input wire clk,
57 |     input wire clk_en,
58 |     input wire in,
59 |     output logic edge_detected = 0
60 | );
61 |     logic in_r0 = INITIAL_INPUT_LEVEL;
62 |     logic in_r1 = INITIAL_INPUT_LEVEL;
63 | 
64 |     always_ff @(posedge clk)
65 |         if (clk_en) begin
66 |             if (!CLK_DLY)
67 |                 in_r0 <= in;
68 |             else begin
69 |                 in_r0 <= in;
70 |                 in_r1 <= in_r0;
71 |             end
72 |         end
73 | 
74 |     always_comb
75 |         if (EDGE_LEVEL) begin
76 |             if (!CLK_DLY)
77 |                 edge_detected = clk_en && in && !in_r0;
78 |             else
79 |                 edge_detected = in_r0 && !in_r1;
80 |         end
81 |         else begin
82 |             if (!CLK_DLY)
83 |                 edge_detected = clk_en && !in && in_r0;
84 |             else
85 |                 edge_detected = !in_r0 && in_r1;
86 |         end
87 | endmodule
88 | `default_nettype wire
89 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/ksl_add_rom.sv:
--------------------------------------------------------------------------------
  1 | /*******************************************************************************
  2 | #   +html+
  3 | #
  4 | #   FILENAME: ksl_add_rom.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 31 Oct 2014
  6 | #
  7 | #   DESCRIPTION:
  8 | #   Values extracted from real chip ROM
  9 | #
 10 | #   CHANGE HISTORY:
 11 | #   31 Oct 2014    Greg Taylor
 12 | #       Initial version
 13 | #
 14 | #   Copyright (C) 2014 Greg Taylor 
 15 | #
 16 | #   This file is part of OPL3 FPGA.
 17 | #
 18 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
 19 | #   it under the terms of the GNU Lesser General Public License as published by
 20 | #   the Free Software Foundation, either version 3 of the License, or
 21 | #   (at your option) any later version.
 22 | #
 23 | #   OPL3 FPGA is distributed in the hope that it will be useful,
 24 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 25 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 26 | #   GNU Lesser General Public License for more details.
 27 | #
 28 | #   You should have received a copy of the GNU Lesser General Public License
 29 | #   along with OPL3 FPGA.  If not, see .
 30 | #
 31 | #   Original Java Code:
 32 | #   Copyright (C) 2008 Robson Cozendey 
 33 | #
 34 | #   Original C++ Code:
 35 | #   Copyright (C) 2012  Steffen Ohrendorf 
 36 | #
 37 | #   Some code based on forum posts in:
 38 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 39 | #   Copyright (C) 2010-2013 by carbon14 and opl3
 40 | #
 41 | #******************************************************************************/
 42 | `timescale 1ns / 1ps
 43 | `default_nettype none
 44 | /* altera message_off 10230 */
 45 | 
 46 | module ksl_add_rom
 47 |     import opl2_pkg::*;
 48 | (
 49 |     input wire clk,
 50 |     input wire [REG_FNUM_WIDTH-1:0] fnum,
 51 |     input wire [REG_BLOCK_WIDTH-1:0] block,
 52 |     input wire [REG_KSL_WIDTH-1:0] ksl,
 53 |     output logic [KSL_ADD_WIDTH-1:0] ksl_add_p2 = 0
 54 | );
 55 |     logic [$clog2(64+1)-1:0] rom_out_p1 = 0;
 56 |     logic [REG_BLOCK_WIDTH+3-1:0] tmp0_p1 = 0;
 57 |     logic signed [KSL_ADD_WIDTH-1:0] tmp1_p1;
 58 |     logic [REG_FNUM_WIDTH-6-1:0] fnum_shifted_p0;
 59 |     logic [REG_KSL_WIDTH-1:0] ksl_p1 = 0;
 60 | 
 61 |     always_comb fnum_shifted_p0 = fnum >> 6;
 62 | 
 63 |     always_ff @(posedge clk)
 64 |         unique case (fnum_shifted_p0)
 65 |         0: rom_out_p1 <= 0;
 66 |         1: rom_out_p1 <= 32;
 67 |         2: rom_out_p1 <= 40;
 68 |         3: rom_out_p1 <= 45;
 69 |         4: rom_out_p1 <= 48;
 70 |         5: rom_out_p1 <= 51;
 71 |         6: rom_out_p1 <= 53;
 72 |         7: rom_out_p1 <= 55;
 73 |         8: rom_out_p1 <= 56;
 74 |         9: rom_out_p1 <= 58;
 75 |         10: rom_out_p1 <= 59;
 76 |         11: rom_out_p1 <= 60;
 77 |         12: rom_out_p1 <= 61;
 78 |         13: rom_out_p1 <= 62;
 79 |         14: rom_out_p1 <= 63;
 80 |         15: rom_out_p1 <= 64;
 81 |         endcase
 82 | 
 83 |     always_ff @(posedge clk)
 84 |         tmp0_p1 <= block - 8;
 85 | 
 86 |     always_comb tmp1_p1 = signed'(rom_out_p1 + (tmp0_p1 << 3));
 87 | 
 88 |     always_ff @(posedge clk) begin
 89 |         ksl_p1 <= ksl;
 90 | 
 91 |         unique case (ksl_p1)
 92 |         0: ksl_add_p2 <= 0;
 93 |         1: ksl_add_p2 <= tmp1_p1 <= 0 ? 0 : tmp1_p1 << 1;
 94 |         2: ksl_add_p2 <= tmp1_p1 <= 0 ? 0 : tmp1_p1;
 95 |         3: ksl_add_p2 <= tmp1_p1 <= 0 ? 0 : tmp1_p1 << 2;
 96 |         endcase
 97 |     end
 98 | endmodule
 99 | `default_nettype wire
100 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/leds.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: leds.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 1 April 2024
 6 | #
 7 | #   DESCRIPTION:
 8 | #
 9 | #   CHANGE HISTORY:
10 | #   1 April 2024    Greg Taylor
11 | #       Initial version
12 | #
13 | #   Copyright (C) 2014 Greg Taylor 
14 | #
15 | #   This file is part of OPL3 FPGA.
16 | #
17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
18 | #   it under the terms of the GNU Lesser General Public License as published by
19 | #   the Free Software Foundation, either version 3 of the License, or
20 | #   (at your option) any later version.
21 | #
22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 | #   GNU Lesser General Public License for more details.
26 | #
27 | #   You should have received a copy of the GNU Lesser General Public License
28 | #   along with OPL3 FPGA.  If not, see .
29 | #
30 | #   Original Java Code:
31 | #   Copyright (C) 2008 Robson Cozendey 
32 | #
33 | #   Original C++ Code:
34 | #   Copyright (C) 2012  Steffen Ohrendorf 
35 | #
36 | #   Some code based on forum posts in:
37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
39 | #
40 | #******************************************************************************/
41 | `timescale 1ns / 1ps
42 | `default_nettype none
43 | 
44 | module leds
45 |     import opl2_pkg::*;
46 | (
47 |     input wire clk,
48 |     input var opl2_reg_wr_t opl2_reg_wr,
49 |     output logic [NUM_LEDS-1:0] led = 0
50 | );
51 |     generate
52 |     if (NUM_LEDS == 0)
53 |         always_comb led = '0;
54 |     else begin
55 |         genvar i;
56 |         for (i = 0; i < NUM_LEDS; ++i) begin: led_gen
57 |             always_ff @(posedge clk)
58 |                 if (opl2_reg_wr.valid && opl2_reg_wr.address == 'hB0 + i)
59 |                     led[i] <= opl2_reg_wr.data[5]; // kon bit
60 |         end
61 |     end
62 |     endgenerate
63 | endmodule
64 | `default_nettype wire
65 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/mem_simple_dual_port.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: mem_simple_dual_port.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 1 April 2024
 6 | #
 7 | #   DESCRIPTION:
 8 | #
 9 | #   CHANGE HISTORY:
10 | #   1 April 2024    Greg Taylor
11 | #       Initial version
12 | #
13 | #   Copyright (C) 2014 Greg Taylor 
14 | #
15 | #   This file is part of OPL3 FPGA.
16 | #
17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
18 | #   it under the terms of the GNU Lesser General Public License as published by
19 | #   the Free Software Foundation, either version 3 of the License, or
20 | #   (at your option) any later version.
21 | #
22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 | #   GNU Lesser General Public License for more details.
26 | #
27 | #   You should have received a copy of the GNU Lesser General Public License
28 | #   along with OPL3 FPGA.  If not, see .
29 | #
30 | #   Original Java Code:
31 | #   Copyright (C) 2008 Robson Cozendey 
32 | #
33 | #   Original C++ Code:
34 | #   Copyright (C) 2012  Steffen Ohrendorf 
35 | #
36 | #   Some code based on forum posts in:
37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
39 | #
40 | #******************************************************************************/
41 | `timescale 1ns / 1ps
42 | `default_nettype none
43 | 
44 | module mem_simple_dual_port #(
45 |     parameter DATA_WIDTH = 0,
46 |     parameter DEPTH = 0,
47 |     parameter OUTPUT_DELAY = 0, // 0, 1, or 2
48 |     parameter logic [DATA_WIDTH-1:0] DEFAULT_VALUE = 0
49 | ) (
50 |     input wire clka,
51 |     input wire clkb,
52 |     input wire wea,
53 |     input wire reb, // only used if OUTPUT_DELAY >0
54 |     input wire [$clog2(DEPTH)-1:0] addra,
55 |     input wire [$clog2(DEPTH)-1:0] addrb,
56 |     input wire [DATA_WIDTH-1:0] dia,
57 |     output logic [DATA_WIDTH-1:0] dob
58 | );
59 |     logic [DATA_WIDTH-1:0] dob_p0;
60 | 
61 |     logic [DATA_WIDTH-1:0] ram [DEPTH-1:0] = '{default: DEFAULT_VALUE};
62 | 
63 |     always_ff @(posedge clka)
64 |         if (wea)
65 |             ram[addra] <= dia;
66 | 
67 |     always_comb dob_p0 = ram[addrb];
68 | 
69 |     generate
70 |     if (OUTPUT_DELAY != 0) begin
71 |         logic [DATA_WIDTH-1:0] dob_p1 = DEFAULT_VALUE;
72 | 
73 |         always_ff @(posedge clkb)
74 |             if (reb)
75 |                 dob_p1 <= dob_p0;
76 | 
77 |         if (OUTPUT_DELAY == 1)
78 |             always_comb dob = dob_p1;
79 |         else if (OUTPUT_DELAY == 2) begin
80 |             logic [DATA_WIDTH-1:0] dob_p2 = DEFAULT_VALUE;
81 | 
82 |             always_ff @(posedge clkb)
83 |                 dob_p2 <= dob_p1;
84 | 
85 |             always_comb dob = dob_p2;
86 |         end
87 |         // else
88 |         //     $fatal("OUTPUT_DELAY must be 0, 1, or 2"); unsupported by Quartus 17
89 |     end
90 |     else
91 |         always_comb dob = dob_p0;
92 |     endgenerate
93 | endmodule
94 | `default_nettype wire
95 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/mem_simple_dual_port_async_read.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: mem_simple_dual_port_async_read.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 19 May 2024
 6 | #
 7 | #   DESCRIPTION:
 8 | #   Quartus needs special syn_ramstyle = "MLAB, no_rw_check"
 9 | #   directive on RAM to place in MLAB (LUT RAM), otherwise registers get used for async read. Was not able
10 | #   to successfully include this in mem_simple_dual_port even with generate statements
11 | #   so created a separate module. Discovered this directive at https://community.intel.com/t5/Programmable-Devices/Synthesis-ramstyle/m-p/74079
12 | #
13 | #   CHANGE HISTORY:
14 | #   19 May 2024    Greg Taylor
15 | #       Initial version
16 | #
17 | #   Copyright (C) 2014 Greg Taylor 
18 | #
19 | #   This file is part of OPL3 FPGA.
20 | #
21 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
22 | #   it under the terms of the GNU Lesser General Public License as published by
23 | #   the Free Software Foundation, either version 3 of the License, or
24 | #   (at your option) any later version.
25 | #
26 | #   OPL3 FPGA is distributed in the hope that it will be useful,
27 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
28 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 | #   GNU Lesser General Public License for more details.
30 | #
31 | #   You should have received a copy of the GNU Lesser General Public License
32 | #   along with OPL3 FPGA.  If not, see .
33 | #
34 | #   Original Java Code:
35 | #   Copyright (C) 2008 Robson Cozendey 
36 | #
37 | #   Original C++ Code:
38 | #   Copyright (C) 2012  Steffen Ohrendorf 
39 | #
40 | #   Some code based on forum posts in:
41 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
42 | #   Copyright (C) 2010-2013 by carbon14 and opl3
43 | #
44 | #******************************************************************************/
45 | `timescale 1ns / 1ps
46 | `default_nettype none
47 | 
48 | module mem_simple_dual_port_async_read #(
49 |     parameter DATA_WIDTH = 0,
50 |     parameter DEPTH = 0,
51 |     parameter logic [DATA_WIDTH-1:0] DEFAULT_VALUE = 0
52 | ) (
53 |     input wire clka,
54 |     input wire wea,
55 |     input wire [$clog2(DEPTH)-1:0] addra,
56 |     input wire [$clog2(DEPTH)-1:0] addrb,
57 |     input wire [DATA_WIDTH-1:0] dia,
58 |     output logic [DATA_WIDTH-1:0] dob
59 | );
60 |     /* synthesis syn_ramstyle = "MLAB, no_rw_check" */
61 |     logic [DATA_WIDTH-1:0] ram [DEPTH-1:0] = '{default: DEFAULT_VALUE};
62 | 
63 |     always_ff @(posedge clka)
64 |         if (wea)
65 |             ram[addra] <= dia;
66 | 
67 |     always_comb dob = ram[addrb];
68 | endmodule
69 | `default_nettype wire


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/mem_single_bank.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: mem_single_bank.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 20 Sept 2025
 6 | #
 7 | #   DESCRIPTION:
 8 | #
 9 | #   CHANGE HISTORY:
10 | #   20 Sept 2025    Greg Taylor
11 | #       Initial version
12 | #
13 | #   Copyright (C) 2014 Greg Taylor 
14 | #
15 | #   This file is part of OPL3 FPGA.
16 | #
17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
18 | #   it under the terms of the GNU Lesser General Public License as published by
19 | #   the Free Software Foundation, either version 3 of the License, or
20 | #   (at your option) any later version.
21 | #
22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 | #   GNU Lesser General Public License for more details.
26 | #
27 | #   You should have received a copy of the GNU Lesser General Public License
28 | #   along with OPL3 FPGA.  If not, see .
29 | #
30 | #   Original Java Code:
31 | #   Copyright (C) 2008 Robson Cozendey 
32 | #
33 | #   Original C++ Code:
34 | #   Copyright (C) 2012  Steffen Ohrendorf 
35 | #
36 | #   Some code based on forum posts in:
37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
39 | #
40 | #******************************************************************************/
41 | `timescale 1ns / 1ps
42 | `default_nettype none
43 | 
44 | module mem_single_bank #(
45 |     parameter DATA_WIDTH = 0,
46 |     parameter DEPTH = 0,
47 |     parameter OUTPUT_DELAY = 0, // 0, 1, or 2
48 |     parameter DEFAULT_VALUE = 0
49 | ) (
50 |     input wire clk,
51 |     input wire wea,
52 |     input wire reb, // only used if OUTPUT_DELAY >0
53 |     input wire [$clog2(DEPTH)-1:0] addra,
54 |     input wire [$clog2(DEPTH)-1:0] addrb,
55 |     input wire [DATA_WIDTH-1:0] dia,
56 |     output logic [DATA_WIDTH-1:0] dob
57 | );
58 |     generate
59 |     if (OUTPUT_DELAY == 0)
60 |         mem_simple_dual_port_async_read #(
61 |             .DATA_WIDTH(DATA_WIDTH),
62 |             .DEPTH(DEPTH),
63 |             .DEFAULT_VALUE(DEFAULT_VALUE)
64 |         ) mem_bank (
65 |             .clka(clk),
66 |             .wea,
67 |             .addra,
68 |             .addrb,
69 |             .dia,
70 |             .dob
71 |         );
72 |     else
73 |         mem_simple_dual_port #(
74 |             .DATA_WIDTH(DATA_WIDTH),
75 |             .DEPTH(DEPTH),
76 |             .OUTPUT_DELAY(OUTPUT_DELAY),
77 |             .DEFAULT_VALUE(DEFAULT_VALUE)
78 |         ) mem_bank (
79 |             .clka(clk),
80 |             .clkb(clk),
81 |             .wea,
82 |             .reb,
83 |             .addra,
84 |             .addrb,
85 |             .dia,
86 |             .dob
87 |         );
88 |     endgenerate
89 | endmodule
90 | `default_nettype wire
91 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/mem_single_bank_reset.sv:
--------------------------------------------------------------------------------
  1 | /*******************************************************************************
  2 | #   +html+
  3 | #
  4 | #   FILENAME: mem_single_bank_reset.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 20 Sept 2025
  6 | #
  7 | #   DESCRIPTION:
  8 | #
  9 | #   CHANGE HISTORY:
 10 | #   20 Sept 2025    Greg Taylor
 11 | #       Initial version
 12 | #
 13 | #   Copyright (C) 2014 Greg Taylor 
 14 | #
 15 | #   This file is part of OPL3 FPGA.
 16 | #
 17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
 18 | #   it under the terms of the GNU Lesser General Public License as published by
 19 | #   the Free Software Foundation, either version 3 of the License, or
 20 | #   (at your option) any later version.
 21 | #
 22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
 23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25 | #   GNU Lesser General Public License for more details.
 26 | #
 27 | #   You should have received a copy of the GNU Lesser General Public License
 28 | #   along with OPL3 FPGA.  If not, see .
 29 | #
 30 | #   Original Java Code:
 31 | #   Copyright (C) 2008 Robson Cozendey 
 32 | #
 33 | #   Original C++ Code:
 34 | #   Copyright (C) 2012  Steffen Ohrendorf 
 35 | #
 36 | #   Some code based on forum posts in:
 37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
 39 | #
 40 | #******************************************************************************/
 41 | `timescale 1ns / 1ps
 42 | `default_nettype none
 43 | /* altera message_off 10230 */
 44 | 
 45 | module mem_single_bank_reset #(
 46 |     parameter DATA_WIDTH = 0,
 47 |     parameter DEPTH = 0,
 48 |     parameter OUTPUT_DELAY = 0, // 0, 1, or 2
 49 |     parameter DEFAULT_VALUE = '0
 50 | ) (
 51 |     input wire clk,
 52 |     input wire reset,
 53 |     input wire reset_mem,
 54 |     input wire wea,
 55 |     input wire reb, // only used if OUTPUT_DELAY >0
 56 |     input wire [$clog2(DEPTH)-1:0] addra,
 57 |     input wire [$clog2(DEPTH)-1:0] addrb,
 58 |     input wire [DATA_WIDTH-1:0] dia,
 59 |     output logic [DATA_WIDTH-1:0] dob,
 60 |     output logic reset_mem_done_pulse
 61 | );
 62 |     enum {
 63 |         IDLE,
 64 |         RESETTING
 65 |     } state = IDLE, next_state;
 66 | 
 67 |     struct packed {
 68 |         logic [$clog2(DEPTH)-1:0] addr;
 69 |         logic reset_mem_done;
 70 |     } self = 0, next_self;
 71 | 
 72 |     always_ff @(posedge clk) begin
 73 |         state <= next_state;
 74 |         self <= next_self;
 75 | 
 76 |         if (reset) begin
 77 |             state <= IDLE;
 78 |             self <= 0;
 79 |         end
 80 |     end
 81 | 
 82 |     always_comb begin
 83 |         next_state = state;
 84 |         next_self = self;
 85 | 
 86 |         reset_mem_done_pulse = self.reset_mem_done;
 87 | 
 88 |         unique case (state)
 89 |         IDLE: begin
 90 |             if (reset_mem)
 91 |                 next_state = RESETTING;
 92 |             next_self = 0;
 93 |         end
 94 |         RESETTING: begin
 95 |             if (self.addr == DEPTH - 1) begin
 96 |                 next_state = IDLE;
 97 |                 next_self.reset_mem_done = 1;
 98 |             end
 99 |             else
100 |                 next_self.addr = self.addr + 1;
101 |         end
102 |         endcase
103 |     end
104 | 
105 |     mem_single_bank #(
106 |         .DATA_WIDTH(DATA_WIDTH),
107 |         .DEPTH(DEPTH),
108 |         .OUTPUT_DELAY(OUTPUT_DELAY),
109 |         .DEFAULT_VALUE(DEFAULT_VALUE)
110 |     ) mem_single_bank (
111 |         .clk,
112 |         .wea(state == RESETTING || wea),
113 |         .reb,
114 |         .addra(state == RESETTING ? self.addr : addra),
115 |         .addrb,
116 |         .dia(state == RESETTING ? DEFAULT_VALUE : dia),
117 |         .dob
118 |     );
119 | endmodule
120 | `default_nettype wire
121 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/opl2_fpga.sv:
--------------------------------------------------------------------------------
  1 | /*******************************************************************************
  2 | #   +html+
  3 | #
  4 | #   FILENAME: opl3.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 24 Feb 2015
  6 | #
  7 | #   DESCRIPTION:
  8 | #
  9 | #   CHANGE HISTORY:
 10 | #   24 Feb 2015        Greg Taylor
 11 | #       Initial version
 12 | #
 13 | #   Copyright (C) 2014 Greg Taylor 
 14 | #
 15 | #   This file is part of OPL3 FPGA.
 16 | #
 17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
 18 | #   it under the terms of the GNU Lesser General Public License as published by
 19 | #   the Free Software Foundation, either version 3 of the License, or
 20 | #   (at your option) any later version.
 21 | #
 22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
 23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25 | #   GNU Lesser General Public License for more details.
 26 | #
 27 | #   You should have received a copy of the GNU Lesser General Public License
 28 | #   along with OPL3 FPGA.  If not, see .
 29 | #
 30 | #   Original Java Code:
 31 | #   Copyright (C) 2008 Robson Cozendey 
 32 | #
 33 | #   Original C++ Code:
 34 | #   Copyright (C) 2012  Steffen Ohrendorf 
 35 | #
 36 | #   Some code based on forum posts in:
 37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
 39 | #
 40 | #******************************************************************************/
 41 | `timescale 1ns / 1ps
 42 | `default_nettype none
 43 | 
 44 | module opl2_fpga
 45 |     import opl2_pkg::*;
 46 | (
 47 |     input wire clk, // opl3 master clk
 48 |     input wire clk_host, // if different from clk, set INSTANTIATE_MASTER_HOST_CDC to 1
 49 |     input wire clk_dac, // only used if INSTANTIATE_SAMPLE_DAC_CDC is set
 50 |     input wire ic_n, // reset, clk_host domain
 51 |     input wire cs_n, // clk_host domain
 52 |     input wire rd_n, // clk_host domain
 53 |     input wire wr_n, // clk_host domain
 54 |     input wire address, // clk_host domain
 55 |     input wire [REG_FILE_DATA_WIDTH-1:0] din, // clk_host domain
 56 |     output logic [REG_FILE_DATA_WIDTH-1:0] dout, // clk_host domain
 57 |     output logic sample_valid, // clk domain: if INSTANTIATE_SAMPLE_DAC_CDC ? clk_audio : clk
 58 |     output logic signed [DAC_OUTPUT_WIDTH-1:0] sample, // clk domain: if INSTANTIATE_SAMPLE_DAC_CDC ? clk_audio : clk
 59 |     output logic [NUM_LEDS-1:0] led, // master clk domain
 60 |     output logic irq_n // clk_host domain
 61 | );
 62 |     logic reset;
 63 |     logic sample_clk_en;
 64 |     opl2_reg_wr_t opl2_reg_wr;
 65 |     logic [REG_FILE_DATA_WIDTH-1:0] status;
 66 |     logic force_timer_overflow;
 67 | 
 68 |     reset_sync reset_sync (
 69 |         .clk,
 70 |         .arst_n(ic_n),
 71 |         .reset
 72 |     );
 73 | 
 74 |     host_if host_if (
 75 |         .*
 76 |     );
 77 | 
 78 |     // pulse once per sample period
 79 |     clk_div #(
 80 |         .CLK_DIV_COUNT(CLK_DIV_COUNT)
 81 |     ) sample_clk_gen (
 82 |         .clk_en(sample_clk_en),
 83 |         .*
 84 |     );
 85 | 
 86 |     channels channels (
 87 |         .*
 88 |     );
 89 | 
 90 |     leds leds (
 91 |         .*
 92 |     );
 93 | 
 94 |     /*
 95 |      * If we don't need timers, don't instantiate to save area
 96 |      */
 97 |     generate
 98 |     if (INSTANTIATE_TIMERS)
 99 |         timers timers (
100 |             .*
101 |         );
102 |     else
103 |         always_comb
104 |             irq_n = 1;
105 |     endgenerate
106 | endmodule
107 | `default_nettype wire
108 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/pipeline_sr.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: pipeline_sr.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 1 April 2024
 6 | #
 7 | #   DESCRIPTION:
 8 | #
 9 | #   CHANGE HISTORY:
10 | #   1 April 2024    Greg Taylor
11 | #       Initial version
12 | #
13 | #   Copyright (C) 2014 Greg Taylor 
14 | #
15 | #   This file is part of OPL3 FPGA.
16 | #
17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
18 | #   it under the terms of the GNU Lesser General Public License as published by
19 | #   the Free Software Foundation, either version 3 of the License, or
20 | #   (at your option) any later version.
21 | #
22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 | #   GNU Lesser General Public License for more details.
26 | #
27 | #   You should have received a copy of the GNU Lesser General Public License
28 | #   along with OPL3 FPGA.  If not, see .
29 | #
30 | #   Original Java Code:
31 | #   Copyright (C) 2008 Robson Cozendey 
32 | #
33 | #   Original C++ Code:
34 | #   Copyright (C) 2012  Steffen Ohrendorf 
35 | #
36 | #   Some code based on forum posts in:
37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
39 | #
40 | #******************************************************************************/
41 | `timescale 1ns / 1ps
42 | `default_nettype none
43 | 
44 | module pipeline_sr #(
45 |     parameter DATA_WIDTH = 1,
46 |     parameter STARTING_CYCLE = 1,
47 |     parameter ENDING_CYCLE = 1,
48 |     parameter POR_VALUE = 0 // power on reset value of pipeline registers
49 | ) (
50 |     input wire clk,
51 |     input wire [DATA_WIDTH-1:0] in,
52 |     output logic [ENDING_CYCLE:STARTING_CYCLE] [DATA_WIDTH-1:0] out = '{default: POR_VALUE}
53 | );
54 |     always_ff @(posedge clk) begin
55 |         out <= out << DATA_WIDTH;
56 |         out[STARTING_CYCLE] <= in;
57 |     end
58 | endmodule
59 | `default_nettype wire


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/reset_sync.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: reset_sync.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 21 July 2009
 6 | #
 7 | #   DESCRIPTION:
 8 | #   To be used as the source for a local reset; takes global asynchronous reset
 9 | #   as input. Ensures that deassertion of the local reset signal is synchronous
10 | #   to the local clock signal. Assertion of local reset remains asynchronous.
11 | #   Local reset remains asserted for 2 clock cycles after global asynchronous
12 | #   reset is deasserted. Taken from Xilinx Whitepaper 272.
13 | #   http://www.xilinx.com/support/documentation/white_papers/wp272.pdf
14 | #
15 | #   CHANGE HISTORY:
16 | #   21 July 2009        Greg Taylor
17 | #       Initial version
18 | #
19 | #   Copyright (C) 2014 Greg Taylor 
20 | #
21 | #   This file is part of OPL3 FPGA.
22 | #
23 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
24 | #   it under the terms of the GNU Lesser General Public License as published by
25 | #   the Free Software Foundation, either version 3 of the License, or
26 | #   (at your option) any later version.
27 | #
28 | #   OPL3 FPGA is distributed in the hope that it will be useful,
29 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
30 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31 | #   GNU Lesser General Public License for more details.
32 | #
33 | #   You should have received a copy of the GNU Lesser General Public License
34 | #   along with OPL3 FPGA.  If not, see .
35 | #
36 | #   Original Java Code:
37 | #   Copyright (C) 2008 Robson Cozendey 
38 | #
39 | #   Original C++ Code:
40 | #   Copyright (C) 2012  Steffen Ohrendorf 
41 | #
42 | #   Some code based on forum posts in:
43 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
44 | #   Copyright (C) 2010-2013 by carbon14 and opl3
45 | #
46 | #******************************************************************************/
47 | `timescale 1ns / 1ps
48 | `default_nettype none
49 | 
50 | module reset_sync (
51 |     input wire clk, // clock domain of the local logic
52 |     input wire arst_n, // global asynchronous active-low reset signal
53 |     output logic reset   // synchronous active-high local reset
54 | );
55 |     logic r0 = 1, r1 = 1, r2 = 1;
56 | 
57 |     always_ff @(posedge clk or negedge arst_n)
58 |         if (!arst_n) begin
59 |             r0 <= 1;
60 |             r1 <= 1;
61 |             r2 <= 1;
62 |         end
63 |         else begin
64 |             r0 <= 0;
65 |             r1 <= r0;
66 |             r2 <= r1;
67 |         end
68 | 
69 |     always_comb reset = r2;
70 | endmodule
71 | `default_nettype wire
72 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/synchronizer.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #
 3 | #   FILENAME: synchronizer.sv
 4 | #   AUTHOR: Greg Taylor     CREATION DATE: 31 March 2009
 5 | #
 6 | #   DESCRIPTION: Synchronize signal across time domains (2 stage)
 7 | #
 8 | #   CHANGE HISTORY:
 9 | #   31 March 2009        Greg Taylor
10 | #       Initial version
11 | #
12 | #	13 March 2013		 Greg Taylor
13 | #		Added SystemVerilog assertions to check for incorrect usage
14 | #		From:
15 | #		Mark Litterick, “Pragmatic Simulation-Based Verification of Clock Domain
16 | #		Crossing Signals and Jitter Using SystemVerilog Assertions,” DVCon 2006
17 | #  		www.verilab.com/files/sva_cdc_paper_dvcon2006.pdf
18 | #
19 | #******************************************************************************/
20 | `timescale 1ns / 1ps
21 | `default_nettype none
22 | 
23 | module synchronizer #(
24 |     parameter DATA_WIDTH = 1
25 | ) (
26 |     input wire clk,   // clock domain of out
27 |     input wire [DATA_WIDTH-1:0] in,
28 |     output logic [DATA_WIDTH-1:0] out
29 | );
30 |     logic [1:0] [DATA_WIDTH-1:0] sync_regs = 0;
31 | 
32 |     always_ff @(posedge clk)
33 |     	{sync_regs[1], sync_regs[0]} <= {sync_regs[0], in};
34 | 
35 |     always_comb out = sync_regs[1];
36 | endmodule
37 | `default_nettype wire
38 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/timer.sv:
--------------------------------------------------------------------------------
  1 | /*******************************************************************************
  2 | #   +html+
  3 | #
  4 | #   FILENAME: timer.sv
  5 | #   AUTHOR: Greg Taylor     CREATION DATE: 11 Jan 2015
  6 | #
  7 | #   DESCRIPTION:
  8 | #
  9 | #   CHANGE HISTORY:
 10 | #   11 Jan 2015    Greg Taylor
 11 | #       Initial version
 12 | #
 13 | #   Copyright (C) 2015 Greg Taylor 
 14 | #
 15 | #   This file is part of OPL3 FPGA.
 16 | #
 17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
 18 | #   it under the terms of the GNU Lesser General Public License as published by
 19 | #   the Free Software Foundation, either version 3 of the License, or
 20 | #   (at your option) any later version.
 21 | #
 22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
 23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25 | #   GNU Lesser General Public License for more details.
 26 | #
 27 | #   You should have received a copy of the GNU Lesser General Public License
 28 | #   along with OPL3 FPGA.  If not, see .
 29 | #
 30 | #   Original Java Code:
 31 | #   Copyright (C) 2008 Robson Cozendey 
 32 | #
 33 | #   Original C++ Code:
 34 | #   Copyright (C) 2012  Steffen Ohrendorf 
 35 | #
 36 | #   Some code based on forum posts in:
 37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
 39 | #
 40 | #******************************************************************************/
 41 | `timescale 1ns / 1ps
 42 | `default_nettype none
 43 | /* altera message_off 10230 */
 44 | 
 45 | module timer
 46 |     import opl2_pkg::*;
 47 | #(
 48 |     parameter real TIMER_TICK_INTERVAL = 0 // time in seconds
 49 | ) (
 50 |     input wire clk,
 51 |     input wire reset,
 52 |     input wire [REG_TIMER_WIDTH-1:0] timer_reg,
 53 |     input wire start_timer,
 54 |     output logic timer_overflow_pulse = 0
 55 | );
 56 |     localparam int TICK_TIMER_COUNT_VALUE = CLK_FREQ*TIMER_TICK_INTERVAL;
 57 | 
 58 |     logic [$clog2(TICK_TIMER_COUNT_VALUE)-1:0] tick_counter = 0;
 59 |     logic tick_pulse = 0;
 60 |     logic [REG_TIMER_WIDTH-1:0] timer = 0;
 61 |     logic start_timer_set_pulse;
 62 | 
 63 |     /*
 64 |      * Detect when start_timer is initially set, use it to reset the timer value
 65 |      * back to timer_reg. Also if start_timer is not set clock will not run.
 66 |      */
 67 |     edge_detector #(
 68 |         .EDGE_LEVEL(1),
 69 |         .CLK_DLY(0)
 70 |     ) start_timer_edge_detect (
 71 |         .clk(clk),
 72 |         .clk_en(1'b1),
 73 |         .in(start_timer),
 74 |         .edge_detected(start_timer_set_pulse)
 75 |     );
 76 | 
 77 |     always_comb tick_pulse = tick_counter == TICK_TIMER_COUNT_VALUE - 1;
 78 | 
 79 |     always_ff @(posedge clk) begin
 80 |         if (start_timer) begin
 81 |             if (tick_pulse || start_timer_set_pulse)
 82 |                 tick_counter <= 0;
 83 |             else
 84 |                 tick_counter <= tick_counter + 1;
 85 |         end
 86 | 
 87 |         if (reset)
 88 |             tick_counter <= 0;
 89 |     end
 90 | 
 91 |     /*
 92 |      * Timer gets set to timer_reg upon overflow
 93 |      */
 94 |     always_ff @(posedge clk) begin
 95 |         if (start_timer_set_pulse)
 96 |             timer <= timer_reg;
 97 |         else if (tick_pulse) begin
 98 |             if (timer == 2**REG_TIMER_WIDTH - 1)
 99 |                 timer <= timer_reg;
100 |             else
101 |                 timer <= timer + 1;
102 |         end
103 | 
104 |         if (reset)
105 |             timer <= 0;
106 |     end
107 | 
108 |     always_ff @(posedge clk)
109 |         timer_overflow_pulse <= (timer == 2**REG_TIMER_WIDTH - 1) && tick_pulse;
110 | 
111 | endmodule
112 | `default_nettype wire
113 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/tremolo.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: tremolo.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 2 Nov 2014
 6 | #
 7 | #   DESCRIPTION:
 8 | #
 9 | #   CHANGE HISTORY:
10 | #   2 Nov 2014    Greg Taylor
11 | #       Initial version
12 | #
13 | #   Copyright (C) 2014 Greg Taylor 
14 | #
15 | #   This file is part of OPL3 FPGA.
16 | #
17 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
18 | #   it under the terms of the GNU Lesser General Public License as published by
19 | #   the Free Software Foundation, either version 3 of the License, or
20 | #   (at your option) any later version.
21 | #
22 | #   OPL3 FPGA is distributed in the hope that it will be useful,
23 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 | #   GNU Lesser General Public License for more details.
26 | #
27 | #   You should have received a copy of the GNU Lesser General Public License
28 | #   along with OPL3 FPGA.  If not, see .
29 | #
30 | #   Original Java Code:
31 | #   Copyright (C) 2008 Robson Cozendey 
32 | #
33 | #   Original C++ Code:
34 | #   Copyright (C) 2012  Steffen Ohrendorf 
35 | #
36 | #   Some code based on forum posts in:
37 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
38 | #   Copyright (C) 2010-2013 by carbon14 and opl3
39 | #
40 | #******************************************************************************/
41 | `timescale 1ns / 1ps
42 | `default_nettype none
43 | /* altera message_off 10230 */
44 | 
45 | module tremolo
46 |     import opl2_pkg::*;
47 | (
48 |     input wire clk,
49 |     input wire sample_clk_en,
50 |     input wire [OP_NUM_WIDTH-1:0] op_num,
51 |     input wire dam, // depth of tremolo
52 |     output logic [AM_VAL_WIDTH-1:0] am_val_p2 = 0
53 | );
54 |     localparam PIPELINE_DELAY = 2;
55 | 
56 |     logic [TREMOLO_INDEX_WIDTH-1:0] tremolo_index_p1 = '0;
57 |     logic [TREMOLO_INDEX_WIDTH-8-1:0] am_val_tmp0_p1;
58 |     logic [AM_VAL_WIDTH-1:0] am_val_tmp1_p1;
59 |     logic dam_p1 = 0;
60 | 
61 |     /*
62 |      * Low-Frequency Oscillator (LFO)
63 |      * 3.7 Hz (Sample Freq/2**14)
64 |      */
65 |     always_ff @(posedge clk)
66 |         if (sample_clk_en && op_num == 0)
67 |             if (tremolo_index_p1 == TREMOLO_MAX_COUNT - 1)
68 |                 tremolo_index_p1 <= 0;
69 |             else
70 |                 tremolo_index_p1 <= tremolo_index_p1 + 1;
71 | 
72 |     always_comb am_val_tmp0_p1 = tremolo_index_p1 >> 8;
73 | 
74 |     always_comb
75 |         if (am_val_tmp0_p1 > 26)
76 |             am_val_tmp1_p1 = 2*26 + ~am_val_tmp0_p1;
77 |         else
78 |             am_val_tmp1_p1 = am_val_tmp0_p1;
79 | 
80 |     always_ff @(posedge clk) begin
81 |         dam_p1 <= dam;
82 | 
83 |         if (dam_p1)
84 |             am_val_p2 <= am_val_tmp1_p1;
85 |         else
86 |             am_val_p2 <= am_val_tmp1_p1 >> 2;
87 |     end
88 | endmodule
89 | `default_nettype wire
90 | 


--------------------------------------------------------------------------------
/rtl/opl2_fpga_MiSTer/src/vibrato.sv:
--------------------------------------------------------------------------------
 1 | /*******************************************************************************
 2 | #   +html+
 3 | #
 4 | #   FILENAME: vibrato.sv
 5 | #   AUTHOR: Greg Taylor     CREATION DATE: 13 Oct 2014
 6 | #
 7 | #   DESCRIPTION:
 8 | #   Prepare the phase increment for the NCO (calc multiplier and vibrato)
 9 | #
10 | #   CHANGE HISTORY:
11 | #   13 Oct 2014    Greg Taylor
12 | #       Initial version
13 | #
14 | #   Copyright (C) 2014 Greg Taylor 
15 | #
16 | #   This file is part of OPL3 FPGA.
17 | #
18 | #   OPL3 FPGA is free software: you can redistribute it and/or modify
19 | #   it under the terms of the GNU Lesser General Public License as published by
20 | #   the Free Software Foundation, either version 3 of the License, or
21 | #   (at your option) any later version.
22 | #
23 | #   OPL3 FPGA is distributed in the hope that it will be useful,
24 | #   but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 | #   GNU Lesser General Public License for more details.
27 | #
28 | #   You should have received a copy of the GNU Lesser General Public License
29 | #   along with OPL3 FPGA.  If not, see .
30 | #
31 | #   Original Java Code:
32 | #   Copyright (C) 2008 Robson Cozendey 
33 | #
34 | #   Original C++ Code:
35 | #   Copyright (C) 2012  Steffen Ohrendorf 
36 | #
37 | #   Some code based on forum posts in:
38 | #   http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
39 | #   Copyright (C) 2010-2013 by carbon14 and opl3
40 | #
41 | #******************************************************************************/
42 | `timescale 1ns / 1ps
43 | `default_nettype none
44 | /* altera message_off 10230 */
45 | 
46 | module vibrato
47 |     import opl2_pkg::*;
48 | (
49 |     input wire clk,
50 |     input wire sample_clk_en,
51 |     input wire [REG_FNUM_WIDTH-1:0] fnum,
52 |     input wire dvb,
53 |     output logic [VIB_VAL_WIDTH-1:0] vib_val_p2 = 0
54 | );
55 |     localparam VIBRATO_INDEX_WIDTH = 13;
56 | 
57 |     logic [VIBRATO_INDEX_WIDTH-1:0] vibrato_index_p1 = 0;
58 |     logic [VIB_VAL_WIDTH-1:0] delta0_p1;
59 |     logic [VIB_VAL_WIDTH-1:0] delta1_p1;
60 |     logic [VIB_VAL_WIDTH-1:0] delta2_p1;
61 |     logic [REG_FNUM_WIDTH-1:0] fnum_p1 = 0;
62 |     logic dvb_p1 = 0;
63 | 
64 |     always_ff @(posedge clk) begin
65 |         fnum_p1 <= fnum;
66 |         dvb_p1 <= dvb;
67 |     end
68 | 
69 |     /*
70 |      * Low-Frequency Oscillator (LFO)
71 |      * 6.07Hz (Sample Freq/2**13)
72 |      */
73 |     always_ff @(posedge clk)
74 |         if (sample_clk_en)
75 |             vibrato_index_p1 <= vibrato_index_p1 + 1;
76 | 
77 |     always_comb delta0_p1 = fnum_p1 >> 7;
78 |     always_comb delta1_p1 = ((vibrato_index_p1 >> 10) & 3) == 3 ? delta0_p1 >> 1 : delta0_p1;
79 |     always_comb delta2_p1 = !dvb_p1 ? delta1_p1 >> 1 : delta1_p1;
80 | 
81 |     always_ff @(posedge clk)
82 |         vib_val_p2 <= ((vibrato_index_p1 >> 10) & 4) != 0 ? ~delta2_p1 : delta2_p1;
83 | endmodule
84 | `default_nettype wire
85 | 


--------------------------------------------------------------------------------
/rtl/pause.v:
--------------------------------------------------------------------------------
  1 | //============================================================================
  2 | //  Generic pause handling for MiSTer cores.
  3 | //
  4 | //  https://github.com/JimmyStones/Pause_MiSTer
  5 | //
  6 | //  Copyright (c) 2021 Jim Gregory
  7 | //
  8 | //  This program is free software; you can redistribute it and/or modify it
  9 | //  under the terms of the GNU General Public License as published by the Free
 10 | //  Software Foundation; either version 3 of the License, or (at your option)
 11 | //  any later version.
 12 | //
 13 | //  This program is distributed in the hope that it will be useful, but WITHOUT
 14 | //  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 15 | //  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 16 | //  more details.
 17 | //
 18 | //  You should have received a copy of the GNU General Public License along
 19 | //  with this program; if not, write to the Free Software Foundation, Inc.,
 20 | //  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 21 | //============================================================================
 22 | /*
 23 |  Features:
 24 |   - Pause can be triggered by user input, hiscore module or OSD opening (optionally controlled by setting in OSD)
 25 |   - When paused the RGB outputs will be halved after 10 seconds to reduce burn-in (optionally controlled by setting in OSD)
 26 |   - Reset signal will cancel user triggered pause
 27 |   
 28 |  Version history:
 29 |  0001 - 2021-03-15 -	First marked release
 30 |  0002 - 2021-08-28 -	Add optional output of dim_video signal (currently used by Galaga)
 31 | ============================================================================
 32 | */
 33 | module pause #(
 34 | 	parameter						RW=8,						// Width of red channel
 35 | 	parameter						GW=8,						// Width of green channel
 36 | 	parameter						BW=8,						// Width of blue channel
 37 | 	parameter						CLKSPD = 12				// Main clock speed in MHz
 38 | )
 39 | (
 40 | 	input								clk_sys,					// Core system clock (should match HPS module)
 41 | 	input								reset,					// CPU reset signal (active-high)
 42 | 	input								user_button,			// User pause button signal (active-high)
 43 | 	input								pause_request,			// Pause requested by other code (active-high)
 44 | 	input [1:0]						options,					// Pause options from OSD 
 45 | 																	//   [0] = pause in OSD (active-high)
 46 | 																	//   [1] = dim video (active-high)
 47 | 	input 							OSD_STATUS,				// OSD is open (active-high)
 48 | 	input	[(RW-1):0]				r,							// Red channel
 49 | 	input	[(GW-1):0]				g,							// Green channel
 50 | 	input	[(BW-1):0]				b,							// Blue channel
 51 | 
 52 | 	output							pause_cpu,				// Pause signal to CPU (active-high)
 53 | `ifdef PAUSE_OUTPUT_DIM
 54 | 	output							dim_video,				// Dim video requested (active-high)
 55 | `endif
 56 | 	output [(RW+GW+BW-1):0]		rgb_out					// RGB output to arcade_video module
 57 | 
 58 | );
 59 | 
 60 | // Option constants
 61 | localparam 		pause_in_osd	= 1'b0;
 62 | localparam 		dim_video_timer= 1'b1;
 63 | 
 64 | reg				pause_toggle	= 1'b0;					// User paused (active-high)
 65 | reg [31:0]		pause_timer		= 1'b0;					// Time since pause
 66 | reg [31:0]		dim_timeout		= (CLKSPD*10000000);	// Time until video output dim (10 seconds @ CLKSPD Mhz)
 67 | 
 68 | `ifndef PAUSE_OUTPUT_DIM
 69 | wire 			dim_video;				 				// Dim video requested (active-high)
 70 | `endif
 71 | 
 72 | assign pause_cpu = (pause_request | pause_toggle  | (OSD_STATUS & options[pause_in_osd])) & !reset;
 73 | assign dim_video = (pause_timer >= dim_timeout);
 74 | 
 75 | always @(posedge clk_sys) begin
 76 | 
 77 | 	// Track user pause button down
 78 | 	reg user_button_last;
 79 | 	user_button_last <= user_button;
 80 |     
 81 | 	if (!user_button_last & user_button) begin
 82 |         pause_toggle <= ~pause_toggle;
 83 |     end
 84 | 
 85 | 	// Clear user pause on reset
 86 | 	if (pause_toggle & reset) begin
 87 |         pause_toggle <= 0;
 88 |     end
 89 | 
 90 | 	if (pause_cpu & options[dim_video_timer]) begin
 91 | 		// Track pause duration for video dim
 92 | 		if (pause_timer> 2,g >> 2, b >> 2} : {r,g,b};
102 | 
103 | endmodule


--------------------------------------------------------------------------------
/rtl/pll/pll_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*"
2 |  
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/pll/pll_0002.v:
--------------------------------------------------------------------------------
 1 | `timescale 1ns/10ps
 2 | module  pll_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 'outclk1'
14 | 	output wire outclk_1,
15 | 
16 | 	// interface 'locked'
17 | 	output wire locked
18 | );
19 | 
20 | 	altera_pll #(
21 | 		.fractional_vco_multiplier("false"),
22 | 		.reference_clock_frequency("50.0 MHz"),
23 | 		.operation_mode("direct"),
24 | 		.number_of_clocks(2),
25 | 		.output_clock_frequency0("70.000000 MHz"),
26 | 		.phase_shift0("0 ps"),
27 | 		.duty_cycle0(50),
28 | 		.output_clock_frequency1("70.000000 MHz"),
29 | 		.phase_shift1("-3571 ps"),
30 | 		.duty_cycle1(50),
31 | 		.output_clock_frequency2("0 MHz"),
32 | 		.phase_shift2("0 ps"),
33 | 		.duty_cycle2(50),
34 | 		.output_clock_frequency3("0 MHz"),
35 | 		.phase_shift3("0 ps"),
36 | 		.duty_cycle3(50),
37 | 		.output_clock_frequency4("0 MHz"),
38 | 		.phase_shift4("0 ps"),
39 | 		.duty_cycle4(50),
40 | 		.output_clock_frequency5("0 MHz"),
41 | 		.phase_shift5("0 ps"),
42 | 		.duty_cycle5(50),
43 | 		.output_clock_frequency6("0 MHz"),
44 | 		.phase_shift6("0 ps"),
45 | 		.duty_cycle6(50),
46 | 		.output_clock_frequency7("0 MHz"),
47 | 		.phase_shift7("0 ps"),
48 | 		.duty_cycle7(50),
49 | 		.output_clock_frequency8("0 MHz"),
50 | 		.phase_shift8("0 ps"),
51 | 		.duty_cycle8(50),
52 | 		.output_clock_frequency9("0 MHz"),
53 | 		.phase_shift9("0 ps"),
54 | 		.duty_cycle9(50),
55 | 		.output_clock_frequency10("0 MHz"),
56 | 		.phase_shift10("0 ps"),
57 | 		.duty_cycle10(50),
58 | 		.output_clock_frequency11("0 MHz"),
59 | 		.phase_shift11("0 ps"),
60 | 		.duty_cycle11(50),
61 | 		.output_clock_frequency12("0 MHz"),
62 | 		.phase_shift12("0 ps"),
63 | 		.duty_cycle12(50),
64 | 		.output_clock_frequency13("0 MHz"),
65 | 		.phase_shift13("0 ps"),
66 | 		.duty_cycle13(50),
67 | 		.output_clock_frequency14("0 MHz"),
68 | 		.phase_shift14("0 ps"),
69 | 		.duty_cycle14(50),
70 | 		.output_clock_frequency15("0 MHz"),
71 | 		.phase_shift15("0 ps"),
72 | 		.duty_cycle15(50),
73 | 		.output_clock_frequency16("0 MHz"),
74 | 		.phase_shift16("0 ps"),
75 | 		.duty_cycle16(50),
76 | 		.output_clock_frequency17("0 MHz"),
77 | 		.phase_shift17("0 ps"),
78 | 		.duty_cycle17(50),
79 | 		.pll_type("General"),
80 | 		.pll_subtype("General")
81 | 	) altera_pll_i (
82 | 		.rst	(rst),
83 | 		.outclk	({outclk_1, outclk_0}),
84 | 		.locked	(locked),
85 | 		.fboutclk	( ),
86 | 		.fbclk	(1'b0),
87 | 		.refclk	(refclk)
88 | 	);
89 | endmodule
90 | 
91 | 


--------------------------------------------------------------------------------
/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/t80/T80.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80pa.vhd ]
2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vhd ]
3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ]
4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ]
5 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ]
6 | 


--------------------------------------------------------------------------------
/rtl/video_timing.v:
--------------------------------------------------------------------------------
  1 | 
  2 | module video_timing
  3 | (
  4 |     input clk,
  5 |     input reset,
  6 | 
  7 |     input [15:0] crtc0,
  8 |     input [15:0] crtc1,
  9 |     input [15:0] crtc2,
 10 |     input [15:0] crtc3,
 11 | 
 12 |     input refresh_mod,
 13 | 
 14 |     input signed [3:0] hs_offset,
 15 |     input signed [3:0] vs_offset,
 16 | 
 17 |     input signed [3:0] hs_width,
 18 |     input signed [3:0] vs_width,
 19 | 
 20 |     output [8:0] hc,
 21 |     output [8:0] vc,
 22 | 
 23 |     output reg  hbl_delay,
 24 |     output reg  hsync,
 25 |     output reg  vbl,
 26 |     output reg  vsync
 27 | );
 28 | 
 29 | // 320x240 timings
 30 | 
 31 | wire [8:0] HBL_CNT = { crtc0[15:8]-1, 1'b1 };
 32 | wire [8:0] HTOTAL  = { crtc0[7:0], 1'b1 };                                                           // horz total clocks and blank start
 33 | wire [8:0] HBSTART = HTOTAL - HBL_CNT;                                                               // horz blank begin
 34 | 
 35 | wire [8:0] HSSTART = 360 + $signed(hs_offset) - (refresh_mod ? 4'd4 : 3'd0);                         // horz sync begin
 36 | wire [8:0] HSEND   = 380 + $signed(hs_offset) + $signed(hs_offset) + (refresh_mod ? 4'd4 : 3'd0);    // horz sync end
 37 | 
 38 | wire [8:0] VBL_CNT = { crtc2[15:8], 1'b1 };
 39 | wire [8:0] VTOTAL  = { crtc2[7:0], 1'b1 };
 40 | wire [8:0] VBSTART = VTOTAL - VBL_CNT;
 41 | 
 42 | wire [8:0] VSSTART = 250 + $signed(vs_offset);
 43 | wire [8:0] VSEND   = 253 + $signed(vs_offset) + $signed(vs_width);
 44 | 
 45 | reg hbl;
 46 | 
 47 | reg [8:0] v;
 48 | reg [8:0] h;
 49 | 
 50 | assign hc = h;
 51 | 
 52 | assign vc = v;
 53 | 
 54 | 
 55 | reg [1:0] vtotal_282_flag;
 56 | always @ (posedge clk) begin // Set horizontal lines flag for 60Hz
 57 |     if (VTOTAL == 269)
 58 |         vtotal_282_flag <= 0;
 59 |     else
 60 |         vtotal_282_flag <= 1;
 61 | end
 62 | 
 63 | always @ (posedge clk) begin
 64 | 
 65 |     if (reset) begin
 66 |         h <= 0;
 67 |         v <= 0;
 68 | 
 69 |         hbl <= 0;
 70 |         hbl_delay <= 0;
 71 |         vbl <= 0;
 72 |         hsync <= 0;
 73 |         vsync <= 0;
 74 |     end else begin
 75 |         // counter
 76 |         hbl_delay <= hbl;
 77 |         if (h == HTOTAL - (refresh_mod ? 4'd5 : 3'd0)) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq)
 78 |             h <= 0;
 79 |             hbl <= 0;
 80 | 
 81 |             // v signals
 82 |             if ( v == VBSTART-1 ) begin
 83 |                 vbl <= 1;
 84 |             end else if ( v == VSSTART ) begin
 85 |                 vsync <= 0;
 86 |             end else if ( v == VSEND ) begin
 87 |                 vsync <= 1;
 88 |             end
 89 | 
 90 |             if (v == VTOTAL - (refresh_mod ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) begin // 282 Lines standard (263 Lines for 60Hz)
 91 |                 v <= 0;
 92 |                 vbl <= 0;
 93 |             end else begin
 94 |                 v <= v + 1'd1;
 95 |             end
 96 |         end else begin
 97 |             h <= h + 1'd1;
 98 |         end
 99 | 
100 |         // h signals
101 |         if ( h == HBSTART-1 ) begin
102 |             hbl <= 1;
103 |         end else if ( h == HSSTART ) begin
104 |             hsync <= 0;
105 |         end else if ( h == HSEND ) begin
106 |             hsync <= 1;
107 |         end
108 |     end
109 | end
110 | 
111 | endmodule
112 | 


--------------------------------------------------------------------------------
/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'b0, 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)
106 | (
107 | 	input        reset,
108 | 	input        clk,
109 | 
110 | 	inout  [3:0] ADC_BUS,
111 | 	output reg   dout,
112 | 	output       active
113 | );
114 | 
115 | wire [11:0] adc_data;
116 | wire        adc_sync;
117 | ltc2308 #(1, 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;
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       sd_cd,
 12 | 
 13 | 	output		     scl,
 14 | 	inout 		     sda
 15 | );
 16 | 
 17 | 
 18 | reg        start = 0;
 19 | wire       ready;
 20 | wire       error;
 21 | reg        rw;
 22 | wire [7:0] dout;
 23 | reg [15:0] din;
 24 | 
 25 | i2c #(50_000_000, 500_000) i2c
 26 | (
 27 | 	.CLK(clk),
 28 | 	.START(start),
 29 | 	.READ(rw),
 30 | 	.I2C_ADDR('h20),
 31 | 	.I2C_WLEN(1),
 32 | 	.I2C_WDATA1(din[15:8]),
 33 | 	.I2C_WDATA2(din[7:0]),
 34 | 	.I2C_RDATA(dout),
 35 | 	.END(ready),
 36 | 	.ACK(error),
 37 | 	.I2C_SCL(scl),
 38 |  	.I2C_SDA(sda)
 39 | );
 40 | 
 41 | always@(posedge clk) begin
 42 | 	reg  [3:0] idx = 0;
 43 | 	reg  [1:0] state = 0;
 44 | 	reg [15:0] timeout = 0;
 45 | 
 46 | 	if(~&timeout) begin
 47 | 		timeout <= timeout + 1'd1;
 48 | 		start   <= 0;
 49 | 		state   <= 0;
 50 | 		idx     <= 0;
 51 | 		btn     <= 0;
 52 | 		rw      <= 0;
 53 | 		sd_cd   <= 1;
 54 | 	end
 55 | 	else begin
 56 | 		if(~&init_data[idx]) begin
 57 | 			case(state)
 58 | 			0:	begin
 59 | 					start <= 1;
 60 | 					state <= 1;
 61 | 					din   <= init_data[idx];
 62 | 				end
 63 | 			1: if(~ready) state <= 2;
 64 | 			2:	begin
 65 | 					start <= 0;
 66 | 					if(ready) begin
 67 | 						state <= 0;
 68 | 						if(!error) idx <= idx + 1'd1;
 69 | 					end
 70 | 				end
 71 | 			endcase
 72 | 		end
 73 | 		else begin
 74 | 			case(state)
 75 | 			0:	begin
 76 | 					start <= 1;
 77 | 					state <= 1;
 78 | 					din   <= {8'h09,5'b00000,led};
 79 | 				end
 80 | 			1: if(~ready) state <= 2;
 81 | 			2:	begin
 82 | 					start <= 0;
 83 | 					if(ready) begin
 84 | 						state <= 0;
 85 | 						rw <= 0;
 86 | 						if(!error) begin
 87 | 							if(rw) {sd_cd, btn} <= {dout[7], dout[5:3]};
 88 | 							rw <= ~rw;
 89 | 						end
 90 | 					end
 91 | 				end
 92 | 			endcase
 93 | 		end
 94 | 	end
 95 | end
 96 | 
 97 | wire [15:0] init_data[12] = 
 98 | '{
 99 | 	16'h00F8,
100 | 	16'h0138,
101 | 	16'h0200,
102 | 	16'h0300,
103 | 	16'h0400,
104 | 	16'h0524,
105 | 	16'h06FF,
106 | 	16'h0700,
107 | 	16'h0800,
108 | 	16'h0900,
109 | 	16'h0A00,
110 | 	16'hFFFF
111 | };
112 | 
113 | endmodule
114 | 


--------------------------------------------------------------------------------
/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_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 VERILOG_FILE       [file join $::quartus(qip_path) pll_cfg.v ]
5 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_core.v ]
6 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_top.v ]
7 | 


--------------------------------------------------------------------------------
/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/pll_q20.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       [2: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 [2: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) begin
26 | //                scanline <= 0;
27 | //            end
28 | //		end else begin
29 |             scanline <= scanline ^ scanlines;
30 | //        end
31 | 	end
32 | 	if (old_vs && ~vs_in) scanline <= 0;
33 | end
34 | 
35 | wire [7:0] r,g,b;
36 | assign {r,g,b} = din;
37 | 
38 | reg [23:0] d;
39 | always @(*) begin
40 | 	case(scanline)
41 | 		1: // reduce 25% = 1/2 + 1/4
42 | 			d = {{1'b0, r[7:1]} + {2'b00, r[7:2]},
43 | 			     {1'b0, g[7:1]} + {2'b00, g[7:2]},
44 | 				  {1'b0, b[7:1]} + {2'b00, b[7:2]}};
45 | 
46 | 		2: // reduce 50% = 1/2
47 | 			d = {{1'b0, r[7:1]},
48 | 				  {1'b0, g[7:1]},
49 | 				  {1'b0, b[7:1]}};
50 | 
51 | 		3: // reduce 75% = 1/4
52 | 			d = {{2'b00, r[7:2]},
53 | 			     {2'b00, g[7:2]},
54 | 				  {2'b00, b[7:2]}};
55 | 
56 |         4: // black
57 |             d = 0;
58 | 		default: d = {r,g,b};
59 | 	endcase
60 | end
61 | 
62 | always @(posedge clk) begin
63 | 	reg [23:0] dout1, dout2;
64 | 	reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2;
65 | 
66 | 	dout   <= dout2; dout2 <= dout1; dout1 <= d;     
67 | 	vs_out <= vs2;   vs2   <= vs1;   vs1   <= vs_in; 
68 | 	hs_out <= hs2;   hs2   <= hs1;   hs1   <= hs_in; 
69 | 	de_out <= de2;   de2   <= de1;   de1   <= de_in; 
70 | 	ce_out <= ce2;   ce2   <= ce1;   ce1   <= ce_in; 
71 | end
72 | 
73 | endmodule
74 | 


--------------------------------------------------------------------------------
/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 VERILOG_FILE       [file join $::quartus(qip_path) i2c.v ]
20 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ]
21 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) i2s.v ]
22 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) spdif.v ]
23 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) audio_out.v ]
24 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) iir_filter.v ]
25 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ]
26 | set_global_assignment -name VERILOG_FILE       [file join $::quartus(qip_path) sigma_delta_dac.v ]
27 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mt32pi.sv ]
28 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.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 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) yc_out.sv ]
36 | 


--------------------------------------------------------------------------------
/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 ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM2_*
49 | 
50 | set_global_assignment -name VERILOG_MACRO "MISTER_DUAL_SDRAM=1"
51 | 


--------------------------------------------------------------------------------
/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 -to   [get_ports {AUDIO_SPDIF}]
29 | set_false_path -to   [get_ports {AUDIO_L}]
30 | set_false_path -to   [get_ports {AUDIO_R}]
31 | set_false_path -to   {cfg[*]}
32 | set_false_path -from {cfg[*]}
33 | set_false_path -from {VSET[*]}
34 | set_false_path -to   {wcalc[*] hcalc[*]}
35 | set_false_path -to {hdmi_width[*] hdmi_height[*]}
36 | 
37 | set_multicycle_path -to {*_osd|osd_vcnt*} -setup 2
38 | set_multicycle_path -to {*_osd|osd_vcnt*} -hold 1
39 | 
40 | set_false_path -to   {*_osd|v_cnt*}
41 | set_false_path -to   {*_osd|v_osd_start*}
42 | set_false_path -to   {*_osd|v_info_start*}
43 | set_false_path -to   {*_osd|h_osd_start*}
44 | set_false_path -from {*_osd|v_osd_start*}
45 | set_false_path -from {*_osd|v_info_start*}
46 | set_false_path -from {*_osd|h_osd_start*}
47 | set_false_path -from {*_osd|rot*}
48 | set_false_path -from {*_osd|dsp_width*}
49 | set_false_path -to   {*_osd|half}
50 | 
51 | set_false_path -to   {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
52 | set_false_path -from {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
53 | set_false_path -to   {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]}
54 | set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]}
55 | set_false_path -to   {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
56 | set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
57 | set_false_path -from {aflt_* acx* acy* areset* arc*}
58 | set_false_path -from {vs_line*}
59 | 
60 | set_false_path -from {ascal|o_ihsize*}
61 | set_false_path -from {ascal|o_ivsize*}
62 | set_false_path -from {ascal|o_format*}
63 | set_false_path -from {ascal|o_hdown}
64 | set_false_path -from {ascal|o_vdown}
65 | set_false_path -from {ascal|o_hmin* ascal|o_hmax* ascal|o_vmin* ascal|o_vmax*}
66 | set_false_path -from {ascal|o_hdisp* ascal|o_vdisp*}
67 | set_false_path -from {ascal|o_htotal* ascal|o_vtotal*}
68 | set_false_path -from {ascal|o_hsstart* ascal|o_vsstart* ascal|o_hsend* ascal|o_vsend*}
69 | set_false_path -from {ascal|o_hsize* ascal|o_vsize*}
70 | 
71 | set_false_path -from {mcp23009|sd_cd}
72 | 


--------------------------------------------------------------------------------
/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 | 
11 | 	input  [23:0] din,
12 | 	output [23:0] dout,
13 | 
14 | 	output reg    hsync_o,
15 | 	output reg    vsync_o,
16 | 	output reg    csync_o
17 | );
18 | 
19 | wire [5:0] red   = din[23:18];
20 | wire [5:0] green = din[15:10];
21 | wire [5:0] blue  = din[7:2];
22 | 
23 | // http://marsee101.blog19.fc2.com/blog-entry-2311.html
24 | // Y  =  16 + 0.257*R + 0.504*G + 0.098*B (Y  =  0.299*R + 0.587*G + 0.114*B)
25 | // Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
26 | // Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr =  0.500*R - 0.419*G - 0.081*B)
27 | 
28 | reg  [7:0] y, pb, pr;
29 | reg [23:0] rgb;
30 | always @(posedge clk) begin
31 | 	reg [18:0] y_1r, pb_1r, pr_1r;
32 | 	reg [18:0] y_1g, pb_1g, pr_1g;
33 | 	reg [18:0] y_1b, pb_1b, pr_1b;
34 | 	reg [18:0] y_2, pb_2, pr_2;
35 | 	reg [23:0] din1, din2;
36 | 	reg hsync2, vsync2, csync2;
37 | 	reg hsync1, vsync1, csync1;
38 | 
39 | 	y_1r  <= 19'd04096 + ({red, 8'd0} + {red, 3'd0});
40 | 	pb_1r <= 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0});
41 | 	pr_1r <= 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0});
42 | 
43 | 	y_1g  <= {green, 9'd0} + {green, 2'd0};
44 | 	pb_1g <= {green, 8'd0} + {green, 5'd0} + {green, 3'd0};
45 | 	pr_1g <= {green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0};
46 | 
47 | 	y_1b  <= {blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0};
48 | 	pb_1b <= {blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0};
49 | 	pr_1b <= {blue, 6'd0} + {blue, 3'd0};
50 | 
51 | 	y_2  <= y_1r  + y_1g  + y_1b;
52 | 	pb_2 <= pb_1r - pb_1g + pb_1b;
53 | 	pr_2 <= pr_1r - pr_1g - pr_1b;
54 | 
55 | 	y  <= ( y_2[18] ||  !y_2[17:12]) ? 8'd16 : (y_2[17:8] > 235) ? 8'd235 :  y_2[15:8];
56 | 	pb <= (pb_2[18] || !pb_2[17:12]) ? 8'd16 : (&pb_2[17:12])    ? 8'd240 : pb_2[15:8];
57 | 	pr <= (pr_2[18] || !pr_2[17:12]) ? 8'd16 : (&pr_2[17:12])    ? 8'd240 : pr_2[15:8];
58 | 
59 | 	hsync_o <= hsync2; hsync2 <= hsync1; hsync1 <= hsync;
60 | 	vsync_o <= vsync2; vsync2 <= vsync1; vsync1 <= vsync;
61 | 	csync_o <= csync2; csync2 <= csync1; csync1 <= csync;
62 | 
63 | 	rgb <= din2; din2 <= din1; din1 <= din;
64 | end
65 | 
66 | assign dout = ypbpr_en ? {pr, y, pb} : rgb;
67 | 
68 | endmodule
69 | 


--------------------------------------------------------------------------------
/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 | 	// video output signals
 30 | 	output reg [7:0] VGA_R,
 31 | 	output reg [7:0] VGA_G,
 32 | 	output reg [7:0] VGA_B,
 33 | 	output reg       VGA_VS,
 34 | 	output reg       VGA_HS,
 35 | 	output           VGA_DE,
 36 | 	
 37 | 	// optional aligned blank
 38 | 	output reg       HBlank_out,
 39 | 	output reg       VBlank_out,
 40 | 	
 41 | 	// optional aligned de
 42 | 	output reg       DE_out
 43 | );
 44 | 
 45 | wire hs, vs;
 46 | s_fix sync_v(clk_vid, HSync, hs);
 47 | s_fix sync_h(clk_vid, VSync, vs);
 48 | 
 49 | wire hbl = hs | HBlank;
 50 | wire vbl = vs | VBlank;
 51 | 
 52 | assign VGA_DE = ~(HBlank_out | VBlank_out);
 53 | 
 54 | always @(posedge clk_vid) begin
 55 | 	if(ce_pix) begin
 56 | 		HBlank_out <= hbl;
 57 | 
 58 | 		VGA_HS <= hs;
 59 | 		if(~VGA_HS & hs) VGA_VS <= vs;
 60 | 
 61 | 		VGA_R  <= R;
 62 | 		VGA_G  <= G;
 63 | 		VGA_B  <= B;
 64 | 		DE_out <= DE_in;
 65 | 
 66 | 		if(HBlank_out & ~hbl) VBlank_out <= vbl;
 67 | 	end
 68 | end
 69 | 
 70 | endmodule
 71 | 
 72 | module s_fix
 73 | (
 74 | 	input clk,
 75 | 	
 76 | 	input sync_in,
 77 | 	output sync_out
 78 | );
 79 | 
 80 | assign sync_out = sync_in ^ pol;
 81 | 
 82 | reg pol;
 83 | always @(posedge clk) begin
 84 | 	integer pos = 0, neg = 0, cnt = 0;
 85 | 	reg s1,s2;
 86 | 
 87 | 	s1 <= sync_in;
 88 | 	s2 <= s1;
 89 | 
 90 | 	if(~s2 & s1) neg <= cnt;
 91 | 	if(s2 & ~s1) pos <= cnt;
 92 | 
 93 | 	cnt <= cnt + 1;
 94 | 	if(s2 != s1) cnt <= 0;
 95 | 
 96 | 	pol <= pos > neg;
 97 | end
 98 | 
 99 | endmodule
100 | 


--------------------------------------------------------------------------------
/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 | 


--------------------------------------------------------------------------------
/zerowing.qpf:
--------------------------------------------------------------------------------
 1 | # -------------------------------------------------------------------------- #
 2 | #
 3 | # Copyright (C) 2020  Intel Corporation. All rights reserved.
 4 | # Your use of Intel Corporation's design tools, logic functions 
 5 | # and other software and tools, and any partner logic 
 6 | # functions, and any output files from any of the foregoing 
 7 | # (including device programming or simulation files), and any 
 8 | # associated documentation or information are expressly subject 
 9 | # to the terms and conditions of the Intel Program License 
10 | # Subscription Agreement, the Intel Quartus Prime License Agreement,
11 | # the Intel FPGA IP License Agreement, or other applicable license
12 | # agreement, including, without limitation, that your use is for
13 | # the sole purpose of programming logic devices manufactured by
14 | # Intel and sold by Intel or its authorized distributors.  Please
15 | # refer to the applicable agreement for further details, at
16 | # https://fpgasoftware.intel.com/eula.
17 | #
18 | # -------------------------------------------------------------------------- #
19 | #
20 | # Quartus Prime
21 | # Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
22 | # Date created = 15:57:56  May 09, 2023
23 | #
24 | # -------------------------------------------------------------------------- #
25 | 
26 | QUARTUS_VERSION = "20.1"
27 | DATE = "15:57:56  May 09, 2023"
28 | 
29 | # Revisions
30 | 
31 | PROJECT_REVISION = "zerowing"
32 | 


--------------------------------------------------------------------------------
/zerowing.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 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
16 | 
17 | set_global_assignment -name LAST_QUARTUS_VERSION "20.1.1 Lite Edition"
18 | 
19 | set_global_assignment -name GENERATE_RBF_FILE ON
20 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
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 TIMING_ANALYZER_MULTICORNER_ANALYSIS ON
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 "AGGRESSIVE PERFORMANCE"
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 MEDIUM
51 | set_global_assignment -name SEED 1
52 | 
53 | set_global_assignment -name VERILOG_MACRO "MISTER_FB=1"
54 | 
55 | #enable it only if 8bit indexed mode is used in core
56 | #set_global_assignment -name VERILOG_MACRO "MISTER_FB_PALETTE=1"
57 | 
58 | #do not enable DEBUG_NOHDMI in release!
59 | #set_global_assignment -name VERILOG_MACRO "MISTER_DEBUG_NOHDMI=1"
60 | 
61 | # disable bilinear filtering when downscaling
62 | #set_global_assignment -name VERILOG_MACRO "MISTER_DOWNSCALE_NN=1"
63 | 
64 | # disable adaptive scanline filtering
65 | #set_global_assignment -name VERILOG_MACRO "MISTER_DISABLE_ADAPTIVE=1"
66 | 
67 | # Enable YC / Composite output
68 | set_global_assignment -name VERILOG_MACRO "MISTER_ENABLE_YC=1"
69 | 
70 | #enable dimming during pause
71 | set_global_assignment -name VERILOG_MACRO "PAUSE_OUTPUT_DIM=1"
72 | 
73 | source sys/sys.tcl
74 | source sys/sys_analog.tcl
75 | source files.qip
76 | 
77 | set_global_assignment -name ENABLE_SIGNALTAP OFF
78 | set_global_assignment -name SYNTHESIS_EFFORT FAST
79 | set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 4.0
80 | set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL NORMAL
81 | 
82 | set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION ALWAYS
83 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
84 | 


--------------------------------------------------------------------------------