├── README.md ├── dist ├── Assets │ └── vectrex │ │ ├── common │ │ ├── .keep │ │ ├── 0 - 2021 Romset │ │ │ └── .keep │ │ └── 0 - 2024 Romset │ │ │ └── .keep │ │ └── obsidian.Vectrex │ │ ├── 0 - 2021 Romset │ │ ├── Armor..Attack (World).json │ │ ├── Bedlam (USA, Europe).json │ │ ├── Berzerk (World).json │ │ ├── Blitz! - Action Football (USA, Europe).json │ │ ├── Clean Sweep (World).json │ │ ├── Cosmic Chasm (World).json │ │ ├── Dark Tower (USA).json │ │ ├── Fortress of Narzod (USA, Europe).json │ │ ├── Heads-up - Action Soccer (USA).json │ │ ├── HyperChase - Auto Race (World).json │ │ ├── Mine Storm (World).json │ │ ├── Mine Storm II (USA).json │ │ ├── Mr Boston Clean Sweep (Europe).json │ │ ├── Pitcher's Duel (USA).json │ │ ├── Polar Rescue (USA).json │ │ ├── Pole Position (USA).json │ │ ├── Rip Off (World).json │ │ ├── Scramble (USA, Europe).json │ │ ├── Solar Quest (World).json │ │ ├── Space Wars (World).json │ │ ├── Spike (USA, Europe).json │ │ ├── Spin Ball (USA).json │ │ ├── Star Castle (USA).json │ │ ├── Star Ship (Europe).json │ │ ├── Star Trek - The Motion Picture (USA).json │ │ ├── StarHawk (World).json │ │ ├── Tour De France (USA).json │ │ ├── WebWarp (Europe).json │ │ └── WebWars (USA).json │ │ ├── 0 - 2024 Romset │ │ ├── Armor Attack (World).json │ │ ├── Bedlam (USA, Europe).json │ │ ├── Berzerk (Europe) (Rev 2).json │ │ ├── Berzerk (USA).json │ │ ├── Blitz! - Action Football (USA, Europe) (Alt).json │ │ ├── Blitz! - Action Football (World).json │ │ ├── Clean Sweep (World).json │ │ ├── Cosmic Chasm (World).json │ │ ├── Dark Tower (USA) (Proto).json │ │ ├── Fortress of Narzod (USA, Europe).json │ │ ├── Heads-Up - Action Soccer (World).json │ │ ├── HyperChase - Auto Race (World).json │ │ ├── Mail Plane (USA) (Proto) (05838962).json │ │ ├── Mail Plane (USA) (Proto) (DA1AC0DB).json │ │ ├── Mine Storm (World).json │ │ ├── Mine Storm II (USA) (Rev 2).json │ │ ├── Mr. Boston Clean Sweep (Europe).json │ │ ├── Pitcher's Duel (USA) (Proto).json │ │ ├── Polar Rescue (USA) (Beta).json │ │ ├── Polar Rescue (USA).json │ │ ├── Pole Position (USA) (Alt).json │ │ ├── Pole Position (USA).json │ │ ├── Rip Off (World).json │ │ ├── Scramble (USA, Europe).json │ │ ├── Solar Quest (World).json │ │ ├── Space Wars (World).json │ │ ├── Spike (USA, Europe).json │ │ ├── Spinball (USA).json │ │ ├── Star Castle (USA).json │ │ ├── Star Ship (Europe).json │ │ ├── Star Trek - The Motion Picture (USA).json │ │ ├── StarHawk (World).json │ │ ├── Test Cartridge (USA) (Rev 4) (Proto).json │ │ ├── Tour De France (USA) (Proto).json │ │ ├── WebWarp (Europe).json │ │ └── WebWars (USA).json │ │ └── 0 - Select ROM and Overlay.json ├── Cores │ └── obsidian.Vectrex │ │ ├── audio.json │ │ ├── bitstream.rbf_r │ │ ├── core.json │ │ ├── data.json │ │ ├── icon.bin │ │ ├── info.txt │ │ ├── input.json │ │ ├── interact.json │ │ ├── variants.json │ │ └── video.json └── Platforms │ ├── _images │ └── vectrex.bin │ └── vectrex.json └── src └── fpga ├── .gitignore ├── ap_core.qpf ├── ap_core.qsf ├── ap_core_assignment_defaults.qdf ├── apf ├── apf.qip ├── apf_constraints.sdc ├── apf_top.v ├── build_id.mif ├── build_id_gen.tcl ├── common.v ├── io_bridge_peripheral.v ├── io_pad_controller.v ├── mf_datatable.qip ├── mf_datatable.v ├── mf_ddio_bidir_12.ppf ├── mf_ddio_bidir_12.qip └── mf_ddio_bidir_12.v ├── core ├── core_bridge_cmd.v ├── core_constraints.sdc ├── core_top.v ├── data_loader.sv ├── iir_1st_order.v ├── mf_pllbase.bsf ├── mf_pllbase.ppf ├── mf_pllbase.qip ├── mf_pllbase.sip ├── mf_pllbase.spd ├── mf_pllbase.v ├── mf_pllbase │ ├── mf_pllbase_0002.qip │ └── mf_pllbase_0002.v ├── mf_pllbase_sim.f ├── mf_pllbase_sim │ ├── aldec │ │ └── rivierapro_setup.tcl │ ├── cadence │ │ ├── cds.lib │ │ ├── hdl.var │ │ └── ncsim_setup.sh │ ├── mentor │ │ └── msim_setup.tcl │ ├── mf_pllbase.vo │ └── synopsys │ │ ├── vcs │ │ └── vcs_setup.sh │ │ └── vcsmx │ │ ├── synopsys_sim.setup │ │ └── vcsmx_setup.sh ├── pin_ddio_clk.ppf ├── pin_ddio_clk.qip ├── pin_ddio_clk.v ├── rtl │ ├── alphablend.sv │ ├── alphablend.sv1 │ ├── alphablend.sv2 │ ├── compressor.sv │ ├── compressor_lut.vhd │ ├── cpu09l_128a.vhd │ ├── expander_lut.vhd │ ├── gen_dpram.vhd │ ├── gen_ram.vhd │ ├── gen_rom.qip │ ├── gen_rom.vhd │ ├── m6522a.vhd │ ├── mc6809.v │ ├── mc6809is.v │ ├── rom_storage.vhd │ ├── sdram.sv │ ├── sdram.sv1 │ ├── sp0256.vhd │ ├── sp0256_al2_decoded.vhd │ ├── vectrex.vhd │ └── ym2149.sv ├── sound_i2s.sv ├── stp1.stp └── sync_fifo.sv └── output_files ├── .gitignore ├── ap_core.jdi ├── ap_core.rbf ├── ap_core.sof ├── bitstream.rbf_r ├── reverse_bits.exe └── run.bat /README.md: -------------------------------------------------------------------------------- 1 | # Vectrex for Analogue Pocket 2 | 3 | Vectrex for Analogue Pocket by Obsidian-dot-dev. 4 | 5 | + Based on Dar's FPGA Vectrex core [Dar](https://darfpga.blogspot.com/) 6 | + Based on the [Port to MiSTer by Sorgelig](https://github.com/MiSTer-devel/Vectrex_MiSTer) 7 | + Template code based on the Analogue Pocket port of Asteroids by [ericlewis](https://github.com/ericlewis/openfpga-asteroids) 8 | 9 | ## Supported 10 | 11 | + High-resolution 540x720 display for super crisp lines at perfect 2x integer scaling. 12 | + Screen overlays! 13 | + Auto-loading of overlays. 14 | + Variable beam "persistence" setting. Lower values are less flickery, but more blurry. Higher values are sharper but more flickery. 15 | + Selectable "overburn" setting to simulate the bright points that occur at the "Vertices" of lines drawn by the beam scanner. Note that the rest of the line becomes dimmer when this is enabled. 16 | + Button remapping. 17 | + Analog controls on gamepads when docked. 18 | + Audio low-pass filter to approximate the frequency response of the 3" speaker in the original console 19 | 20 | ## Known Issues 21 | 22 | + Color mode and external peripherals are not currently supported. 23 | + Some games require analog controls; these are only playable in dock with a compatible joystick. 24 | 25 | ## Phosphor Decay 26 | 27 | When enabled, the "Phosphor Decay" option modifies pixel persistence behavior, giving a more natural and less "smudgy" appearance to the image. This decay model stacks on-top of the decay provided by the persistence slider. Because the two effects stack, a lower persistence value is recommended when this option is enabled. 28 | 29 | ## Audio Filter 30 | 31 | To more accurately simulate the audio response of the original console, an optional 5kHz low-pass filter is provided. This value was chosen to estimate the response of a 3" paper-cone driver like the one found in the Vectrex console. 32 | 33 | Note: In looking at the original schematic, it appears the only audio filtering is provided by a 22kHz LPF network, applied before the signal is amplified by an LM386. The impacts of either of these would be negligible relative to the frequency response of the speaker. 34 | 35 | ## BIOS 36 | 37 | This core now relies on a BIOS ROM named `vectrex.bin` to be present in `Assets/vectrex/common`. The core will fail to run without this dependency. 38 | 39 | ## ROMs and Overlays 40 | 41 | ROM files are not included with this core. 42 | 43 | ROMs in the standard `.vec` format are supported. These can be placed in the standard `assets/vectrex/common` folder. 44 | 45 | Where available, this core uses `.ovr` overlays in the same format as MiSTer. Please copy the overlays assets from that package, and put them in `assets/vectrex/common/overlays`. 46 | 47 | These overlays are not included in this repo, but you can find a complete copy of compatible assets in the `overlays.zip` archive located in [MiSTer's Vectrex repo's overlay directory](https://github.com/MiSTer-devel/Vectrex_MiSTer/tree/master/overlays) 48 | 49 | The use of overlay files is not required - users may manually select only a `.vec` file if desired. Overlays can be swapped in-game by selecting the "Load Overlay" option in the interact menu. 50 | 51 | ## Auto-loading ROMs and Overlays via .json files 52 | 53 | This core now uses `.json` instance files to simultaneous load ROMs along with their corresponding overlays. Sets of `.json` files for the officially released games + prototypes are provided for reference images. 54 | 55 | Two sets of auto-load json files are provided: 56 | + `0 - 2024 Romset` contains json data for the newet 2024 NoIntro images. 57 | + `0 - 2021 Romset` contains json data for the previous 2021 NoIntro images. 58 | 59 | For the supported json data, it is expected that corresponding game data is stored under `Assets/vectrex/common/0 - 2021 Romset` or `Assets/vectrex/common/0 - 2024 Romset`, and the overlays are stored under `assets/vectrex/common/overlays`. 60 | 61 | Within the `.json` files: 62 | + The `.vec` entries correspond to the filenames of ROMs as they appear in the Vectrex "No-Intro" romset. 63 | + The `.ovr` entries correspond to the filenames of overlays as they appear in the MiSTeR "overlays.zip" archive. 64 | 65 | Additional auto-load entries can be added by replacing the filenames of the `.vec` and `.ovr` entries. 66 | 67 | ## Compatibility 68 | 69 | All 22 of the original 28 games not requiring 3d imager or light-pen have been tested as working. Many popular homebrew titles also run correctly on this core. Overall performance and compatibility should match the MiSTeR version. 70 | 71 | ## Release Notes 72 | 73 | 0.9.4: 74 | + Fix BIOS path. 75 | 76 | 0.9.3: 77 | + Added audio low-pass filter. 78 | + Moved cart loading to SRAM. 79 | + Removed built-in BIOS. 80 | + Moved the existing 2021 No-Intro .json's to the "0 - 2021 Romset" folder. 81 | + Added 2024 No-Intro .json's to the "0 - 2024 Romset" folder. 82 | + Increased vector dynamic range to 6 bits from 5 bits for slightly improved image quality. 83 | + Companding for improved dynamic-range. 84 | + Optional "Phosphor decay" mode that gives a less "smeary" persistence effect. 85 | + Persistence control now has 32 levels, with better granularity. 86 | + Roms can be loaded directly without requiring an overlay now. 87 | 88 | 0.9.2: 89 | + When manually loading games, overlays are no longer required to start the core. Overlays can still be selected from the UI. 90 | 91 | 0.9.1: 92 | + Added .json instance files for auto-loading of games + overlays 93 | + Added support for analog joysticks when docked. 94 | + Fixed SDRAM refresh when overlays are disabled. 95 | 96 | 0.9.0: 97 | + Initial release 98 | 99 | ## Attribution 100 | 101 | ``` 102 | --------------------------------------------------------------------------------- 103 | -- Vectrex by Dar (darfpga@aol.fr) (27/12/2017) 104 | -- http://darfpga.blogspot.fr 105 | ---------------------------------------------------------------------------------------------------------------------------------------------------------- 106 | -- SP0256-al2 prom decoding scheme and speech synthesis algorithm are from : 107 | -- 108 | -- Copyright Joseph Zbiciak, all rights reserved. 109 | -- Copyright tim lindner, all rights reserved. 110 | -- 111 | -- See C source code and license in sp0256.c from MAME source 112 | -- 113 | -- VHDL code is by Dar. 114 | --------------------------------------------------------------------------------- 115 | -- gen_ram.vhd & io_ps2_keyboard 116 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 117 | -- http://www.syntiac.com/fpga64.html 118 | --------------------------------------------------------------------------------- 119 | -- VIA m6522 120 | -- Copyright (c) MikeJ - March 2003 121 | -- + modification 122 | --------------------------------------------------------------------------------- 123 | -- YM2149 (AY-3-8910) 124 | -- Copyright (c) MikeJ - Jan 2005 125 | --------------------------------------------------------------------------------- 126 | -- cpu09l_128 127 | -- Copyright (C) 2003 - 2010 John Kent 128 | -- + modification 129 | ``` 130 | -------------------------------------------------------------------------------- /dist/Assets/vectrex/common/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Assets/vectrex/common/.keep -------------------------------------------------------------------------------- /dist/Assets/vectrex/common/0 - 2021 Romset/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Assets/vectrex/common/0 - 2021 Romset/.keep -------------------------------------------------------------------------------- /dist/Assets/vectrex/common/0 - 2024 Romset/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Assets/vectrex/common/0 - 2024 Romset/.keep -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Armor..Attack (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Armor..Attack (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/ArmorAttack.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Bedlam (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Bedlam (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Bedlam.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Berzerk (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Berzerk (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Berzerk.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Blitz! - Action Football (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Blitz! - Action Football (USA, Europe) (0F11CE0C).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Blitz__Action_Football.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Clean Sweep (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Clean Sweep (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Clean_Sweep.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Cosmic Chasm (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Cosmic Chasm (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Cosmic_Chasm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Dark Tower (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Dark Tower (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Dark_Tower_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Fortress of Narzod (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Fortress of Narzod (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Fortress_of_Narzod.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Heads-up - Action Soccer (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Heads-Up - Action Soccer (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Heads-Up_Action_Soccer.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/HyperChase - Auto Race (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/HyperChase - Auto Race (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/HyperChase_Auto_Race.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Mine Storm (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Mine Storm (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mine_Storm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Mine Storm II (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Mine Storm II (USA) (Rev 2).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mine_Storm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Mr Boston Clean Sweep (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Mr. Boston Clean Sweep (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mr_Boston_Clean_Sweep.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Pitcher's Duel (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Pitcher's Duel (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Pitchers_Duel_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Polar Rescue (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Polar Rescue (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Polar_Rescue.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Pole Position (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Pole Position (USA) (A00ED3D6).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Pole_Position.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Rip Off (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Rip Off (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Rip_Off.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Scramble (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Scramble (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Scramble.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Solar Quest (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Solar Quest (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Solar_Quest.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Space Wars (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Space Wars (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Space_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Spike (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Spike (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Spike.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Spin Ball (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Spin ball (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Spinball.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Star Castle (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Star Castle (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Castle.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Star Ship (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Star Ship (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Ship.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Star Trek - The Motion Picture (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Star Trek - The Motion Picture (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Trek-The_Motion_Picture.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/StarHawk (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/StarHawk (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Hawk.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/Tour De France (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/Tour De France (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Tour_De_France_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/WebWarp (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/WebWarp (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Web_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2021 Romset/WebWars (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2021 Romset/WebWars (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Web_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Armor Attack (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Armor Attack (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/ArmorAttack.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Bedlam (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Bedlam (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Bedlam.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Berzerk (Europe) (Rev 2).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Berzerk (Europe) (Rev 2).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Berzerk.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Berzerk (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Berzerk (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Berzerk.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Blitz! - Action Football (USA, Europe) (Alt).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Blitz! - Action Football (USA, Europe) (Alt).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Blitz__Action_Football.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Blitz! - Action Football (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Blitz! - Action Football (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Blitz__Action_Football.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Clean Sweep (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Clean Sweep (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Clean_Sweep.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Cosmic Chasm (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Cosmic Chasm (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Cosmic_Chasm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Dark Tower (USA) (Proto).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Dark Tower (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Dark_Tower_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Fortress of Narzod (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Fortress of Narzod (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Fortress_of_Narzod.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Heads-Up - Action Soccer (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Heads-Up - Action Soccer (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Heads-Up_Action_Soccer.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/HyperChase - Auto Race (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/HyperChase - Auto Race (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/HyperChase_Auto_Race.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Mail Plane (USA) (Proto) (05838962).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Mail Plane (USA) (Proto) (05838962).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "Blank_Overlay.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Mail Plane (USA) (Proto) (DA1AC0DB).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Mail Plane (USA) (Proto) (DA1AC0DB).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "Blank_Overlay.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Mine Storm (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Mine Storm (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mine_Storm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Mine Storm II (USA) (Rev 2).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Mine Storm II (USA) (Rev 2).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mine_Storm.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Mr. Boston Clean Sweep (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Mr. Boston Clean Sweep (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Mr_Boston_Clean_Sweep.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Pitcher's Duel (USA) (Proto).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Pitcher's Duel (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Pitchers_Duel_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Polar Rescue (USA) (Beta).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Polar Rescue (USA) (Beta).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Polar_Rescue.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Polar Rescue (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Polar Rescue (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Polar_Rescue.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Pole Position (USA) (Alt).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Pole Position (USA) (Alt).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Pole_Position.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Pole Position (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Pole Position (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Pole_Position.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Rip Off (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Rip Off (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Rip_Off.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Scramble (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Scramble (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Scramble.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Solar Quest (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Solar Quest (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Solar_Quest.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Space Wars (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Space Wars (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Space_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Spike (USA, Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Spike (USA, Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Spike.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Spinball (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Spinball (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Spinball.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Star Castle (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Star Castle (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Castle.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Star Ship (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Star Ship (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Ship.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Star Trek - The Motion Picture (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Star Trek - The Motion Picture (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Trek-The_Motion_Picture.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/StarHawk (World).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/StarHawk (World).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Star_Hawk.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Test Cartridge (USA) (Rev 4) (Proto).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Test Cartridge (USA) (Rev 4) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "Blank_Overlay.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/Tour De France (USA) (Proto).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/Tour De France (USA) (Proto).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Tour_De_France_Proto.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/WebWarp (Europe).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/WebWarp (Europe).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Web_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - 2024 Romset/WebWars (USA).json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | }, 8 | "data_path": "", 9 | "data_slots": [ 10 | { 11 | "id": 1, 12 | "filename": "0 - 2024 Romset/WebWars (USA).vec" 13 | }, 14 | { 15 | "id": 2, 16 | "filename": "overlays/Web_Wars.ovr" 17 | } 18 | ] 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /dist/Assets/vectrex/obsidian.Vectrex/0 - Select ROM and Overlay.json: -------------------------------------------------------------------------------- 1 | { 2 | "instance":{ 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 0, 6 | "select": false 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/audio.json: -------------------------------------------------------------------------------- 1 | { 2 | "audio": { 3 | "magic": "APF_VER_1" 4 | } 5 | } -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/bitstream.rbf_r: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Cores/obsidian.Vectrex/bitstream.rbf_r -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/core.json: -------------------------------------------------------------------------------- 1 | { 2 | "core": { 3 | "magic": "APF_VER_1", 4 | "metadata": { 5 | "platform_ids": ["vectrex"], 6 | "shortname": "Vectrex", 7 | "description": "GCE Vectrex", 8 | "author": "obsidian", 9 | "url": "https://github.com/obsidian-dot-dev/openFPGA-Vectrex", 10 | "version": "0.9.4", 11 | "date_release": "2024-04-28" 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/obsidian.Vectrex/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "magic": "APF_VER_1", 4 | "data_slots": [ 5 | { 6 | "name": "Game JSON Data", 7 | "id" : 0, 8 | "required" : true, 9 | "parameters" : "0x1D3" 10 | }, 11 | { 12 | "name": "BIOS", 13 | "id": 3, 14 | "required": true, 15 | "parameters": "0", 16 | "filename": "vectrex.bin", 17 | "size_exact": 8192, 18 | "address": "0x00010000" 19 | }, 20 | { 21 | "name": "Game", 22 | "id": 1, 23 | "required": true, 24 | "parameters": "0x109", 25 | "extensions": ["vec", "bin"], 26 | "address": "0x00000000" 27 | }, 28 | { 29 | "name": "Overlay", 30 | "id": 2, 31 | "required": false, 32 | "parameters": "0x109", 33 | "extensions": ["ovr"], 34 | "address": "0x01000000" 35 | } 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/icon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Cores/obsidian.Vectrex/icon.bin -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/info.txt: -------------------------------------------------------------------------------- 1 | GCE Vectrex released in 1982. 2 | Port of the original core by Dar. -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "magic": "APF_VER_1", 4 | "controllers": [ 5 | { 6 | "type": "default", 7 | "mappings": [ 8 | { 9 | "id": 0, 10 | "name": "Button 1", 11 | "key": "pad_btn_x" 12 | }, 13 | { 14 | "id": 1, 15 | "name": "Button 2", 16 | "key": "pad_btn_b" 17 | }, 18 | { 19 | "id": 2, 20 | "name": "Button 3", 21 | "key": "pad_btn_y" 22 | }, 23 | 24 | { 25 | "id": 3, 26 | "name": "Button 4", 27 | "key": "pad_btn_a" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/interact.json: -------------------------------------------------------------------------------- 1 | { 2 | "interact": { 3 | "magic": "APF_VER_1", 4 | "variables": [ 5 | { 6 | "name": "Persistence", 7 | "id": 1, 8 | "type": "slider_u32", 9 | "enabled": true, 10 | "persist": true, 11 | "address": "0x80000000", 12 | "writeonly": true, 13 | "defaultval": 5, 14 | "graphical": { 15 | "signed": false, 16 | "min": 2, 17 | "max": 31, 18 | "adjust_small": 1, 19 | "adjust_large": 1 20 | } 21 | }, 22 | { 23 | "name": "Overburn", 24 | "id": 2, 25 | "type": "check", 26 | "enabled": true, 27 | "persist": true, 28 | "writeonly": true, 29 | "address": "0x90000000", 30 | "defaultval": 0, 31 | "value": 1, 32 | "mask": "0xFFFFFFFE" 33 | }, 34 | { 35 | "name": "Phosphor Decay", 36 | "id": 3, 37 | "type": "check", 38 | "enabled": true, 39 | "persist": true, 40 | "writeonly": true, 41 | "address": "0xC0000000", 42 | "defaultval": 1, 43 | "value": 1, 44 | "mask": "0xFFFFFFFE" 45 | }, 46 | { 47 | "name": "Show Overlay", 48 | "id": 4, 49 | "type": "check", 50 | "enabled": true, 51 | "persist": true, 52 | "writeonly": true, 53 | "address": "0xA0000000", 54 | "defaultval": 1, 55 | "value": 1, 56 | "mask": "0xFFFFFFFE" 57 | }, 58 | { 59 | "name": "Audio Filter", 60 | "id": 5, 61 | "type": "check", 62 | "enabled": true, 63 | "persist": true, 64 | "writeonly": true, 65 | "address": "0xB0000000", 66 | "defaultval": 1, 67 | "value": 1, 68 | "mask": "0xFFFFFFFE" 69 | } 70 | ], 71 | "messages": [] 72 | } 73 | } -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/variants.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "magic": "APF_VER_1", 4 | "variant_list": [] 5 | } 6 | } -------------------------------------------------------------------------------- /dist/Cores/obsidian.Vectrex/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "video": { 3 | "magic": "APF_VER_1", 4 | "scaler_modes": [ 5 | { 6 | "width": 540, 7 | "height": 719, 8 | "aspect_w": 3, 9 | "aspect_h": 4, 10 | "rotation": 0, 11 | "mirror": 0 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /dist/Platforms/_images/vectrex.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidian-dot-dev/openFPGA-Vectrex/7f95a55ba5a020c9893ccf0d7854caa65cfea56c/dist/Platforms/_images/vectrex.bin -------------------------------------------------------------------------------- /dist/Platforms/vectrex.json: -------------------------------------------------------------------------------- 1 | { 2 | "platform": { 3 | "category": "Console", 4 | "name": "Vectrex", 5 | "year": 1982, 6 | "manufacturer": "GCE" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/fpga/.gitignore: -------------------------------------------------------------------------------- 1 | */db/ 2 | */incremental_db/ 3 | */simulation/ 4 | */greybox_tmp/ 5 | incremental_db/ 6 | db/ 7 | PLLJ_PLLSPE_INFO.txt 8 | c5_pin_model_dump.txt 9 | cr_ie_info.json 10 | *.pin 11 | *.pof 12 | *.ptf.* 13 | *.qar 14 | *.qarlog 15 | *.qws 16 | *.rpt 17 | *.smsg 18 | *.sof 19 | *.sopc_builder 20 | *.summary 21 | *.txt 22 | *.bak 23 | *.cmp 24 | *.done 25 | *.xml 26 | *.sld 27 | *.cdf 28 | 29 | -------------------------------------------------------------------------------- /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/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/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/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 : 20240425; 13 | 0E1 : 00215937; 14 | 0E2 : 00294a38; 15 | 16 | END; 17 | -------------------------------------------------------------------------------- /src/fpga/apf/build_id_gen.tcl: -------------------------------------------------------------------------------- 1 | # ================================================================================ 2 | # (c) 2011 Altera Corporation. All rights reserved. 3 | # Altera products are protected under numerous U.S. and foreign patents, maskwork 4 | # rights, copyrights and other intellectual property laws. 5 | # 6 | # This reference design file, and your use thereof, is subject to and governed 7 | # by the terms and conditions of the applicable Altera Reference Design License 8 | # Agreement (either as signed by you, agreed by you upon download or as a 9 | # "click-through" agreement upon installation andor found at www.altera.com). 10 | # By using this reference design file, you indicate your acceptance of such terms 11 | # and conditions between you and Altera Corporation. In the event that you do 12 | # not agree with such terms and conditions, you may not use the reference design 13 | # file and please promptly destroy any copies you have made. 14 | # 15 | # This reference design file is being provided on an "as-is" basis and as an 16 | # accommodation and therefore all warranties, representations or guarantees of 17 | # any kind (whether express, implied or statutory) including, without limitation, 18 | # warranties of merchantability, non-infringement, or fitness for a particular 19 | # purpose, are specifically disclaimed. By making this reference design file 20 | # available, Altera expressly does not recommend, suggest or require that this 21 | # reference design file be used in combination with any other product not 22 | # provided by Altera. 23 | # ================================================================================ 24 | # 25 | # Build ID Verilog Module Script 26 | # Jeff Wiencrot - 8/1/2011 27 | # 28 | # Generates a Verilog module that contains a timestamp, physical address, and host name 29 | # from the current build. These values are available from the build_date, build_time, 30 | # physical_address, and host_name output ports of the build_id module in the build_id.v 31 | # Verilog source file. 32 | # 33 | # The format for each value is as follows: 34 | # Date - 32-bit decimal number of the format mmddyyyy 35 | # Time - 32-bit decimal number of the format hhmmss 36 | # Phyiscal Address - 48-bit hexadecimal number 37 | # Host name - 120-bit hexadecimal number with pairs of digits equal to the 38 | # hexadecimal code for the first 15 ASCII characters of the host 39 | # name. For added clarity, host names that have fewer than 30 40 | # hexadecimal digits (15 characters) are padded on the left with 41 | # zeros. 42 | # 43 | # Usage: 44 | # 45 | # To manually execute this script, source this file using the following Tcl commands: 46 | # source build_id_verilog.tcl 47 | # 48 | # To have this script automatically execute each time your project is built, use the 49 | # following command (see: http://www.altera.com/support/examples/tcl/auto_processing.html): 50 | # set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:build_id_verilog.tcl 51 | # 52 | # Comment out the last line to prevent the process from automatically executing when 53 | # the file is sourced. The process can then be executed with the following command: 54 | # generateBuildID_Verilog 55 | # 56 | # 57 | # For more information, see "build_identification.pdf" 58 | # 59 | # ================================================================================ 60 | # 61 | # 2021-01-21 Analogue 62 | # 63 | # Only care about generating build date/time, so the rest was removed. 64 | # The original can be downloaded from the Intel resource page 65 | # 66 | 67 | proc generateBuildID_Verilog {} { 68 | 69 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) 70 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] 71 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ] 72 | 73 | # Create a Verilog file for output 74 | set outputFileName "apf/build_id.v" 75 | set outputFile [open $outputFileName "w"] 76 | 77 | # Output the Verilog source 78 | puts $outputFile "// Build ID Verilog Module" 79 | puts $outputFile "//" 80 | puts $outputFile "// Note - these are stored as binary coded decimal" 81 | puts $outputFile "// Date: $buildDate" 82 | puts $outputFile "// Time: $buildTime" 83 | puts $outputFile "" 84 | puts $outputFile "module build_id" 85 | puts $outputFile "(" 86 | puts $outputFile " output \[31:0\] build_date," 87 | puts $outputFile " output \[31:0\] build_time" 88 | puts $outputFile ");" 89 | puts $outputFile "" 90 | puts $outputFile " assign build_date = 32'h$buildDate;" 91 | puts $outputFile " assign build_time = 32'h$buildTime;" 92 | puts $outputFile "" 93 | puts $outputFile "endmodule" 94 | close $outputFile 95 | 96 | 97 | 98 | # Send confirmation message to the Messages window 99 | #post_message "APF core build date/time generated: [pwd]/$outputFileName" 100 | #post_message "Date: $buildDate" 101 | #post_message "Time: $buildTime" 102 | } 103 | 104 | 105 | proc generateBuildID_MIF {} { 106 | 107 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) 108 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] 109 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ] 110 | set buildUnique [expr {int(rand()*(4294967295))}] 111 | 112 | set buildDateNoLeadingZeros [string trimleft $buildDate "0"] 113 | set buildTimeNoLeadingZeros [string trimleft $buildTime "0"] 114 | set buildDate4Byte [format "%08d" $buildDateNoLeadingZeros] 115 | set buildTime4Byte [format "%08d" $buildTimeNoLeadingZeros] 116 | set buildUnique4Byte [format "%08x" $buildUnique] 117 | 118 | #set buildDate4Byte \ 119 | [concat [string range $buildDate 0 1] \ 120 | [string range $buildDate 2 3] \ 121 | [string range $buildDate 4 5] \ 122 | [string range $buildDate 6 7] ] 123 | 124 | 125 | set buildDateNumBytes 4 126 | set buildTimeNumBytes 4 127 | 128 | # Calculate depth of the memory (8-bit) words 129 | set memoryDepth [expr $buildDateNumBytes + $buildTimeNumBytes] 130 | 131 | # Create a Memory Initialization File for output 132 | set outputFileName "apf/build_id.mif" 133 | set outputFile [open $outputFileName "w"] 134 | 135 | # Output the MIF header (see: http://quartushelp.altera.com/current/mergedProjects/reference/glossary/def_mif.htm) 136 | puts $outputFile "-- Build ID Memory Initialization File" 137 | puts $outputFile "--" 138 | puts $outputFile "" 139 | puts $outputFile "DEPTH = 256;" 140 | puts $outputFile "WIDTH = 32;" 141 | puts $outputFile "ADDRESS_RADIX = HEX;" 142 | puts $outputFile "DATA_RADIX = HEX;" 143 | puts $outputFile "" 144 | puts $outputFile "CONTENT" 145 | puts $outputFile "BEGIN" 146 | puts $outputFile "" 147 | puts $outputFile " 0E0 : $buildDate4Byte;" 148 | puts $outputFile " 0E1 : $buildTime4Byte;" 149 | puts $outputFile " 0E2 : $buildUnique4Byte;" 150 | puts $outputFile "" 151 | puts $outputFile "END;" 152 | 153 | # Close file to complete write 154 | close $outputFile 155 | 156 | # Send confirmation message to the Messages window 157 | post_message "APF core build date/time generated: [pwd]/$outputFileName" 158 | } 159 | 160 | generateBuildID_MIF 161 | 162 | # 2021-01-21 Analogue 163 | # 164 | # There are some circumstances where you want all parts of a FPGA flow to be deterministic, especially 165 | # when trying to hash out timing issues. 166 | # You should comment this line out and temporarily bypass buildid generation so that synthesis/par 167 | # have consistent working input. MIF bram contents like above won't affect the random seed or trigger 168 | # recompilation. 169 | # Don't forget to re-enable before you release. 170 | # 171 | # generateBuildID_Verilog 172 | -------------------------------------------------------------------------------- /src/fpga/apf/common.v: -------------------------------------------------------------------------------- 1 | // Software License Agreement 2 | 3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”), 4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the 5 | // Company's customer, solely for use in designing, testing and creating 6 | // applications for use with Company's Products or Services. The software is 7 | // owned by the Company and/or its licensors, and is protected under applicable 8 | // laws, including, but not limited to, U.S. copyright law. All rights are 9 | // reserved. By using the APF code you are agreeing to the terms of the End User 10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] 11 | // and incorporated herein by reference. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED 14 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, 15 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR 16 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM 17 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE 18 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, 19 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND 20 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING 21 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR 22 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY 23 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, 24 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR 25 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY 26 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY 27 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, 28 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU 29 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH 30 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE 31 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW. 32 | // 33 | // 2-stage synchronizer 34 | // 35 | module synch_2 #(parameter WIDTH = 1) ( 36 | input wire [WIDTH-1:0] i, // input signal 37 | output reg [WIDTH-1:0] o, // synchronized output 38 | input wire clk, // clock to synchronize on 39 | output wire rise, // one-cycle rising edge pulse 40 | output wire fall // one-cycle falling edge pulse 41 | ); 42 | 43 | reg [WIDTH-1:0] stage_1; 44 | reg [WIDTH-1:0] stage_2; 45 | reg [WIDTH-1:0] stage_3; 46 | 47 | assign rise = (WIDTH == 1) ? (o & ~stage_2) : 1'b0; 48 | assign fall = (WIDTH == 1) ? (~o & stage_2) : 1'b0; 49 | always @(posedge clk) 50 | {stage_2, o, stage_1} <= {o, stage_1, i}; 51 | 52 | endmodule 53 | 54 | 55 | // 56 | // 3-stage synchronizer 57 | // 58 | module synch_3 #(parameter WIDTH = 1) ( 59 | input wire [WIDTH-1:0] i, // input signal 60 | output reg [WIDTH-1:0] o, // synchronized output 61 | input wire clk, // clock to synchronize on 62 | output wire rise, // one-cycle rising edge pulse 63 | output wire fall // one-cycle falling edge pulse 64 | ); 65 | 66 | reg [WIDTH-1:0] stage_1; 67 | reg [WIDTH-1:0] stage_2; 68 | reg [WIDTH-1:0] stage_3; 69 | 70 | assign rise = (WIDTH == 1) ? (o & ~stage_3) : 1'b0; 71 | assign fall = (WIDTH == 1) ? (~o & stage_3) : 1'b0; 72 | always @(posedge clk) 73 | {stage_3, o, stage_2, stage_1} <= {o, stage_2, stage_1, i}; 74 | 75 | endmodule 76 | 77 | 78 | module bram_block_dp #( 79 | parameter DATA = 32, 80 | parameter ADDR = 7 81 | ) ( 82 | input wire a_clk, 83 | input wire a_wr, 84 | input wire [ADDR-1:0] a_addr, 85 | input wire [DATA-1:0] a_din, 86 | output reg [DATA-1:0] a_dout, 87 | 88 | input wire b_clk, 89 | input wire b_wr, 90 | input wire [ADDR-1:0] b_addr, 91 | input wire [DATA-1:0] b_din, 92 | output reg [DATA-1:0] b_dout 93 | ); 94 | 95 | reg [DATA-1:0] mem [(2**ADDR)-1:0]; 96 | 97 | always @(posedge a_clk) begin 98 | if(a_wr) begin 99 | a_dout <= a_din; 100 | mem[a_addr] <= a_din; 101 | end else 102 | a_dout <= mem[a_addr]; 103 | end 104 | 105 | always @(posedge b_clk) begin 106 | if(b_wr) begin 107 | b_dout <= b_din; 108 | mem[b_addr] <= b_din; 109 | end else 110 | b_dout <= mem[b_addr]; 111 | end 112 | 113 | endmodule 114 | 115 | 116 | module bram_block_dp_nonstd #( 117 | parameter DATA = 32, 118 | parameter ADDR = 7, 119 | parameter DEPTH = 128 120 | ) ( 121 | input wire a_clk, 122 | input wire a_wr, 123 | input wire [ADDR-1:0] a_addr, 124 | input wire [DATA-1:0] a_din, 125 | output reg [DATA-1:0] a_dout, 126 | 127 | input wire b_clk, 128 | input wire b_wr, 129 | input wire [ADDR-1:0] b_addr, 130 | input wire [DATA-1:0] b_din, 131 | output reg [DATA-1:0] b_dout 132 | ); 133 | 134 | reg [DATA-1:0] mem [DEPTH-1:0]; 135 | 136 | always @(posedge a_clk) begin 137 | if(a_wr) begin 138 | a_dout <= a_din; 139 | mem[a_addr] <= a_din; 140 | end else 141 | a_dout <= mem[a_addr]; 142 | end 143 | 144 | always @(posedge b_clk) begin 145 | if(b_wr) begin 146 | b_dout <= b_din; 147 | mem[b_addr] <= b_din; 148 | end else 149 | b_dout <= mem[b_addr]; 150 | end 151 | 152 | endmodule -------------------------------------------------------------------------------- /src/fpga/apf/io_pad_controller.v: -------------------------------------------------------------------------------- 1 | // Software License Agreement 2 | 3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”), 4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the 5 | // Company's customer, solely for use in designing, testing and creating 6 | // applications for use with Company's Products or Services. The software is 7 | // owned by the Company and/or its licensors, and is protected under applicable 8 | // laws, including, but not limited to, U.S. copyright law. All rights are 9 | // reserved. By using the APF code you are agreeing to the terms of the End User 10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] 11 | // and incorporated herein by reference. To the extent any use of the APF requires 12 | // application of the MIT License or the GNU General Public License and terms of 13 | // this APF Software License Agreement and EULA are inconsistent with such license, 14 | // the applicable terms of the MIT License or the GNU General Public License, as 15 | // applicable, will prevail. 16 | 17 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED 18 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, 19 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR 20 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM 21 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE 22 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, 23 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND 24 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING 25 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR 26 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY 27 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, 28 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR 29 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY 30 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY 31 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, 32 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU 33 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH 34 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE 35 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW. 36 | // 37 | // pad controller 38 | // 2020-08-17 Analogue 39 | // 40 | 41 | module io_pad_controller ( 42 | 43 | input wire clk, 44 | input wire reset_n, 45 | 46 | inout reg pad_1wire, 47 | 48 | output reg [31:0] cont1_key, 49 | output reg [31:0] cont2_key, 50 | output reg [31:0] cont3_key, 51 | output reg [31:0] cont4_key, 52 | output reg [31:0] cont1_joy, 53 | output reg [31:0] cont2_joy, 54 | output reg [31:0] cont3_joy, 55 | output reg [31:0] cont4_joy, 56 | output reg [15:0] cont1_trig, 57 | output reg [15:0] cont2_trig, 58 | output reg [15:0] cont3_trig, 59 | output reg [15:0] cont4_trig, 60 | 61 | output reg rx_timed_out 62 | ); 63 | 64 | wire reset_n_s; 65 | synch_3 s00(reset_n, reset_n_s, clk); 66 | 67 | wire pad_1wire_s, pad_1wire_r, pad_1wire_f; 68 | synch_3 s01(pad_1wire, pad_1wire_s, clk, pad_1wire_r, pad_1wire_f); 69 | 70 | 71 | // 72 | // protocol fsm 73 | // 74 | 75 | reg [20:0] rx_timeout; // ~28ms 76 | 77 | reg [15:0] auto_poll_cnt; // 882us 78 | reg auto_poll_queue; 79 | 80 | reg [18:0] heartbeat_cnt; // 7ms 81 | reg heartbeat_queue; 82 | 83 | 84 | localparam ST_RESET = 'd0; 85 | localparam ST_IDLE = 'd1; 86 | localparam ST_RX_BUTTON_1 = 'd2; 87 | localparam ST_RX_BUTTON_2 = 'd3; 88 | localparam ST_TX_SCALER = 'd4; 89 | localparam ST_END_TX = 'd5; 90 | 91 | reg [3:0] state; 92 | reg [3:0] cnt; 93 | 94 | always @(posedge clk) begin 95 | tx_word_start <= 0; 96 | 97 | auto_poll_cnt <= auto_poll_cnt + 1'b1; 98 | heartbeat_cnt <= heartbeat_cnt + 1'b1; 99 | 100 | // increment rx timeout, override and reset when idle below 101 | rx_timeout <= rx_timeout + 1'b1; 102 | 103 | case(state) 104 | ST_RESET: begin 105 | reset_tr_n <= 0; 106 | rx_timed_out <= 0; 107 | 108 | if(&rx_timeout[19:0]) begin 109 | state <= ST_IDLE; 110 | end 111 | end 112 | ST_IDLE: begin 113 | // idle state 114 | reset_tr_n <= 1; 115 | rx_timeout <= 0; 116 | cnt <= 0; 117 | if(auto_poll_queue) begin 118 | auto_poll_queue <= 0; 119 | 120 | tx_word_start <= 1; 121 | tx_word <= 32'h4A10000C; 122 | 123 | state <= ST_RX_BUTTON_1; 124 | end else if(heartbeat_queue) begin 125 | heartbeat_queue <= 0; 126 | 127 | tx_word_start <= 1; 128 | tx_word <= 32'h4AFE0000; 129 | 130 | state <= ST_END_TX; 131 | end 132 | end 133 | // receive button words 134 | ST_RX_BUTTON_1: begin 135 | if(tx_word_done) begin 136 | state <= ST_RX_BUTTON_2; 137 | end 138 | end 139 | ST_RX_BUTTON_2: begin 140 | if(rx_word_done) begin 141 | cnt <= cnt + 1'b1; 142 | case(cnt) 143 | 0: cont1_key <= rx_word; 144 | 1: cont1_joy <= rx_word; 145 | 2: cont1_trig <= rx_word[15:0]; 146 | 147 | 3: cont2_key <= rx_word; 148 | 4: cont2_joy <= rx_word; 149 | 5: cont2_trig <= rx_word[15:0]; 150 | 151 | 6: cont3_key <= rx_word; 152 | 7: cont3_joy <= rx_word; 153 | 8: cont3_trig <= rx_word[15:0]; 154 | 155 | 9: cont4_key <= rx_word; 156 | 10: cont4_joy <= rx_word; 157 | 11: begin 158 | cont4_trig <= rx_word[15:0]; 159 | state <= ST_IDLE; 160 | end 161 | endcase 162 | end 163 | end 164 | // do nothing 165 | ST_END_TX: begin 166 | // done sending, idle again 167 | if(tx_word_done) begin 168 | state <= ST_IDLE; 169 | end 170 | end 171 | endcase 172 | 173 | 174 | if(&auto_poll_cnt) begin 175 | auto_poll_queue <= 1; 176 | end 177 | if(&heartbeat_cnt) begin 178 | heartbeat_queue <= 1; 179 | end 180 | 181 | if(&rx_timeout) begin 182 | // reset protocol FSM which will also reset t/r engine 183 | rx_timed_out <= 1; 184 | rx_timeout <= 0; 185 | state <= ST_RESET; 186 | end 187 | 188 | if(~reset_n_s) begin 189 | state <= ST_RESET; 190 | end 191 | end 192 | 193 | 194 | 195 | 196 | 197 | // 198 | // word receive/transmit engine 199 | // 200 | reg reset_tr_n; 201 | localparam BITLEN = 60; 202 | 203 | reg rx_word_done; 204 | reg [31:0] rx_word_shift; 205 | reg [31:0] rx_word; 206 | 207 | reg tx_word_start, tx_word_start_1; 208 | reg tx_word_done; 209 | reg [31:0] tx_word; 210 | reg [31:0] tx_word_shift; 211 | 212 | reg [7:0] tr_cnt; 213 | reg [5:0] tr_bit; 214 | 215 | localparam TR_IDLE = 'd1; 216 | localparam TR_TX_START = 'd2; 217 | localparam TR_TX_CONTINUE = 'd3; 218 | localparam TR_TX_DONE = 'd4; 219 | localparam TR_RX_START = 'd5; 220 | localparam TR_RX_WAITEDGE = 'd6; 221 | localparam TR_RX_DONE = 'd7; 222 | 223 | reg [3:0] tr_state; 224 | 225 | always @(posedge clk) begin 226 | 227 | rx_word_done <= 0; 228 | tx_word_done <= 0; 229 | 230 | tx_word_start_1 <= tx_word_start; 231 | 232 | case(tr_state) 233 | TR_IDLE: begin 234 | tr_bit <= 0; 235 | tr_cnt <= 0; 236 | 237 | pad_1wire <= 1'bZ; 238 | 239 | if(tx_word_start & ~tx_word_start_1) begin 240 | // transmit word 241 | tx_word_shift <= tx_word; 242 | tr_state <= TR_TX_START; 243 | end 244 | 245 | if(pad_1wire_f) begin 246 | // receive word 247 | tr_state <= TR_RX_START; 248 | end 249 | end 250 | 251 | // transmit 32bit 252 | TR_TX_START: begin 253 | // insert delay 254 | tr_cnt <= tr_cnt + 1'b1; 255 | if(&tr_cnt) begin 256 | // drive from tristate(high) to explicitly high to prevent glitching 257 | pad_1wire <= 1'b1; 258 | tr_state <= TR_TX_CONTINUE; 259 | end 260 | end 261 | TR_TX_CONTINUE: begin 262 | tr_cnt <= tr_cnt + 1'b1; 263 | case(tr_cnt) 264 | 0: begin 265 | pad_1wire <= 1'b0; 266 | end 267 | (BITLEN/3): begin 268 | pad_1wire <= tx_word_shift[31]; 269 | end 270 | (BITLEN*2/3): begin 271 | pad_1wire <= 1'b1; 272 | end 273 | (BITLEN-1): begin 274 | tr_cnt <= 0; 275 | tx_word_shift <= {tx_word_shift[30:0], 1'b1}; 276 | 277 | tr_bit <= tr_bit + 1'b1; 278 | if(tr_bit == 31) begin 279 | tr_state <= TR_TX_DONE; 280 | end 281 | end 282 | endcase 283 | end 284 | TR_TX_DONE: begin 285 | tx_word_done <= 1; 286 | tr_state <= TR_IDLE; 287 | end 288 | 289 | // receive 32bit 290 | TR_RX_START: begin 291 | tr_cnt <= tr_cnt + 1'b1; 292 | case(tr_cnt) 293 | (BITLEN/2-4): begin 294 | rx_word_shift <= {rx_word_shift[30:0], pad_1wire_s}; 295 | end 296 | (BITLEN*5/6): begin 297 | tr_cnt <= 0; 298 | 299 | // wait for next falling edge 300 | tr_state <= TR_RX_WAITEDGE; 301 | tr_bit <= tr_bit + 1'b1; 302 | if(tr_bit == 31) begin 303 | // if this is bit32, don't wait and finish 304 | tr_state <= TR_RX_DONE; 305 | end 306 | end 307 | endcase 308 | end 309 | TR_RX_WAITEDGE: begin 310 | if(pad_1wire_f) begin 311 | tr_state <= TR_RX_START; 312 | end 313 | end 314 | TR_RX_DONE: begin 315 | rx_word <= rx_word_shift; 316 | rx_word_done <= 1; 317 | tr_state <= TR_IDLE; 318 | end 319 | 320 | default: begin 321 | tr_state <= TR_IDLE; 322 | end 323 | endcase 324 | 325 | if(~reset_n_s | ~reset_tr_n) tr_state <= TR_IDLE; 326 | end 327 | 328 | endmodule -------------------------------------------------------------------------------- /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/apf/mf_ddio_bidir_12.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /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 "23.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/apf/mf_ddio_bidir_12.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %ALTDDIO_BIDIR% 2 | // GENERATION: STANDARD 3 | // VERSION: WM1.0 4 | // MODULE: ALTDDIO_BIDIR 5 | 6 | // ============================================================ 7 | // File Name: mf_ddio_bidir_12.v 8 | // Megafunction Name(s): 9 | // ALTDDIO_BIDIR 10 | // 11 | // Simulation Library Files(s): 12 | // 13 | // ============================================================ 14 | // ************************************************************ 15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | // 17 | // 23.1std.0 Build 991 11/28/2023 SC Lite Edition 18 | // ************************************************************ 19 | 20 | 21 | //Copyright (C) 2023 Intel Corporation. All rights reserved. 22 | //Your use of Intel Corporation's design tools, logic functions 23 | //and other software and tools, and any partner logic 24 | //functions, and any output files from any of the foregoing 25 | //(including device programming or simulation files), and any 26 | //associated documentation or information are expressly subject 27 | //to the terms and conditions of the Intel Program License 28 | //Subscription Agreement, the Intel Quartus Prime License Agreement, 29 | //the Intel FPGA IP License Agreement, or other applicable license 30 | //agreement, including, without limitation, that your use is for 31 | //the sole purpose of programming logic devices manufactured by 32 | //Intel and sold by Intel or its authorized distributors. Please 33 | //refer to the applicable agreement for further details, at 34 | //https://fpgasoftware.intel.com/eula. 35 | 36 | 37 | // synopsys translate_off 38 | `timescale 1 ps / 1 ps 39 | // synopsys translate_on 40 | module mf_ddio_bidir_12 ( 41 | datain_h, 42 | datain_l, 43 | inclock, 44 | oe, 45 | outclock, 46 | dataout_h, 47 | dataout_l, 48 | padio); 49 | 50 | input [11:0] datain_h; 51 | input [11:0] datain_l; 52 | input inclock; 53 | input oe; 54 | input outclock; 55 | output [11:0] dataout_h; 56 | output [11:0] dataout_l; 57 | inout [11:0] padio; 58 | 59 | wire [11:0] sub_wire0; 60 | wire [11:0] sub_wire1; 61 | wire [11:0] dataout_h = sub_wire0[11:0]; 62 | wire [11:0] dataout_l = sub_wire1[11:0]; 63 | 64 | altddio_bidir ALTDDIO_BIDIR_component ( 65 | .datain_h (datain_h), 66 | .datain_l (datain_l), 67 | .inclock (inclock), 68 | .oe (oe), 69 | .outclock (outclock), 70 | .padio (padio), 71 | .dataout_h (sub_wire0), 72 | .dataout_l (sub_wire1), 73 | .aclr (1'b0), 74 | .aset (1'b0), 75 | .combout (), 76 | .dqsundelayedout (), 77 | .inclocken (1'b1), 78 | .oe_out (), 79 | .outclocken (1'b1), 80 | .sclr (1'b0), 81 | .sset (1'b0)); 82 | defparam 83 | ALTDDIO_BIDIR_component.extend_oe_disable = "OFF", 84 | ALTDDIO_BIDIR_component.implement_input_in_lcell = "OFF", 85 | ALTDDIO_BIDIR_component.intended_device_family = "Cyclone V", 86 | ALTDDIO_BIDIR_component.invert_output = "OFF", 87 | ALTDDIO_BIDIR_component.lpm_hint = "UNUSED", 88 | ALTDDIO_BIDIR_component.lpm_type = "altddio_bidir", 89 | ALTDDIO_BIDIR_component.oe_reg = "UNREGISTERED", 90 | ALTDDIO_BIDIR_component.power_up_high = "OFF", 91 | ALTDDIO_BIDIR_component.width = 12; 92 | 93 | 94 | endmodule 95 | 96 | // ============================================================ 97 | // CNX file retrieval info 98 | // ============================================================ 99 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 100 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 101 | // Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF" 102 | // Retrieval info: CONSTANT: IMPLEMENT_INPUT_IN_LCELL STRING "OFF" 103 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 104 | // Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF" 105 | // Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED" 106 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_bidir" 107 | // Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED" 108 | // Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF" 109 | // Retrieval info: CONSTANT: WIDTH NUMERIC "12" 110 | // Retrieval info: USED_PORT: datain_h 0 0 12 0 INPUT NODEFVAL "datain_h[11..0]" 111 | // Retrieval info: CONNECT: @datain_h 0 0 12 0 datain_h 0 0 12 0 112 | // Retrieval info: USED_PORT: datain_l 0 0 12 0 INPUT NODEFVAL "datain_l[11..0]" 113 | // Retrieval info: CONNECT: @datain_l 0 0 12 0 datain_l 0 0 12 0 114 | // Retrieval info: USED_PORT: dataout_h 0 0 12 0 OUTPUT NODEFVAL "dataout_h[11..0]" 115 | // Retrieval info: CONNECT: dataout_h 0 0 12 0 @dataout_h 0 0 12 0 116 | // Retrieval info: USED_PORT: dataout_l 0 0 12 0 OUTPUT NODEFVAL "dataout_l[11..0]" 117 | // Retrieval info: CONNECT: dataout_l 0 0 12 0 @dataout_l 0 0 12 0 118 | // Retrieval info: USED_PORT: inclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "inclock" 119 | // Retrieval info: CONNECT: @inclock 0 0 0 0 inclock 0 0 0 0 120 | // Retrieval info: USED_PORT: oe 0 0 0 0 INPUT NODEFVAL "oe" 121 | // Retrieval info: CONNECT: @oe 0 0 0 0 oe 0 0 0 0 122 | // Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock" 123 | // Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0 124 | // Retrieval info: USED_PORT: padio 0 0 12 0 BIDIR NODEFVAL "padio[11..0]" 125 | // Retrieval info: CONNECT: padio 0 0 12 0 @padio 0 0 12 0 126 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.v TRUE FALSE 127 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.qip TRUE FALSE 128 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.bsf FALSE TRUE 129 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_inst.v FALSE TRUE 130 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_bb.v FALSE TRUE 131 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.inc FALSE TRUE 132 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.cmp FALSE TRUE 133 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.ppf TRUE FALSE 134 | -------------------------------------------------------------------------------- /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 { ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ 12 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } \ 13 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \ 14 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk } \ 15 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[4].gpll~PLL_OUTPUT_COUNTER|divclk } -------------------------------------------------------------------------------- /src/fpga/core/data_loader.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 | // A data loader for consuming APF bridge writes and directing them to some storage medium 26 | // 27 | // This takes the 32 bit words from APF, and splits it into four / OUTPUT_WORD_SIZE words (4 separate bytes, or 2 16-bit words). 28 | // You can configure the cycle delay by setting WRITE_MEM_CLOCK_DELAY 29 | module data_loader #( 30 | // Upper 4 bits of address 31 | parameter ADDRESS_MASK_UPPER_4 = 0, 32 | parameter ADDRESS_SIZE = 28, 33 | 34 | // Number of clk_memory cycles to delay each write output 35 | // Min 4. Component will assert this value is within the valid range 36 | // Be aware that APF sends data every ~75 74MHz cycles, so you cannot send data slower than this 37 | parameter WRITE_MEM_CLOCK_DELAY = 4, 38 | 39 | // Number of clk_memory cycles to hold the write_en signal high 40 | // Min 1. Component will assert this value is within the valid range 41 | parameter WRITE_MEM_EN_CYCLE_LENGTH = 1, 42 | 43 | // Word size in number of bytes. Can either be 1 (output 8 bits), or 2 (output 16 bits) 44 | // Component will assert this value is within the valid range 45 | parameter OUTPUT_WORD_SIZE = 1 46 | ) ( 47 | input wire clk_74a, 48 | input wire clk_memory, 49 | 50 | input wire bridge_wr, 51 | input wire bridge_endian_little, 52 | input wire [31:0] bridge_addr, 53 | input wire [31:0] bridge_wr_data, 54 | 55 | // These outputs are synced to the memory clock 56 | output reg write_en = 0, 57 | output reg [ADDRESS_SIZE-1:0] write_addr = 0, 58 | output reg [8 * OUTPUT_WORD_SIZE - 1:0] write_data = 0 59 | ); 60 | 61 | `define MAX(x, y) ((x > y) ? x : y) 62 | 63 | localparam WORD_SIZE = 8 * OUTPUT_WORD_SIZE; 64 | 65 | // Only use the lower 28 bits of the address 66 | localparam FIFO_SIZE = WORD_SIZE + 28; 67 | 68 | wire mem_empty; 69 | 70 | wire [FIFO_SIZE - 1:0] fifo_out; 71 | 72 | reg read_req = 0; 73 | reg write_req = 0; 74 | reg [31:0] shift_data; 75 | reg [27:0] buff_bridge_addr; 76 | 77 | wire [FIFO_SIZE - 1:0] fifo_in = {shift_data[WORD_SIZE-1:0], buff_bridge_addr[27:0]}; 78 | 79 | dcfifo dcfifo_component ( 80 | .data(fifo_in), 81 | .rdclk(clk_memory), 82 | .rdreq(read_req), 83 | .wrclk(clk_74a), 84 | .wrreq(write_req), 85 | .q(fifo_out), 86 | .rdempty(mem_empty) 87 | // .wrempty(), 88 | // .aclr(), 89 | // .eccstatus(), 90 | // .rdfull(), 91 | // .rdusedw(), 92 | // .wrfull(), 93 | // .wrusedw() 94 | ); 95 | defparam dcfifo_component.clocks_are_synchronized = "FALSE", 96 | dcfifo_component.intended_device_family = "Cyclone V", dcfifo_component.lpm_numwords = 4, 97 | dcfifo_component.lpm_showahead = "OFF", dcfifo_component.lpm_type = "dcfifo", 98 | dcfifo_component.lpm_width = FIFO_SIZE, dcfifo_component.lpm_widthu = 2, 99 | dcfifo_component.overflow_checking = "OFF", dcfifo_component.rdsync_delaypipe = 5, 100 | dcfifo_component.underflow_checking = "OFF", dcfifo_component.use_eab = "OFF", 101 | dcfifo_component.wrsync_delaypipe = 5; 102 | 103 | /// APF to Mem clock 104 | 105 | reg prev_bridge_wr = 0; 106 | reg [2:0] write_count = 0; 107 | reg [2:0] write_state = 0; 108 | 109 | localparam WRITE_START = 1; 110 | localparam WRITE_REQ_SHIFT = 2; 111 | 112 | // Receive APF writes and buffer them into the memory clock domain 113 | always @(posedge clk_74a) begin 114 | prev_bridge_wr <= bridge_wr; 115 | 116 | if (~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin 117 | // Beginning APF write to core 118 | write_state <= WRITE_REQ_SHIFT; 119 | write_req <= 1; 120 | write_count <= 0; 121 | 122 | shift_data <= bridge_endian_little ? bridge_wr_data : { 123 | bridge_wr_data[7:0], bridge_wr_data[15:8], bridge_wr_data[23:16], bridge_wr_data[31:24] 124 | }; 125 | 126 | buff_bridge_addr <= bridge_addr[27:0]; 127 | end 128 | 129 | case (write_state) 130 | WRITE_START: begin 131 | write_req <= 1; 132 | 133 | write_state <= WRITE_REQ_SHIFT; 134 | end 135 | WRITE_REQ_SHIFT: begin 136 | write_req <= 0; 137 | 138 | // We will be writing again in the next cycle 139 | shift_data <= {8'h0, shift_data[31:WORD_SIZE]}; 140 | buff_bridge_addr <= buff_bridge_addr + OUTPUT_WORD_SIZE; 141 | 142 | write_count <= write_count + 1; 143 | 144 | if (write_count == (4 / OUTPUT_WORD_SIZE) - 1) begin 145 | // Finished write 146 | write_state <= 0; 147 | end else begin 148 | write_state <= WRITE_START; 149 | end 150 | end 151 | endcase 152 | end 153 | 154 | /// Mem clock to core 155 | 156 | reg [5:0] read_state = 0; 157 | 158 | localparam READ_DELAY = 1; 159 | localparam READ_WRITE = 2; 160 | localparam READ_WRITE_EN_CYCLE_OFF = READ_WRITE + WRITE_MEM_EN_CYCLE_LENGTH; 161 | localparam READ_WRITE_END_DEFAULT = WRITE_MEM_CLOCK_DELAY - 1; 162 | // Must use max to prevent READ_WRITE_END from being the same as READ_WRITE_EN_CYCLE_OFF 163 | localparam READ_WRITE_END = 164 | `MAX(READ_WRITE_END_DEFAULT, READ_WRITE_EN_CYCLE_OFF + 1); 165 | localparam HAS_DELAY = READ_WRITE_END_DEFAULT > READ_WRITE_EN_CYCLE_OFF; 166 | 167 | always @(posedge clk_memory) begin 168 | if (read_state != 0) begin 169 | read_state <= read_state + 1; 170 | end else if (~mem_empty) begin 171 | // Start read 172 | read_state <= READ_DELAY; 173 | read_req <= 1; 174 | end 175 | 176 | case (read_state) 177 | READ_DELAY: begin 178 | read_req <= 0; 179 | write_en <= 0; 180 | end 181 | READ_WRITE: begin 182 | // Read data is available 183 | write_en <= 1; 184 | 185 | // Lowest 28 bits are the address 186 | write_addr <= fifo_out[27:0]; 187 | 188 | write_data <= fifo_out[WORD_SIZE+27:28]; 189 | 190 | read_req <= 0; 191 | end 192 | READ_WRITE_EN_CYCLE_OFF: begin 193 | write_en <= 0; 194 | 195 | if (!HAS_DELAY) begin 196 | // No extra delay, immediately go back to start 197 | read_state <= 0; 198 | end 199 | end 200 | READ_WRITE_END: begin 201 | read_state <= 0; 202 | end 203 | endcase 204 | end 205 | 206 | initial begin 207 | // Verify parameters 208 | if (WRITE_MEM_CLOCK_DELAY < 4) begin 209 | $error("WRITE_MEM_CLOCK_DELAY has a minimum value of 4. Received %d", WRITE_MEM_CLOCK_DELAY); 210 | end 211 | 212 | if (WRITE_MEM_EN_CYCLE_LENGTH < 1 || WRITE_MEM_EN_CYCLE_LENGTH >= WRITE_MEM_CLOCK_DELAY - 2) begin 213 | $error( 214 | "WRITE_MEM_EN_CYCLE_LENGTH must be between 1 and %d (inclusive, based off of WRITE_MEM_CLOCK_DELAY). Received %d", 215 | WRITE_MEM_CLOCK_DELAY - 2 - 1, WRITE_MEM_EN_CYCLE_LENGTH); 216 | end 217 | 218 | if (OUTPUT_WORD_SIZE < 1 || OUTPUT_WORD_SIZE > 2) begin 219 | $error("OUTPUT_WORD_SIZE must be 1 or 2. Received %d", OUTPUT_WORD_SIZE); 220 | end 221 | end 222 | 223 | endmodule 224 | -------------------------------------------------------------------------------- /src/fpga/core/iir_1st_order.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 | `timescale 1 ps / 1 ps 24 | 25 | module iir_1st_order 26 | #( 27 | parameter COEFF_WIDTH = 18, 28 | parameter COEFF_SCALE = 15, 29 | parameter DATA_WIDTH = 16, 30 | parameter COUNT_BITS = 10 31 | ) 32 | ( 33 | input clk, 34 | input reset, 35 | input [COUNT_BITS - 1 : 0] div, 36 | input signed [COEFF_WIDTH - 1 : 0] A2, B1, B2, 37 | input signed [DATA_WIDTH - 1 :0] in, 38 | output [DATA_WIDTH - 1:0] out 39 | ); 40 | 41 | reg signed [DATA_WIDTH-1:0] x0,x1,y0; 42 | reg signed [DATA_WIDTH + COEFF_WIDTH - 1 : 0] out32; 43 | reg [COUNT_BITS - 1:0] count; 44 | 45 | // Usage: 46 | // Design your 1st order iir low/high-pass with a tool that will give you the 47 | // filter coefficients for the difference equation. Filter coefficients can 48 | // be generated in Octave/matlab/scipy using a command similar to 49 | // [B, A] = butter( 1, 3500/(106528/2), 'low') for a 3500 hz 1st order low-pass 50 | // assuming 106528Hz sample rate. 51 | // 52 | // The Matlab output is: 53 | // B = [0.093863 0.093863] 54 | // A = [1.00000 -0.81227] 55 | // 56 | // Then scale coefficients by multiplying by 2^COEFF_SCALE and round to nearest integer 57 | // 58 | // B = [3076 3076] 59 | // A = [32768 -26616] 60 | // 61 | // Discard A(1) because it is assumed 1.0 before scaling 62 | // 63 | // This leaves you with A2 = -26616 , B1 = 3076 , B2 = 3076 64 | // B1 + B2 - A2 should sum to 2^COEFF_SCALE = 32768 65 | // 66 | // Sample frequency is "clk rate/div": for Genesis this is 53.69mhz/504 = 106528hz 67 | // 68 | // COEFF_WIDTH must be at least COEFF_SCALE+1 and must be large enough to 69 | // handle temporary overflow during this computation: out32 <= (B1*x0 + B2*x1) - A2*y0 70 | 71 | assign out = y0; 72 | 73 | always @ (posedge clk) begin 74 | out32 <= (B1*x0 + B2*x1) - A2*y0; //Previous output is y0 not y1 75 | end 76 | 77 | always @ (posedge clk) begin 78 | if(reset) begin 79 | count <= 0; 80 | x0 <= 0; 81 | x1 <= 0; 82 | y0 <= 0; 83 | end 84 | else begin 85 | count <= count + 1'd1; 86 | if (count == div - 1) begin 87 | count <= 0; 88 | y0 <= {out32[DATA_WIDTH + COEFF_WIDTH - 1] , out32[COEFF_SCALE + DATA_WIDTH - 2 : COEFF_SCALE]}; 89 | x1 <= x0; 90 | x0 <= in; 91 | end 92 | end 93 | end 94 | 95 | endmodule //iir_1st_order 96 | 97 | module iir_2nd_order 98 | #( 99 | parameter COEFF_WIDTH = 18, 100 | parameter COEFF_SCALE = 14, 101 | parameter DATA_WIDTH = 16, 102 | parameter COUNT_BITS = 10 103 | ) 104 | ( 105 | input clk, 106 | input reset, 107 | input [COUNT_BITS - 1 : 0] div, 108 | input signed [COEFF_WIDTH - 1 : 0] A2, A3, B1, B2, B3, 109 | input signed [DATA_WIDTH - 1 : 0] in, 110 | output [DATA_WIDTH - 1 : 0] out 111 | ); 112 | 113 | reg signed [DATA_WIDTH-1 : 0] x0,x1,x2; 114 | reg signed [DATA_WIDTH-1 : 0] y0,y1; 115 | reg signed [(DATA_WIDTH + COEFF_WIDTH - 1) : 0] out32; 116 | reg [COUNT_BITS : 0] count; 117 | 118 | 119 | // Usage: 120 | // Design your 1st order iir low/high-pass with a tool that will give you the 121 | // filter coefficients for the difference equation. Filter coefficients can 122 | // be generated in Octave/matlab/scipy using a command similar to 123 | // [B, A] = butter( 2, 5000/(48000/2), 'low') for a 5000 hz 2nd order low-pass 124 | // assuming 48000Hz sample rate. 125 | // 126 | // Output is: 127 | // B = [ 0.072231 0.144462 0.072231] 128 | // A = [1.00000 -1.10923 0.39815] 129 | // 130 | // Then scale coefficients by multiplying by 2^COEFF_SCALE and round to nearest integer 131 | // Make sure your coefficients can be stored as a signed number with COEFF_WIDTH bits. 132 | // 133 | // B = [1183 2367 1183] 134 | // A = [16384 -18174 6523] 135 | // 136 | // Discard A(1) because it is assumed 1.0 before scaling 137 | // 138 | // This leaves you with A2 = -18174 , A3 = 6523, B1 = 1183 , B2 = 2367 , B3 = 1183 139 | // B1 + B2 + B3 - A2 - A3 should sum to 2^COEFF_SCALE = 16384 140 | // 141 | // Sample frequency is "clk rate/div" 142 | // 143 | // COEFF_WIDTH must be at least COEFF_SCALE+1 and must be large enough to 144 | // handle temporary overflow during this computation: 145 | // out32 <= (B1*x0 + B2*x1 + B3*x2) - (A2*y0 + A3*y1); 146 | 147 | assign out = y0; 148 | 149 | always @ (*) begin 150 | out32 <= (B1*x0 + B2*x1 + B3*x2) - (A2*y0 + A3*y1); //Previous output is y0 not y1 151 | end 152 | 153 | always @ (posedge clk) begin 154 | if(reset) begin 155 | count <= 0; 156 | x0 <= 0; 157 | x1 <= 0; 158 | x2 <= 0; 159 | y0 <= 0; 160 | y1 <= 0; 161 | end 162 | else begin 163 | count <= count + 1'd1; 164 | if (count == div - 1) begin 165 | count <= 0; 166 | y1 <= y0; 167 | y0 <= {out32[DATA_WIDTH + COEFF_WIDTH - 1] , out32[(DATA_WIDTH + COEFF_SCALE - 2) : COEFF_SCALE]}; 168 | x2 <= x1; 169 | x1 <= x0; 170 | x0 <= in; 171 | end 172 | end 173 | end 174 | 175 | endmodule //iir_2nd_order -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase.bsf: -------------------------------------------------------------------------------- 1 | /* 2 | WARNING: Do NOT edit the input and output ports in this file in a text 3 | editor if you plan to continue editing the block that represents it in 4 | the Block Editor! File corruption is VERY likely to occur. 5 | */ 6 | /* 7 | Copyright (C) 2023 Intel Corporation. All rights reserved. 8 | Your use of Intel Corporation's design tools, logic functions 9 | and other software and tools, and any partner logic 10 | functions, and any output files from any of the foregoing 11 | (including device programming or simulation files), and any 12 | associated documentation or information are expressly subject 13 | to the terms and conditions of the Intel Program License 14 | Subscription Agreement, the Intel Quartus Prime License Agreement, 15 | the Intel FPGA IP License Agreement, or other applicable license 16 | agreement, including, without limitation, that your use is for 17 | the sole purpose of programming logic devices manufactured by 18 | Intel and sold by Intel or its authorized distributors. Please 19 | refer to the applicable agreement for further details, at 20 | https://fpgasoftware.intel.com/eula. 21 | */ 22 | (header "symbol" (version "1.1")) 23 | (symbol 24 | (rect 0 0 160 224) 25 | (text "mf_pllbase" (rect 48 -1 91 11)(font "Arial" (font_size 10))) 26 | (text "inst" (rect 8 208 20 220)(font "Arial" )) 27 | (port 28 | (pt 0 72) 29 | (input) 30 | (text "refclk" (rect 0 0 22 12)(font "Arial" (font_size 8))) 31 | (text "refclk" (rect 4 61 40 72)(font "Arial" (font_size 8))) 32 | (line (pt 0 72)(pt 48 72)(line_width 1)) 33 | ) 34 | (port 35 | (pt 0 112) 36 | (input) 37 | (text "rst" (rect 0 0 10 12)(font "Arial" (font_size 8))) 38 | (text "rst" (rect 4 101 22 112)(font "Arial" (font_size 8))) 39 | (line (pt 0 112)(pt 48 112)(line_width 1)) 40 | ) 41 | (port 42 | (pt 160 72) 43 | (output) 44 | (text "outclk_0" (rect 0 0 33 12)(font "Arial" (font_size 8))) 45 | (text "outclk_0" (rect 117 61 165 72)(font "Arial" (font_size 8))) 46 | (line (pt 160 72)(pt 112 72)(line_width 1)) 47 | ) 48 | (port 49 | (pt 160 112) 50 | (output) 51 | (text "outclk_1" (rect 0 0 31 12)(font "Arial" (font_size 8))) 52 | (text "outclk_1" (rect 119 101 167 112)(font "Arial" (font_size 8))) 53 | (line (pt 160 112)(pt 112 112)(line_width 1)) 54 | ) 55 | (port 56 | (pt 160 152) 57 | (output) 58 | (text "outclk_2" (rect 0 0 33 12)(font "Arial" (font_size 8))) 59 | (text "outclk_2" (rect 117 141 165 152)(font "Arial" (font_size 8))) 60 | (line (pt 160 152)(pt 112 152)(line_width 1)) 61 | ) 62 | (port 63 | (pt 160 192) 64 | (output) 65 | (text "locked" (rect 0 0 24 12)(font "Arial" (font_size 8))) 66 | (text "locked" (rect 127 181 163 192)(font "Arial" (font_size 8))) 67 | (line (pt 160 192)(pt 112 192)(line_width 1)) 68 | ) 69 | (drawing 70 | (text "refclk" (rect 16 43 68 99)(font "Arial" (color 128 0 0)(font_size 9))) 71 | (text "clk" (rect 53 67 124 144)(font "Arial" (color 0 0 0))) 72 | (text "reset" (rect 19 83 68 179)(font "Arial" (color 128 0 0)(font_size 9))) 73 | (text "reset" (rect 53 107 136 224)(font "Arial" (color 0 0 0))) 74 | (text "outclk0" (rect 113 43 268 99)(font "Arial" (color 128 0 0)(font_size 9))) 75 | (text "clk" (rect 97 67 212 144)(font "Arial" (color 0 0 0))) 76 | (text "outclk1" (rect 113 83 268 179)(font "Arial" (color 128 0 0)(font_size 9))) 77 | (text "clk" (rect 97 107 212 224)(font "Arial" (color 0 0 0))) 78 | (text "outclk2" (rect 113 123 268 259)(font "Arial" (color 128 0 0)(font_size 9))) 79 | (text "clk" (rect 97 147 212 304)(font "Arial" (color 0 0 0))) 80 | (text "locked" (rect 113 163 262 339)(font "Arial" (color 128 0 0)(font_size 9))) 81 | (text "export" (rect 82 187 200 384)(font "Arial" (color 0 0 0))) 82 | (text " altera_pll " (rect 118 208 308 426)(font "Arial" )) 83 | (line (pt 48 32)(pt 112 32)(line_width 1)) 84 | (line (pt 112 32)(pt 112 208)(line_width 1)) 85 | (line (pt 48 208)(pt 112 208)(line_width 1)) 86 | (line (pt 48 32)(pt 48 208)(line_width 1)) 87 | (line (pt 49 52)(pt 49 76)(line_width 1)) 88 | (line (pt 50 52)(pt 50 76)(line_width 1)) 89 | (line (pt 49 92)(pt 49 116)(line_width 1)) 90 | (line (pt 50 92)(pt 50 116)(line_width 1)) 91 | (line (pt 111 52)(pt 111 76)(line_width 1)) 92 | (line (pt 110 52)(pt 110 76)(line_width 1)) 93 | (line (pt 111 92)(pt 111 116)(line_width 1)) 94 | (line (pt 110 92)(pt 110 116)(line_width 1)) 95 | (line (pt 111 132)(pt 111 156)(line_width 1)) 96 | (line (pt 110 132)(pt 110 156)(line_width 1)) 97 | (line (pt 111 172)(pt 111 196)(line_width 1)) 98 | (line (pt 110 172)(pt 110 196)(line_width 1)) 99 | (line (pt 0 0)(pt 160 0)(line_width 1)) 100 | (line (pt 160 0)(pt 160 224)(line_width 1)) 101 | (line (pt 0 224)(pt 160 224)(line_width 1)) 102 | (line (pt 0 0)(pt 0 224)(line_width 1)) 103 | ) 104 | ) 105 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase.ppf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /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 "23.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/mf_pllbase.spd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /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 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 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/mf_pllbase/mf_pllbase_0002.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/10ps 2 | module mf_pllbase_0002( 3 | 4 | // interface 'refclk' 5 | input wire refclk, 6 | 7 | // interface 'reset' 8 | input wire rst, 9 | 10 | // interface 'outclk0' 11 | output wire outclk_0, 12 | 13 | // interface 'outclk1' 14 | output wire outclk_1, 15 | 16 | // interface 'outclk2' 17 | output wire outclk_2, 18 | 19 | // interface 'outclk3' 20 | output wire outclk_3, 21 | 22 | // interface 'locked' 23 | output wire locked 24 | ); 25 | 26 | altera_pll #( 27 | .fractional_vco_multiplier("true"), 28 | .reference_clock_frequency("74.25 MHz"), 29 | .operation_mode("direct"), 30 | .number_of_clocks(4), 31 | .output_clock_frequency0("48.000000 MHz"), 32 | .phase_shift0("0 ps"), 33 | .duty_cycle0(50), 34 | .output_clock_frequency1("24.000000 MHz"), 35 | .phase_shift1("0 ps"), 36 | .duty_cycle1(50), 37 | .output_clock_frequency2("24.000000 MHz"), 38 | .phase_shift2("10417 ps"), 39 | .duty_cycle2(50), 40 | .output_clock_frequency3("96.000000 MHz"), 41 | .phase_shift3("0 ps"), 42 | .duty_cycle3(50), 43 | .output_clock_frequency4("0 MHz"), 44 | .phase_shift4("0 ps"), 45 | .duty_cycle4(50), 46 | .output_clock_frequency5("0 MHz"), 47 | .phase_shift5("0 ps"), 48 | .duty_cycle5(50), 49 | .output_clock_frequency6("0 MHz"), 50 | .phase_shift6("0 ps"), 51 | .duty_cycle6(50), 52 | .output_clock_frequency7("0 MHz"), 53 | .phase_shift7("0 ps"), 54 | .duty_cycle7(50), 55 | .output_clock_frequency8("0 MHz"), 56 | .phase_shift8("0 ps"), 57 | .duty_cycle8(50), 58 | .output_clock_frequency9("0 MHz"), 59 | .phase_shift9("0 ps"), 60 | .duty_cycle9(50), 61 | .output_clock_frequency10("0 MHz"), 62 | .phase_shift10("0 ps"), 63 | .duty_cycle10(50), 64 | .output_clock_frequency11("0 MHz"), 65 | .phase_shift11("0 ps"), 66 | .duty_cycle11(50), 67 | .output_clock_frequency12("0 MHz"), 68 | .phase_shift12("0 ps"), 69 | .duty_cycle12(50), 70 | .output_clock_frequency13("0 MHz"), 71 | .phase_shift13("0 ps"), 72 | .duty_cycle13(50), 73 | .output_clock_frequency14("0 MHz"), 74 | .phase_shift14("0 ps"), 75 | .duty_cycle14(50), 76 | .output_clock_frequency15("0 MHz"), 77 | .phase_shift15("0 ps"), 78 | .duty_cycle15(50), 79 | .output_clock_frequency16("0 MHz"), 80 | .phase_shift16("0 ps"), 81 | .duty_cycle16(50), 82 | .output_clock_frequency17("0 MHz"), 83 | .phase_shift17("0 ps"), 84 | .duty_cycle17(50), 85 | .pll_type("General"), 86 | .pll_subtype("General") 87 | ) altera_pll_i ( 88 | .rst (rst), 89 | .outclk ({outclk_3, outclk_2, outclk_1, outclk_0}), 90 | .locked (locked), 91 | .fboutclk ( ), 92 | .fbclk (1'b0), 93 | .refclk (refclk) 94 | ); 95 | endmodule 96 | 97 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim.f: -------------------------------------------------------------------------------- 1 | mf_pllbase_sim/mf_pllbase.vo 2 | -------------------------------------------------------------------------------- /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/mf_pllbase_sim/cadence/hdl.var: -------------------------------------------------------------------------------- 1 | 2 | DEFINE WORK work 3 | -------------------------------------------------------------------------------- /src/fpga/core/mf_pllbase_sim/cadence/ncsim_setup.sh: -------------------------------------------------------------------------------- 1 | 2 | # (C) 2001-2022 Altera Corporation. All rights reserved. 3 | # Your use of Altera Corporation's design tools, logic functions and 4 | # other software and tools, and its AMPP partner logic functions, and 5 | # any output files any of the foregoing (including device programming 6 | # or simulation files), and any associated documentation or information 7 | # are expressly subject to the terms and conditions of the Altera 8 | # Program License Subscription Agreement, Altera MegaCore Function 9 | # License Agreement, or other applicable license agreement, including, 10 | # without limitation, that your use is for the sole purpose of 11 | # programming logic devices manufactured by Altera and sold by Altera 12 | # or its authorized distributors. Please refer to the applicable 13 | # agreement for further details. 14 | 15 | # ACDS 21.1 850 win32 2022.10.11.16:30:49 16 | 17 | # ---------------------------------------- 18 | # ncsim - auto-generated simulation script 19 | 20 | # ---------------------------------------- 21 | # This script provides commands to simulate the following IP detected in 22 | # your Quartus project: 23 | # mf_pllbase 24 | # 25 | # Altera recommends that you source this Quartus-generated IP simulation 26 | # script from your own customized top-level script, and avoid editing this 27 | # generated script. 28 | # 29 | # To write a top-level shell script that compiles Altera simulation libraries 30 | # and the Quartus-generated IP in your project, along with your design and 31 | # testbench files, copy the text from the TOP-LEVEL TEMPLATE section below 32 | # into a new file, e.g. named "ncsim.sh", and modify text as directed. 33 | # 34 | # You can also modify the simulation flow to suit your needs. Set the 35 | # following variables to 1 to disable their corresponding processes: 36 | # - SKIP_FILE_COPY: skip copying ROM/RAM initialization files 37 | # - SKIP_DEV_COM: skip compiling the Quartus EDA simulation library 38 | # - SKIP_COM: skip compiling Quartus-generated IP simulation files 39 | # - SKIP_ELAB and SKIP_SIM: skip elaboration and simulation 40 | # 41 | # ---------------------------------------- 42 | # # TOP-LEVEL TEMPLATE - BEGIN 43 | # # 44 | # # QSYS_SIMDIR is used in the Quartus-generated IP simulation script to 45 | # # construct paths to the files required to simulate the IP in your Quartus 46 | # # project. By default, the IP script assumes that you are launching the 47 | # # simulator from the IP script location. If launching from another 48 | # # location, set QSYS_SIMDIR to the output directory you specified when you 49 | # # generated the IP script, relative to the directory from which you launch 50 | # # the simulator. In this case, you must also copy the generated files 51 | # # "cds.lib" and "hdl.var" - plus the directory "cds_libs" if generated - 52 | # # into the location from which you launch the simulator, or incorporate 53 | # # into any existing library setup. 54 | # # 55 | # # Run Quartus-generated IP simulation script once to compile Quartus EDA 56 | # # simulation libraries and Quartus-generated IP simulation files, and copy 57 | # # any ROM/RAM initialization files to the simulation directory. 58 | # # - If necessary, specify any compilation options: 59 | # # USER_DEFINED_COMPILE_OPTIONS 60 | # # USER_DEFINED_VHDL_COMPILE_OPTIONS applied to vhdl compiler 61 | # # USER_DEFINED_VERILOG_COMPILE_OPTIONS applied to verilog compiler 62 | # # 63 | # source