├── dist ├── Assets │ └── genesis │ │ └── common │ │ └── .keep ├── Cores │ └── ericlewis.Genesis │ │ ├── audio.json │ │ ├── icon.bin │ │ ├── variants.json │ │ ├── bitstream.rbf_r │ │ ├── data.json │ │ ├── core.json │ │ ├── input.json │ │ └── video.json └── Platforms │ ├── _images │ └── genesis.bin │ └── genesis.json ├── src └── fpga │ ├── output_files │ ├── .gitignore │ ├── ap_core.rbf │ ├── ap_core.sof │ ├── bitstream.rbf_r │ ├── reverse_bits.exe │ └── run.bat │ ├── core │ ├── mf_pllbase_sim.f │ ├── mf_pllbase_sim │ │ ├── cadence │ │ │ ├── hdl.var │ │ │ └── cds.lib │ │ └── synopsys │ │ │ └── vcsmx │ │ │ └── synopsys_sim.setup │ ├── mf_pllbase.spd │ ├── rtl │ │ ├── SVP │ │ │ ├── SVP.qip │ │ │ └── SSP160x_PKG.vhd │ │ ├── jt12 │ │ │ ├── adpcm │ │ │ │ ├── gen_lingain.py │ │ │ │ ├── jt10_adpcmb_gain.v │ │ │ │ ├── jt10_cen_burst.v │ │ │ │ ├── jt10_adpcm_div.v │ │ │ │ ├── jt10_adpcm_dbrom.v │ │ │ │ ├── jt10_adpcmb_interpol.v │ │ │ │ ├── jt10_adpcm_acc.v │ │ │ │ ├── jt10_adpcmb_cnt.v │ │ │ │ ├── jt10_adpcm.v │ │ │ │ ├── jt10_adpcm_drvB.v │ │ │ │ ├── jt10_adpcmb.v │ │ │ │ ├── jt10_adpcm_dt.v │ │ │ │ └── jt10_adpcm_comb.v │ │ │ ├── jt03.yaml │ │ │ ├── jt12_rst.v │ │ │ ├── jt12_sh.v │ │ │ ├── jt12.vhd │ │ │ ├── jt12_eg_cnt.v │ │ │ ├── jt12_sumch.v │ │ │ ├── dac │ │ │ │ ├── jt12_dac.v │ │ │ │ └── jt12_dac2.v │ │ │ ├── jt12_sh_rst.v │ │ │ ├── jt12_dout.v │ │ │ ├── jt12_pg_sum.v │ │ │ ├── mixer │ │ │ │ ├── jt12_comb.v │ │ │ │ ├── jt12_fm_uprate.v │ │ │ │ ├── jt12_decim.v │ │ │ │ ├── jt12_mixer.v │ │ │ │ └── jt12_interpol.v │ │ │ ├── jt12_eg_final.v │ │ │ ├── jt12_pg_inc.v │ │ │ ├── alt │ │ │ │ ├── eg_step_ram.v │ │ │ │ ├── eg_step.v │ │ │ │ ├── eg_mux.v │ │ │ │ └── eg_cnt.v │ │ │ ├── jt12_single_acc.v │ │ │ ├── README.md │ │ │ ├── jt03_acc.v │ │ │ ├── jt12_sh24.v │ │ │ ├── jt12_eg_pure.v │ │ │ ├── jt12_pg_comb.v │ │ │ ├── jt03_fm.qip │ │ │ ├── jt12_pg_dt.v │ │ │ ├── jt12.v │ │ │ ├── jt12_csr.v │ │ │ ├── jt12_pcm.v │ │ │ ├── jt03.qip │ │ │ ├── jt12_pg.v │ │ │ ├── jt12_eg_ctrl.v │ │ │ ├── jt12_pcm_interpol.v │ │ │ ├── jt12.qip │ │ │ ├── jt12_eg_step.v │ │ │ ├── jt03.v │ │ │ ├── jt10.v │ │ │ ├── jt12_timers.v │ │ │ ├── jt12_acc.v │ │ │ ├── jt12_eg_comb.v │ │ │ └── jt12_kon.v │ │ ├── FX68K │ │ │ ├── fx68k.qip │ │ │ └── fx68k.sdc │ │ ├── T80 │ │ │ └── T80.qip │ │ ├── jt89 │ │ │ ├── jt89.qip │ │ │ ├── jt89.vhd │ │ │ ├── jt89_vol.v │ │ │ ├── jt89_tone.v │ │ │ ├── jt89_mixer.v │ │ │ └── jt89_noise.v │ │ ├── cofi.sv │ │ ├── mlab.vhd │ │ ├── genesis_lpf.v │ │ └── cheatcodes.sv │ ├── mf_pllbase │ │ ├── mf_pllbase_0002.qip │ │ └── mf_pllbase_0002.v │ ├── pin_ddio_clk.qip │ ├── pin_ddio_clk.ppf │ ├── mf_pllbase.sip │ ├── mf_pllbase.ppf │ ├── core_constraints.sdc │ └── sync_fifo.sv │ ├── apf │ ├── build_id.mif │ ├── mf_datatable.qip │ ├── mf_ddio_bidir_12.qip │ ├── apf_constraints.sdc │ ├── apf.qip │ └── mf_ddio_bidir_12.ppf │ ├── .gitignore │ └── ap_core.qpf └── README.md /dist/Assets/genesis/common/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fpga/output_files/.gitignore: -------------------------------------------------------------------------------- 1 | !*.sof 2 | !*.rbf -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim.f: -------------------------------------------------------------------------------- 1 | mf_pllbase_sim/mf_pllbase.vo 2 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim/cadence/hdl.var: -------------------------------------------------------------------------------- 1 | 2 | DEFINE WORK work 3 | -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/audio.json: -------------------------------------------------------------------------------- 1 | { 2 | "audio": { 3 | "magic": "APF_VER_1" 4 | } 5 | } -------------------------------------------------------------------------------- /dist/Platforms/_images/genesis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/dist/Platforms/_images/genesis.bin -------------------------------------------------------------------------------- /src/fpga/output_files/ap_core.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/src/fpga/output_files/ap_core.rbf -------------------------------------------------------------------------------- /src/fpga/output_files/ap_core.sof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/src/fpga/output_files/ap_core.sof -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/icon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/dist/Cores/ericlewis.Genesis/icon.bin -------------------------------------------------------------------------------- /src/fpga/output_files/bitstream.rbf_r: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/src/fpga/output_files/bitstream.rbf_r -------------------------------------------------------------------------------- /src/fpga/output_files/reverse_bits.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/src/fpga/output_files/reverse_bits.exe -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/variants.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "magic": "APF_VER_1", 4 | "variant_list": [] 5 | } 6 | } -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/bitstream.rbf_r: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/openFPGA-Genesis/HEAD/dist/Cores/ericlewis.Genesis/bitstream.rbf_r -------------------------------------------------------------------------------- /dist/Platforms/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "platform": { 3 | "category": "Console", 4 | "name": "Genesis", 5 | "year": 1988, 6 | "manufacturer": "Sega" 7 | } 8 | } -------------------------------------------------------------------------------- /src/fpga/output_files/run.bat: -------------------------------------------------------------------------------- 1 | reverse_bits.exe ap_core.rbf bitstream.rbf_r 2 | copy /y bitstream.rbf_r "E:\Cores\ericlewis.Genesis\bitstream.rbf_r" 3 | copy /y bitstream.rbf_r "..\..\..\dist\Cores\ericlewis.Genesis\bitstream.rbf_r" -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase.spd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/SVP/SVP.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) SSP160x.vhd ] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) SSP160x_PKG.vhd ] 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) SVP.vhd ] 4 | -------------------------------------------------------------------------------- /src/fpga/apf/build_id.mif: -------------------------------------------------------------------------------- 1 | -- Build ID Memory Initialization File 2 | -- 3 | 4 | DEPTH = 256; 5 | WIDTH = 32; 6 | ADDRESS_RADIX = HEX; 7 | DATA_RADIX = HEX; 8 | 9 | CONTENT 10 | BEGIN 11 | 12 | 0E0 : 20221019; 13 | 0E1 : 00093038; 14 | 0E2 : a2a432a2; 15 | 16 | END; 17 | -------------------------------------------------------------------------------- /src/fpga/apf/mf_datatable.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_datatable.v"] 5 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/gen_lingain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | 5 | db=0 6 | 7 | for k in range(64): 8 | lin = 10**(db/20)*511 9 | sys.stdout.write(" mem[%03d] = 9'd%03d;" % (k, lin)) 10 | if( k%4 == 3 ): 11 | sys.stdout.write("\n") 12 | # else: 13 | # sys.stdout.write(" ") 14 | db = db - 0.75 15 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase/mf_pllbase_0002.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 2 | 3 | set_instance_assignment -name PLL_AUTO_RESET OFF -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 5 | -------------------------------------------------------------------------------- /src/fpga/core/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 ] -------------------------------------------------------------------------------- /src/fpga/apf/mf_ddio_bidir_12.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.ppf"] 6 | -------------------------------------------------------------------------------- /src/fpga/core/pin_ddio_clk.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_OUT" 2 | set_global_assignment -name IP_TOOL_VERSION "18.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pin_ddio_clk.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pin_ddio_clk_inst.v"] 6 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pin_ddio_clk.ppf"] 7 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/T80/T80.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.vhd ] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80pa.vhd ] 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vhd ] 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ] 5 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ] 6 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ] 7 | -------------------------------------------------------------------------------- /src/fpga/core/pin_ddio_clk.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt89.vhd ] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ] 7 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase.sip: -------------------------------------------------------------------------------- 1 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_NAME "altera_pll" 2 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_ENV "mwpim" 4 | set_global_assignment -library "lib_mf_pllbase" -name SPD_FILE [file join $::quartus(sip_path) "mf_pllbase.spd"] 5 | 6 | set_global_assignment -library "lib_mf_pllbase" -name MISC_FILE [file join $::quartus(sip_path) "mf_pllbase_sim/mf_pllbase.vo"] 7 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | 4 | package jt89 is 5 | 6 | component jt89 7 | port 8 | ( 9 | rst : in std_logic; 10 | clk : in std_logic; -- CPU clock 11 | clk_en : in std_logic := '1'; -- optional clock enable, if not needed leave as '1' 12 | din : in std_logic_vector(7 downto 0); 13 | wr_n : in std_logic; 14 | ready : out std_logic; 15 | sound : out std_logic_vector(10 downto 0) -- signed 16 | ); 17 | end component; 18 | 19 | end; 20 | -------------------------------------------------------------------------------- /src/fpga/apf/apf_constraints.sdc: -------------------------------------------------------------------------------- 1 | # 2 | # APF constraints 3 | # Do not edit this file. 4 | # 5 | # Add your own constraints in the \core_constraints.sdc in the core directory, which will also be loaded. 6 | 7 | create_clock -name clk_74a -period 13.468 [get_ports clk_74a] 8 | create_clock -name clk_74b -period 13.468 [get_ports clk_74b] 9 | create_clock -name bridge_spiclk -period 13.468 [get_ports bridge_spiclk] 10 | 11 | # autogenerate PLL clock names for use down below 12 | derive_pll_clocks 13 | 14 | 15 | # io constraints go here 16 | # 17 | 18 | 19 | # load in user constraints 20 | read_sdc "core/core_constraints.sdc" -------------------------------------------------------------------------------- /src/fpga/apf/apf.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "apf_top.v"] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "common.v"] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_bridge_peripheral.v"] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_pad_controller.v"] 5 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) "apf_constraints.sdc"] 6 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.qip"] 7 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_datatable.qip"] 8 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim/synopsys/vcsmx/synopsys_sim.setup: -------------------------------------------------------------------------------- 1 | 2 | WORK > DEFAULT 3 | DEFAULT: ./libraries/work/ 4 | work: ./libraries/work/ 5 | altera_ver: ./libraries/altera_ver/ 6 | lpm_ver: ./libraries/lpm_ver/ 7 | sgate_ver: ./libraries/sgate_ver/ 8 | altera_mf_ver: ./libraries/altera_mf_ver/ 9 | altera_lnsim_ver: ./libraries/altera_lnsim_ver/ 10 | cyclonev_ver: ./libraries/cyclonev_ver/ 11 | cyclonev_hssi_ver: ./libraries/cyclonev_hssi_ver/ 12 | cyclonev_pcie_hip_ver: ./libraries/cyclonev_pcie_hip_ver/ 13 | LIBRARY_SCAN = TRUE 14 | -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "magic": "APF_VER_1", 4 | "data_slots": [ 5 | { 6 | "id": 0, 7 | "name": "Cartridge", 8 | "required": true, 9 | "parameters": "0x109", 10 | "extensions": ["md", "bin", "gen", "smd"], 11 | "address": "0x10000000" 12 | }, 13 | { 14 | "id": 10, 15 | "name": "Save", 16 | "required": false, 17 | "nonvolatile": true, 18 | "parameters": "0x84", 19 | "extensions": ["sav"], 20 | "address": "0x60000000" 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt03.yaml: -------------------------------------------------------------------------------- 1 | here: 2 | - jt03.v 3 | - jt12.vhd 4 | - jt12_top.v 5 | - jt03_acc.v 6 | - jt12_single_acc.v 7 | - jt12_eg.v 8 | - jt12_eg_cnt.v 9 | - jt12_eg_comb.v 10 | - jt12_eg_step.v 11 | - jt12_eg_pure.v 12 | - jt12_eg_final.v 13 | - jt12_eg_ctrl.v 14 | - jt12_exprom.v 15 | - jt12_kon.v 16 | - jt12_lfo.v 17 | - jt12_mmr.v 18 | - jt12_div.v 19 | - jt12_mod.v 20 | - jt12_op.v 21 | - jt12_csr.v 22 | - jt12_pg.v 23 | - jt12_pg_inc.v 24 | - jt12_pg_dt.v 25 | - jt12_pg_sum.v 26 | - jt12_pg_comb.v 27 | - jt12_pm.v 28 | - jt12_logsin.v 29 | - jt12_reg.v 30 | - jt12_sh.v 31 | - jt12_sh_rst.v 32 | - jt12_sh24.v 33 | - jt12_sumch.v 34 | - jt12_timers.v 35 | - jt12_dout.v 36 | - ../jt49/hdl/jt49.yaml 37 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase.ppf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/fpga/apf/mf_ddio_bidir_12.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/fpga/core/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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Genesis for Analogue Pocket 2 | 3 | This is a port of a mister port of the [fpgagen](https://github.com/Torlus/fpgagen) core for Analogue Pocket. 4 | I am sure I am forgetting something else here... I know some JT and Kitrinx modules are used. So, shout out to them. 5 | 6 | - Various modules by [Jotego](https://www.patreon.com/topapate) are used 7 | - Composite mode module is by [Kitrinx](https://github.com/Kitrinx) 8 | - Many improvements from [sorgelig](https://github.com/sorgelig) 9 | - Many improvements from [srg320](https://github.com/srg320) 10 | - Various modules by [agg23](https://github.com/agg23) 11 | - Special thanks to [tpwrules](https://github.com/tpwrules) 12 | 13 | fpgagen - a SEGA Megadrive/Genesis clone in a FPGA. 14 | Copyright (c) 2010-2013 Gregory Estrade (greg@torlus.com) 15 | All rights reserved 16 | 17 | ## Important to read this first! 18 | - This core is far from complete and I am aware of most issues. 19 | - No PAL. -------------------------------------------------------------------------------- /src/fpga/.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | greybox_tmp 3 | hps_isw_handoff 4 | incremental_db 5 | output_files 6 | PLLJ_PLLSPE_INFO.txt 7 | simulation 8 | vip 9 | .qsys_edit 10 | *_netlist 11 | *_sim 12 | *.bak 13 | *.bsf 14 | *.cdf 15 | *.cmp 16 | *.csv 17 | *.done 18 | *.f 19 | *.pin 20 | *.pof 21 | *.ptf.* 22 | *.qar 23 | *.qarlog 24 | *.qdf 25 | *.qws 26 | *.rbf 27 | *.rbf_r 28 | *.rpt 29 | *.sip 30 | *.sld 31 | *.smsg 32 | *.sof 33 | *.sopc_builder 34 | *.sopcinfo 35 | *.spd 36 | *.summary 37 | *.txt 38 | *.log 39 | *.xml 40 | *~ 41 | **/.DS_Store 42 | build_id.mif 43 | build_id.v 44 | c5_pin_model_dump.txt 45 | cr_ie_info.json 46 | # Gateman directories and files 47 | !.gateman/* 48 | !gateware.json 49 | !/pkg/* 50 | /pkg/**/*.rom 51 | /pkg/**/*.zip 52 | /pkg/**/*.arc 53 | /staging/* 54 | /release/* 55 | # Editor directories and files 56 | .vscode/* 57 | !.vscode/extensions.json 58 | .idea 59 | *.suo 60 | *.ntvs* 61 | *.njsproj 62 | *.sln 63 | *.sw? 64 | 65 | # Pocket directories and files 66 | !info.txt 67 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_rst.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | module jt12_rst( 23 | input rst, 24 | input clk, 25 | output reg rst_n 26 | ); 27 | 28 | reg r; 29 | 30 | always @(negedge clk) 31 | if( rst ) begin 32 | r <= 1'b0; 33 | rst_n <= 1'b0; 34 | end else begin 35 | { rst_n, r } <= { r, 1'b1 }; 36 | end 37 | 38 | endmodule // jt12_rst -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/core.json: -------------------------------------------------------------------------------- 1 | { 2 | "core": { 3 | "magic": "APF_VER_1", 4 | "metadata": { 5 | "platform_ids": ["genesis"], 6 | "shortname": "Genesis", 7 | "description": "Sega Genesis, known as the Mega Drive outside North America, is a 16-bit fourth-generation home video game console developed and sold by Sega.", 8 | "author": "ericlewis", 9 | "url": "https://github.com/ericlewis/openfpga-genesis", 10 | "version": "0.4.2", 11 | "date_release": "2022-10-08" 12 | }, 13 | "framework": { 14 | "target_product": "Analogue Pocket", 15 | "version_required": "1.1", 16 | "sleep_supported": false, 17 | "dock": { 18 | "supported": true, 19 | "analog_output": false 20 | }, 21 | "hardware": { 22 | "link_port": false, 23 | "cartridge_adapter": -1 24 | } 25 | }, 26 | "cores": [ 27 | { 28 | "name": "default", 29 | "id": 0, 30 | "filename": "bitstream.rbf_r" 31 | } 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "magic": "APF_VER_1", 4 | "controllers": [ 5 | { 6 | "type": "default", 7 | "mappings": [ 8 | { 9 | "id": 1, 10 | "name": "A Button", 11 | "key": "pad_btn_y" 12 | }, 13 | { 14 | "id": 2, 15 | "name": "B Button", 16 | "key": "pad_btn_b" 17 | }, 18 | { 19 | "id": 3, 20 | "name": "C Button", 21 | "key": "pad_btn_a" 22 | }, 23 | { 24 | "id": 4, 25 | "name": "X Button", 26 | "key": "pad_trig_l" 27 | }, 28 | { 29 | "id": 5, 30 | "name": "Y Button", 31 | "key": "pad_btn_x" 32 | }, 33 | { 34 | "id": 6, 35 | "name": "Z Button", 36 | "key": "pad_trig_r" 37 | }, 38 | { 39 | "id": 7, 40 | "name": "Start", 41 | "key": "pad_btn_start" 42 | }, 43 | { 44 | "id": 8, 45 | "name": "Mode", 46 | "key": "pad_btn_select" 47 | } 48 | ] 49 | } 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim/cadence/cds.lib: -------------------------------------------------------------------------------- 1 | 2 | DEFINE std $CDS_ROOT/tools/inca/files/STD/ 3 | DEFINE synopsys $CDS_ROOT/tools/inca/files/SYNOPSYS/ 4 | DEFINE ieee $CDS_ROOT/tools/inca/files/IEEE/ 5 | DEFINE ambit $CDS_ROOT/tools/inca/files/AMBIT/ 6 | DEFINE vital_memory $CDS_ROOT/tools/inca/files/VITAL_MEMORY/ 7 | DEFINE ncutils $CDS_ROOT/tools/inca/files/NCUTILS/ 8 | DEFINE ncinternal $CDS_ROOT/tools/inca/files/NCINTERNAL/ 9 | DEFINE ncmodels $CDS_ROOT/tools/inca/files/NCMODELS/ 10 | DEFINE cds_assertions $CDS_ROOT/tools/inca/files/CDS_ASSERTIONS/ 11 | DEFINE work ./libraries/work/ 12 | DEFINE altera_ver ./libraries/altera_ver/ 13 | DEFINE lpm_ver ./libraries/lpm_ver/ 14 | DEFINE sgate_ver ./libraries/sgate_ver/ 15 | DEFINE altera_mf_ver ./libraries/altera_mf_ver/ 16 | DEFINE altera_lnsim_ver ./libraries/altera_lnsim_ver/ 17 | DEFINE cyclonev_ver ./libraries/cyclonev_ver/ 18 | DEFINE cyclonev_hssi_ver ./libraries/cyclonev_hssi_ver/ 19 | DEFINE cyclonev_pcie_hip_ver ./libraries/cyclonev_pcie_hip_ver/ 20 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_sh.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 1-31-2017 19 | */ 20 | 21 | 22 | // stages must be greater than 2 23 | module jt12_sh #(parameter width=5, stages=24 ) 24 | ( 25 | input clk, 26 | input clk_en /* synthesis direct_enable */, 27 | input [width-1:0] din, 28 | output [width-1:0] drop 29 | ); 30 | 31 | reg [stages-1:0] bits[width-1:0]; 32 | 33 | genvar i; 34 | generate 35 | for (i=0; i < width; i=i+1) begin: bit_shifter 36 | always @(posedge clk) if(clk_en) begin 37 | bits[i] <= {bits[i][stages-2:0], din[i]}; 38 | end 39 | assign drop[i] = bits[i][stages-1]; 40 | end 41 | endgenerate 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/cofi.sv: -------------------------------------------------------------------------------- 1 | // Composite-like horizontal blending by Kitrinx 2 | 3 | module cofi ( 4 | input clk, 5 | input pix_ce, 6 | input enable, 7 | 8 | input hblank, 9 | input vblank, 10 | input hs, 11 | input vs, 12 | input [7:0] red, 13 | input [7:0] green, 14 | input [7:0] blue, 15 | 16 | output reg hblank_out, 17 | output reg vblank_out, 18 | output reg hs_out, 19 | output reg vs_out, 20 | output reg [7:0] red_out, 21 | output reg [7:0] green_out, 22 | output reg [7:0] blue_out 23 | ); 24 | 25 | function bit [7:0] color_blend ( 26 | input [7:0] color_prev, 27 | input [7:0] color_curr, 28 | input blank_last 29 | ); 30 | var 31 | reg [8:0] sum; 32 | begin 33 | sum = color_curr; 34 | if(!blank_last) sum = sum + color_prev; 35 | color_blend = sum[8:1]; 36 | end 37 | endfunction 38 | 39 | reg [7:0] red_last; 40 | reg [7:0] green_last; 41 | reg [7:0] blue_last; 42 | 43 | always @(posedge clk) if (pix_ce) begin 44 | 45 | hblank_out <= hblank; 46 | vblank_out <= vblank; 47 | vs_out <= vs; 48 | hs_out <= hs; 49 | 50 | red_last <= red; 51 | blue_last <= blue; 52 | green_last <= green; 53 | 54 | red_out <= enable ? color_blend(red_last, red, hblank_out) : red; 55 | blue_out <= enable ? color_blend(blue_last, blue, hblank_out) : blue; 56 | green_out <= enable ? color_blend(green_last, green, hblank_out) : green; 57 | 58 | end 59 | 60 | endmodule 61 | -------------------------------------------------------------------------------- /src/fpga/ap_core.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2019 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 18.1.1 Build 646 04/11/2019 SJ Lite Edition 22 | # Date created = 21:31:36 January 22, 2020 23 | # 24 | # -------------------------------------------------------------------------- # 25 | 26 | QUARTUS_VERSION = "18.1" 27 | DATE = "21:31:36 January 22, 2020" 28 | 29 | # Revisions 30 | 31 | PROJECT_REVISION = "ap_core" 32 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcmb_gain.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Gain is assumed to be 0.75dB per bit. 23 | 24 | module jt10_adpcmb_gain( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen55, 28 | input [ 7:0] tl, // ADPCM Total Level 29 | input signed [15:0] pcm_in, 30 | output reg signed [15:0] pcm_out 31 | ); 32 | 33 | wire signed [15:0] factor = {8'd0, tl}; 34 | wire signed [31:0] pcm_mul = pcm_in * factor; // linear gain 35 | 36 | always @(posedge clk) if(cen55) 37 | pcm_out <= pcm_mul[23:8]; 38 | 39 | endmodule // jt10_adpcm_gain 40 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | 4 | package jt12 is 5 | 6 | component jt12 7 | port 8 | ( 9 | rst : in std_logic; 10 | clk : in std_logic; -- CPU clock 11 | cen : in std_logic := '1'; -- optional clock enable, if not needed leave as '1' 12 | din : in std_logic_vector(7 downto 0); 13 | addr : in std_logic_vector(1 downto 0); 14 | cs_n : in std_logic; 15 | wr_n : in std_logic; 16 | 17 | dout : out std_logic_vector(7 downto 0); 18 | irq_n : out std_logic; 19 | en_hifi_pcm: in std_logic; -- set high to use interpolation on PCM samples 20 | 21 | -- combined output 22 | snd_right : out std_logic_vector(15 downto 0); -- signed 23 | snd_left : out std_logic_vector(15 downto 0); -- signed 24 | snd_sample : out std_logic 25 | ); 26 | end component; 27 | 28 | component jt12_genmix 29 | port 30 | ( 31 | rst : in std_logic; 32 | clk : in std_logic; -- expects 54 MHz clock 33 | fm_left : in std_logic_vector(15 downto 0); -- FM at 55kHz 34 | fm_right: in std_logic_vector(15 downto 0); -- FM at 55kHz 35 | psg_snd : in std_logic_vector(10 downto 0); -- PSG at 220kHz 36 | fm_en : in std_logic; 37 | psg_en : in std_logic; 38 | -- Mixed sound at 54 MHz 39 | snd_left : out std_logic_vector(15 downto 0); 40 | snd_right : out std_logic_vector(15 downto 0) 41 | ); 42 | end component; 43 | 44 | end; 45 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_eg_cnt.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 29-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_cnt( 23 | input rst, 24 | input clk, 25 | input clk_en /* synthesis direct_enable */, 26 | input zero, 27 | output reg [14:0] eg_cnt 28 | ); 29 | 30 | reg [1:0] eg_cnt_base; 31 | 32 | always @(posedge clk, posedge rst) begin : envelope_counter 33 | if( rst ) begin 34 | eg_cnt_base <= 2'd0; 35 | eg_cnt <=15'd0; 36 | end 37 | else begin 38 | if( zero && clk_en ) begin 39 | // envelope counter increases every 3 output samples, 40 | // there is one sample every 24 clock ticks 41 | if( eg_cnt_base == 2'd2 ) begin 42 | eg_cnt <= eg_cnt + 1'b1; 43 | eg_cnt_base <= 2'd0; 44 | end 45 | else eg_cnt_base <= eg_cnt_base + 1'b1; 46 | end 47 | end 48 | end 49 | 50 | endmodule // jt12_eg_cnt -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_sumch.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 1-31-2017 19 | */ 20 | 21 | 22 | /* The input is {op[1:0], ch[2:0]} 23 | it adds 1 to the channel and overflow to the operator correctly */ 24 | 25 | module jt12_sumch 26 | ( 27 | input [4:0] chin, 28 | output reg [4:0] chout 29 | ); 30 | 31 | parameter num_ch=6; 32 | 33 | reg [2:0] aux; 34 | 35 | always @(*) begin 36 | aux = chin[2:0] + 3'd1; 37 | if( num_ch==6 ) begin 38 | chout[2:0] = aux[1:0]==2'b11 ? aux+3'd1 : aux; 39 | chout[4:3] = chin[2:0]==3'd6 ? chin[4:3]+2'd1 : chin[4:3]; // next operator 40 | end else begin // 3 channels 41 | chout[2:0] = aux[1:0]==2'b11 ? 3'd0 : aux; 42 | chout[4:3] = chin[2:0]==3'd2 ? chin[4:3]+2'd1 : chin[4:3]; // next operator 43 | end 44 | end 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /dist/Cores/ericlewis.Genesis/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "video": { 3 | "magic": "APF_VER_1", 4 | "scaler_modes": [ 5 | { 6 | "width": 256, 7 | "height": 224, 8 | "aspect_w": 64, 9 | "aspect_h": 49, 10 | "rotation": 0, 11 | "mirror": 0 12 | }, 13 | { 14 | "width": 320, 15 | "height": 224, 16 | "aspect_w": 64, 17 | "aspect_h": 49, 18 | "rotation": 0, 19 | "mirror": 0 20 | }, 21 | { 22 | "width": 256, 23 | "height": 240, 24 | "aspect_w": 128, 25 | "aspect_h": 105, 26 | "rotation": 0, 27 | "mirror": 0 28 | }, 29 | { 30 | "width": 320, 31 | "height": 240, 32 | "aspect_w": 128, 33 | "aspect_h": 105, 34 | "rotation": 0, 35 | "mirror": 0 36 | }, 37 | { 38 | "width": 320, 39 | "height": 224, 40 | "aspect_w": 10, 41 | "aspect_h": 7, 42 | "rotation": 0, 43 | "mirror": 0 44 | }, 45 | { 46 | "width": 320, 47 | "height": 240, 48 | "aspect_w": 4, 49 | "aspect_h": 3, 50 | "rotation": 0, 51 | "mirror": 0 52 | } 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/dac/jt12_dac.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: March, 9th 2017 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | /* 24 | 25 | input sampling rate must be the same as clk frequency 26 | interpolation the input signal accordingly to get the 27 | right sampling rate 28 | 29 | */ 30 | 31 | module jt12_dac #(parameter width=12) 32 | ( 33 | input clk, 34 | input rst, 35 | input signed [width-1:0] din, 36 | output dout 37 | ); 38 | localparam acc_w = width+1; 39 | 40 | reg [width-1:0] nosign; 41 | reg [acc_w-1:0] acc; 42 | wire [acc_w-2:0] err = acc[acc_w-2:0]; 43 | 44 | assign dout = acc[acc_w-1]; 45 | 46 | always @(posedge clk) 47 | if( rst ) begin 48 | acc <= {(acc_w){1'b0}}; 49 | nosign <= {width{1'b0}}; 50 | end 51 | else begin 52 | nosign <= { ~din[width-1], din[width-2:0] }; 53 | acc <= nosign + err; 54 | end 55 | 56 | endmodule 57 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_sh_rst.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 1-31-2017 19 | */ 20 | 21 | 22 | // stages must be greater than 2 23 | module jt12_sh_rst #(parameter width=5, stages=32, rstval=1'b0 ) 24 | ( 25 | input rst, 26 | input clk, 27 | input clk_en /* synthesis direct_enable */, 28 | input [width-1:0] din, 29 | output [width-1:0] drop 30 | ); 31 | 32 | reg [stages-1:0] bits[width-1:0]; 33 | 34 | genvar i; 35 | integer k; 36 | generate 37 | initial 38 | for (k=0; k < width; k=k+1) begin 39 | bits[k] = { stages{rstval}}; 40 | end 41 | endgenerate 42 | 43 | generate 44 | for (i=0; i < width; i=i+1) begin: bit_shifter 45 | always @(posedge clk, posedge rst) 46 | if( rst ) begin 47 | bits[i] <= {stages{rstval}}; 48 | end else if(clk_en) begin 49 | bits[i] <= {bits[i][stages-2:0], din[i]}; 50 | end 51 | assign drop[i] = bits[i][stages-1]; 52 | end 53 | endgenerate 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_dout.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | module jt12_dout( 23 | // input rst_n, 24 | input clk, // CPU clock 25 | input flag_A, 26 | input flag_B, 27 | input busy, 28 | input [5:0] adpcma_flags, 29 | input adpcmb_flag, 30 | input [7:0] psg_dout, 31 | input [1:0] addr, 32 | output reg [7:0] dout 33 | ); 34 | 35 | parameter use_ssg=0, use_adpcm=0; 36 | 37 | always @(posedge clk) begin 38 | casez( addr ) 39 | 2'b00: dout <= {busy, 5'd0, flag_B, flag_A }; // YM2203 40 | 2'b01: dout <= (use_ssg ==1) ? psg_dout : {busy, 5'd0, flag_B, flag_A }; 41 | 2'b1?: dout <= (use_adpcm==1) ? 42 | { adpcmb_flag, 1'b0, adpcma_flags } : 43 | { busy, 5'd0, flag_B, flag_A }; 44 | endcase 45 | end 46 | 47 | endmodule // jt12_dout -------------------------------------------------------------------------------- /src/fpga/core/rtl/mlab.vhd: -------------------------------------------------------------------------------- 1 | LIBRARY ieee; 2 | USE ieee.std_logic_1164.all; 3 | 4 | LIBRARY altera_mf; 5 | USE altera_mf.altera_mf_components.all; 6 | 7 | ENTITY mlab IS 8 | generic ( 9 | addr_width : integer := 8; 10 | data_width : integer := 8 11 | ); 12 | PORT 13 | ( 14 | clock : in STD_LOGIC; 15 | rdaddress : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); 16 | wraddress : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); 17 | data : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); 18 | wren : in STD_LOGIC := '0'; 19 | q : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); 20 | cs : in std_logic := '1' 21 | ); 22 | END ENTITY; 23 | 24 | ARCHITECTURE SYN OF mlab IS 25 | signal q0 : std_logic_vector((data_width - 1) downto 0); 26 | BEGIN 27 | q<= q0 when cs = '1' else (others => '1'); 28 | 29 | altdpram_component : altdpram 30 | GENERIC MAP ( 31 | indata_aclr => "OFF", 32 | indata_reg => "INCLOCK", 33 | intended_device_family => "Cyclone V", 34 | lpm_type => "altdpram", 35 | outdata_aclr => "OFF", 36 | outdata_reg => "UNREGISTERED", 37 | ram_block_type => "MLAB", 38 | rdaddress_aclr => "OFF", 39 | rdaddress_reg => "UNREGISTERED", 40 | rdcontrol_aclr => "OFF", 41 | rdcontrol_reg => "UNREGISTERED", 42 | read_during_write_mode_mixed_ports => "CONSTRAINED_DONT_CARE", 43 | width => data_width, 44 | widthad => addr_width, 45 | width_byteena => 1, 46 | wraddress_aclr => "OFF", 47 | wraddress_reg => "INCLOCK", 48 | wrcontrol_aclr => "OFF", 49 | wrcontrol_reg => "INCLOCK" 50 | ) 51 | PORT MAP ( 52 | data => data, 53 | outclock => clock, 54 | rdaddress => rdaddress, 55 | wren => wren, 56 | inclock => clock, 57 | wraddress => wraddress, 58 | q => q0 59 | ); 60 | 61 | END SYN; -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pg_sum.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 2-11-2018 19 | 20 | Based on information posted by Nemesis on: 21 | http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 22 | 23 | Based on jt51_phasegen.v, from JT51 24 | 25 | */ 26 | 27 | module jt12_pg_sum ( 28 | input [ 3:0] mul, 29 | input [19:0] phase_in, 30 | input pg_rst, 31 | input signed [5:0] detune_signed, 32 | input [16:0] phinc_pure, 33 | 34 | output reg [19:0] phase_out, 35 | output reg [ 9:0] phase_op 36 | ); 37 | 38 | reg [16:0] phinc_premul; 39 | reg [19:0] phinc_mul; 40 | 41 | always @(*) begin 42 | phinc_premul = phinc_pure + {{11{detune_signed[5]}},detune_signed}; 43 | phinc_mul = ( mul==4'd0 ) ? {4'b0,phinc_premul[16:1]} : ({3'd0,phinc_premul} * mul); 44 | 45 | phase_out = pg_rst ? 20'd0 : (phase_in + { phinc_mul}); 46 | phase_op = phase_out[19:10]; 47 | end 48 | 49 | endmodule // jt12_pg_sum -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/dac/jt12_dac2.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: March, 9th 2017 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | /* 24 | 25 | input sampling rate must be the same as clk frequency 26 | interpolate input signal accordingly to get the 27 | right sampling rate. 28 | 29 | Refer to sigmadelta.ods to see how the internal width (int_w) 30 | was determined. 31 | 32 | */ 33 | 34 | module jt12_dac2 #(parameter width=12) 35 | ( 36 | input clk, 37 | input rst, 38 | input signed [width-1:0] din, 39 | output reg dout 40 | ); 41 | 42 | localparam int_w = width+5; 43 | 44 | reg [int_w-1:0] y, error, error_1, error_2; 45 | 46 | wire [width-1:0] undin = { ~din[width-1], din[width-2:0] }; 47 | 48 | always @(*) begin 49 | y = undin + { error_1, 1'b0} - error_2; 50 | dout = ~y[int_w-1]; 51 | error = y - {dout, {width{1'b0}}}; 52 | end 53 | 54 | always @(posedge clk) 55 | if( rst ) begin 56 | error_1 <= {int_w{1'b0}}; 57 | error_2 <= {int_w{1'b0}}; 58 | end else begin 59 | error_1 <= error; 60 | error_2 <= error_1; 61 | end 62 | 63 | endmodule 64 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/mixer/jt12_comb.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 10-12-2018 20 | 21 | */ 22 | 23 | module jt12_comb #(parameter 24 | w=16, // bit width 25 | m=1 // depth of comb filter 26 | )( 27 | input rst, 28 | input clk, 29 | (* direct_enable *) input cen, 30 | input signed [w-1:0] snd_in, 31 | output reg signed [w-1:0] snd_out 32 | ); 33 | 34 | wire signed [w-1:0] prev; 35 | 36 | // m-delay stage 37 | generate 38 | genvar k; 39 | reg signed [w-1:0] mem[0:m-1]; 40 | assign prev=mem[m-1]; 41 | for(k=0;k. 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 29-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_final( 23 | input [ 6:0] lfo_mod, 24 | input amsen, 25 | input [ 1:0] ams, 26 | input [ 6:0] tl, 27 | input [ 9:0] eg_pure_in, 28 | input ssg_inv, 29 | output reg [9:0] eg_limited 30 | ); 31 | 32 | reg [ 8:0] am_final; 33 | reg [11:0] sum_eg_tl; 34 | reg [11:0] sum_eg_tl_am; 35 | reg [ 5:0] am_inverted; 36 | reg [ 9:0] eg_pream; 37 | 38 | always @(*) begin 39 | am_inverted = lfo_mod[6] ? ~lfo_mod[5:0] : lfo_mod[5:0]; 40 | end 41 | 42 | always @(*) begin 43 | casez( {amsen, ams } ) 44 | default: am_final = 9'd0; 45 | 3'b1_01: am_final = { 5'd0, am_inverted[5:2] }; 46 | 3'b1_10: am_final = { 3'd0, am_inverted }; 47 | 3'b1_11: am_final = { 2'd0, am_inverted, 1'b0 }; 48 | endcase 49 | eg_pream = ssg_inv ? (10'h200-eg_pure_in) : eg_pure_in; 50 | sum_eg_tl = { 1'b0, tl, 3'd0 } + {1'b0, eg_pream}; // leading zeros needed to compute correctly 51 | sum_eg_tl_am = sum_eg_tl + { 3'd0, am_final }; 52 | end 53 | 54 | always @(*) 55 | eg_limited = sum_eg_tl_am[11:10]==2'd0 ? sum_eg_tl_am[9:0] : 10'h3ff; 56 | 57 | endmodule // jt12_eg_final -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pg_inc.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 2-11-2018 19 | 20 | Based on information posted by Nemesis on: 21 | http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 22 | 23 | Based on jt51_phasegen.v, from JT51 24 | 25 | */ 26 | 27 | module jt12_pg_inc ( 28 | input [ 2:0] block, 29 | input [10:0] fnum, 30 | input signed [8:0] pm_offset, 31 | output reg [16:0] phinc_pure 32 | ); 33 | 34 | reg [11:0] fnum_mod; 35 | 36 | always @(*) begin 37 | fnum_mod = {fnum,1'b0} + {{3{pm_offset[8]}},pm_offset}; 38 | case ( block ) 39 | 3'd0: phinc_pure = { 7'd0, fnum_mod[11:2] }; 40 | 3'd1: phinc_pure = { 6'd0, fnum_mod[11:1] }; 41 | 3'd2: phinc_pure = { 5'd0, fnum_mod[11:0] }; 42 | 3'd3: phinc_pure = { 4'd0, fnum_mod, 1'd0 }; 43 | 3'd4: phinc_pure = { 3'd0, fnum_mod, 2'd0 }; 44 | 3'd5: phinc_pure = { 2'd0, fnum_mod, 3'd0 }; 45 | 3'd6: phinc_pure = { 1'd0, fnum_mod, 4'd0 }; 46 | 3'd7: phinc_pure = { fnum_mod, 5'd0 }; 47 | endcase 48 | end 49 | 50 | endmodule // jt12_pg_inc -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_cen_burst.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Let a fixed number of clock enable pulses to pass through 23 | 24 | module jt10_cen_burst #(parameter cntmax=3'd6, cntw=3)( 25 | input rst_n, 26 | input clk, 27 | input cen, // 8MHz cen 28 | input start, 29 | input start_cen, 30 | output cen_out 31 | ); 32 | 33 | reg [cntw-1:0] cnt; 34 | reg last_start; 35 | reg pass; 36 | 37 | always @(posedge clk or negedge rst_n) 38 | if( !rst_n ) begin 39 | cnt <= {cntw{1'b1}}; 40 | pass <= 1'b0; 41 | end else if(cen) begin 42 | last_start <= start; 43 | if( start && start_cen ) begin 44 | cnt <= 'd0; 45 | pass <= 1'b1; 46 | end else begin 47 | if(cnt != cntmax ) cnt <= cnt+1; 48 | else pass <= 1'b0; 49 | end 50 | end 51 | 52 | reg pass_negedge; 53 | assign cen_out = cen & pass_negedge; 54 | 55 | always @(negedge clk) begin 56 | pass_negedge <= pass; 57 | end 58 | 59 | endmodule // jt10_cen_burst -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89_vol.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT89. 2 | 3 | JT89 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT89 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT89. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: December, 1st 2018 19 | 20 | This work was originally based in the implementation found on the 21 | SMS core of MiST 22 | 23 | */ 24 | 25 | module jt89_vol( 26 | input clk, 27 | input clk_en, 28 | input rst, 29 | input din, 30 | input [3:0] vol, 31 | output reg signed [8:0] snd 32 | ); 33 | 34 | 35 | reg [7:0] max; 36 | 37 | always @(*) 38 | case ( vol ) // 2dB per LSB (20*log10) 39 | 4'd0: max = 8'd255; 40 | 4'd1: max = 8'd203; 41 | 4'd2: max = 8'd161; 42 | 4'd3: max = 8'd128; 43 | 4'd4: max = 8'd102; 44 | 4'd5: max = 8'd81; 45 | 4'd6: max = 8'd64; 46 | 4'd7: max = 8'd51; 47 | 4'd8: max = 8'd40; 48 | 4'd9: max = 8'd32; 49 | 4'd10: max = 8'd26; 50 | 4'd11: max = 8'd20; 51 | 4'd12: max = 8'd16; 52 | 4'd13: max = 8'd13; 53 | 4'd14: max = 8'd10; 54 | 4'd15: max = 8'd0; 55 | endcase 56 | 57 | always @(posedge clk) 58 | if( rst ) 59 | snd <= 9'd0; 60 | else if( clk_en ) 61 | snd <= din ? {1'b0,max} : -{1'b0,max}; 62 | 63 | endmodule -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89_tone.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT89. 2 | 3 | JT89 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT89 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT89. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: March, 8th 2017 19 | 20 | This work was originally based in the implementation found on the 21 | SMS core of MiST 22 | 23 | */ 24 | 25 | module jt89_tone( 26 | input clk, 27 | (* direct_enable = 1 *) input clk_en, 28 | input rst, 29 | input [9:0] tone, 30 | input [3:0] vol, 31 | output [8:0] snd, 32 | output reg out 33 | ); 34 | 35 | reg [9:0] cnt; 36 | reg last_out; 37 | 38 | jt89_vol u_vol( 39 | .rst ( rst ), 40 | .clk ( clk ), 41 | .clk_en ( clk_en ), 42 | .din ( out ), 43 | .vol ( vol ), 44 | .snd ( snd ) 45 | ); 46 | 47 | always @(posedge clk) 48 | if( rst ) begin 49 | cnt <= 10'd0; 50 | out <= 1'b0; 51 | end else if( clk_en ) begin 52 | if( tone==10'd0 || tone==10'd1 ) // special case. This is used for sample playing. 53 | out <= 1'b1; 54 | else begin 55 | if( cnt[9:0]==10'd1 ) begin 56 | cnt[9:0] <= (tone==10'd0) ? 10'd1 : tone; 57 | out <= ~out; 58 | end 59 | else cnt <= cnt-10'b1; 60 | end 61 | end 62 | 63 | endmodule 64 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/alt/eg_step_ram.v: -------------------------------------------------------------------------------- 1 | /* 2 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 3 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 4 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 | | eg_step_ram/ | | 3/3 | 0/0 | 7/7 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_step | 6 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 | 8 | */ 9 | 10 | module eg_step_ram( 11 | input [2:0] state_V, 12 | input [5:0] rate_V, 13 | input [2:0] cnt_V, 14 | output reg step_V 15 | ); 16 | 17 | localparam ATTACK=3'd0, DECAY1=3'd1, DECAY2=3'd2, RELEASE=3'd7, HOLD=3'd3; 18 | reg [7:0] step_idx; 19 | reg [7:0] step_ram; 20 | 21 | always @(*) 22 | case( { rate_V[5:4]==2'b11, rate_V[1:0]} ) 23 | 3'd0: step_ram = 8'b00000000; 24 | 3'd1: step_ram = 8'b10001000; // 2 25 | 3'd2: step_ram = 8'b10101010; // 4 26 | 3'd3: step_ram = 8'b11101110; // 6 27 | 3'd4: step_ram = 8'b10101010; // 4 28 | 3'd5: step_ram = 8'b11101010; // 5 29 | 3'd6: step_ram = 8'b11101110; // 6 30 | 3'd7: step_ram = 8'b11111110; // 7 31 | endcase 32 | 33 | always @(*) begin : rate_step 34 | if( rate_V[5:2]==4'hf && state_V == ATTACK) 35 | step_idx = 8'b11111111; // Maximum attack speed, rates 60&61 36 | else 37 | if( rate_V[5:2]==4'd0 && state_V != ATTACK) 38 | step_idx = 8'b11111110; // limit slowest decay rate_IV 39 | else 40 | step_idx = step_ram; 41 | // a rate_IV of zero keeps the level still 42 | step_V = rate_V[5:1]==5'd0 ? 1'b0 : step_idx[ cnt_V ]; 43 | end 44 | 45 | endmodule // eg_step -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_div.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // calculates d=a/b 23 | // a = b*d + r 24 | 25 | module jt10_adpcm_div #(parameter dw=16)( 26 | input rst_n, 27 | input clk, // CPU clock 28 | input cen, 29 | input start, // strobe 30 | input [dw-1:0] a, 31 | input [dw-1:0] b, 32 | output reg [dw-1:0] d, 33 | output reg [dw-1:0] r, 34 | output working 35 | ); 36 | 37 | reg [dw-1:0] cycle; 38 | assign working = cycle[0]; 39 | 40 | wire [dw:0] sub = { r[dw-2:0], d[dw-1] } - b; 41 | 42 | always @(posedge clk or negedge rst_n) 43 | if( !rst_n ) begin 44 | cycle <= 'd0; 45 | end else if(cen) begin 46 | if( start ) begin 47 | cycle <= ~16'd0; 48 | r <= 16'd0; 49 | d <= a; 50 | end else if(cycle[0]) begin 51 | cycle <= { 1'b0, cycle[dw-1:1] }; 52 | if( sub[dw] == 0 ) begin 53 | r <= sub[dw-1:0]; 54 | d <= { d[dw-2:0], 1'b1}; 55 | end else begin 56 | r <= { r[dw-2:0], d[dw-1] }; 57 | d <= { d[dw-2:0], 1'b0 }; 58 | end 59 | end 60 | end 61 | 62 | endmodule // jt10_adpcm_div 63 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/alt/eg_step.v: -------------------------------------------------------------------------------- 1 | /* 2 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 3 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 4 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 | | eg_step/ | | 3/3 | 0/0 | 7/7 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_step | 6 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 | */ 8 | 9 | module eg_step( 10 | input [2:0] state_V, 11 | input [5:0] rate_V, 12 | input [2:0] cnt_V, 13 | output reg step_V 14 | ); 15 | 16 | localparam ATTACK=3'd0, DECAY1=3'd1, DECAY2=3'd2, RELEASE=3'd7, HOLD=3'd3; 17 | reg [7:0] step_idx; 18 | 19 | always @(*) begin : rate_step 20 | if( rate_V[5:4]==2'b11 ) begin // 0 means 1x, 1 means 2x 21 | if( rate_V[5:2]==4'hf && state_V == ATTACK) 22 | step_idx = 8'b11111111; // Maximum attack speed, rates 60&61 23 | else 24 | case( rate_V[1:0] ) 25 | 2'd0: step_idx = 8'b00000000; 26 | 2'd1: step_idx = 8'b10001000; // 2 27 | 2'd2: step_idx = 8'b10101010; // 4 28 | 2'd3: step_idx = 8'b11101110; // 6 29 | endcase 30 | end 31 | else begin 32 | if( rate_V[5:2]==4'd0 && state_V != ATTACK) 33 | step_idx = 8'b11111110; // limit slowest decay rate_IV 34 | else 35 | case( rate_V[1:0] ) 36 | 2'd0: step_idx = 8'b10101010; // 4 37 | 2'd1: step_idx = 8'b11101010; // 5 38 | 2'd2: step_idx = 8'b11101110; // 6 39 | 2'd3: step_idx = 8'b11111110; // 7 40 | endcase 41 | end 42 | // a rate_IV of zero keeps the level still 43 | step_V = rate_V[5:1]==5'd0 ? 1'b0 : step_idx[ cnt_V ]; 44 | end 45 | 46 | endmodule // eg_step -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_single_acc.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 27-1-2017 20 | 21 | */ 22 | 23 | // Accumulates an arbitrary number of inputs with saturation 24 | // restart the sum when input "zero" is high 25 | 26 | 27 | module jt12_single_acc #(parameter 28 | win=14, // input data width 29 | wout=16 // output data width 30 | )( 31 | input clk, 32 | input clk_en /* synthesis direct_enable */, 33 | input [win-1:0] op_result, 34 | input sum_en, 35 | input zero, 36 | output reg [wout-1:0] snd 37 | ); 38 | 39 | // for full resolution use win=14, wout=16 40 | // for cut down resolution use win=9, wout=12 41 | // wout-win should be > 0 42 | 43 | reg signed [wout-1:0] next, acc, current; 44 | reg overflow; 45 | 46 | wire [wout-1:0] plus_inf = { 1'b0, {(wout-1){1'b1}} }; // maximum positive value 47 | wire [wout-1:0] minus_inf = { 1'b1, {(wout-1){1'b0}} }; // minimum negative value 48 | 49 | always @(*) begin 50 | current = sum_en ? { {(wout-win){op_result[win-1]}}, op_result } : {wout{1'b0}}; 51 | next = zero ? current : current + acc; 52 | overflow = !zero && 53 | (current[wout-1] == acc[wout-1]) && 54 | (acc[wout-1]!=next[wout-1]); 55 | end 56 | 57 | always @(posedge clk) if( clk_en ) begin 58 | acc <= overflow ? (acc[wout-1] ? minus_inf : plus_inf) : next; 59 | if(zero) snd <= acc; 60 | end 61 | 62 | endmodule // jt12_single_acc -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/README.md: -------------------------------------------------------------------------------- 1 | # JT12 FPGA Clone of Yamaha OPN hardware by Jose Tejada (@topapate) 2 | =================================================================== 3 | 4 | You can show your appreciation through 5 | * [Patreon](https://patreon.com/topapate), by supporting releases 6 | * [Paypal](https://paypal.me/topapate), with a donation 7 | 8 | 9 | JT12 is an FM sound source written in Verilog, fully compatible with YM2612/YM3438 (Megadrive), YM2610 (NeoGeo) and YM2203 (PC88, arcades). 10 | 11 | The implementation tries to be as close to original hardware as possible. Low usage of FPGA resources has also been a design goal. Except in the operator section (jt12_op) where an exact replica of the original circuit is done. This could be done in less space with a different style but because this piece of the circuit was reversed engineered by Sauraen, I decided to use that knowledge. 12 | 13 | ## Directories 14 | 15 | * hdl -> all relevant RTL files, written in verilog 16 | * ver -> test benches 17 | * ver/verilator -> test bench that can play vgm files 18 | 19 | ## Usage 20 | 21 | Chip | Top Level | QIP File 22 | --------|---------------|--------- 23 | YM2610 | jt10.v | jt10.qip 24 | YM2612 | jt12.v | jt12.qip 25 | YM2203 | jt03.v | jt03.qip 26 | 27 | ## Simulation 28 | 29 | There are several simulation test benches in the **ver** folder. The most important one is in the **ver/verilator** folder. The simulation script is called with the shell script **go** in the same folder. The script will compile the file **test.cpp** together with other files and the design and will simulate the tune specificied with the -f command. It can read **vgm** tunes and generate .wav output of them. 30 | 31 | ## Related Projects 32 | 33 | Other sound chips from the same author 34 | 35 | Chip | Repository 36 | -----------------------|------------ 37 | YM2203, YM2612, YM2610 | [JT12](https://github.com/jotego/jt12) 38 | YM2151 | [JT51](https://github.com/jotego/jt51) 39 | YM3526 | [JTOPL](https://github.com/jotego/jtopl) 40 | YM2149 | [JT49](https://github.com/jotego/jt49) 41 | sn76489an | [JT89](https://github.com/jotego/jt89) 42 | OKI 6295 | [JT6295](https://github.com/jotego/jt6295) 43 | OKI MSM5205 | [JT5205](https://github.com/jotego/jt5205) -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt03_acc.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 15-11-2018 20 | 21 | */ 22 | 23 | 24 | // Use for YM2203 25 | // no left/right channels 26 | // full operator resolution 27 | // clamped to maximum output of signed 16 bits 28 | // This version does not clamp each channel individually 29 | // That does not correspond to real hardware behaviour. I should 30 | // change it. 31 | 32 | module jt03_acc 33 | ( 34 | input rst, 35 | input clk, 36 | input clk_en /* synthesis direct_enable */, 37 | input signed [13:0] op_result, 38 | input s1_enters, 39 | input s2_enters, 40 | input s3_enters, 41 | input s4_enters, 42 | input zero, 43 | input [2:0] alg, 44 | // combined output 45 | output signed [15:0] snd 46 | ); 47 | 48 | reg sum_en; 49 | 50 | always @(*) begin 51 | case ( alg ) 52 | default: sum_en = s4_enters; 53 | 3'd4: sum_en = s2_enters | s4_enters; 54 | 3'd5,3'd6: sum_en = ~s1_enters; 55 | 3'd7: sum_en = 1'b1; 56 | endcase 57 | end 58 | 59 | localparam res=18; 60 | wire [res-1:0] hires; 61 | assign snd = hires[res-1:res-16]; 62 | 63 | jt12_single_acc #(.win(14),.wout(res)) u_mono( 64 | .clk ( clk ), 65 | .clk_en ( clk_en ), 66 | .op_result ( op_result ), 67 | .sum_en ( sum_en ), 68 | .zero ( zero ), 69 | .snd ( hires ) 70 | ); 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_sh24.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 1-31-2017 19 | */ 20 | 21 | 22 | module jt12_sh24 #(parameter width=5 ) 23 | ( 24 | input clk, 25 | input clk_en /* synthesis direct_enable */, 26 | input [width-1:0] din, 27 | output reg [width-1:0] st1, 28 | output reg [width-1:0] st2, 29 | output reg [width-1:0] st3, 30 | output reg [width-1:0] st4, 31 | output reg [width-1:0] st5, 32 | output reg [width-1:0] st6, 33 | output reg [width-1:0] st7, 34 | output reg [width-1:0] st8, 35 | output reg [width-1:0] st9, 36 | output reg [width-1:0] st10, 37 | output reg [width-1:0] st11, 38 | output reg [width-1:0] st12, 39 | output reg [width-1:0] st13, 40 | output reg [width-1:0] st14, 41 | output reg [width-1:0] st15, 42 | output reg [width-1:0] st16, 43 | output reg [width-1:0] st17, 44 | output reg [width-1:0] st18, 45 | output reg [width-1:0] st19, 46 | output reg [width-1:0] st20, 47 | output reg [width-1:0] st21, 48 | output reg [width-1:0] st22, 49 | output reg [width-1:0] st23, 50 | output reg [width-1:0] st24 51 | ); 52 | 53 | always @(posedge clk) if(clk_en) begin 54 | st24<= st23; 55 | st23<= st22; 56 | st22<= st21; 57 | st21<= st20; 58 | st20<= st19; 59 | st19<= st18; 60 | st18<= st17; 61 | st17<= st16; 62 | st16<= st15; 63 | st15<= st14; 64 | st14<= st13; 65 | st13<= st12; 66 | st12<= st11; 67 | st11<= st10; 68 | st10<= st9; 69 | st9 <= st8; 70 | st8 <= st7; 71 | st7 <= st6; 72 | st6 <= st5; 73 | st5 <= st4; 74 | st4 <= st3; 75 | st3 <= st2; 76 | st2 <= st1; 77 | st1 <= din; 78 | end 79 | 80 | endmodule 81 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89_mixer.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT89. 2 | 3 | JT89 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT89 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT89. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: December, 1st 2018 19 | 20 | */ 21 | 22 | module jt89_mixer #(parameter bw=9, interpol16=0)( 23 | input rst, 24 | input clk, 25 | input clk_en, 26 | input cen_16, 27 | input cen_4, 28 | input [bw-1:0] ch0, 29 | input [bw-1:0] ch1, 30 | input [bw-1:0] ch2, 31 | input [bw-1:0] noise, 32 | output signed [bw+1:0] sound 33 | ); 34 | 35 | reg signed [bw+1:0] fresh; 36 | 37 | always @(posedge clk) 38 | fresh <= 39 | { {2{ch0[bw-1]}}, ch0 }+ 40 | { {2{ch1[bw-1]}}, ch1 }+ 41 | { {2{ch2[bw-1]}}, ch2 }+ 42 | { {2{noise[bw-1]}}, noise }; 43 | 44 | generate 45 | if( interpol16==1 ) begin 46 | wire signed [bw+1:0] snd4; 47 | localparam calcw=bw+8; 48 | jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate1 ( 49 | .rst ( rst ), 50 | .clk ( clk ), 51 | .cen_in ( cen_16 ), 52 | .cen_out( cen_4 ), 53 | .snd_in ( fresh ), 54 | .snd_out( snd4 ) 55 | ); 56 | jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate2 ( 57 | .rst ( rst ), 58 | .clk ( clk ), 59 | .cen_in ( cen_4 ), 60 | .cen_out( clk_en ), 61 | .snd_in ( snd4 ), 62 | .snd_out( sound ) 63 | ); 64 | end else 65 | assign sound = fresh; 66 | endgenerate 67 | 68 | endmodule -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt89/jt89_noise.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT89. 2 | 3 | JT89 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT89 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT89. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: March, 8th 2017 19 | 20 | This work was originally based in the implementation found on the 21 | SMS core of MiST 22 | 23 | */ 24 | 25 | module jt89_noise( 26 | input clk, 27 | (* direct_enable = 1 *) input clk_en, 28 | input rst, 29 | input clr, 30 | input [2:0] ctrl3, 31 | input [3:0] vol, 32 | input [9:0] tone2, 33 | output [8:0] snd 34 | ); 35 | 36 | reg [15:0] shift; 37 | reg [10:0] cnt; 38 | reg update; 39 | 40 | jt89_vol u_vol( 41 | .rst ( rst ), 42 | .clk ( clk ), 43 | .clk_en ( clk_en ), 44 | .din ( shift[0] ), 45 | .vol ( vol ), 46 | .snd ( snd ) 47 | ); 48 | 49 | always @(posedge clk) 50 | if( rst ) begin 51 | cnt <= 'd0; 52 | end else if( clk_en ) begin 53 | if( cnt==11'd1 ) begin 54 | case( ctrl3[1:0] ) 55 | 2'd0: cnt <= 11'h20; // clk_en already divides by 16 56 | 2'd1: cnt <= 11'h40; 57 | 2'd2: cnt <= 11'h80; 58 | 2'd3: cnt <= (tone2 == 0) ? 11'h02 : {tone2, 1'b0}; 59 | endcase 60 | end else begin 61 | cnt <= cnt-11'b1; 62 | end 63 | end 64 | 65 | wire fb = ctrl3[2]?(shift[0]^shift[3]):shift[0]; 66 | 67 | always @(posedge clk) 68 | if( rst || clr ) 69 | shift <= { 1'b1, 15'd0 }; 70 | else if( clk_en ) begin 71 | if( cnt==1 ) begin 72 | shift <= (|shift == 1'b0) ? {1'b1, 15'd0 } : {fb, shift[15:1]}; 73 | end 74 | end 75 | 76 | endmodule 77 | -------------------------------------------------------------------------------- /src/fpga/core/core_constraints.sdc: -------------------------------------------------------------------------------- 1 | # 2 | # user core constraints 3 | # 4 | # put your clock groups in here as well as any net assignments 5 | # 6 | 7 | set_clock_groups -asynchronous \ 8 | -group { bridge_spiclk } \ 9 | -group { clk_74a } \ 10 | -group { clk_74b } \ 11 | -group { \ 12 | ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk \ 13 | ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk \ 14 | } \ 15 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \ 16 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk } \ 17 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[4].gpll~PLL_OUTPUT_COUNTER|divclk } \ 18 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[5].gpll~PLL_OUTPUT_COUNTER|divclk } 19 | 20 | derive_clock_uncertainty 21 | 22 | set_false_path -to [get_ports {dram_clk}] 23 | 24 | set_multicycle_path -from {ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk} -to {ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk} -setup 2 25 | set_multicycle_path -from {ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk} -to {ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk} -hold 1 26 | 27 | set_multicycle_path -from {ic|sdram|dout*} -to {ic|system|data*} -setup 2 28 | set_multicycle_path -from {ic|sdram|dout*} -to {ic|system|data*} -hold 1 29 | 30 | set_multicycle_path -setup -start -from [get_keepers {*fx68k:*|Ir[*]}] -to [get_keepers {*fx68k:*|microAddr[*]}] 2 31 | set_multicycle_path -hold -start -from [get_keepers {*fx68k:*|Ir[*]}] -to [get_keepers {*fx68k:*|microAddr[*]}] 1 32 | set_multicycle_path -setup -start -from [get_keepers {*fx68k:*|Ir[*]}] -to [get_keepers {*fx68k:*|nanoAddr[*]}] 2 33 | set_multicycle_path -hold -start -from [get_keepers {*fx68k:*|Ir[*]}] -to [get_keepers {*fx68k:*|nanoAddr[*]}] 1 34 | set_multicycle_path -setup -start -from [get_keepers {*|nanoLatch[*]}] -to [get_keepers {*|excUnit|alu|pswCcr[*]}] 2 35 | set_multicycle_path -hold -start -from [get_keepers {*|nanoLatch[*]}] -to [get_keepers {*|excUnit|alu|pswCcr[*]}] 1 36 | set_multicycle_path -setup -start -from [get_keepers {*|excUnit|alu|oper[*]}] -to [get_keepers {*|excUnit|alu|pswCcr[*]}] 2 37 | set_multicycle_path -hold -start -from [get_keepers {*|excUnit|alu|oper[*]}] -to [get_keepers {*|excUnit|alu|pswCcr[*]}] 1 -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_eg_pure.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 29-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_pure( 23 | input attack, 24 | input step, 25 | input [ 5:1] rate, 26 | input [ 9:0] eg_in, 27 | input ssg_en, 28 | input sum_up, 29 | output reg [9:0] eg_pure 30 | ); 31 | 32 | reg [ 3:0] dr_sum; 33 | reg [ 9:0] dr_adj; 34 | reg [10:0] dr_result; 35 | 36 | always @(*) begin : dr_calculation 37 | case( rate[5:2] ) 38 | 4'b1100: dr_sum = { 2'b0, step, ~step }; // 12 39 | 4'b1101: dr_sum = { 1'b0, step, ~step, 1'b0 }; // 13 40 | 4'b1110: dr_sum = { step, ~step, 2'b0 }; // 14 41 | 4'b1111: dr_sum = 4'd8;// 15 42 | default: dr_sum = { 2'b0, step, 1'b0 }; 43 | endcase 44 | // Decay rate attenuation is multiplied by 4 for SSG operation 45 | dr_adj = ssg_en ? {4'd0, dr_sum, 2'd0} : {6'd0, dr_sum}; 46 | dr_result = dr_adj + eg_in; 47 | end 48 | 49 | reg [ 7:0] ar_sum0; 50 | reg [ 8:0] ar_sum1; 51 | reg [10:0] ar_result; 52 | reg [ 9:0] ar_sum; 53 | 54 | always @(*) begin : ar_calculation 55 | casez( rate[5:2] ) 56 | default: ar_sum0 = {2'd0, eg_in[9:4]}; 57 | 4'b1101: ar_sum0 = {1'd0, eg_in[9:3]}; 58 | 4'b111?: ar_sum0 = eg_in[9:2]; 59 | endcase 60 | ar_sum1 = ar_sum0+9'd1; 61 | if( rate[5:4] == 2'b11 ) 62 | ar_sum = step ? { ar_sum1, 1'b0 } : { 1'b0, ar_sum1 }; 63 | else 64 | ar_sum = step ? { 1'b0, ar_sum1 } : 10'd0; 65 | ar_result = eg_in-ar_sum; 66 | end 67 | /////////////////////////////////////////////////////////// 68 | // rate not used below this point 69 | reg [9:0] eg_pre_fastar; // pre fast attack rate 70 | always @(*) begin 71 | if(sum_up) begin 72 | if( attack ) 73 | eg_pre_fastar = ar_result[10] ? 10'd0: ar_result[9:0]; 74 | else 75 | eg_pre_fastar = dr_result[10] ? 10'h3FF : dr_result[9:0]; 76 | end 77 | else eg_pre_fastar = eg_in; 78 | eg_pure = (attack&rate[5:1]==5'h1F) ? 10'd0 : eg_pre_fastar; 79 | end 80 | 81 | endmodule // jt12_eg_pure -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_dbrom.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // dB to linear 23 | 24 | module jt10_adpcm_dbrom( 25 | input clk, // CPU clock 26 | input [5:0] db, 27 | output reg [8:0] lin 28 | ); 29 | 30 | reg [8:0] mem[0:63]; 31 | 32 | initial begin // generated with file gen_lingain.py 33 | mem[000] = 9'd511; mem[001] = 9'd468; mem[002] = 9'd429; mem[003] = 9'd394; 34 | mem[004] = 9'd361; mem[005] = 9'd331; mem[006] = 9'd304; mem[007] = 9'd279; 35 | mem[008] = 9'd256; mem[009] = 9'd234; mem[010] = 9'd215; mem[011] = 9'd197; 36 | mem[012] = 9'd181; mem[013] = 9'd166; mem[014] = 9'd152; mem[015] = 9'd139; 37 | mem[016] = 9'd128; mem[017] = 9'd117; mem[018] = 9'd107; mem[019] = 9'd099; 38 | mem[020] = 9'd090; mem[021] = 9'd083; mem[022] = 9'd076; mem[023] = 9'd070; 39 | mem[024] = 9'd064; mem[025] = 9'd059; mem[026] = 9'd054; mem[027] = 9'd049; 40 | mem[028] = 9'd045; mem[029] = 9'd041; mem[030] = 9'd038; mem[031] = 9'd035; 41 | mem[032] = 9'd032; mem[033] = 9'd029; mem[034] = 9'd027; mem[035] = 9'd024; 42 | mem[036] = 9'd022; mem[037] = 9'd020; mem[038] = 9'd019; mem[039] = 9'd017; 43 | mem[040] = 9'd016; mem[041] = 9'd014; mem[042] = 9'd013; mem[043] = 9'd012; 44 | mem[044] = 9'd011; mem[045] = 9'd010; mem[046] = 9'd009; mem[047] = 9'd008; 45 | mem[048] = 9'd008; mem[049] = 9'd007; mem[050] = 9'd006; mem[051] = 9'd006; 46 | mem[052] = 9'd005; mem[053] = 9'd005; mem[054] = 9'd004; mem[055] = 9'd004; 47 | mem[056] = 9'd004; mem[057] = 9'd003; mem[058] = 9'd003; mem[059] = 9'd003; 48 | mem[060] = 9'd002; mem[061] = 9'd002; mem[062] = 9'd002; mem[063] = 9'd002; 49 | end 50 | 51 | always @(posedge clk) 52 | lin <= mem[db]; 53 | 54 | endmodule // jt10_adpcm_dbrom -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/mixer/jt12_fm_uprate.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 11-12-2018 20 | 21 | Each channel can use the full range of the DAC as they do not 22 | get summed in the real chip. 23 | 24 | Operator data is summed up without adding extra bits. This is 25 | the case of real YM3438, which was used on Megadrive 2 models. 26 | 27 | */ 28 | 29 | /* rate up-scaler for FM+PSG channel 30 | */ 31 | 32 | module jt12_fm_uprate( 33 | input rst, 34 | input clk, 35 | input signed [15:0] fm_snd, 36 | input signed [11:0] psg_snd, 37 | input fm_en, // enable FM 38 | input cen_1008, 39 | input cen_252, 40 | input cen_63, 41 | input cen_9, 42 | output signed [15:0] snd // Mixed sound at clk sample rate 43 | ); 44 | 45 | wire signed [15:0] fm2,fm3,fm4; 46 | 47 | reg [15:0] mixed; 48 | always @(posedge clk) 49 | mixed <= (fm_en?fm_snd:16'd0) + {{1{psg_snd[11]}},psg_snd,3'b0}; 50 | 51 | // 1008 --> 252 x4 52 | jt12_interpol #(.calcw(17),.inw(16),.rate(4),.m(1),.n(1)) 53 | u_fm2( 54 | .clk ( clk ), 55 | .rst ( rst ), 56 | .cen_in ( cen_1008 ), 57 | .cen_out( cen_252 ), 58 | .snd_in ( mixed ), 59 | .snd_out( fm2 ) 60 | ); 61 | 62 | // 252 --> 63 x4 63 | jt12_interpol #(.calcw(19),.inw(16),.rate(4),.m(1),.n(3)) 64 | u_fm3( 65 | .clk ( clk ), 66 | .rst ( rst ), 67 | .cen_in ( cen_252 ), 68 | .cen_out( cen_63 ), 69 | .snd_in ( fm2 ), 70 | .snd_out( fm3 ) 71 | ); 72 | 73 | // 63 --> 9 x7 74 | jt12_interpol #(.calcw(21),.inw(16),.rate(7),.m(2),.n(2)) 75 | u_fm4( 76 | .clk ( clk ), 77 | .rst ( rst ), 78 | .cen_in ( cen_63 ), 79 | .cen_out( cen_9 ), 80 | .snd_in ( fm3 ), 81 | .snd_out( fm4 ) 82 | ); 83 | 84 | // 9 --> 1 x9 85 | jt12_interpol #(.calcw(21),.inw(16),.rate(9),.m(2),.n(2)) 86 | u_fm5( 87 | .clk ( clk ), 88 | .rst ( rst ), 89 | .cen_in ( cen_9 ), 90 | .cen_out( 1'b1 ), 91 | .snd_in ( fm4 ), 92 | .snd_out( snd ) 93 | ); 94 | 95 | endmodule // jt12_fm_uprate -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pg_comb.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 2-11-2018 19 | 20 | Based on information posted by Nemesis on: 21 | http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 22 | 23 | 100% compared with Alexey Khokholov (Nuke.YKT) work with identical results. 24 | */ 25 | 26 | module jt12_pg_comb( 27 | input [ 2:0] block, 28 | input [10:0] fnum, 29 | // Phase Modulation 30 | input [ 4:0] lfo_mod, 31 | input [ 2:0] pms, 32 | // output [ 7:0] pm_out, 33 | 34 | // Detune 35 | input [ 2:0] detune, 36 | 37 | output [ 4:0] keycode, 38 | output signed [5:0] detune_out, 39 | // Phase increment 40 | output [16:0] phinc_out, 41 | // Phase add 42 | input [ 3:0] mul, 43 | input [19:0] phase_in, 44 | input pg_rst, 45 | // input signed [7:0] pm_in, 46 | input signed [5:0] detune_in, 47 | input [16:0] phinc_in, 48 | 49 | output [19:0] phase_out, 50 | output [ 9:0] phase_op 51 | ); 52 | 53 | wire signed [8:0] pm_offset; 54 | 55 | /* pm, pg_dt and pg_inc operate in parallel */ 56 | jt12_pm u_pm( 57 | .lfo_mod ( lfo_mod ), 58 | .fnum ( fnum ), 59 | .pms ( pms ), 60 | .pm_offset ( pm_offset ) 61 | ); 62 | 63 | jt12_pg_dt u_dt( 64 | .block ( block ), 65 | .fnum ( fnum ), 66 | .detune ( detune ), 67 | .keycode ( keycode ), 68 | .detune_signed( detune_out ) 69 | ); 70 | 71 | jt12_pg_inc u_inc( 72 | .block ( block ), 73 | .fnum ( fnum ), 74 | .pm_offset ( pm_offset ), 75 | .phinc_pure ( phinc_out ) 76 | ); 77 | 78 | // pg_sum uses the output from the previous blocks 79 | 80 | jt12_pg_sum u_sum( 81 | .mul ( mul ), 82 | .phase_in ( phase_in ), 83 | .pg_rst ( pg_rst ), 84 | .detune_signed ( detune_in ), 85 | .phinc_pure ( phinc_in ), 86 | .phase_out ( phase_out ), 87 | .phase_op ( phase_op ) 88 | ); 89 | 90 | endmodule // jt12_pg_comb -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt03_fm.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03.v ] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03_acc.v ] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] 12 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] 13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] 14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] 15 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] 16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] 17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] 18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] 19 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] 21 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] 22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] 23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] 24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] 25 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] 26 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] 27 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] 28 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] 29 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] 30 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] 31 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] 32 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] 33 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] 34 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/mixer/jt12_decim.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 10-12-2018 20 | 21 | */ 22 | 23 | module jt12_decim #(parameter calcw=18, inw=16, 24 | n=2, // number of stages 25 | m=1, // depth of comb filter 26 | rate=2 // it will stuff with as many as (rate-1) zeros 27 | )( 28 | input rst, 29 | input clk, 30 | (* direct_enable *) input cen_in, 31 | (* direct_enable *) input cen_out, 32 | input signed [inw-1:0] snd_in, 33 | output reg signed [inw-1:0] snd_out 34 | ); 35 | 36 | reg signed [calcw-1:0] inter6; 37 | wire signed [calcw-1:0] integ_op, comb_op; 38 | localparam wdiff = calcw - inw; 39 | 40 | // integrator at clk x cen sampling rate 41 | generate 42 | genvar k2; 43 | reg [calcw-1:0] integ_data[0:n]; 44 | assign integ_op = integ_data[n]; 45 | always @(*) 46 | integ_data[0] = { {wdiff{snd_in[inw-1]}}, snd_in }; 47 | for(k2=1;k2<=n;k2=k2+1) begin : integ_gen 48 | always @(posedge clk) 49 | if(rst) begin 50 | integ_data[k2] <= {calcw{1'b0}}; 51 | end else if(cen_in) begin 52 | integ_data[k2] <= integ_data[k2] + integ_data[k2-1]; 53 | end 54 | end 55 | endgenerate 56 | 57 | // interpolator 58 | always @(posedge clk) 59 | if(rst) begin 60 | inter6 <= {calcw{1'b0}}; 61 | end else if(cen_out) begin 62 | inter6 <= integ_op; 63 | end 64 | 65 | generate 66 | genvar k; 67 | wire [calcw-1:0] comb_data[0:n]; 68 | assign comb_data[0] = inter6; 69 | assign comb_op = comb_data[n]; 70 | for(k=0;k. 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | module jt10_adpcmb_interpol( 23 | input rst_n, 24 | input clk, 25 | input cen, // 8MHz cen 26 | input cen55, // clk & cen55 = 55 kHz 27 | input adv, 28 | input signed [15:0] pcmdec, 29 | output signed [15:0] pcmout 30 | ); 31 | 32 | localparam stages=6; 33 | 34 | reg signed [15:0] pcmlast, delta_x; 35 | reg signed [16:0] pre_dx; 36 | reg start_div=1'b0; 37 | reg [3:0] deltan, pre_dn; 38 | reg [stages-1:0] adv2; 39 | reg signed [15:0] pcminter; 40 | wire [15:0] next_step; 41 | reg [15:0] step; 42 | reg step_sign, next_step_sign; 43 | 44 | assign pcmout = pcminter; 45 | 46 | always @(posedge clk) if(cen) begin 47 | adv2 <= {adv2[stages-2:0], cen55 & adv }; // give some time to get the data from memory 48 | end 49 | 50 | always @(posedge clk) if(cen55) begin 51 | if ( adv ) begin 52 | pre_dn <= 'd1; 53 | deltan <= pre_dn; 54 | end else if ( pre_dn != 4'hF ) 55 | pre_dn <= pre_dn + 1'd1; 56 | end 57 | 58 | 59 | always @(posedge clk) if(cen) begin 60 | start_div <= 1'b0; 61 | if(adv2[1]) begin 62 | pcmlast <= pcmdec; 63 | end 64 | if(adv2[4]) begin 65 | pre_dx <= { pcmdec[15], pcmdec } - { pcmlast[15], pcmlast }; 66 | end 67 | if( adv2[5] ) begin 68 | start_div <= 1'b1; 69 | delta_x <= pre_dx[16] ? ~pre_dx[15:0]+1'd1 : pre_dx[15:0]; 70 | next_step_sign <= pre_dx[16]; 71 | end 72 | end 73 | 74 | always @(posedge clk) if(cen55) begin 75 | if( adv ) begin 76 | step <= next_step; 77 | step_sign <= next_step_sign; 78 | pcminter <= pcmlast; 79 | end 80 | else pcminter <= ( (pcminter < pcmlast) == step_sign ) ? pcminter : step_sign ? pcminter - step : pcminter + step; 81 | end 82 | 83 | jt10_adpcm_div #(.dw(16)) u_div( 84 | .rst_n ( rst_n ), 85 | .clk ( clk ), 86 | .cen ( cen ), 87 | .start ( start_div ), 88 | .a ( delta_x ), 89 | .b ( {12'd0, deltan } ), 90 | .d ( next_step ), 91 | .r ( ), 92 | .working( ) 93 | ); 94 | 95 | 96 | endmodule // jt10_adpcmb_interpol -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/mixer/jt12_mixer.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 11-12-2018 20 | 21 | Each channel can use the full range of the DAC as they do not 22 | get summed in the real chip. 23 | 24 | Operator data is summed up without adding extra bits. This is 25 | the case of real YM3438, which was used on Megadrive 2 models. 26 | 27 | */ 28 | 29 | // Generic mixer 30 | // wout should be larger or equal than any input (w0,w1,w2,w3) 31 | 32 | module jt12_mixer #(parameter w0=16,w1=16,w2=16,w3=16,wout=20) 33 | ( 34 | input clk, 35 | input cen, 36 | // input signals 37 | input signed [w0-1:0] ch0, 38 | input signed [w1-1:0] ch1, 39 | input signed [w2-1:0] ch2, 40 | input signed [w3-1:0] ch3, 41 | // gain for each channel in 4.4 fixed point format 42 | input [7:0] gain0, 43 | input [7:0] gain1, 44 | input [7:0] gain2, 45 | input [7:0] gain3, 46 | output reg signed [wout-1:0] mixed 47 | ); 48 | 49 | reg signed [w0+7:0] ch0_amp; 50 | reg signed [w1+7:0] ch1_amp; 51 | reg signed [w2+7:0] ch2_amp; 52 | reg signed [w3+7:0] ch3_amp; 53 | 54 | // rescale to wout+4+8 55 | wire signed [wout+11:0] scaled0 = { {wout+4-w0{ch0_amp[w0+7]}}, ch0_amp }; 56 | wire signed [wout+11:0] scaled1 = { {wout+4-w1{ch1_amp[w1+7]}}, ch1_amp }; 57 | wire signed [wout+11:0] scaled2 = { {wout+4-w2{ch2_amp[w2+7]}}, ch2_amp }; 58 | wire signed [wout+11:0] scaled3 = { {wout+4-w3{ch3_amp[w3+7]}}, ch3_amp }; 59 | 60 | reg signed [wout+11:0] sum, limited; 61 | 62 | wire signed [wout+11:0] max_pos = { {12{1'b0}}, {(wout-1){1'b1}}}; 63 | 64 | wire signed [8:0] 65 | g0 = {1'b0, gain0}, 66 | g1 = {1'b0, gain1}, 67 | g2 = {1'b0, gain2}, 68 | g3 = {1'b0, gain3}; 69 | 70 | // Apply gain 71 | always @(posedge clk) if(cen) begin 72 | ch0_amp <= g0 * ch0; 73 | ch1_amp <= g1 * ch1; 74 | ch2_amp <= g2 * ch2; 75 | ch3_amp <= g3 * ch3; 76 | 77 | // divides by 16 to take off the decimal part and leave only 78 | // the integer part 79 | sum <= (scaled0 + scaled1 + scaled2 + scaled3)>>>4; 80 | limited <= sum>max_pos ? max_pos : (sum<~max_pos ? ~max_pos : sum); 81 | mixed <= limited[wout-1:0]; 82 | end 83 | 84 | endmodule // jt12_mixer 85 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_acc.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Adds all 6 channels and apply linear interpolation to rise 23 | // sampling frequency to 55.5 kHz 24 | 25 | module jt10_adpcm_acc( 26 | input rst_n, 27 | input clk, // CPU clock 28 | input cen, // 111 kHz 29 | // pipeline channel 30 | input [5:0] cur_ch, 31 | input [5:0] en_ch, 32 | input match, 33 | 34 | input en_sum, 35 | input signed [15:0] pcm_in, // 18.5 kHz 36 | output reg signed [15:0] pcm_out // 55.5 kHz 37 | ); 38 | 39 | wire signed [17:0] pcm_in_long = en_sum ? { {2{pcm_in[15]}}, pcm_in } : 18'd0; 40 | reg signed [17:0] acc, last, pcm_full; 41 | reg signed [17:0] step; 42 | 43 | reg signed [17:0] diff; 44 | reg signed [22:0] diff_ext, step_full; 45 | 46 | always @(*) begin 47 | diff = acc-last; 48 | diff_ext = { {5{diff[17]}}, diff }; 49 | step_full = diff_ext // 1/128 50 | + ( diff_ext << 1 ) // 1/64 51 | + ( diff_ext << 3 ) // 1/16 52 | + ( diff_ext << 5 ); // 1/4 53 | 54 | end 55 | 56 | wire adv = en_ch[0] & cur_ch[0]; 57 | 58 | always @(posedge clk or negedge rst_n) 59 | if( !rst_n ) begin 60 | step <= 'd0; 61 | acc <= 18'd0; 62 | last <= 18'd0; 63 | end else if(cen) begin 64 | if( match ) 65 | acc <= cur_ch[0] ? pcm_in_long : ( pcm_in_long + acc ); 66 | if( adv ) begin 67 | // step = diff * (1/4+1/16+1/64+1/128) 68 | step <= { {2{step_full[22]}}, step_full[22:7] }; // >>>7; 69 | last <= acc; 70 | end 71 | end 72 | wire overflow = |pcm_full[17:15] & ~&pcm_full[17:15]; 73 | 74 | always @(posedge clk or negedge rst_n) 75 | if( !rst_n ) begin 76 | pcm_full <= 18'd0; 77 | end else if(cen && cur_ch[0]) begin 78 | case( en_ch ) 79 | 6'b000_001: pcm_full <= last; 80 | 6'b000_100, 81 | 6'b010_000: pcm_full <= pcm_full + step; 82 | default:; 83 | endcase 84 | if( overflow ) 85 | pcm_out <= pcm_full[17] ? 16'h8000 : 16'h7fff; // saturate 86 | else 87 | pcm_out <= pcm_full[15:0]; 88 | end 89 | 90 | endmodule // jt10_adpcm_acc -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pg_dt.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 2-11-2018 19 | 20 | Based on information posted by Nemesis on: 21 | http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 22 | 23 | Note that detune produces an output even for fnum==0, is that correct? 24 | 25 | Based on jt51_phasegen.v, from JT51 26 | 27 | */ 28 | 29 | module jt12_pg_dt( 30 | input [ 2:0] block, 31 | input [10:0] fnum, 32 | input [ 2:0] detune, 33 | 34 | output reg [ 4:0] keycode, 35 | output reg signed [5:0] detune_signed 36 | ); 37 | 38 | reg [5:0] detune_kf; 39 | reg [4:0] pow2; 40 | reg [5:0] detune_unlimited; 41 | reg [4:0] detune_limit, detune_limited; 42 | 43 | 44 | always @(*) begin 45 | keycode = { block, fnum[10], fnum[10] ? (|fnum[9:7]) : (&fnum[9:7])}; 46 | case( detune[1:0] ) 47 | 2'd1: detune_kf = { 1'b0, keycode } - 6'd4; 48 | 2'd2: detune_kf = { 1'b0, keycode } + 6'd4; 49 | 2'd3: detune_kf = { 1'b0, keycode } + 6'd8; 50 | default:detune_kf = { 1'b0, keycode }; 51 | endcase 52 | case( detune_kf[2:0] ) 53 | 3'd0: pow2 = 5'd16; 54 | 3'd1: pow2 = 5'd17; 55 | 3'd2: pow2 = 5'd19; 56 | 3'd3: pow2 = 5'd20; 57 | 3'd4: pow2 = 5'd22; 58 | 3'd5: pow2 = 5'd24; 59 | 3'd6: pow2 = 5'd26; 60 | 3'd7: pow2 = 5'd29; 61 | endcase 62 | case( detune[1:0] ) 63 | 2'd0: detune_limit = 5'd0; 64 | 2'd1: detune_limit = 5'd8; 65 | 2'd2: detune_limit = 5'd16; 66 | 2'd3: detune_limit = 5'd22; 67 | endcase 68 | case( detune_kf[5:3] ) 69 | 3'd0: detune_unlimited = { 5'd0, pow2[4] }; // <2 70 | 3'd1: detune_unlimited = { 4'd0, pow2[4:3] }; // <4 71 | 3'd2: detune_unlimited = { 3'd0, pow2[4:2] }; // <8 72 | 3'd3: detune_unlimited = { 2'd0, pow2[4:1] }; 73 | 3'd4: detune_unlimited = { 1'd0, pow2[4:0] }; 74 | 3'd5: detune_unlimited = { pow2[4:0], 1'd0 }; 75 | default:detune_unlimited = 6'd0; 76 | endcase 77 | detune_limited = detune_unlimited > {1'b0, detune_limit} ? 78 | detune_limit : detune_unlimited[4:0]; 79 | detune_signed = !detune[2] ? {1'b0,detune_limited} : (~{1'b0,detune_limited}+6'd1); 80 | end 81 | 82 | endmodule 83 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 27-12-2018 20 | 21 | */ 22 | 23 | // Wrapper to output only combined channels. Defaults to YM2612 mode. 24 | 25 | module jt12 ( 26 | input rst, // rst should be at least 6 clk&cen cycles long 27 | input clk, // CPU clock 28 | input cen, // optional clock enable, if not needed leave as 1'b1 29 | input [7:0] din, 30 | input [1:0] addr, 31 | input cs_n, 32 | input wr_n, 33 | 34 | output [7:0] dout, 35 | output irq_n, 36 | // configuration 37 | input en_hifi_pcm, 38 | input ladder, 39 | // combined output 40 | output signed [15:0] snd_right, 41 | output signed [15:0] snd_left, 42 | output snd_sample 43 | ); 44 | 45 | // Default parameters for JT12 select a YM2612 46 | jt12_top u_jt12( 47 | .rst ( rst ), // rst should be at least 6 clk&cen cycles long 48 | .clk ( clk ), // CPU clock 49 | .cen ( cen ), // optional clock enable, it not needed leave as 1'b1 50 | .din ( din ), 51 | .addr ( addr ), 52 | .cs_n ( cs_n ), 53 | .wr_n ( wr_n ), 54 | 55 | .dout ( dout ), 56 | .irq_n ( irq_n ), 57 | // configuration 58 | .en_hifi_pcm ( en_hifi_pcm ), 59 | .ladder ( ladder ), 60 | // Unused ADPCM pins 61 | .adpcma_addr ( ), // real hardware has 10 pins multiplexed through RMPX pin 62 | .adpcma_bank ( ), 63 | .adpcma_roe_n ( ), // ADPCM-A ROM output enable 64 | .adpcma_data ( 8'd0 ), // Data from RAM 65 | .adpcmb_addr ( ), // real hardware has 12 pins multiplexed through PMPX pin 66 | .adpcmb_roe_n ( ), // ADPCM-B ROM output enable 67 | // Separated output 68 | .psg_A (), 69 | .psg_B (), 70 | .psg_C (), 71 | .fm_snd_left (), 72 | .fm_snd_right (), 73 | // Unused YM2203 74 | .IOA_in (), 75 | .IOB_in (), 76 | // combined output 77 | .psg_snd (), 78 | .snd_right ( snd_right ), // FM+PSG 79 | .snd_left ( snd_left ), // FM+PSG 80 | .snd_sample ( snd_sample ), 81 | .debug_view ( ) 82 | ); 83 | endmodule // jt03 84 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/mixer/jt12_interpol.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 10-12-2018 20 | 21 | */ 22 | 23 | module jt12_interpol #(parameter calcw=18, inw=16, 24 | n=2, // number of stages 25 | m=1, // depth of comb filter 26 | rate=2 // it will stuff with as many as (rate-1) zeros 27 | )( 28 | input rst, 29 | input clk, 30 | (* direct_enable *) input cen_in, 31 | (* direct_enable *) input cen_out, 32 | input signed [inw-1:0] snd_in, 33 | output reg signed [inw-1:0] snd_out 34 | ); 35 | 36 | reg signed [calcw-1:0] inter6; 37 | wire signed [calcw-1:0] comb_op, integ_op; 38 | localparam wdiff = calcw - inw; 39 | 40 | generate 41 | genvar k; 42 | wire [calcw-1:0] comb_data[0:n]; 43 | assign comb_data[0] = { {wdiff{snd_in[inw-1]}}, snd_in }; 44 | assign comb_op = comb_data[n]; 45 | for(k=0;k. 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 14-2-2017 20 | 21 | */ 22 | 23 | module jt12_csr( // Circular Shift Register + input mux 24 | input rst, 25 | input clk, 26 | input clk_en /* synthesis direct_enable */, 27 | input [ 7:0] din, 28 | input [43:0] shift_in, 29 | output [43:0] shift_out, 30 | 31 | input up_tl, 32 | input up_dt1, 33 | input up_ks_ar, 34 | input up_amen_dr, 35 | input up_sr, 36 | input up_sl_rr, 37 | input up_ssgeg, 38 | input update_op_I, 39 | input update_op_II, 40 | input update_op_IV 41 | ); 42 | 43 | localparam regop_width=44; 44 | 45 | reg [regop_width-1:0] regop_in; 46 | 47 | jt12_sh_rst #(.width(regop_width),.stages(12)) u_regch( 48 | .clk ( clk ), 49 | .clk_en ( clk_en ), 50 | .rst ( rst ), 51 | .din ( regop_in ), 52 | .drop ( shift_out ) 53 | ); 54 | 55 | wire up_tl_op = up_tl & update_op_IV; 56 | wire up_dt1_op = up_dt1 & update_op_I; 57 | wire up_mul_op = up_dt1 & update_op_II; 58 | wire up_ks_op = up_ks_ar & update_op_II; 59 | wire up_ar_op = up_ks_ar & update_op_I; 60 | wire up_amen_op = up_amen_dr& update_op_IV; 61 | wire up_dr_op = up_amen_dr& update_op_I; 62 | wire up_sr_op = up_sr & update_op_I; 63 | wire up_sl_op = up_sl_rr & update_op_I; 64 | wire up_rr_op = up_sl_rr & update_op_I; 65 | wire up_ssg_op = up_ssgeg & update_op_I; 66 | 67 | always @(*) 68 | regop_in = { 69 | up_tl_op ? din[6:0] : shift_in[43:37], // 7 70 | up_dt1_op ? din[6:4] : shift_in[36:34], // 3 71 | up_mul_op ? din[3:0] : shift_in[33:30], // 4 72 | up_ks_op ? din[7:6] : shift_in[29:28], // 2 73 | up_ar_op ? din[4:0] : shift_in[27:23], // 5 74 | up_amen_op ? din[7] : shift_in[ 22], // 1 75 | up_dr_op ? din[4:0] : shift_in[21:17], // 5 76 | up_sr_op ? din[4:0] : shift_in[16:12], // 5 77 | up_sl_op ? din[7:4] : shift_in[11: 8], // 4 78 | up_rr_op ? din[3:0] : shift_in[ 7: 4], // 4 79 | up_ssg_op ? din[3:0] : shift_in[ 3: 0] // 4 80 | }; 81 | 82 | endmodule // jt12_reg -------------------------------------------------------------------------------- /src/fpga/core/sync_fifo.sv: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2022 Adam Gastineau 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | // An easily reusable method for synchronizing multiple bits across clock domains 26 | // Uses a shallow depth (4 entries) FIFO, so make sure to empty it quickly 27 | module sync_fifo #( 28 | parameter WIDTH = 2 29 | ) ( 30 | input wire clk_write, 31 | input wire clk_read, 32 | 33 | input wire write_en, 34 | input wire [WIDTH - 1:0] data_in, 35 | output reg [WIDTH - 1:0] data_out = 0 36 | ); 37 | 38 | reg read_req = 0; 39 | wire empty; 40 | 41 | wire [WIDTH - 1:0] fifo_out; 42 | 43 | dcfifo dcfifo_component ( 44 | .data(data_in), 45 | .rdclk(clk_read), 46 | .rdreq(read_req), 47 | .wrclk(clk_write), 48 | .wrreq(write_en), 49 | .q(fifo_out), 50 | .rdempty(empty), 51 | .aclr(), 52 | .eccstatus(), 53 | .rdfull(), 54 | .rdusedw(), 55 | .wrempty(), 56 | .wrfull(), 57 | .wrusedw() 58 | ); 59 | defparam dcfifo_component.intended_device_family = "Cyclone V", dcfifo_component.lpm_numwords = 4, 60 | dcfifo_component.lpm_showahead = "OFF", dcfifo_component.lpm_type = "dcfifo", 61 | dcfifo_component.lpm_width = 32, dcfifo_component.lpm_widthu = 2, 62 | dcfifo_component.overflow_checking = "ON", dcfifo_component.rdsync_delaypipe = 5, 63 | dcfifo_component.underflow_checking = "ON", dcfifo_component.use_eab = "ON", 64 | dcfifo_component.wrsync_delaypipe = 5; 65 | 66 | reg [1:0] read_state = 0; 67 | 68 | localparam READ_DELAY = 1; 69 | localparam READ_WRITE = 2; 70 | 71 | always @(posedge clk_read) begin 72 | read_req <= 0; 73 | 74 | if (~empty) begin 75 | read_state <= READ_DELAY; 76 | read_req <= 1; 77 | end 78 | 79 | case (read_state) 80 | READ_DELAY: begin 81 | read_state <= READ_WRITE; 82 | end 83 | READ_WRITE: begin 84 | read_state <= 0; 85 | 86 | data_out <= fifo_out; 87 | end 88 | endcase 89 | end 90 | 91 | endmodule 92 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/SVP/SSP160x_PKG.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.Std_Logic_1164.all; 3 | library STD; 4 | use ieee.numeric_std.all; 5 | 6 | package SSP160x_PKG is 7 | 8 | constant REG_0 : std_logic_vector(3 downto 0) := x"0"; 9 | constant REG_X : std_logic_vector(3 downto 0) := x"1"; 10 | constant REG_Y : std_logic_vector(3 downto 0) := x"2"; 11 | constant REG_AH : std_logic_vector(3 downto 0) := x"3"; 12 | constant REG_ST : std_logic_vector(3 downto 0) := x"4"; 13 | constant REG_SP : std_logic_vector(3 downto 0) := x"5"; 14 | constant REG_PC : std_logic_vector(3 downto 0) := x"6"; 15 | constant REG_P : std_logic_vector(3 downto 0) := x"7"; 16 | constant REG_EXT0 : std_logic_vector(3 downto 0) := x"8"; 17 | constant REG_EXT1 : std_logic_vector(3 downto 0) := x"9"; 18 | constant REG_EXT2 : std_logic_vector(3 downto 0) := x"A"; 19 | constant REG_EXT3 : std_logic_vector(3 downto 0) := x"B"; 20 | constant REG_EXT4 : std_logic_vector(3 downto 0) := x"C"; 21 | constant REG_EXT5 : std_logic_vector(3 downto 0) := x"D"; 22 | constant REG_EXT6 : std_logic_vector(3 downto 0) := x"E"; 23 | constant REG_AL : std_logic_vector(3 downto 0) := x"F"; 24 | 25 | type InstrType_t is ( 26 | IT_NON, 27 | IT_LD, 28 | IT_ADD, 29 | IT_SUB, 30 | IT_AND, 31 | IT_OR, 32 | IT_EOR, 33 | IT_CMP, 34 | IT_SHL, 35 | IT_SHR, 36 | IT_NEG, 37 | IT_ABS, 38 | IT_MLD, 39 | IT_MPYA, 40 | IT_MPYS, 41 | IT_BRA, 42 | IT_CALL, 43 | IT_SETI 44 | ); 45 | 46 | type InstrAddr_t is ( 47 | IA_NON, 48 | IA_ACC, 49 | IA_REGX, 50 | IA_REGY, 51 | IA_PTR, 52 | IA_RAM, 53 | IA_IMM8, 54 | IA_IMM16, 55 | IA_INDPTR, 56 | IA_INDACC, 57 | IA_PREG 58 | ); 59 | 60 | type Instr_r is record 61 | IT : InstrType_t; 62 | AS : InstrAddr_t; 63 | AD : InstrAddr_t; 64 | X : std_logic_vector(3 downto 0); 65 | Y : std_logic_vector(3 downto 0); 66 | RAM : std_logic_vector(1 downto 0); 67 | end record; 68 | 69 | 70 | type PointRegs_t is array (0 to 7) of std_logic_vector(7 downto 0); 71 | type Stack_t is array (0 to 5) of std_logic_vector(15 downto 0); 72 | 73 | 74 | function ModAdj(data: std_logic_vector(7 downto 0); m: std_logic_vector(2 downto 0); inc: std_logic) return std_logic_vector; 75 | 76 | end SSP160x_PKG; 77 | 78 | package body SSP160x_PKG is 79 | 80 | function ModAdj(data: std_logic_vector(7 downto 0); m: std_logic_vector(2 downto 0); inc: std_logic) return std_logic_vector is 81 | variable mask: std_logic_vector(7 downto 0); 82 | variable temp: std_logic_vector(7 downto 0); 83 | variable res: std_logic_vector(7 downto 0); 84 | begin 85 | case m is 86 | when "001" => mask := "00000001"; 87 | when "010" => mask := "00000011"; 88 | when "011" => mask := "00000111"; 89 | when "100" => mask := "00001111"; 90 | when "101" => mask := "00011111"; 91 | when "110" => mask := "00111111"; 92 | when "111" => mask := "01111111"; 93 | when others => mask := "11111111"; 94 | end case; 95 | if inc = '1' then 96 | temp := std_logic_vector(unsigned(data) + 1); 97 | else 98 | temp := std_logic_vector(unsigned(data) - 1); 99 | end if; 100 | 101 | res := (data and not mask) or (temp and mask); 102 | return res; 103 | end function; 104 | 105 | end package body SSP160x_PKG; 106 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pcm.v: -------------------------------------------------------------------------------- 1 | module jt12_pcm( 2 | input rst, 3 | input clk, 4 | input clk_en /* synthesis direct_enable */, 5 | input zero, 6 | input signed [8:0] pcm, 7 | input pcm_wr, 8 | output reg signed [8:0] pcm_resampled 9 | ); 10 | 11 | // reg [2:0] ratesel; 12 | // reg [3:0] cnt8; 13 | // reg wrcnt, wrclr; 14 | reg last_zero; 15 | wire zero_edge = !last_zero && zero; 16 | /* 17 | always @(posedge clk) 18 | if(rst) begin 19 | cnt8 <= 4'd0; 20 | wrclr <= 1'd0; 21 | ratesel <= 3'd1; 22 | wrcnt <= 1'b0; 23 | end else if(clk_en) begin 24 | if( pcm_wr ) begin 25 | if( wrcnt ) begin 26 | // case( cnt8[3:2] ) 27 | // 2'd3: ratesel <= 3'b111; // x8 28 | // 2'd2: ratesel <= 3'b011; // x4 29 | // 2'd1: ratesel <= 3'b001; // x2 30 | // 2'd0: ratesel <= 3'b000; // x1 31 | // endcase 32 | cnt8 <= 4'd0; 33 | wrcnt <= 1'b0; 34 | end 35 | else wrcnt <= 1'b1; 36 | end else 37 | if( cnt8!=4'hf && zero ) cnt8 <= cnt8 + 4'd1; 38 | end 39 | */ 40 | // up-rate PCM samples 41 | reg rate1, rate2; //, rate4, rate8; 42 | reg cen1, cen2; //, cen4, cen8; 43 | 44 | always @(posedge clk, posedge rst) 45 | if(rst) 46 | rate2 <= 1'b0; 47 | else begin 48 | last_zero <= zero; 49 | rate1 <= zero_edge; 50 | if(zero_edge) begin 51 | rate2 <= ~rate2; 52 | // if(rate2) begin 53 | // rate4 <= ~rate4; 54 | // if(rate4) rate8<=~rate8; 55 | // end 56 | end 57 | end 58 | 59 | always @(posedge clk) begin 60 | cen1 <= rate1; 61 | cen2 <= rate1 && rate2; 62 | // cen4 <= rate1 && rate2 && rate4; 63 | // cen8 <= rate1 && rate2 && rate4 && rate8; 64 | end 65 | 66 | wire signed [8:0] pcm3; //,pcm2, pcm1; 67 | 68 | //always @(posedge clk) if( clk_en ) 69 | // pcm_resampled <= ratesel[0] ? pcm3 : pcm; 70 | always @(*) 71 | pcm_resampled = pcm3; 72 | 73 | // rate x2 74 | //wire signed [8:0] pcm_in2 = ratesel[1] ? pcm2 : pcm; 75 | jt12_interpol #(.calcw(10),.inw(9),.rate(2),.m(1),.n(2)) 76 | u_uprate_3( 77 | .clk ( clk ), 78 | .rst ( rst ), 79 | .cen_in ( cen2 ), 80 | .cen_out( cen1 ), 81 | // .snd_in ( pcm_in2 ), 82 | .snd_in ( pcm ), 83 | .snd_out( pcm3 ) 84 | ); 85 | /* 86 | // rate x2 87 | wire signed [8:0] pcm_in1 = ratesel[2] ? pcm1 : pcm; 88 | jt12_interpol #(.calcw(10),.inw(9),.rate(2),.m(1),.n(2)) 89 | u_uprate_2( 90 | .clk ( clk ), 91 | .rst ( rst ), 92 | .cen_in ( cen4 ), 93 | .cen_out( cen2 ), 94 | .snd_in ( pcm_in1 ), 95 | .snd_out( pcm2 ) 96 | ); 97 | 98 | // rate x2 99 | jt12_interpol #(.calcw(10),.inw(9),.rate(2),.m(1),.n(2)) 100 | u_uprate_1( 101 | .clk ( clk ), 102 | .rst ( rst ), 103 | .cen_in ( cen8 ), 104 | .cen_out( cen4 ), 105 | .snd_in ( pcm ), 106 | .snd_out( pcm1 ) 107 | ); 108 | */ 109 | endmodule // jt12_pcm -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt03.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03.v ] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03_acc.v ] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] 12 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] 13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] 14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] 15 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] 16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] 17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] 18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] 19 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] 21 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] 22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] 23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] 24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] 25 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] 26 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] 27 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] 28 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] 29 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] 30 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] 31 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] 32 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] 33 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] 34 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_dout.v ] 35 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49.qip ] 36 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pg.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 14-2-2016 19 | 20 | Based on information posted by Nemesis on: 21 | http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 22 | 23 | Based on jt51_phasegen.v, from JT51 24 | 25 | */ 26 | 27 | 28 | /* 29 | 30 | tab size 4 31 | 32 | */ 33 | 34 | module jt12_pg( 35 | input clk, 36 | input clk_en /* synthesis direct_enable */, 37 | input rst, 38 | // Channel frequency 39 | input [10:0] fnum_I, 40 | input [ 2:0] block_I, 41 | // Operator multiplying 42 | input [ 3:0] mul_II, 43 | // Operator detuning 44 | input [ 2:0] dt1_I, // same as JT51's DT1 45 | // phase modulation from LFO 46 | input [ 6:0] lfo_mod, 47 | input [ 2:0] pms_I, 48 | // phase operation 49 | input pg_rst_II, 50 | input pg_stop, // not implemented 51 | 52 | output reg [ 4:0] keycode_II, 53 | output [ 9:0] phase_VIII 54 | ); 55 | 56 | parameter num_ch=6; 57 | 58 | wire [4:0] keycode_I; 59 | wire signed [5:0] detune_mod_I; 60 | reg signed [5:0] detune_mod_II; 61 | wire [16:0] phinc_I; 62 | reg [16:0] phinc_II; 63 | wire [19:0] phase_drop, phase_in; 64 | wire [ 9:0] phase_II; 65 | 66 | always @(posedge clk) if(clk_en) begin 67 | keycode_II <= keycode_I; 68 | detune_mod_II <= detune_mod_I; 69 | phinc_II <= phinc_I; 70 | end 71 | 72 | jt12_pg_comb u_comb( 73 | .block ( block_I ), 74 | .fnum ( fnum_I ), 75 | // Phase Modulation 76 | .lfo_mod ( lfo_mod[6:2] ), 77 | .pms ( pms_I ), 78 | 79 | // Detune 80 | .detune ( dt1_I ), 81 | .keycode ( keycode_I ), 82 | .detune_out ( detune_mod_I ), 83 | // Phase increment 84 | .phinc_out ( phinc_I ), 85 | // Phase add 86 | .mul ( mul_II ), 87 | .phase_in ( phase_drop ), 88 | .pg_rst ( pg_rst_II ), 89 | .detune_in ( detune_mod_II ), 90 | .phinc_in ( phinc_II ), 91 | 92 | .phase_out ( phase_in ), 93 | .phase_op ( phase_II ) 94 | ); 95 | 96 | jt12_sh_rst #( .width(20), .stages(4*num_ch) ) u_phsh( 97 | .clk ( clk ), 98 | .clk_en ( clk_en ), 99 | .rst ( rst ), 100 | .din ( phase_in ), 101 | .drop ( phase_drop) 102 | ); 103 | 104 | jt12_sh_rst #( .width(10), .stages(6) ) u_pad( 105 | .clk ( clk ), 106 | .clk_en ( clk_en ), 107 | .rst ( rst ), 108 | .din ( phase_II ), 109 | .drop ( phase_VIII) 110 | ); 111 | 112 | endmodule 113 | 114 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_eg_ctrl.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 29-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_ctrl( 23 | input keyon_now, 24 | input keyoff_now, 25 | input [2:0] state_in, 26 | input [9:0] eg, 27 | // envelope configuration 28 | input [4:0] arate, // attack rate 29 | input [4:0] rate1, // decay rate 30 | input [4:0] rate2, // sustain rate 31 | input [3:0] rrate, 32 | input [3:0] sl, // sustain level 33 | // SSG operation 34 | input ssg_en, 35 | input [2:0] ssg_eg, 36 | // SSG output inversion 37 | input ssg_inv_in, 38 | output reg ssg_inv_out, 39 | 40 | output reg [4:0] base_rate, 41 | output reg [2:0] state_next, 42 | output reg pg_rst 43 | ); 44 | 45 | localparam ATTACK = 3'b001, 46 | DECAY = 3'b010, 47 | HOLD = 3'b100, 48 | RELEASE= 3'b000; // default state is release 49 | 50 | // wire is_decaying = state_in[1] | state_in[2]; 51 | 52 | reg [4:0] sustain; 53 | 54 | always @(*) 55 | if( sl == 4'd15 ) 56 | sustain = 5'h1f; // 93dB 57 | else 58 | sustain = {1'b0, sl}; 59 | 60 | wire ssg_en_out; 61 | reg ssg_en_in, ssg_pg_rst; 62 | 63 | // aliases 64 | wire ssg_att = ssg_eg[2]; 65 | wire ssg_alt = ssg_eg[1]; 66 | wire ssg_hold = ssg_eg[0] & ssg_en; 67 | 68 | reg ssg_over; 69 | 70 | 71 | always @(*) begin 72 | ssg_over = ssg_en && eg[9]; // eg >=10'h200 73 | ssg_pg_rst = ssg_over && !( ssg_alt || ssg_hold ); 74 | pg_rst = keyon_now | ssg_pg_rst; 75 | end 76 | 77 | always @(*) 78 | casez ( { keyoff_now, keyon_now, state_in} ) 79 | 5'b01_???: begin // key on 80 | base_rate = arate; 81 | state_next = ATTACK; 82 | ssg_inv_out = ssg_att & ssg_en; 83 | end 84 | {2'b00, ATTACK}: 85 | if( eg==10'd0 ) begin 86 | base_rate = rate1; 87 | state_next = DECAY; 88 | ssg_inv_out = ssg_inv_in; 89 | end 90 | else begin 91 | base_rate = arate; 92 | state_next = ATTACK; 93 | ssg_inv_out = ssg_inv_in; 94 | end 95 | {2'b00, DECAY}: begin 96 | if( ssg_over ) begin 97 | base_rate = ssg_hold ? 5'd0 : arate; 98 | state_next = ssg_hold ? HOLD : ATTACK; 99 | ssg_inv_out = ssg_en & (ssg_alt ^ ssg_inv_in); 100 | end 101 | else begin 102 | base_rate = eg[9:5] >= sustain ? rate2 : rate1; // equal comparison according to Nuke 103 | state_next = DECAY; 104 | ssg_inv_out = ssg_inv_in; 105 | end 106 | end 107 | {2'b00, HOLD}: begin 108 | base_rate = 5'd0; 109 | state_next = HOLD; 110 | ssg_inv_out = ssg_inv_in; 111 | end 112 | default: begin // RELEASE, note that keyoff_now==1 will enter this state too 113 | base_rate = { rrate, 1'b1 }; 114 | state_next = RELEASE; // release 115 | ssg_inv_out = 1'b0; // this can produce a glitch in the output 116 | // But to release from SSG cannot be done nicely while 117 | // inverting the ouput 118 | end 119 | endcase 120 | 121 | 122 | endmodule // jt12_eg_ctrl -------------------------------------------------------------------------------- /src/fpga/core/rtl/genesis_lpf.v: -------------------------------------------------------------------------------- 1 | /*MIT License 2 | 3 | Copyright (c) 2019 Gregory Hogan (Soltan_G42) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE.*/ 22 | 23 | // This module is intended to be used from system.sv to low pass Genesis audio. 24 | // Both Model 1 and Model 2 Genesis models have a global 1st order low-pass 25 | // audio filter. The model 2 has an addition 2nd order low-pass for FM audio 26 | 27 | module genesis_lpf( 28 | input clk, 29 | input reset, 30 | input [1:0] lpf_mode, 31 | input signed [15:0] in, 32 | output signed [15:0] out); 33 | 34 | reg [9:0] div = 504; //For genesis we'll sample at 53.69mhz/504 = 106528 Hz 35 | 36 | //Coefficients computed with Octave/Matlab/Online filter calculators. 37 | //or with scipy.signal.bessel or similar tools 38 | reg signed [17:0] A2; 39 | reg signed [17:0] B2; 40 | reg signed [17:0] B1; 41 | 42 | wire signed [15:0] audio_post_lpf1; 43 | 44 | always @ (*) begin 45 | case(lpf_mode[1:0]) 46 | 2'b00 : begin //Model 1 Low Pass at 3.1khz with adjusted slope 47 | A2 = -18'd27504; 48 | B1 = 18'd10528; 49 | B2 = -18'd5264; 50 | end 51 | 2'b01 : begin //model 2 is measured around 3.96khz 52 | A2 = -18'sd26328; 53 | B1 = 18'sd12888; 54 | B2 = -18'sd6440; 55 | end 56 | 2'b10 : begin //8.5khz low pass as a "Minimal" filter. 57 | A2 = -18'd19088; 58 | B1 = 18'd6840; 59 | B2 = 18'd6840; 60 | end 61 | default: begin //Space for a 4th filter. This filter is not used 62 | A2 = -18'sd32768; 63 | B1 = 18'sd0; 64 | B2 = 18'sd0; 65 | end 66 | endcase 67 | end 68 | 69 | iir_1st_order lpf6db(.clk(clk), 70 | .reset(reset), 71 | .div(div), 72 | .A2(A2), 73 | .B1(B1), 74 | .B2(B2), 75 | .in(in), 76 | .out(audio_post_lpf1)); 77 | 78 | assign out = ( lpf_mode[1:0] == 2'b11 ) ? in : audio_post_lpf1; 79 | 80 | endmodule //genesis_lpf 81 | 82 | //This module is intended to be used from system.sv to filter the FM sound before it's mixed with PSG. 83 | //The model 2 genesis has such a filter. The model 1 has only a global low-pass 84 | module genesis_fm_lpf( 85 | input clk, 86 | input reset, 87 | input signed [15:0] in, 88 | output signed [15:0] out); 89 | 90 | wire signed [15:0] middle; 91 | 92 | iir_2nd_order fm2(.clk(clk), 93 | .reset(reset), 94 | .div(10'd504), //Divider for 106528hz 95 | .A2(-18'sd24704), 96 | .A3(18'sd10728), 97 | .B1(18'sd1083), 98 | .B2(18'sd1204), 99 | .B3(18'sd121), 100 | .in(in), 101 | .out(out)); 102 | endmodule //genesis_fm_lpf -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_pcm_interpol.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | module jt12_pcm_interpol 23 | #(parameter dw=9, stepw=5) 24 | ( 25 | input rst_n, 26 | input clk, 27 | input cen, // 8MHz cen 28 | input cen55, // clk & cen55 = 55 kHz 29 | input pcm_wr, // advance to next sample 30 | input signed [dw-1:0] pcmin, 31 | output reg signed [dw-1:0] pcmout 32 | ); 33 | 34 | reg [stepw-1:0] dn, pre_dn={stepw{1'b1}}; 35 | wire posedge_pcmwr = pcm_wr && !last_pcm_wr; 36 | wire negedge_pcmwr = !pcm_wr && last_pcm_wr; 37 | 38 | reg start_div = 0; 39 | wire working; 40 | 41 | reg signed [dw-1:0] pcmnew, dx, pcmlast, pcminter; 42 | wire signed [dw:0] dx_ext = { pcmin[dw-1], pcmin } - { pcmnew[dw-1], pcmnew }; 43 | reg sign, last_pcm_wr; 44 | 45 | // latch new data and compute the two deltas : dx and dn, slope = dx/dn 46 | always @(posedge clk) begin 47 | last_pcm_wr <= pcm_wr; 48 | start_div <= posedge_pcmwr; 49 | 50 | if( posedge_pcmwr ) begin 51 | pre_dn <= 1; 52 | pcmnew <= pcmin; 53 | pcmlast <= pcmnew; 54 | dn <= pre_dn; 55 | dx <= dx_ext[dw] ? ~dx_ext[dw-1:0] + 'd1 : dx_ext[dw-1:0]; 56 | sign <= dx_ext[dw]; 57 | start_div <= 1; 58 | end 59 | 60 | if( !pcm_wr && cen55 ) begin 61 | if( pre_dn != {stepw{1'b1}} ) pre_dn <= pre_dn + 'd1; 62 | end 63 | end 64 | 65 | // interpolate samples 66 | wire [dw-1:0] step; 67 | wire signed [dw-1:0] next_up = pcminter + step; 68 | wire signed [dw-1:0] next_down = pcminter - step; 69 | wire overflow_up = 0;//next_up[dw-1] != pcmnew[dw-1]; 70 | wire overflow_down = 0;//next_down[dw-1] != pcmnew[dw-1]; 71 | 72 | 73 | always @(posedge clk) begin 74 | if( negedge_pcmwr ) begin 75 | pcminter <= pcmlast; 76 | end else if(cen55 && !working && !pcm_wr) begin // only advance if the divider has finished 77 | if( sign ) begin // subtract 78 | if( next_down > pcmnew && !overflow_down ) 79 | pcminter <= next_down; 80 | else 81 | pcminter <= pcmnew; // done 82 | end 83 | else begin // add 84 | if( next_up < pcmnew && !overflow_up ) 85 | pcminter <= next_up; 86 | else 87 | pcminter <= pcmnew; // done 88 | end 89 | end 90 | end 91 | 92 | // output only at cen55 93 | 94 | always @(posedge clk) if(cen55) pcmout <= pcminter; 95 | 96 | jt10_adpcm_div #(.dw(dw)) u_div( 97 | .rst_n ( rst_n ), 98 | .clk ( clk ), 99 | .cen ( 1'b1 ), 100 | .start ( start_div ), 101 | .a ( dx ), 102 | .b ( { {dw-stepw{1'b0}}, dn } ), 103 | .d ( step ), 104 | .r ( ), 105 | .working( working ) 106 | ); 107 | 108 | 109 | endmodule // jt10_adpcmb_interpol -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12.v ] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_acc.v ] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] 12 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] 13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] 14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] 15 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] 16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] 17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] 18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] 19 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] 21 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] 22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] 23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] 24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] 25 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] 26 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] 27 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] 28 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] 29 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] 30 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] 31 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] 32 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] 33 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pcm_interpol.v ] 34 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] 35 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_dout.v ] 36 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_rst.v ] 37 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_div.v ] 38 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_genmix.v ] 39 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_decim.v ] 40 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_interpol.v ] 41 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_comb.v ] 42 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_fm_uprate.v ] 43 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_eg_step.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 29-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_step( 23 | input attack, 24 | input [ 4:0] base_rate, 25 | input [ 4:0] keycode, 26 | input [14:0] eg_cnt, 27 | input cnt_in, 28 | input [ 1:0] ks, 29 | output cnt_lsb, 30 | output reg step, 31 | output reg [5:0] rate, 32 | output reg sum_up 33 | ); 34 | 35 | reg [6:0] pre_rate; 36 | 37 | always @(*) begin : pre_rate_calc 38 | if( base_rate == 5'd0 ) 39 | pre_rate = 7'd0; 40 | else 41 | case( ks ) 42 | 2'd3: pre_rate = { base_rate, 1'b0 } + { 1'b0, keycode }; 43 | 2'd2: pre_rate = { base_rate, 1'b0 } + { 2'b0, keycode[4:1] }; 44 | 2'd1: pre_rate = { base_rate, 1'b0 } + { 3'b0, keycode[4:2] }; 45 | 2'd0: pre_rate = { base_rate, 1'b0 } + { 4'b0, keycode[4:3] }; 46 | endcase 47 | end 48 | 49 | always @(*) 50 | rate = pre_rate[6] ? 6'd63 : pre_rate[5:0]; 51 | 52 | reg [2:0] cnt; 53 | 54 | reg [4:0] mux_sel; 55 | always @(*) begin 56 | mux_sel = attack ? (rate[5:2]+4'd1): {1'b0,rate[5:2]}; 57 | end // always @(*) 58 | 59 | always @(*) 60 | case( mux_sel ) 61 | 5'h0: cnt = eg_cnt[14:12]; 62 | 5'h1: cnt = eg_cnt[13:11]; 63 | 5'h2: cnt = eg_cnt[12:10]; 64 | 5'h3: cnt = eg_cnt[11: 9]; 65 | 5'h4: cnt = eg_cnt[10: 8]; 66 | 5'h5: cnt = eg_cnt[ 9: 7]; 67 | 5'h6: cnt = eg_cnt[ 8: 6]; 68 | 5'h7: cnt = eg_cnt[ 7: 5]; 69 | 5'h8: cnt = eg_cnt[ 6: 4]; 70 | 5'h9: cnt = eg_cnt[ 5: 3]; 71 | 5'ha: cnt = eg_cnt[ 4: 2]; 72 | 5'hb: cnt = eg_cnt[ 3: 1]; 73 | default: cnt = eg_cnt[ 2: 0]; 74 | endcase 75 | 76 | //////////////////////////////// 77 | reg [7:0] step_idx; 78 | 79 | always @(*) begin : rate_step 80 | if( rate[5:4]==2'b11 ) begin // 0 means 1x, 1 means 2x 81 | if( rate[5:2]==4'hf && attack) 82 | step_idx = 8'b11111111; // Maximum attack speed, rates 60&61 83 | else 84 | case( rate[1:0] ) 85 | 2'd0: step_idx = 8'b00000000; 86 | 2'd1: step_idx = 8'b10001000; // 2 87 | 2'd2: step_idx = 8'b10101010; // 4 88 | 2'd3: step_idx = 8'b11101110; // 6 89 | endcase 90 | end 91 | else begin 92 | if( rate[5:2]==4'd0 && !attack) 93 | step_idx = 8'b11111110; // limit slowest decay rate 94 | else 95 | case( rate[1:0] ) 96 | 2'd0: step_idx = 8'b10101010; // 4 97 | 2'd1: step_idx = 8'b11101010; // 5 98 | 2'd2: step_idx = 8'b11101110; // 6 99 | 2'd3: step_idx = 8'b11111110; // 7 100 | endcase 101 | end 102 | // a rate of zero keeps the level still 103 | step = rate[5:1]==5'd0 ? 1'b0 : step_idx[ cnt ]; 104 | end 105 | 106 | assign cnt_lsb = cnt[0]; 107 | always @(*) begin 108 | sum_up = cnt[0] != cnt_in; 109 | end 110 | 111 | endmodule // eg_step -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcmb_cnt.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // ADPCM-B counter 23 | 24 | module jt10_adpcmb_cnt( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen, // clk & cen = 55 kHz 28 | 29 | // counter control 30 | input [15:0] delta_n, 31 | input clr, 32 | input on, 33 | input acmd_up_b, 34 | // Address 35 | input [15:0] astart, 36 | input [15:0] aend, 37 | input arepeat, 38 | output reg [23:0] addr, 39 | output reg nibble_sel, 40 | // Flag 41 | output reg chon, 42 | output reg flag, 43 | input clr_flag, 44 | output reg restart, 45 | 46 | output reg adv 47 | ); 48 | 49 | // Counter 50 | reg [15:0] cnt; 51 | 52 | always @(posedge clk or negedge rst_n) 53 | if(!rst_n) begin 54 | cnt <= 'd0; 55 | adv <= 'b0; 56 | end else if(cen) begin 57 | if( clr) begin 58 | cnt <= 'd0; 59 | adv <= 'b0; 60 | end else begin 61 | if( on ) 62 | {adv, cnt} <= {1'b0, cnt} + {1'b0, delta_n }; 63 | else begin 64 | cnt <= 'd0; 65 | adv <= 1'b1; // let the rest of the signal chain advance 66 | // when channel is off so all registers go to reset values 67 | end 68 | end 69 | end 70 | 71 | reg set_flag, last_set; 72 | 73 | always @(posedge clk or negedge rst_n) 74 | if(!rst_n) begin 75 | flag <= 1'b0; 76 | last_set <= 'b0; 77 | end else begin 78 | last_set <= set_flag; 79 | if( clr_flag ) flag <= 1'b0; 80 | if( !last_set && set_flag ) flag <= 1'b1; 81 | end 82 | 83 | // Address 84 | always @(posedge clk or negedge rst_n) 85 | if(!rst_n) begin 86 | addr <= 'd0; 87 | nibble_sel <= 'b0; 88 | set_flag <= 'd0; 89 | chon <= 'b0; 90 | restart <= 'b0; 91 | end else if( !on || clr ) begin 92 | restart <= 'd0; 93 | chon <= 'd0; 94 | end else if( acmd_up_b && on ) begin 95 | restart <= 'd1; 96 | end else if( cen ) begin 97 | if( restart && adv ) begin 98 | addr <= {astart,8'd0}; 99 | nibble_sel <= 'b0; 100 | restart <= 'd0; 101 | chon <= 'd1; 102 | end else if( chon && adv ) begin 103 | if( { addr, nibble_sel } != { aend, 8'hFF, 1'b1 } ) begin 104 | { addr, nibble_sel } <= { addr, nibble_sel } + 25'd1; 105 | set_flag <= 'd0; 106 | end else if(arepeat) begin 107 | restart <= 'd1; 108 | end else begin 109 | set_flag <= 'd1; 110 | chon <= 'd0; 111 | end 112 | end 113 | end // cen 114 | 115 | 116 | endmodule // jt10_adpcmb_cnt 117 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/alt/eg_mux.v: -------------------------------------------------------------------------------- 1 | /* 2 | Using two large case statements: 3 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 4 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 5 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 6 | | eg_mux/ | | 11/12 | 13/14 | 31/31 | 1/1 | 0/0 | 0/0 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | eg_mux | 7 | | +u_cntsh | | 1/1 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_mux/u_cntsh | 8 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 9 | Using one large case statement: 10 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 11 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 12 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 13 | | eg_mux/ | | 11/12 | 13/14 | 21/21 | 1/1 | 0/0 | 0/0 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | eg_mux | 14 | | +u_cntsh | | 1/1 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_mux/u_cntsh | 15 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 16 | */ 17 | 18 | module eg_mux( 19 | input clk, 20 | input clk_en, 21 | input rst, 22 | input [14:0] eg_cnt, 23 | input [2:0] state_IV, 24 | input [5:0] rate_IV, 25 | 26 | output reg [2:0] state_V, 27 | output reg [5:0] rate_V, 28 | output reg [2:0] cnt_V, 29 | output reg sum_up 30 | ); 31 | 32 | localparam ATTACK=3'd0, DECAY1=3'd1, DECAY2=3'd2, RELEASE=3'd7, HOLD=3'd3; 33 | wire cnt_out; 34 | reg [3:0] mux_sel; 35 | 36 | always @(*) begin 37 | mux_sel = (state_IV == ATTACK && rate_IV[5:2]!=4'hf) ? (rate_IV[5:2]+4'd1): rate_IV[5:2]; 38 | end // always @(*) 39 | 40 | always @(posedge clk) if( clk_en ) begin 41 | if( rst ) begin 42 | state_V <= RELEASE; 43 | rate_V <= 6'h1F; // should it be 6'h3F? TODO 44 | //cnt_V<= 3'd0; 45 | end 46 | else begin 47 | state_V <= state_IV; 48 | rate_V <= rate_IV; 49 | case( mux_sel ) 50 | 4'h0: cnt_V <= eg_cnt[14:12]; 51 | 4'h1: cnt_V <= eg_cnt[13:11]; 52 | 4'h2: cnt_V <= eg_cnt[12:10]; 53 | 4'h3: cnt_V <= eg_cnt[11: 9]; 54 | 4'h4: cnt_V <= eg_cnt[10: 8]; 55 | 4'h5: cnt_V <= eg_cnt[ 9: 7]; 56 | 4'h6: cnt_V <= eg_cnt[ 8: 6]; 57 | 4'h7: cnt_V <= eg_cnt[ 7: 5]; 58 | 4'h8: cnt_V <= eg_cnt[ 6: 4]; 59 | 4'h9: cnt_V <= eg_cnt[ 5: 3]; 60 | 4'ha: cnt_V <= eg_cnt[ 4: 2]; 61 | 4'hb: cnt_V <= eg_cnt[ 3: 1]; 62 | default: cnt_V <= eg_cnt[ 2: 0]; 63 | endcase 64 | end 65 | end 66 | 67 | jt12_sh/*_rst*/ #( .width(1), .stages(24) ) u_cntsh( 68 | .clk ( clk ), 69 | .clk_en ( clk_en ), 70 | // .rst ( rst ), 71 | .din ( cnt_V[0] ), 72 | .drop ( cnt_out ) 73 | ); 74 | 75 | always @(posedge clk) 76 | if( clk_en ) 77 | sum_up <= cnt_V[0] != cnt_out; 78 | 79 | endmodule // eg_mux -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/alt/eg_cnt.v: -------------------------------------------------------------------------------- 1 | /* 2 | Using two large case statements: 3 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 4 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 5 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 6 | | eg_cnt/ | | 9/13 | 13/19 | 15/18 | 0/3 | 0/0 | 0/0 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | eg_cnt | 7 | | +u_cntsh | | 4/4 | 6/6 | 3/3 | 3/3 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_cnt/u_cntsh | 8 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 9 | 10 | Using one large case statement: 11 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 12 | | Module | Partition | Slices* | Slice Reg | LUTs | LUTRAM | BRAM/FIFO | DSP48A1 | BUFG | BUFIO | BUFR | DCM | PLL_ADV | Full Hierarchical | 13 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 14 | | eg_cnt/ | | 8/11 | 13/19 | 12/15 | 0/3 | 0/0 | 0/0 | 1/1 | 0/0 | 0/0 | 0/0 | 0/0 | eg_cnt | 15 | | +u_cntsh | | 3/3 | 6/6 | 3/3 | 3/3 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | 0/0 | eg_cnt/u_cntsh | 16 | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 17 | */ 18 | 19 | module eg_cnt( 20 | input clk, 21 | input clk_en, 22 | input rst, 23 | input [14:0] eg_cnt, 24 | input [2:0] state_IV, 25 | input [5:0] rate_IV, 26 | 27 | output reg [2:0] state_V, 28 | output reg [5:0] rate_V, 29 | output [2:0] cnt_V, 30 | output reg sum_up 31 | ); 32 | 33 | localparam ATTACK=3'd0, DECAY1=3'd1, DECAY2=3'd2, RELEASE=3'd7, HOLD=3'd3; 34 | wire [2:0] cnt_out; 35 | assign cnt_V = cnt_out; 36 | reg lsb; 37 | reg [2:0] cnt_in; 38 | reg [3:0] mux_sel; 39 | 40 | always @(*) begin 41 | mux_sel = (state_IV == ATTACK && rate_IV[5:2]!=4'hf) ? (rate_IV[5:2]+4'd1): rate_IV[5:2]; 42 | case( mux_sel ) 43 | 4'h0: lsb = eg_cnt[12]; 44 | 4'h1: lsb = eg_cnt[11]; 45 | 4'h2: lsb = eg_cnt[10]; 46 | 4'h3: lsb = eg_cnt[ 9]; 47 | 4'h4: lsb = eg_cnt[ 8]; 48 | 4'h5: lsb = eg_cnt[ 7]; 49 | 4'h6: lsb = eg_cnt[ 6]; 50 | 4'h7: lsb = eg_cnt[ 5]; 51 | 4'h8: lsb = eg_cnt[ 4]; 52 | 4'h9: lsb = eg_cnt[ 3]; 53 | 4'ha: lsb = eg_cnt[ 2]; 54 | 4'hb: lsb = eg_cnt[ 1]; 55 | default: lsb = eg_cnt[ 0]; 56 | endcase 57 | cnt_in =lsb!=cnt_out ? (cnt_out+3'd1) : cnt_out; 58 | end 59 | 60 | always @(posedge clk) if( clk_en ) begin 61 | if( rst ) begin 62 | state_V <= RELEASE; 63 | rate_V <= 6'h1F; // should it be 6'h3F? TODO 64 | //cnt_V<= 3'd0; 65 | end 66 | else begin 67 | state_V <= state_IV; 68 | rate_V <= rate_IV; 69 | end 70 | end 71 | 72 | jt12_sh/*_rst*/ #( .width(3), .stages(24) ) u_cntsh( 73 | .clk ( clk ), 74 | .clk_en ( clk_en ), 75 | // .rst ( rst ), 76 | .din ( cnt_in ), 77 | .drop ( cnt_out ) 78 | ); 79 | 80 | always @(posedge clk) 81 | if( clk_en ) 82 | sum_up <= lsb!=cnt_out; 83 | 84 | endmodule // eg_mux -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt03.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 27-12-2018 20 | */ 21 | 22 | // Wrapper to output only combined channels. Defaults to YM2203 mode. 23 | 24 | 25 | 26 | module jt03( 27 | input rst, // rst should be at least 6 clk&cen cycles long 28 | input clk, // CPU clock 29 | input cen, // optional clock enable, if not needed leave as 1'b1 30 | input [7:0] din, 31 | input addr, 32 | input cs_n, 33 | input wr_n, 34 | 35 | output [7:0] dout, 36 | output irq_n, 37 | // I/O pins used by YM2203 embedded YM2149 chip 38 | input [7:0] IOA_in, 39 | input [7:0] IOB_in, 40 | // Separated output 41 | output [ 7:0] psg_A, 42 | output [ 7:0] psg_B, 43 | output [ 7:0] psg_C, 44 | output signed [15:0] fm_snd, 45 | // combined output 46 | output [ 9:0] psg_snd, 47 | output signed [15:0] snd, 48 | output snd_sample, 49 | // Debug 50 | //input [ 7:0] debug_bus, 51 | output [ 7:0] debug_view 52 | ); 53 | 54 | jt12_top #( 55 | .use_lfo(0),.use_ssg(1), .num_ch(3), .use_pcm(0), .use_adpcm(0), .mask_div(0) ) 56 | u_jt12( 57 | .rst ( rst ), // rst should be at least 6 clk&cen cycles long 58 | .clk ( clk ), // CPU clock 59 | .cen ( cen ), // optional clock enable, it not needed leave as 1'b1 60 | .din ( din ), 61 | .addr ( {1'b0, addr} ), 62 | .cs_n ( cs_n ), 63 | .wr_n ( wr_n ), 64 | 65 | .dout ( dout ), 66 | .irq_n ( irq_n ), 67 | // YM2203 I/O pins, only input supported 68 | .IOA_in ( IOA_in ), 69 | .IOB_in ( IOB_in ), 70 | // Unused ADPCM pins 71 | .en_hifi_pcm ( 1'b0 ), // used only on YM2612 mode 72 | .adpcma_addr ( ), // real hardware has 10 pins multiplexed through RMPX pin 73 | .adpcma_bank ( ), 74 | .adpcma_roe_n ( ), // ADPCM-A ROM output enable 75 | .adpcma_data ( 8'd0 ), // Data from RAM 76 | .adpcmb_data ( 8'd0 ), 77 | .adpcmb_addr ( ), // real hardware has 12 pins multiplexed through PMPX pin 78 | .adpcmb_roe_n ( ), // ADPCM-B ROM output enable 79 | // Separated output 80 | .psg_A ( psg_A ), 81 | .psg_B ( psg_B ), 82 | .psg_C ( psg_C ), 83 | .psg_snd ( psg_snd ), 84 | .fm_snd_left ( fm_snd ), 85 | .fm_snd_right (), 86 | .adpcmA_l (), 87 | .adpcmA_r (), 88 | .adpcmB_l (), 89 | .adpcmB_r (), 90 | 91 | .snd_right ( snd ), 92 | .snd_left (), 93 | .snd_sample ( snd_sample ), 94 | 95 | //.debug_bus ( debug_bus ), 96 | .debug_bus ( 8'd0 ), 97 | .debug_view ( debug_view ) 98 | ); 99 | 100 | endmodule // jt03 -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt10.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // YM2610 wrapper 23 | // Clock enabled at 7.5 - 8.5MHz 24 | 25 | module jt10( 26 | input rst, // rst should be at least 6 clk&cen cycles long 27 | input clk, // CPU clock 28 | input cen, // optional clock enable, if not needed leave as 1'b1 29 | input [7:0] din, 30 | input [1:0] addr, 31 | input cs_n, 32 | input wr_n, 33 | 34 | output [7:0] dout, 35 | output irq_n, 36 | // ADPCM pins 37 | output [19:0] adpcma_addr, // real hardware has 10 pins multiplexed through RMPX pin 38 | output [3:0] adpcma_bank, 39 | output adpcma_roe_n, // ADPCM-A ROM output enable 40 | input [7:0] adpcma_data, // Data from RAM 41 | output [23:0] adpcmb_addr, // real hardware has 12 pins multiplexed through PMPX pin 42 | output adpcmb_roe_n, // ADPCM-B ROM output enable 43 | input [7:0] adpcmb_data, 44 | // Separated output 45 | output [ 7:0] psg_A, 46 | output [ 7:0] psg_B, 47 | output [ 7:0] psg_C, 48 | output signed [15:0] fm_snd, 49 | // combined output 50 | output [ 9:0] psg_snd, 51 | output signed [15:0] snd_right, 52 | output signed [15:0] snd_left, 53 | output snd_sample 54 | ); 55 | 56 | // Uses 6 FM channels but only 4 are outputted 57 | jt12_top #( 58 | .use_lfo(1),.use_ssg(1), .num_ch(6), .use_pcm(0), .use_adpcm(1), 59 | .JT49_DIV(3) ) 60 | u_jt12( 61 | .rst ( rst ), // rst should be at least 6 clk&cen cycles long 62 | .clk ( clk ), // CPU clock 63 | .cen ( cen ), // optional clock enable, it not needed leave as 1'b1 64 | .din ( din ), 65 | .addr ( addr ), 66 | .cs_n ( cs_n ), 67 | .wr_n ( wr_n ), 68 | 69 | .dout ( dout ), 70 | .irq_n ( irq_n ), 71 | // ADPCM pins 72 | .adpcma_addr ( adpcma_addr ), // real hardware has 10 pins multiplexed through RMPX pin 73 | .adpcma_bank ( adpcma_bank ), 74 | .adpcma_roe_n ( adpcma_roe_n ), // ADPCM-A ROM output enable 75 | .adpcma_data ( adpcma_data ), // Data from RAM 76 | .adpcmb_addr ( adpcmb_addr ), // real hardware has 12 pins multiplexed through PMPX pin 77 | .adpcmb_roe_n ( adpcmb_roe_n ), // ADPCM-B ROM output enable 78 | .adpcmb_data ( adpcmb_data ), // Data from RAM 79 | // Separated output 80 | .psg_A ( psg_A ), 81 | .psg_B ( psg_B ), 82 | .psg_C ( psg_C ), 83 | .psg_snd ( psg_snd ), 84 | .fm_snd_left ( fm_snd ), 85 | .fm_snd_right (), 86 | // Unused YM2203 87 | .IOA_in (), 88 | .IOB_in (), 89 | // Sound output 90 | .snd_right ( snd_right ), 91 | .snd_left ( snd_left ), 92 | .snd_sample ( snd_sample ), 93 | // unused pins 94 | .en_hifi_pcm ( 1'b0 ), // used only on YM2612 mode 95 | .debug_view ( ) 96 | ); 97 | 98 | endmodule // jt03 99 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/cheatcodes.sv: -------------------------------------------------------------------------------- 1 | // Cheat Code handling by Kitrinx 2 | // Apr 21, 2019 3 | 4 | // Code layout: 5 | // {clock bit, code flags, 32'b address, 32'b compare, 32'b replace} 6 | // 128 127:96 95:64 63:32 31:0 7 | // Integer values are in BIG endian byte order, so it up to the loader 8 | // or generator of the code to re-arrange them correctly. 9 | 10 | module CODES( 11 | input clk, // Best to not make it too high speed for timing reasons 12 | input reset, // This should only be triggered when a new rom is loaded or before new codes load, not warm reset 13 | input enable, 14 | output available, 15 | input [128:0] code, 16 | input [ADDR_WIDTH - 1:0] addr_in, 17 | input [DATA_WIDTH - 1:0] data_in, 18 | output [DATA_WIDTH - 1:0] data_out 19 | ); 20 | 21 | parameter ADDR_WIDTH = 16; // Not more than 32 22 | parameter DATA_WIDTH = 8; // Not more than 32 23 | parameter MAX_CODES = 32; 24 | parameter BIG_ENDIAN = 0; 25 | 26 | localparam INDEX_SIZE = $clog2(MAX_CODES-1); // Number of bits for index, must accomodate MAX_CODES 27 | 28 | localparam DATA_S = DATA_WIDTH - 1; 29 | localparam COMP_S = DATA_S + DATA_WIDTH; 30 | localparam ADDR_S = COMP_S + ADDR_WIDTH; 31 | localparam COMP_F_S = ADDR_S + 1; 32 | localparam CODE_WIDTH = COMP_F_S + 1; 33 | localparam ENA_F_S = CODE_WIDTH + 1; 34 | 35 | localparam NO_ADDR_LSB = (DATA_WIDTH == 16) ? 1 : 0; 36 | 37 | reg [ENA_F_S:0] codes[MAX_CODES]; 38 | 39 | wire [ADDR_WIDTH-1: 0] code_addr = code[64+:ADDR_WIDTH] ^ BIG_ENDIAN[0]; 40 | wire [DATA_WIDTH-1: 0] code_compare = code[32+:DATA_WIDTH]; 41 | wire [DATA_WIDTH-1: 0] code_data = code[0+:DATA_WIDTH]; 42 | wire code_comp_f = code[96]; 43 | wire code_width = code[97] && (DATA_WIDTH == 16); 44 | 45 | // If MAX_INDEX is changes, these need to be made larger 46 | wire [INDEX_SIZE-1:0] index, dup_index; 47 | reg [INDEX_SIZE:0] next_index; 48 | wire found_dup; 49 | 50 | assign index = found_dup ? dup_index : next_index[INDEX_SIZE-1:0]; 51 | 52 | // See if the code exists already, so it can be disabled if loaded again 53 | always_comb begin 54 | int x; 55 | dup_index = 0; 56 | found_dup = 0; 57 | 58 | for (x = 0; x < MAX_CODES; x = x + 1) begin 59 | if (codes[x][ADDR_S-:ADDR_WIDTH] == code_addr) begin 60 | dup_index = x[INDEX_SIZE-1:0]; 61 | found_dup = 1; 62 | end 63 | end 64 | end 65 | 66 | assign available = |next_index; 67 | 68 | reg code_change; 69 | always_ff @(posedge clk) begin 70 | int x; 71 | if (reset) begin 72 | next_index <= 0; 73 | code_change <= 0; 74 | for (x = 0; x < MAX_CODES; x = x + 1) codes[x] <= '0; 75 | end else begin 76 | code_change <= code[128]; 77 | if (code[128] && ~code_change && (found_dup || next_index < MAX_CODES)) begin // detect posedge 78 | // replace it if the same address, otherwise, add a new code 79 | codes[index] <= {1'b1, code_width, code_comp_f, code_addr, code_compare, code_data}; 80 | if (~found_dup) next_index <= next_index + 1'b1; 81 | end 82 | end 83 | end 84 | 85 | always_comb begin 86 | int x; 87 | data_out = data_in; 88 | 89 | if (enable) begin 90 | for (x = 0; x < MAX_CODES; x = x + 1) begin 91 | if (codes[x][ENA_F_S] && codes[x][ADDR_S-:(ADDR_WIDTH-NO_ADDR_LSB)] == addr_in[ADDR_WIDTH-1:NO_ADDR_LSB]) begin 92 | if (!codes[x][COMP_F_S] || ( 93 | (DATA_WIDTH == 8 || !codes[x][CODE_WIDTH]) ? (data_in == codes[x][COMP_S-:DATA_WIDTH]) : 94 | (codes[x][ADDR_S-ADDR_WIDTH+1]) ? (data_in[15:8] == codes[x][(COMP_S-DATA_WIDTH+1) +:8]) : 95 | (data_in[7:0] == codes[x][(COMP_S-DATA_WIDTH+1) +:8]) )) 96 | begin 97 | if(DATA_WIDTH == 8 || !codes[x][CODE_WIDTH]) data_out = codes[x][DATA_S-:DATA_WIDTH]; 98 | else if (codes[x][ADDR_S-ADDR_WIDTH+1]) data_out[15:8] = codes[x][(DATA_S-DATA_WIDTH+1) +:8]; 99 | else data_out[7:0] = codes[x][(DATA_S-DATA_WIDTH+1) +:8]; 100 | end 101 | end 102 | end 103 | end 104 | end 105 | 106 | endmodule 107 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // ADPCM-A algorithm 23 | 24 | module jt10_adpcm( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen, // optional clock enable, if not needed leave as 1'b1 28 | input [3:0] data, 29 | input chon, // high if this channel is on 30 | input clr, 31 | output signed [15:0] pcm 32 | ); 33 | 34 | localparam sigw = 12; 35 | 36 | reg signed [sigw-1:0] x1, x2, x3, x4, x5, x6; 37 | reg signed [sigw-1:0] inc4; 38 | reg [5:0] step1, step2, step6, step3, step4, step5; 39 | reg [5:0] step_next, step_1p; 40 | reg sign2, sign3, sign4, sign5, xsign5; 41 | 42 | // All outputs from stage 1 43 | assign pcm = { {16-sigw{x1[sigw-1]}}, x1 }; 44 | 45 | // This could be decomposed in more steps as the pipeline 46 | // has room for it 47 | always @(*) begin 48 | casez( data[2:0] ) 49 | 3'b0??: step_next = step1==6'd0 ? 6'd0 : (step1-1'd1); 50 | 3'b100: step_next = step1+6'd2; 51 | 3'b101: step_next = step1+6'd5; 52 | 3'b110: step_next = step1+6'd7; 53 | 3'b111: step_next = step1+6'd9; 54 | endcase 55 | step_1p = step_next > 6'd48 ? 6'd48 : step_next; 56 | end 57 | 58 | wire [11:0] inc3; 59 | reg [8:0] lut_addr2; 60 | 61 | 62 | jt10_adpcma_lut u_lut( 63 | .clk ( clk ), 64 | .rst_n ( rst_n ), 65 | .cen ( cen ), 66 | .addr ( lut_addr2 ), 67 | .inc ( inc3 ) 68 | ); 69 | 70 | // Original pipeline: 6 stages, 6 channels take 36 clock cycles 71 | // 8 MHz -> /12 divider -> 666 kHz 72 | // 666 kHz -> 18.5 kHz = 55.5/3 kHz 73 | 74 | reg chon2, chon3, chon4; 75 | wire [sigw-1:0] inc3_long = { {sigw-12{1'b0}},inc3 }; 76 | 77 | always @( posedge clk or negedge rst_n ) 78 | if( ! rst_n ) begin 79 | x1 <= 'd0; step1 <= 0; 80 | x2 <= 'd0; step2 <= 0; 81 | x3 <= 'd0; step3 <= 0; 82 | x4 <= 'd0; step4 <= 0; 83 | x5 <= 'd0; step5 <= 0; 84 | x6 <= 'd0; step6 <= 0; 85 | sign2 <= 'b0; 86 | chon2 <= 'b0; chon3 <= 'b0; chon4 <= 'b0; 87 | lut_addr2 <= 'd0; 88 | inc4 <= 'd0; 89 | end else if(cen) begin 90 | // I 91 | sign2 <= data[3]; 92 | x2 <= clr ? {sigw-1{1'b0}} : x1; 93 | step2 <= clr ? 6'd0 : (chon ? step_1p : step1); 94 | chon2 <= ~clr && chon; 95 | lut_addr2 <= { step1, data[2:0] }; 96 | // II 2's complement of inc2 if necessary 97 | sign3 <= sign2; 98 | x3 <= x2; 99 | step3 <= step2; 100 | chon3 <= chon2; 101 | // III 102 | //sign4 <= sign3; 103 | inc4 <= sign3 ? ~inc3_long + 1'd1 : inc3_long; 104 | x4 <= x3; 105 | step4 <= step3; 106 | chon4 <= chon3; 107 | // IV 108 | //sign5 <= sign4; 109 | //xsign5 <= x4[sigw-1]; 110 | x5 <= chon4 ? x4 + inc4 : x4; 111 | step5 <= step4; 112 | // V 113 | x6 <= x5; 114 | step6 <= step5; 115 | // VI: close the loop 116 | x1 <= x6; 117 | step1 <= step6; 118 | end 119 | 120 | endmodule // jt10_adpcm 121 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_timers.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 14-2-2017 19 | 20 | YM3438_APL.pdf 21 | Timer A = 144*(1024-NA)/Phi M 22 | Timer B = 2304*(256-NB)/Phi M 23 | */ 24 | 25 | 26 | module jt12_timers( 27 | input clk, 28 | input rst, 29 | input clk_en /* synthesis direct_enable */, 30 | input zero, 31 | input [9:0] value_A, 32 | input [7:0] value_B, 33 | input load_A, 34 | input load_B, 35 | input clr_flag_A, 36 | input clr_flag_B, 37 | input enable_irq_A, 38 | input enable_irq_B, 39 | output flag_A, 40 | output flag_B, 41 | output overflow_A, 42 | output irq_n 43 | ); 44 | 45 | parameter num_ch = 6; 46 | 47 | assign irq_n = ~( (flag_A&enable_irq_A) | (flag_B&enable_irq_B) ); 48 | 49 | /* 50 | reg zero2; 51 | 52 | always @(posedge clk, posedge rst) begin 53 | if( rst ) 54 | zero2 <= 0; 55 | else if(clk_en) begin 56 | if( zero ) zero2 <= ~zero; 57 | end 58 | end 59 | 60 | wire zero = num_ch == 6 ? zero : (zero2&zero); 61 | */ 62 | jt12_timer #(.CW(10)) timer_A( 63 | .clk ( clk ), 64 | .rst ( rst ), 65 | .cen ( clk_en ), 66 | .zero ( zero ), 67 | .start_value( value_A ), 68 | .load ( load_A ), 69 | .clr_flag ( clr_flag_A ), 70 | .flag ( flag_A ), 71 | .overflow ( overflow_A ) 72 | ); 73 | 74 | jt12_timer #(.CW(8),.FREE_EN(1)) timer_B( 75 | .clk ( clk ), 76 | .rst ( rst ), 77 | .cen ( clk_en ), 78 | .zero ( zero ), 79 | .start_value( value_B ), 80 | .load ( load_B ), 81 | .clr_flag ( clr_flag_B ), 82 | .flag ( flag_B ), 83 | .overflow ( ) 84 | ); 85 | 86 | endmodule 87 | 88 | module jt12_timer #(parameter 89 | CW = 8, // counter bit width. This is the counter that can be loaded 90 | FW = 4, // number of bits for the free-running counter 91 | FREE_EN = 0 // enables a 4-bit free enable count 92 | ) ( 93 | input rst, 94 | input clk, 95 | input cen, 96 | input zero, 97 | input [CW-1:0] start_value, 98 | input load, 99 | input clr_flag, 100 | output reg flag, 101 | output reg overflow 102 | ); 103 | /* verilator lint_off WIDTH */ 104 | reg load_l; 105 | reg [CW-1:0] cnt, next; 106 | reg [FW-1:0] free_cnt, free_next; 107 | reg free_ov; 108 | 109 | always@(posedge clk, posedge rst) 110 | if( rst ) 111 | flag <= 1'b0; 112 | else /*if(cen)*/ begin 113 | if( clr_flag ) 114 | flag <= 1'b0; 115 | else if( cen && zero && load && overflow ) flag<=1'b1; 116 | end 117 | 118 | always @(*) begin 119 | {free_ov, free_next} = { 1'b0, free_cnt} + 1'b1; 120 | {overflow, next } = { 1'b0, cnt } + (FREE_EN ? free_ov : 1'b1); 121 | end 122 | 123 | always @(posedge clk) begin 124 | load_l <= load; 125 | if( !load_l && load ) begin 126 | cnt <= start_value; 127 | end else if( cen && zero && load ) 128 | cnt <= overflow ? start_value : next; 129 | end 130 | 131 | // Free running counter 132 | always @(posedge clk) begin 133 | if( rst ) begin 134 | free_cnt <= 0; 135 | end else if( cen && zero ) begin 136 | free_cnt <= free_cnt+1'd1; 137 | end 138 | end 139 | /* verilator lint_on WIDTH */ 140 | endmodule 141 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_drvB.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | module jt10_adpcm_drvB( 23 | input rst_n, 24 | input clk, 25 | input cen, // 8MHz cen 26 | input cen55, // clk & cen55 = 55 kHz 27 | // Control 28 | input acmd_on_b, // Control - Process start, Key On 29 | input acmd_rep_b, // Control - Repeat 30 | input acmd_rst_b, // Control - Reset 31 | input acmd_up_b, // Control - New command received 32 | input [ 1:0] alr_b, // Left / Right 33 | input [15:0] astart_b, // Start address 34 | input [15:0] aend_b, // End address 35 | input [15:0] adeltan_b, // Delta-N 36 | input [ 7:0] aeg_b, // Envelope Generator Control 37 | output flag, 38 | input clr_flag, 39 | // memory 40 | output [23:0] addr, 41 | input [ 7:0] data, 42 | output reg roe_n, 43 | 44 | output reg signed [15:0] pcm55_l, 45 | output reg signed [15:0] pcm55_r 46 | ); 47 | 48 | wire nibble_sel; 49 | wire adv; // advance to next reading 50 | wire restart; 51 | wire chon; 52 | 53 | // `ifdef SIMULATION 54 | // real fsample; 55 | // always @(posedge acmd_on_b) begin 56 | // fsample = adeltan_b; 57 | // fsample = fsample/65536; 58 | // fsample = fsample * 55.5; 59 | // $display("\nINFO: ADPCM-B ON: %X delta N = %6d (%2.1f kHz)", astart_b, adeltan_b, fsample ); 60 | // end 61 | // `endif 62 | 63 | always @(posedge clk) roe_n <= ~(adv & cen55); 64 | 65 | jt10_adpcmb_cnt u_cnt( 66 | .rst_n ( rst_n ), 67 | .clk ( clk ), 68 | .cen ( cen55 ), 69 | .delta_n ( adeltan_b ), 70 | .acmd_up_b ( acmd_up_b ), 71 | .clr ( acmd_rst_b ), 72 | .on ( acmd_on_b ), 73 | .astart ( astart_b ), 74 | .aend ( aend_b ), 75 | .arepeat ( acmd_rep_b ), 76 | .addr ( addr ), 77 | .nibble_sel ( nibble_sel ), 78 | // Flag control 79 | .chon ( chon ), 80 | .clr_flag ( clr_flag ), 81 | .flag ( flag ), 82 | .restart ( restart ), 83 | .adv ( adv ) 84 | ); 85 | 86 | reg [3:0] din; 87 | 88 | always @(posedge clk) din <= !nibble_sel ? data[7:4] : data[3:0]; 89 | 90 | wire signed [15:0] pcmdec, pcminter, pcmgain; 91 | 92 | jt10_adpcmb u_decoder( 93 | .rst_n ( rst_n ), 94 | .clk ( clk ), 95 | .cen ( cen ), 96 | .adv ( adv & cen55 ), 97 | .data ( din ), 98 | .chon ( chon ), 99 | .clr ( flag | restart ), 100 | .pcm ( pcmdec ) 101 | ); 102 | 103 | `ifndef NOBINTERPOL 104 | jt10_adpcmb_interpol u_interpol( 105 | .rst_n ( rst_n ), 106 | .clk ( clk ), 107 | .cen ( cen ), 108 | .cen55 ( cen55 && chon ), 109 | .adv ( adv ), 110 | .pcmdec ( pcmdec ), 111 | .pcmout ( pcminter ) 112 | ); 113 | `else 114 | assign pcminter = pcmdec; 115 | `endif 116 | 117 | jt10_adpcmb_gain u_gain( 118 | .rst_n ( rst_n ), 119 | .clk ( clk ), 120 | .cen55 ( cen55 ), 121 | .tl ( aeg_b ), 122 | .pcm_in ( pcminter ), 123 | .pcm_out( pcmgain ) 124 | ); 125 | 126 | always @(posedge clk) if(cen55) begin 127 | pcm55_l <= alr_b[1] ? pcmgain : 16'd0; 128 | pcm55_r <= alr_b[0] ? pcmgain : 16'd0; 129 | end 130 | 131 | endmodule // jt10_adpcm_drvB 132 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcmb.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Sampling rates: 2kHz ~ 55.5 kHz. in 0.85Hz steps 23 | 24 | module jt10_adpcmb( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen, // optional clock enable, if not needed leave as 1'b1 28 | input [3:0] data, 29 | input chon, // high if this channel is on 30 | input adv, 31 | input clr, 32 | output signed [15:0] pcm 33 | ); 34 | 35 | localparam stepw = 15, xw=16; 36 | 37 | reg signed [xw-1:0] x1, next_x5; 38 | reg [stepw-1:0] step1; 39 | reg [stepw+1:0] next_step3; 40 | assign pcm = x1[xw-1:xw-16]; 41 | 42 | wire [xw-1:0] limpos = {1'b0, {xw-1{1'b1}}}; 43 | wire [xw-1:0] limneg = {1'b1, {xw-1{1'b0}}}; 44 | 45 | reg [18:0] d2l; 46 | reg [xw-1:0] d3,d4; 47 | reg [3:0] d2; 48 | reg [7:0] step_val; 49 | reg [22:0] step2l; 50 | 51 | always @(*) begin 52 | casez( d2[3:1] ) 53 | 3'b0_??: step_val = 8'd57; 54 | 3'b1_00: step_val = 8'd77; 55 | 3'b1_01: step_val = 8'd102; 56 | 3'b1_10: step_val = 8'd128; 57 | 3'b1_11: step_val = 8'd153; 58 | endcase 59 | d2l = d2 * step1; // 4 + 15 = 19 bits -> div by 8 -> 16 bits 60 | step2l = step_val * step1; // 15 bits + 8 bits = 23 bits -> div 64 -> 17 bits 61 | end 62 | 63 | // Original pipeline: 6 stages, 6 channels take 36 clock cycles 64 | // 8 MHz -> /12 divider -> 666 kHz 65 | // 666 kHz -> 18.5 kHz = 55.5/3 kHz 66 | 67 | reg [3:0] data2; 68 | reg sign_data2, sign_data3, sign_data4, sign_data5; 69 | 70 | reg [3:0] adv2; 71 | reg need_clr; 72 | 73 | wire [3:0] data_use = clr || ~chon ? 4'd0 : data; 74 | 75 | always @( posedge clk or negedge rst_n ) 76 | if( ! rst_n ) begin 77 | x1 <= 'd0; step1 <= 'd127; 78 | d2 <= 'd0; d3 <= 'd0; d4 <= 'd0; 79 | need_clr <= 0; 80 | end else begin 81 | if( clr ) 82 | need_clr <= 1'd1; 83 | if(cen) begin 84 | adv2 <= {1'b0,adv2[3:1]}; 85 | // I 86 | if( adv ) begin 87 | d2 <= {data_use[2:0],1'b1}; 88 | sign_data2 <= data_use[3]; 89 | adv2[3] <= 1'b1; 90 | end 91 | // II multiply and obtain the offset 92 | d3 <= { {xw-16{1'b0}}, d2l[18:3] }; // xw bits 93 | next_step3<= step2l[22:6]; 94 | sign_data3<=sign_data2; 95 | // III 2's complement of d3 if necessary 96 | d4 <= sign_data3 ? ~d3+1'd1 : d3; 97 | sign_data4<=sign_data3; 98 | // IV Advance the waveform 99 | next_x5 <= x1+d4; 100 | sign_data5<=sign_data4; 101 | // V: limit or reset outputs 102 | if( chon ) begin // update values if needed 103 | if( adv2[0] ) begin 104 | if( sign_data5 == x1[xw-1] && (x1[xw-1]!=next_x5[xw-1]) ) 105 | x1 <= x1[xw-1] ? limneg : limpos; 106 | else 107 | x1 <= next_x5; 108 | 109 | if( next_step3 < 127 ) 110 | step1 <= 15'd127; 111 | else if( next_step3 > 24576 ) 112 | step1 <= 15'd24576; 113 | else 114 | step1 <= next_step3[14:0]; 115 | end 116 | end else begin 117 | x1 <= 'd0; 118 | step1 <= 'd127; 119 | end 120 | if( need_clr ) begin 121 | x1 <= 'd0; 122 | step1 <= 'd127; 123 | next_step3 <= 'd127; 124 | d2 <= 'd0; d3 <= 'd0; d4 <= 'd0; 125 | next_x5 <= 'd0; 126 | need_clr <= 1'd0; 127 | end 128 | end 129 | end 130 | 131 | endmodule // jt10_adpcm -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_dt.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Sampling rates: 2kHz ~ 55.5 kHz. in 0.85Hz steps 23 | 24 | module jt10_adpcm_dt( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen, // optional clock enable, if not needed leave as 1'b1 28 | input [3:0] data, 29 | input chon, // high if this channel is on 30 | output signed [15:0] pcm 31 | ); 32 | 33 | localparam stepw = 15; 34 | 35 | reg signed [15:0] x1, x2, x3, x4, x5, x6; 36 | reg [stepw-1:0] step1, step2, step6; 37 | reg [stepw+1:0] step3, step4, step5; 38 | assign pcm = x2; 39 | 40 | reg [18:0] d2l; 41 | reg [15:0] d3,d4; 42 | reg [3:0] d2; 43 | reg sign2, sign3, sign4, sign5; 44 | reg [7:0] step_val; 45 | reg [22:0] step2l; 46 | 47 | always @(*) begin 48 | casez( d2[3:1] ) 49 | 3'b0_??: step_val = 8'd57; 50 | 3'b1_00: step_val = 8'd77; 51 | 3'b1_01: step_val = 8'd102; 52 | 3'b1_10: step_val = 8'd128; 53 | 3'b1_11: step_val = 8'd153; 54 | endcase // data[2:0] 55 | d2l = d2 * step2; // 4 + 15 = 19 bits -> div by 8 -> 16 bits 56 | step2l = step_val * step2; // 15 bits + 8 bits = 23 bits -> div 64 -> 17 bits 57 | end 58 | 59 | // Original pipeline: 6 stages, 6 channels take 36 clock cycles 60 | // 8 MHz -> /12 divider -> 666 kHz 61 | // 666 kHz -> 18.5 kHz = 55.5/3 kHz 62 | 63 | reg chon2, chon3, chon4, chon5; 64 | reg signEqu4, signEqu5; 65 | reg [3:0] data2; 66 | 67 | always @( posedge clk or negedge rst_n ) 68 | if( ! rst_n ) begin 69 | x1 <= 'd0; step1 <= 'd127; 70 | x2 <= 'd0; step2 <= 'd127; 71 | x3 <= 'd0; step3 <= 'd127; 72 | x4 <= 'd0; step4 <= 'd127; 73 | x5 <= 'd0; step5 <= 'd127; 74 | x6 <= 'd0; step6 <= 'd127; 75 | d2 <= 'd0; d3 <= 'd0; d4 <= 'd0; 76 | sign2 <= 'b0; 77 | sign3 <= 'b0; 78 | sign4 <= 'b0; sign5 <= 'b0; 79 | chon2 <= 'b0; chon3 <= 'b0; chon4 <= 'b0; chon5 <= 1'b0; 80 | end else if(cen) begin 81 | // I 82 | d2 <= {data[2:0],1'b1}; 83 | sign2 <= data[3]; 84 | data2 <= data; 85 | x2 <= x1; 86 | step2 <= step1; 87 | chon2 <= chon; 88 | // II multiply and obtain the offset 89 | d3 <= d2l[18:3]; // 16 bits 90 | sign3 <= sign2; 91 | x3 <= x2; 92 | step3 <= step2l[22:6]; 93 | chon3 <= chon2; 94 | // III 2's complement of d3 if necessary 95 | d4 <= sign3 ? ~d3+16'b1 : d3; 96 | sign4 <= sign3; 97 | signEqu4 <= sign3 == x3[15]; 98 | x4 <= x3; 99 | step4 <= step3; 100 | chon4 <= chon3; 101 | // IV Advance the waveform 102 | x5 <= x4+d4; 103 | sign5 <= sign4; 104 | signEqu5 <= signEqu4; 105 | step5 <= step4; 106 | chon5 <= chon4; 107 | // V: limit or reset outputs 108 | if( chon5 ) begin 109 | if( signEqu5 && (sign5!=x5[15]) ) 110 | x6 <= sign5 ? 16'h8000 : 16'h7FFF; 111 | else 112 | x6 <= x5; 113 | 114 | if( step5 < 127 ) 115 | step6 <= 15'd127; 116 | else if( step5 > 24576 ) 117 | step6 <= 15'd24576; 118 | else 119 | step6 <= step5[14:0]; 120 | end else begin 121 | x6 <= 'd0; 122 | step6 <= 'd127; 123 | end 124 | // VI: close the loop 125 | x1 <= x6; 126 | step1 <= step6; 127 | end 128 | 129 | 130 | endmodule // jt10_adpcm -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/adpcm/jt10_adpcm_comb.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 21-03-2019 20 | */ 21 | 22 | // Sampling rates: 2kHz ~ 55.5 kHz. in 0.85Hz steps 23 | 24 | module jt10_adpcm_comb( 25 | input rst_n, 26 | input clk, // CPU clock 27 | input cen, // optional clock enable, if not needed leave as 1'b1 28 | input [3:0] data, 29 | input chon, // high if this channel is on 30 | output signed [15:0] pcm 31 | ); 32 | 33 | localparam stepw = 15; 34 | 35 | reg signed [15:0] x1, x2, x3, x4, x5, x6; 36 | reg [stepw-1:0] step1, step2, step6; 37 | reg [stepw+1:0] step3, step4, step5; 38 | assign pcm = x2; 39 | 40 | reg [18:0] d2l; 41 | reg [15:0] d3,d4; 42 | reg [3:0] d1,d2; 43 | reg sign2, sign3, sign4, sign5; 44 | reg [7:0] step_val; 45 | reg [22:0] step2l; 46 | 47 | // Original pipeline: 6 stages, 6 channels take 36 clock cycles 48 | // 8 MHz -> /12 divider -> 666 kHz 49 | // 666 kHz -> 18.5 kHz = 55.5/3 kHz 50 | 51 | reg chon2, chon3, chon4, chon5; 52 | reg signEqu4, signEqu5; 53 | reg [3:0] data1,data2; 54 | 55 | always @( * ) 56 | if( ! rst_n ) begin 57 | x2 = 'd0; step2 = 'd127; 58 | x3 = 'd0; step3 = 'd127; 59 | x4 = 'd0; step4 = 'd127; 60 | x5 = 'd0; step5 = 'd127; 61 | x6 = 'd0; step6 = 'd127; 62 | d2 = 'd0; d3 = 'd0; d4 = 'd0; 63 | sign2 = 'b0; 64 | sign3 = 'b0; 65 | sign4 = 'b0; sign5 = 'b0; 66 | chon2 = 'b0; chon3 = 'b0; chon4 = 'b0; chon5 = 1'b0; 67 | end else begin 68 | // I 69 | d2 = d1; 70 | sign2 = data1[3]; 71 | data2 = data1; 72 | x2 = x1; 73 | step2 = step1; 74 | chon2 = chon; 75 | // II multiply and obtain the offset 76 | casez( d2[3:1] ) 77 | 3'b0_??: step_val = 8'd57; 78 | 3'b1_00: step_val = 8'd77; 79 | 3'b1_01: step_val = 8'd102; 80 | 3'b1_10: step_val = 8'd128; 81 | 3'b1_11: step_val = 8'd153; 82 | endcase // data[2:0] 83 | d2l = d2 * step2; // 4 + 15 = 19 bits -> div by 8 -> 16 bits 84 | step2l = step_val * step2; // 15 bits + 8 bits = 23 bits -> div 64 -> 17 bits 85 | d3 = d2l[18:3]; // 16 bits 86 | sign3 = sign2; 87 | x3 = x2; 88 | step3 = step2l[22:6]; 89 | chon3 = chon2; 90 | // III 2's complement of d3 if necessary 91 | d4 = sign3 ? ~d3+16'b1 : d3; 92 | sign4 = sign3; 93 | signEqu4 = sign3 == x3[15]; 94 | x4 = x3; 95 | step4 = step3; 96 | chon4 = chon3; 97 | // IV Advance the waveform 98 | x5 = x4+d4; 99 | sign5 = sign4; 100 | signEqu5 = signEqu4; 101 | step5 = step4; 102 | chon5 = chon4; 103 | // V: limit or reset outputs 104 | if( chon5 ) begin 105 | if( signEqu5 && (sign5!=x5[15]) ) 106 | x6 = sign5 ? 16'h8000 : 16'h7FFF; 107 | else 108 | x6 = x5; 109 | 110 | if( step5 < 127 ) 111 | step6 = 15'd127; 112 | else if( step5 > 24576 ) 113 | step6 = 15'd24576; 114 | else 115 | step6 = step5[14:0]; 116 | end else begin 117 | x6 = 'd0; 118 | step6 = 'd127; 119 | end 120 | end 121 | 122 | always @(posedge clk or negedge rst_n) 123 | if( ! rst_n ) begin 124 | x1 <= 'd0; step1 <= 'd127; 125 | d1 <= 'd0; data1 <= 'd0; 126 | end else if(cen) begin 127 | // VI: close the loop 128 | d1 <= {data[2:0],1'b1}; 129 | x1 <= x6; 130 | step1 <= step6; 131 | data1 <= data; 132 | end 133 | 134 | endmodule // jt10_adpcm -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_acc.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | 4 | JT12 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 | JT12 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 JT12. If not, see . 16 | 17 | Author: Jose Tejada Gomez. Twitter: @topapate 18 | Version: 1.0 19 | Date: 27-1-2017 20 | 21 | Each channel can use the full range of the DAC as they do not 22 | get summed in the real chip. 23 | 24 | Operator data is summed up without adding extra bits. This is 25 | the case of real YM3438, which was used on Megadrive 2 models. 26 | 27 | 28 | */ 29 | 30 | /* 31 | YM2612 had a limiter to prevent overflow 32 | YM3438 did not 33 | JT12 always has a limiter enabled 34 | */ 35 | 36 | module jt12_acc( 37 | input rst, 38 | input clk, 39 | input clk_en /* synthesis direct_enable */, 40 | input ladder, 41 | input channel_en, 42 | input signed [8:0] op_result, 43 | input [ 1:0] rl, 44 | input zero, 45 | input s1_enters, 46 | input s2_enters, 47 | input s3_enters, 48 | input s4_enters, 49 | input ch6op, 50 | input [2:0] alg, 51 | input pcm_en, // only enabled for channel 6 52 | input signed [8:0] pcm, 53 | // combined output 54 | output reg signed [15:0] left, 55 | output reg signed [15:0] right 56 | ); 57 | 58 | reg sum_en; 59 | 60 | always @(*) begin 61 | case ( alg ) 62 | default: sum_en = s4_enters; 63 | 3'd4: sum_en = s2_enters | s4_enters; 64 | 3'd5,3'd6: sum_en = ~s1_enters; 65 | 3'd7: sum_en = 1'b1; 66 | endcase 67 | end 68 | 69 | reg pcm_sum; 70 | 71 | always @(posedge clk) if(clk_en) 72 | if( zero ) pcm_sum <= 1'b1; 73 | else if( ch6op ) pcm_sum <= 1'b0; 74 | 75 | wire use_pcm = ch6op && pcm_en; 76 | wire sum_or_pcm = sum_en | use_pcm; 77 | // wire left_en = rl[1]; 78 | // wire right_en= rl[0]; 79 | wire signed [8:0] pcm_data = pcm_sum ? pcm : 9'd0; 80 | // wire [8:0] acc_input = use_pcm ? pcm_data : op_result; 81 | wire signed [8:0] acc_input = ~channel_en ? 9'd0 : (use_pcm ? pcm_data : op_result); 82 | 83 | // Continuous output 84 | // wire signed [11:0] pre_left, pre_right; 85 | wire signed [8:0] acc_out; 86 | // jt12_single_acc #(.win(9),.wout(12)) u_left( 87 | jt12_single_acc #(.win(9),.wout(9)) u_acc( 88 | .clk ( clk ), 89 | .clk_en ( clk_en ), 90 | .op_result ( acc_input ), 91 | // .sum_en ( sum_or_pcm & left_en ), 92 | .sum_en ( sum_or_pcm ), 93 | .zero ( zero ), 94 | // .snd ( pre_left ) 95 | .snd ( acc_out ) 96 | ); 97 | 98 | // jt12_single_acc #(.win(9),.wout(12)) u_right( 99 | // .clk ( clk ), 100 | // .clk_en ( clk_en ), 101 | // .op_result ( acc_input ), 102 | // .sum_en ( sum_or_pcm & right_en ), 103 | // .zero ( zero ), 104 | // .snd ( pre_right ) 105 | // ); 106 | 107 | // Output can be amplied by 8/6=1.33 to use full range 108 | // an easy alternative is to add 1/4th and get 1.25 amplification 109 | // always @(posedge clk) if(clk_en) begin 110 | // left <= pre_left + { {2{pre_left [11]}}, pre_left [11:2] }; 111 | // right <= pre_right + { {2{pre_right[11]}}, pre_right[11:2] }; 112 | // end 113 | 114 | wire signed [15:0] acc_expand = {{7{acc_out[8]}}, acc_out}; 115 | 116 | reg [1:0] rl_latch, rl_old; 117 | 118 | wire signed [4:0] ladder_left = ~ladder ? 5'd0 : (acc_expand >= 0 ? 5'd7 : (rl_old[1] ? 5'd0 : -5'd6)); 119 | wire signed [4:0] ladder_right = ~ladder ? 5'd0 : (acc_expand >= 0 ? 5'd7 : (rl_old[0] ? 5'd0 : -5'd6)); 120 | 121 | always @(posedge clk) if(clk_en) begin 122 | if (channel_en) 123 | rl_latch <= rl; 124 | if (zero) 125 | rl_old <= rl_latch; 126 | 127 | left <= rl_old[1] ? acc_expand + ladder_left : ladder_left; 128 | right <= rl_old[0] ? acc_expand + ladder_right : ladder_right; 129 | end 130 | 131 | endmodule 132 | -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_eg_comb.v: -------------------------------------------------------------------------------- 1 | /* This file is part of JT12. 2 | 3 | JT12 is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | JT12 is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with JT12. If not, see . 15 | 16 | Author: Jose Tejada Gomez. Twitter: @topapate 17 | Version: 1.0 18 | Date: 30-10-2018 19 | 20 | */ 21 | 22 | module jt12_eg_comb( 23 | input keyon_now, 24 | input keyoff_now, 25 | input [2:0] state_in, 26 | input [9:0] eg_in, 27 | // envelope configuration 28 | input [4:0] arate, // attack rate 29 | input [4:0] rate1, // decay rate 30 | input [4:0] rate2, // sustain rate 31 | input [3:0] rrate, 32 | input [3:0] sl, // sustain level 33 | // SSG operation 34 | input ssg_en, 35 | input [2:0] ssg_eg, 36 | // SSG output inversion 37 | input ssg_inv_in, 38 | output ssg_inv_out, 39 | 40 | output [4:0] base_rate, 41 | output [2:0] state_next, 42 | output pg_rst, 43 | /////////////////////////////////// 44 | // II 45 | input step_attack, 46 | input [ 4:0] step_rate_in, 47 | input [ 4:0] keycode, 48 | input [14:0] eg_cnt, 49 | input cnt_in, 50 | input [ 1:0] ks, 51 | output cnt_lsb, 52 | output step, 53 | output [5:0] step_rate_out, 54 | output sum_up_out, 55 | /////////////////////////////////// 56 | // III 57 | input pure_attack, 58 | input pure_step, 59 | input [ 5:1] pure_rate, 60 | input pure_ssg_en, 61 | input [ 9:0] pure_eg_in, 62 | output [9:0] pure_eg_out, 63 | input sum_up_in, 64 | /////////////////////////////////// 65 | // IV 66 | input [ 6:0] lfo_mod, 67 | input amsen, 68 | input [ 1:0] ams, 69 | input [ 6:0] tl, 70 | input [ 9:0] final_eg_in, 71 | input final_ssg_inv, 72 | output [9:0] final_eg_out 73 | ); 74 | 75 | // I 76 | jt12_eg_ctrl u_ctrl( 77 | .keyon_now ( keyon_now ), 78 | .keyoff_now ( keyoff_now ), 79 | .state_in ( state_in ), 80 | .eg ( eg_in ), 81 | // envelope configuration 82 | .arate ( arate ), // attack rate 83 | .rate1 ( rate1 ), // decay rate 84 | .rate2 ( rate2 ), // sustain rate 85 | .rrate ( rrate ), 86 | .sl ( sl ), // sustain level 87 | // SSG operation 88 | .ssg_en ( ssg_en ), 89 | .ssg_eg ( ssg_eg ), 90 | // SSG output inversion 91 | .ssg_inv_in ( ssg_inv_in ), 92 | .ssg_inv_out ( ssg_inv_out ), 93 | 94 | .base_rate ( base_rate ), 95 | .state_next ( state_next ), 96 | .pg_rst ( pg_rst ) 97 | ); 98 | 99 | // II 100 | 101 | jt12_eg_step u_step( 102 | .attack ( step_attack ), 103 | .base_rate ( step_rate_in ), 104 | .keycode ( keycode ), 105 | .eg_cnt ( eg_cnt ), 106 | .cnt_in ( cnt_in ), 107 | .ks ( ks ), 108 | .cnt_lsb ( cnt_lsb ), 109 | .step ( step ), 110 | .rate ( step_rate_out ), 111 | .sum_up ( sum_up_out ) 112 | ); 113 | 114 | // III 115 | 116 | wire [9:0] egin, egout; 117 | jt12_eg_pure u_pure( 118 | .attack ( pure_attack ), 119 | .step ( pure_step ), 120 | .rate ( pure_rate ), 121 | .ssg_en ( pure_ssg_en ), 122 | .eg_in ( pure_eg_in ), 123 | .eg_pure( pure_eg_out ), 124 | .sum_up ( sum_up_in ) 125 | ); 126 | 127 | // IV 128 | 129 | jt12_eg_final u_final( 130 | .lfo_mod ( lfo_mod ), 131 | .amsen ( amsen ), 132 | .ams ( ams ), 133 | .tl ( tl ), 134 | .ssg_inv ( final_ssg_inv ), 135 | .eg_pure_in ( final_eg_in ), 136 | .eg_limited ( final_eg_out ) 137 | ); 138 | 139 | endmodule // jt12_eg_comb -------------------------------------------------------------------------------- /src/fpga/core/rtl/jt12/jt12_kon.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* This file is part of JT12. 4 | 5 | 6 | JT12 program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | JT12 program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with JT12. If not, see . 18 | 19 | Author: Jose Tejada Gomez. Twitter: @topapate 20 | Version: 1.0 21 | Date: 27-1-2017 22 | 23 | */ 24 | 25 | module jt12_kon( 26 | input rst, 27 | input clk, 28 | input clk_en /* synthesis direct_enable */, 29 | input [3:0] keyon_op, 30 | input [2:0] keyon_ch, 31 | input [1:0] next_op, 32 | input [2:0] next_ch, 33 | input up_keyon, 34 | input csm, 35 | // input flag_A, 36 | input overflow_A, 37 | 38 | output reg keyon_I 39 | ); 40 | 41 | parameter num_ch=6; 42 | 43 | wire csr_out; 44 | 45 | generate 46 | if(num_ch==6) begin 47 | // capture overflow signal so it lasts long enough 48 | reg overflow2; 49 | reg [4:0] overflow_cycle; 50 | 51 | always @(posedge clk) if( clk_en ) begin 52 | if(overflow_A) begin 53 | overflow2 <= 1'b1; 54 | overflow_cycle <= { next_op, next_ch }; 55 | end else begin 56 | if(overflow_cycle == {next_op, next_ch}) overflow2<=1'b0; 57 | end 58 | end 59 | 60 | always @(posedge clk) if( clk_en ) 61 | keyon_I <= (csm&&next_ch==3'd2&&overflow2) || csr_out; 62 | 63 | reg up_keyon_reg; 64 | reg [3:0] tkeyon_op; 65 | reg [2:0] tkeyon_ch; 66 | wire key_upnow; 67 | 68 | assign key_upnow = up_keyon_reg && (tkeyon_ch==next_ch) && (next_op == 2'd3); 69 | 70 | always @(posedge clk) if( clk_en ) begin 71 | if (rst) 72 | up_keyon_reg <= 1'b0; 73 | if (up_keyon) begin 74 | up_keyon_reg <= 1'b1; 75 | tkeyon_op <= keyon_op; 76 | tkeyon_ch <= keyon_ch; end 77 | else if (key_upnow) 78 | up_keyon_reg <= 1'b0; 79 | end 80 | 81 | 82 | wire middle1; 83 | wire middle2; 84 | wire middle3; 85 | wire din = key_upnow ? tkeyon_op[3] : csr_out; 86 | wire mid_din2 = key_upnow ? tkeyon_op[1] : middle1; 87 | wire mid_din3 = key_upnow ? tkeyon_op[2] : middle2; 88 | wire mid_din4 = key_upnow ? tkeyon_op[0] : middle3; 89 | 90 | jt12_sh_rst #(.width(1),.stages(6),.rstval(1'b0)) u_konch0( 91 | .clk ( clk ), 92 | .clk_en ( clk_en ), 93 | .rst ( rst ), 94 | .din ( din ), 95 | .drop ( middle1 ) 96 | ); 97 | 98 | jt12_sh_rst #(.width(1),.stages(6),.rstval(1'b0)) u_konch1( 99 | .clk ( clk ), 100 | .clk_en ( clk_en ), 101 | .rst ( rst ), 102 | .din ( mid_din2 ), 103 | .drop ( middle2 ) 104 | ); 105 | 106 | jt12_sh_rst #(.width(1),.stages(6),.rstval(1'b0)) u_konch2( 107 | .clk ( clk ), 108 | .clk_en ( clk_en ), 109 | .rst ( rst ), 110 | .din ( mid_din3 ), 111 | .drop ( middle3 ) 112 | ); 113 | 114 | jt12_sh_rst #(.width(1),.stages(6),.rstval(1'b0)) u_konch3( 115 | .clk ( clk ), 116 | .clk_en ( clk_en ), 117 | .rst ( rst ), 118 | .din ( mid_din4 ), 119 | .drop ( csr_out ) 120 | ); 121 | end 122 | else begin // 3 channels 123 | reg din; 124 | reg [3:0] next_op_hot; 125 | 126 | always @(*) begin 127 | case( next_op ) 128 | 2'd0: next_op_hot = 4'b0001; // S1 129 | 2'd1: next_op_hot = 4'b0100; // S3 130 | 2'd2: next_op_hot = 4'b0010; // S2 131 | 2'd3: next_op_hot = 4'b1000; // S4 132 | endcase 133 | din = keyon_ch[1:0]==next_ch[1:0] && up_keyon ? |(keyon_op&next_op_hot) : csr_out; 134 | end 135 | 136 | always @(posedge clk) if( clk_en ) 137 | keyon_I <= csr_out; // No CSM for YM2203 138 | 139 | jt12_sh_rst #(.width(1),.stages(12),.rstval(1'b0)) u_konch1( 140 | .clk ( clk ), 141 | .clk_en ( clk_en ), 142 | .rst ( rst ), 143 | .din ( din ), 144 | .drop ( csr_out ) 145 | ); 146 | end 147 | endgenerate 148 | 149 | 150 | endmodule 151 | --------------------------------------------------------------------------------