├── .gitattributes ├── .gitignore ├── README.md ├── doc ├── FROM_MINIMIG_TO_NANOMIG.md ├── GAO_HOWTO.md ├── GOWIN_EDA_LINUX.md ├── LCD_SETUP.md ├── nanomig.jpg ├── nanomig_lcd.jpg ├── tn20k_rp2040_zero.jpg ├── win_programmer.png └── wiring_lcd.png ├── sim ├── Makefile ├── README.md ├── TG68KdotC_Kernel.v ├── fx68x_verilator │ ├── LICENSE │ ├── fx68k.sv │ ├── fx68k.txt │ ├── fx68kAlu.sv │ ├── fx68k_MicroRom.v │ ├── fx68k_NanoRom.v │ ├── fx68k_flat.sv │ ├── make.sh │ ├── microrom.mem │ ├── nanorom.mem │ └── uaddrPla.sv ├── ini_parser.cpp ├── ini_parser.h ├── nanomig.gtkw ├── nanomig_sim.png ├── nanomig_tb.cpp ├── nanomig_tb.v ├── nanomig_wave.png ├── screenshots │ └── frame0200.png ├── test_rom │ ├── Makefile │ ├── README.md │ ├── test_rom.bin │ ├── test_rom.png │ └── test_rom.s └── vAmigaTS │ ├── Makefile │ ├── README.md │ └── screenshots │ ├── README.md │ ├── bltint1.png │ ├── bltint2.png │ ├── bltint3.png │ ├── bltint4.png │ ├── bltint5.png │ ├── bltint6.png │ └── bltint7.png └── src ├── build.sh ├── build.tcl ├── build_lcd.tcl ├── build_tc60k.tcl ├── build_tm138k.tcl ├── build_tp25k.tcl ├── fx68k ├── LICENSE ├── README.md ├── fx68k.sv ├── fx68k.txt ├── fx68kAlu.sv ├── microrom.mem ├── nanorom.mem └── uaddrPla.sv ├── gw_sh.grc ├── hdmi ├── audio_clock_regeneration_packet.sv ├── audio_info_frame.sv ├── audio_sample_packet.sv ├── auxiliary_video_information_info_frame.sv ├── hdmi.sv ├── packet_assembler.sv ├── packet_picker.sv ├── serializer.sv ├── source_product_description_info_frame.sv └── tmds_channel.sv ├── impl ├── nanomig_lcd_process_config.json ├── nanomig_process_config.json ├── nanomig_tm138k_process_config.json └── nanomig_tp25k_process_config.json ├── minimig-aga ├── agnus.v ├── agnus_audiodma.v ├── agnus_beamcounter.v ├── agnus_bitplanedma.v ├── agnus_blitter.v ├── agnus_blitter_adrgen.v ├── agnus_blitter_barrelshifter.v ├── agnus_blitter_fill.v ├── agnus_blitter_minterm.v ├── agnus_copper.v ├── agnus_diskdma.v ├── agnus_refresh.v ├── agnus_spritedma.v ├── amiga_clk.v ├── cart.v ├── cia_int.v ├── cia_timera.v ├── cia_timerb.v ├── cia_timerd.v ├── ciaa.v ├── ciab.v ├── cpu_wrapper.v ├── denise.v ├── denise_bitplane_shifter.v ├── denise_bitplanes.v ├── denise_collision.v ├── denise_colortable.v ├── denise_colortable_ram_mf.v ├── denise_hamgenerator.v ├── denise_playfields.v ├── denise_spritepriority.v ├── denise_sprites.v ├── denise_sprites_shifter.v ├── gary.v ├── gayle.v ├── ide.v ├── minimig.v ├── minimig_bankmapper.v ├── minimig_m68k_bridge.v ├── minimig_sram_bridge.v ├── minimig_syscontrol.v ├── paula.v ├── paula_audio.v ├── paula_audio_channel.v ├── paula_audio_mixer.v ├── paula_audio_volume.v ├── paula_floppy.v ├── paula_floppy_fifo.v ├── paula_intcontroller.v ├── paula_uart.v └── userio.v ├── minimig └── Amber.v ├── misc ├── amiga.xml ├── amiga_keymap.v ├── amiga_xml.hex ├── hid.v ├── mcu_spi.v ├── osd_u8g2.v ├── sd_card.v ├── sd_rw.v ├── sdcmd_ctrl.v ├── sysctrl.v ├── video_analyzer.v └── ws2812.v ├── nanomig.gprj ├── nanomig.v ├── nanomig_lcd.gprj ├── nanomig_tc60k.gprj ├── nanomig_tm138k.gprj ├── nanomig_tp25k.gprj ├── tang ├── console60k │ ├── flash_dspi.v │ ├── gowin_clkdiv │ │ ├── gowin_clkdiv.ipc │ │ ├── gowin_clkdiv.mod │ │ └── gowin_clkdiv.v │ ├── gowin_dpb │ │ ├── ide_dpram.ipc │ │ ├── ide_dpram.mod │ │ ├── ide_dpram.v │ │ ├── sector_dpram.ipc │ │ ├── sector_dpram.mod │ │ └── sector_dpram.v │ ├── gowin_pll │ │ ├── pll_142m.ipc │ │ ├── pll_142m.mod │ │ └── pll_142m.v │ ├── nanomig.cst │ ├── nanomig.sdc │ ├── sdram.v │ └── top.sv ├── mega138k │ ├── flash_dspi.v │ ├── gowin_clkdiv │ │ ├── gowin_clkdiv.ipc │ │ ├── gowin_clkdiv.mod │ │ └── gowin_clkdiv.v │ ├── gowin_dpb │ │ ├── ide_dpram.ipc │ │ ├── ide_dpram.mod │ │ ├── ide_dpram.v │ │ ├── sector_dpram.ipc │ │ ├── sector_dpram.mod │ │ └── sector_dpram.v │ ├── gowin_pll │ │ ├── pll_142m.ipc │ │ ├── pll_142m.mod │ │ └── pll_142m.v │ ├── nanomig.cst │ ├── nanomig.sdc │ ├── sdram.v │ └── top.sv ├── nano20k │ ├── flash_dspi.v │ ├── gowin_clkdiv │ │ ├── gowin_clkdiv.ipc │ │ ├── gowin_clkdiv.mod │ │ └── gowin_clkdiv.v │ ├── gowin_dpb │ │ ├── ide_dpram.ipc │ │ ├── ide_dpram.mod │ │ ├── ide_dpram.v │ │ ├── sector_dpram.ipc │ │ ├── sector_dpram.mod │ │ └── sector_dpram.v │ ├── gowin_rpll │ │ ├── pll_142m.ipc │ │ ├── pll_142m.mod │ │ └── pll_142m.v │ ├── nanomig.cst │ ├── nanomig.sdc │ ├── nanomig_lcd.cst │ ├── sdram.v │ ├── top.sv │ └── top_lcd.sv └── primer25k │ ├── flash_dspi.v │ ├── gowin_clkdiv │ ├── gowin_clkdiv.ipc │ ├── gowin_clkdiv.mod │ └── gowin_clkdiv.v │ ├── gowin_dpb │ ├── ide_dpram.ipc │ ├── ide_dpram.mod │ ├── ide_dpram.v │ ├── sector_dpram.ipc │ ├── sector_dpram.mod │ └── sector_dpram.v │ ├── gowin_pll │ ├── pll_142m.ipc │ ├── pll_142m.mod │ └── pll_142m.v │ ├── nanomig.cst │ ├── nanomig.sdc │ ├── sdram.v │ └── top.sv └── tg68k ├── TG68K.vhd ├── TG68K_ALU.vhd ├── TG68K_Pack.vhd └── TG68KdotC_Kernel.vhd /.gitattributes: -------------------------------------------------------------------------------- 1 | *.gprj linguist-language=XML 2 | *.cst linguist-language=Text 3 | *.sdc linguist-language=Text 4 | *.ipc linguist-language=Text 5 | *.mod linguist-language=Text 6 | *.mi linguist-language=Text 7 | *.do linguist-language=Text 8 | *.cfg linguist-language=Text 9 | *.fs linguist-language=Text 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.vcd 3 | build/ 4 | src/impl/gwsynthesis/** 5 | src/impl/temp/** 6 | src/impl/pnr/** 7 | !src/impl/nanomig_*.json 8 | *.user 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NanoMig 2 | 3 | NanoMig is a port of the [Minimig](https://en.wikipedia.org/wiki/Minimig) Commodore Amiga FPGA implementation to the [Tang Nano 20K](https://wiki.sipeed.com/hardware/en/tang/tang-nano-20k/nano-20k.html), [Tang Primer 25K](https://wiki.sipeed.com/hardware/en/tang/tang-primer-25k/primer-25k.html), [Tang Mega 138K Pro](https://wiki.sipeed.com/hardware/en/tang/tang-mega-138k/mega-138k-pro.html) and [Tang Console with Mega 60k module](https://wiki.sipeed.com/hardware/en/tang/tang-console/mega-console.html) FPGA development boards. 4 | 5 | 6 | ![NanoMig](doc/nanomig.jpg) 7 | 8 | This is based on the [MiSTeryNano project](https://github.com/harbaum/MiSTeryNano/) and also relies on a [FPGA companion](http://github.com/harbaum/FPGA-Companion) to be connected to the FPGA board for USB support and on-screen-display control. 9 | 10 | This is still a work in progress. The current version is based on the [MiSTer Minimig AGA code](https://github.com/MiSTer-devel/Minimig-AGA_MiSTer) and runs many Amiga games and demos. 11 | 12 | Current state: 13 | 14 | * Minimig based on [MiSTer Minimig AGA](https://github.com/MiSTer-devel/Minimig-AGA_MiSTer) 15 | * Kick ROM stored in flash ROM 16 | * Up to 2MB chip and 1.5MB slow RAM 17 | * OCS and ECS chipset (no AGA!) 18 | * Up to four virtual floppy drives 19 | * HDMI video and audio, PAL and NTSC 20 | * Keyboard, Mouse and Joystick via USB 21 | * Virtual IDE hard disk read an write support 22 | * Runs on [Tang Nano 20k](https://wiki.sipeed.com/hardware/en/tang/tang-nano-20k/nano-20k.html), [Primer 25K](https://wiki.sipeed.com/hardware/en/tang/tang-primer-25k/primer-25k.html), [Mega 138K Pro](https://wiki.sipeed.com/hardware/en/tang/tang-mega-138k/mega-138k-pro.html) and [Tang Console with Mega 60k module](https://wiki.sipeed.com/hardware/en/tang/tang-console/mega-console.html) 23 | * [Fully simulated](sim) 24 | 25 | Planned features: 26 | * Floppy disk write support 27 | * Accelerated 68020 support (may not fit) 28 | * AGA support (may not fit) 29 | 30 | ## Videos 31 | 32 | These youtube shorts mainly document the progress: 33 | 34 | * [NanoMig #10: World of Commodore Amiga Demo on Tang Primer 25k](https://youtube.com/shorts/XdLlrg1wgko) 35 | * [NanoMig #9: Amiga speedball 2 on Tang Mega 138k Pro](https://youtube.com/shorts/NHFjJwGAOZ0) 36 | * [NanoMig #8: Booting from virtual Harddisk](https://youtube.com/shorts/9LJ0tsSZb60) 37 | 38 |
More ... 39 | 48 |
49 | 50 | ## What's needed? 51 | 52 | The necessary binaries can be found in the [project releases](https://github.com/harbaum/NanoMig/releases). 53 | 54 | * ```nanomig.fs``` needs to be flashed to the FPGA's flash memory 55 | * ```openFPGALoader -f nanomig.fs``` 56 | * Currently supported are Tang Nano 20k with HDMI (```nanomig.fs```), Tang Nano 20k with RGB LCD (```nanomig_lcd.fs```), Tang Primer 25k (```nanomig_tp25k.fs```), Tang Mega 138k (```nanomig_tm128k.fs```), and Tang Console 60k (```nanomig_tc60k.fs```) 57 | * On Nano 20k, Primer 25k and Console 60K Kickstart 1.3 ```kick13.rom``` needs to be flashed to offset 0x400000 _and_ 0x440000. On Mega 138K use addresses 0xc00000 and 0xc40000 instead. 58 | * ```openFPGALoader --external-flash -o 0x400000 kick13.rom``` 59 | * ```openFPGALoader --external-flash -o 0x440000 kick13.rom``` 60 | * For IDE HDD support Kickstart 3.1 ```kick31.rom``` needs to be flashed at offset 0x400000 (Mega: 0xc00000) only 61 | * ```openFPGALoader --external-flash -o 0x400000 kick31.rom``` 62 | * The [latest FPGA Companion firmware](http://github.com/harbaum/FPGA-Companion) needs to be flashed to the support MCU 63 | * Currenly supported are [M0S Dock (BL616)](https://github.com/harbaum/FPGA-Companion/tree/main/src/bl616), [Raspberry Pi Pico (RP2040)](https://github.com/harbaum/FPGA-Companion/tree/main/src/rp2040) and [ESP32-S2/S3](https://github.com/harbaum/FPGA-Companion/tree/main/src/esp32) 64 | * A default ADF disk image named ```df0.adf``` should be placed on SD card (e.g. workbench 1.3) 65 | * For the SD card to work [all components incl. the support MCU](https://github.com/harbaum/NanoMig/issues/5) have to work properly 66 | -------------------------------------------------------------------------------- /doc/GAO_HOWTO.md: -------------------------------------------------------------------------------- 1 | # How to Use GAO (Gowin Analyzer Oscilloscope) 2 | 3 | To get started, follow this guide: [Gowin Analyzer Oscilloscope Tutorial](https://www.reddit.com/r/GowinFPGA/wiki/tutorials/gowin_analyzer_oscilloscope/). 4 | 5 | ## Important Notes 6 | 7 | ### Downgrading the Programmer (Windows Only) 8 | If you're using Windows, you might need to downgrade the programmer software to version 1.9.8.07. You can download `Programmer_20221019.zip` from [this link](https://dl.sipeed.com/shareURL/TANG/programmer). This is recommended in the [Tang Nano Documentation](https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-Doc/questions.html#Using-GAO). 9 | 10 | 11 | ### Troubleshooting Common Issues 12 | 13 | - **Programmer shows 'Error: "spi flash not found"'** 14 | If you receive this error message in the output window, click the “Program/Configure” button once again. 1-2 retries is typically sufficient. 15 | 16 | - **Black Screen on Namomig with Working OSD** 17 | If the screen stays black or displays a uniform color (white, yellow, etc.) while the On-Screen Display (OSD) is working, reflash the Tang Nano. 18 | If reflashing doesn't solve the issue, try reconfiguring the signals and creating a new `ao_0.fs` file. 19 | 20 | 21 | ### The Programmer Window 22 | ![Programmer Window](win_programmer.png) 23 | -------------------------------------------------------------------------------- /doc/LCD_SETUP.md: -------------------------------------------------------------------------------- 1 | # Tang Nano 20k LCD Setup 2 | 3 | Sipeed sells a 5 inch LCD for the Tang Nano 20k. This LCD has a resultion 4 | of 800x480 pixels and attaches directly to the Tang Nano 20k without using the 5 | HDMI connector. This is supported by the Atari ST and Amiga cores. The 6 | Tang Nano 20k additionally comes with a built-in audio amplifier which comes 7 | in handy in this setup to add sound output. 8 | 9 | ![NanoMig on LCD](nanomig_lcd.jpg) 10 | 11 | The LCDs vertical resolution of 480 pixels nicely matches the scandoubled 12 | verical resolution of the Atari ST's 200 lines and leaves some space for 13 | the borders. Also the Amigas NTSC mode with 200 lines (400 interlaced) works 14 | nicely. In PAL mode the Amiga can display 512 lies which cannot be displayed 15 | to full extent on this LCD. This is only a minor issue as many CRTs back in the 16 | days would also no be able to display all lines and most software accomodates 17 | for that by using the bottom lines only for "less important" content. 18 | 19 | # Hardware setup 20 | 21 | All variants of the [FPGA 22 | Companion](https://github.com/harbaum/FPGA-Companion) can be used with 23 | the LCD setup as well. These instructions use the [Waveshare 24 | RP2040-Zero variant](https://www.waveshare.com/wiki/RP2040-Zero) as it 25 | provides a nice and compact solution. The Tang Nano 20k and the RP2040-Zero 26 | need to be wired up in the folloring way: 27 | 28 | ![Wiring for LCD usage](wiring_lcd.png) 29 | 30 | The LCD setup uses different pins on the FPGA to connect to the FPGA Companion 31 | than the regular version. This is due to the fact that the LCD uses most of the 32 | FPGAs spare connections incl. those that normally would be used for the FPGA 33 | Companion. The signals thus had to be moved to FPGA pins neither used by the LCD 34 | nor by the audio amplifier. 35 | 36 | ![Hardware setup](tn20k_rp2040_zero.jpg) 37 | 38 | The signal pins used in this case are: 39 | 40 | | FPGA | RP2040 | Signal | Description | 41 | |---|---|---|---| 42 | | | GP0 | UART_TX | Serial debug output | 43 | | 71 | GP4 | MISO | SPI data from FPGA | 44 | | 73 | GP5 | CSn | SPI chip select to FPGA | 45 | | 74 | GP6 | SCK | SPI clock to FPGA | 46 | | 72 | GP7 | MOSI | SPI data to FPGA | 47 | | 75 | GP8 | IRQn | SPI interrupt from FPGA | 48 | 49 | # Installation 50 | 51 | 1. Install two copies of kickstart 1.3 ROM in the FPGAs flash 52 | * ```openFPGALoader --external-flash -o 0x400000 kick13.rom``` 53 | * ```openFPGALoader --external-flash -o 0x440000 kick13.rom``` 54 | 2. Install [the core](https://github.com/harbaum/NanoMig/releases/) in the FPGAs flash 55 | * ```openFPGALoader -fs nanomig_lcd.fs``` 56 | 57 | If the LCD is connected the Tang Nano 20k should boot up to the Kickstart 58 | floppy disk/hand screen. This should even work without SD card inserted and 59 | without FPGA Companion connected. 60 | 61 | Then install the [RP2040-Zero variant of the FPGA Companion 62 | firmware](https://github.com/harbaum/FPGA-Companion/releases) on the 63 | RP2040-Zero. The RGB LED on the RP2040-Zero should blink green and the 64 | RGB LED on the Tang Nano should also light up first blue, then red (if no 65 | sd card has been inserted, yet) or green. 66 | 67 | Finally a FAT formatted SD card should be inserted into the Tang Nano 20k 68 | and the keyboard and/or mouse connected to the USB-C port of the RP2040-Zero 69 | using a USB-C to USB-A adapter. 70 | -------------------------------------------------------------------------------- /doc/nanomig.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/doc/nanomig.jpg -------------------------------------------------------------------------------- /doc/nanomig_lcd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/doc/nanomig_lcd.jpg -------------------------------------------------------------------------------- /doc/tn20k_rp2040_zero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/doc/tn20k_rp2040_zero.jpg -------------------------------------------------------------------------------- /doc/win_programmer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/doc/win_programmer.png -------------------------------------------------------------------------------- /doc/wiring_lcd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/doc/wiring_lcd.png -------------------------------------------------------------------------------- /sim/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # 4 | 5 | # SD_EMU=1 # set to enable sd card emulation 6 | 7 | PRJ=nanomig 8 | 9 | OBJ_DIR=obj_dir 10 | 11 | # the original fx68k won't simulate. Thus we use this special version for simulation 12 | FX68K_DIR=fx68x_verilator 13 | FX68K_FILES=fx68k.sv fx68kAlu.sv uaddrPla.sv fx68k_MicroRom.v fx68k_NanoRom.v 14 | 15 | # Minimig-AGA 16 | MINIMIG_DIR=../src/minimig-aga 17 | MINIMIG_FILES=../nanomig.v amiga_clk.v cpu_wrapper.v minimig.v 18 | MINIMIG_FILES+=ciaa.v ciab.v cia_int.v cia_timera.v cia_timerb.v cia_timerd.v 19 | MINIMIG_FILES+=paula.v paula_uart.v paula_audio_channel.v paula_audio_mixer.v paula_audio.v paula_audio_volume.v paula_floppy_fifo.v paula_floppy.v paula_intcontroller.v 20 | MINIMIG_FILES+=agnus.v agnus_audiodma.v agnus_blitter_adrgen.v agnus_blitter_minterm.v agnus_diskdma.v agnus_beamcounter.v agnus_blitter_barrelshifter.v agnus_blitter.v agnus_refresh.v agnus_bitplanedma.v agnus_blitter_fill.v agnus_copper.v agnus_spritedma.v 21 | MINIMIG_FILES+=denise.v denise_bitplane_shifter.v denise_collision.v denise_colortable.v denise_playfields.v denise_sprites_shifter.v denise_bitplanes.v denise_hamgenerator.v denise_spritepriority.v denise_sprites.v denise_colortable_ram_mf.v 22 | MINIMIG_FILES+=gary.v gayle.v ide.v minimig_m68k_bridge.v minimig_bankmapper.v minimig_sram_bridge.v minimig_syscontrol.v 23 | MINIMIG_FILES+=../minimig/Amber.v userio.v 24 | TB=nanomig_tb 25 | 26 | MISC_DIR=../src/misc 27 | MISC_FILES=video_analyzer.v 28 | 29 | ifdef SD_EMU 30 | MISC_FILES+=sd_rw.v sdcmd_ctrl.v 31 | endif 32 | 33 | VERILATOR_DIR=/usr/local/share/verilator/include 34 | VERILATOR_FILES=verilated.cpp verilated_vcd_c.cpp verilated_threads.cpp 35 | 36 | HDL_FILES=$(TB).v $(MINIMIG_FILES:%=$(MINIMIG_DIR)/%) $(FX68K_FILES:%=$(FX68K_DIR)/%) TG68KdotC_Kernel.v 37 | HDL_FILES+=$(MISC_FILES:%=$(MISC_DIR)/%) 38 | 39 | # Include ini_parser.cpp in the list of C++ source files 40 | CPP_FILES=$(TB).cpp ini_parser.cpp 41 | 42 | EXTRA_CFLAGS = `sdl2-config --cflags` -DVIDEO 43 | EXTRA_LDFLAGS = `sdl2-config --libs` -lSDL2_image 44 | 45 | ifdef SD_EMU 46 | EXTRA_CFLAGS+=-DSD_EMU 47 | VERILATOR_FLAGS=-DSD_EMU 48 | endif 49 | 50 | all: $(PRJ) 51 | 52 | $(PRJ): ${CPP_FILES} ${HDL_FILES} Makefile 53 | verilator -O3 -Wno-fatal --no-timing --trace --threads 1 --trace-underscore -top-module $(PRJ)_tb $(VERILATOR_FLAGS) -cc ${HDL_FILES} --exe ${CPP_FILES} -o ../$(PRJ) -CFLAGS "${EXTRA_CFLAGS}" -LDFLAGS "${EXTRA_LDFLAGS}" 54 | make -j -C ${OBJ_DIR} -f V$(PRJ)_tb.mk 55 | 56 | $(PRJ).vcd: $(PRJ) 57 | ./$(PRJ) 58 | 59 | # Run the simulation with an optional .ini file 60 | run: $(PRJ) 61 | @if [ -z "$(INI)" ]; then \ 62 | ./$(PRJ); \ 63 | else \ 64 | ./$(PRJ) ini=$(INI) screenshot_dir=$(SCREENSHOT_DIR); \ 65 | fi 66 | 67 | wave: $(PRJ).vcd 68 | gtkwave $(PRJ).gtkw 69 | 70 | clean: 71 | rm -rf obj_dir $(PRJ) 72 | -------------------------------------------------------------------------------- /sim/README.md: -------------------------------------------------------------------------------- 1 | # NanoMig simulation 2 | 3 | The fact that the entire Minimig and the fx68k CPU core are written in 4 | verilog allows them to be run in a verilator simulation on a Linux PC. 5 | 6 | Currently implemented in this testbench are: 7 | 8 | - Run the complete Minimig and fx68k core on a real kickstart 9 | - Video output via SDL 10 | - Floppy disk read emulation 11 | - IDE HDD emulation incl. write support (tested with kick 3.1) 12 | - SD card emulation 13 | - UART emulation (for e.g. diagnostic output of DiagROM) 14 | - Includes a skeleton for a [custom test rom](test_rom) 15 | 16 | Some of these features can be enabled and disabled in the ```Makefile``` 17 | and in ```nanomig.cpp``` itself. Not all options are always tested and 18 | some changes in the HDL core may be broken some tests. By default 19 | the simulation is configured for video emulation in endless 20 | operation. This means that running the simulation will not output 21 | any wave data but will instead just run with emulated video. Using 22 | a kickstart 1.3 ROM this will e.g. display the disk/hand screen after 23 | having simulated 187 frames. 24 | 25 | ![NanoMig simulation](nanomig_sim.png) 26 | 27 | The [original fx68k core](https://github.com/ijor/fx68k) does not 28 | work in verilator. This simulation thus includes a [variant 29 | that runs on verilator](https://github.com/emoon/fx68x_verilator). 30 | 31 | ## Building and running 32 | 33 | The simulation has only been tested on Linux. 34 | 35 | It has been tested with Verilator 5.026 built from the [github master 36 | branch](https://github.com/verilator/verilator). Earlier versions, 37 | especially the ones that come with some Linux distros are likely too 38 | old. Newer versions will probably work. You'll need to adjust the 39 | [Makefile](Makefile#L27) to point to your installed verilator setup. 40 | 41 | For video simulation ```libsdl2``` is needed. 42 | 43 | ### Additional files needed 44 | 45 | At least a kickstart (e.g. 1.3) ROM named ```kick13.rom``` is needed 46 | to run the simulation, HDD emulation has only been tested with 47 | kickstart 3.1. Other ROMs like 48 | [DiagROM](https://github.com/ChuckyGang/DiagROM) may also work 49 | although the video simulation is far from being complete and e.g. the 50 | video output of DiagROM is broken. However, UART output can be enabled 51 | allowing to see the initial diagnostic output of DiagROM. 52 | 53 | Further simulation features like e.g. floppy simulation may 54 | need addtional files like e.g. ADF disk images. See the 55 | [```nanomig_tb.cpp```](nanomig_tb.cpp) for details. 56 | 57 | With all dependencies in place a simple ```make run``` should build 58 | the simulatior and run it. 59 | 60 | ## Running traces 61 | 62 | Tracing can be enabled in [```nanomig_tb.cpp```](nanomig_tb.cpp#L49) by 63 | setting the following lines like e.g.: 64 | 65 | ``` 66 | #define TRACESTART 0.4 67 | #define TRACEEND (TRACESTART + 0.2) // 0.1s ~ 1G 68 | ``` 69 | 70 | This will start writing out a trace file after 0.4 seconds of simulated run 71 | time and it will write a trace for 0.2 seconds of runtime. The traces 72 | will be ~1 GBytes per 100ms simulated runtime. 73 | 74 | The resulting VCD trace can e.g. be loaded into 75 | [gtkwave](https://gtkwave.sourceforge.net/) for further inspection. 76 | 77 | ![NanoMig trace in gtkwave](nanomig_wave.png) 78 | 79 | ## Floppy disk simulation 80 | 81 | The floppy disk can be simulated including the SD card itself or by 82 | omitting the SD card. By default the SD card itself is not simulated 83 | and the simulation environment sends data into the Minimig floppy 84 | implementation directly. This should be sufficient for most tests. 85 | 86 | Floppy simulation is now by default enabled and expects a file named 87 | ```df0.adf``` to be present. This will then be inserted as DF0. If 88 | no such file is present, then the simulation behaves as if no disk 89 | is inserted in the amiga kick displays the disk/hand logo after 90 | around 3 seconds simulation time. 91 | 92 | When booting kickstart 1.3, the floppy will first be accessed at 93 | around 3 seconds simulation time with some debug output about disk IO 94 | on the console. 95 | 96 | ## Screenshots 97 | 98 | With video emulation enabled all frames are written to the 99 | [screenshots](screenshots) directory in PNG format. 100 | -------------------------------------------------------------------------------- /sim/fx68x_verilator/fx68k.txt: -------------------------------------------------------------------------------- 1 | FX68K 2 | 3 | 68000 cycle accurate core 4 | Copyright (c) 2018 by Jorge Cwik 5 | fx68k@fxatari.com 6 | 7 | 8 | FX68K is a 68K cycle exact compatible core. In theory at least, it should be impossible to distinguish functionally from a real 68K processor. 9 | 10 | On Cyclone families it uses just over 5,100 LEs and about 5KB internal ram, reaching a max clock frequency close to 40MHz. Some optimizations are still possible to implement and increase the performance. 11 | 12 | The core is fully synchronous. Considerable effort was done to avoid any asynchronous logic. 13 | 14 | Written in SystemVerilog. 15 | 16 | The timing of the external bus signals is exactly as the original processor. The only feature that is not implemented yet is bus retry using the external HALT input signal. 17 | 18 | It was designed to replace an actual chip on a real board. This wasn't yet tested however and not all necessary output enable control signals are fully implemented. 19 | 20 | 21 | Copyright 22 | 23 | // 24 | // This source file is free software; you can redistribute it and/or modify 25 | // it under the terms of the GNU General Public License as published by 26 | // the Free Software Foundation; either version 3 of the License, or 27 | // (at your option) any later version. 28 | // 29 | // This source file is distributed in the hope that it will be useful, 30 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | // GNU General Public License for more details. 33 | // 34 | // You should have received a copy of the GNU General Public License 35 | // along with this program. If not, see . 36 | // 37 | 38 | 39 | Developer Notes 40 | 41 | 42 | The core receives a clock that must be at least twice the frequency of the desired nominal speed. The core also receives two signals for masking both phases of the clock (PHI1 and PHI2). These signals are implemented as simple clock enable for all the flip flops used by the core. This way, the original clock frequency can be any multiple and it doesn't even need to be regular or constant. 43 | 44 | These two signals are enPhi1 and enPhi2. They must be a single cycle pulse, and they don't need to be registered. Because they are actually used as clock enable, the output signals change one cycle later. 45 | 46 | enPhi1 should be asserted one cycle before the high phase of the nominal clock, and enPhi2 one cycle before the low phase. 47 | 48 | E.g., during a bus cycle, AS is asserted one cycle after enPhi1 is asserted, and AS is deasserted one cycle after enPhi2 is asserted. This follows the original bus timing that specify AS being asserted on the raising edge of the clock, and deasserted on the falling edge one. 49 | 50 | All signals follow the original polarity and then most are low active. 51 | 52 | extReset is external reset and is synchronous and high active. Hence is doesn't have to be registered. 53 | 54 | pwrUp qualifies external reset as being a cold power up reset. If it is asserted, then extReset must be asserted as well. Most system don't need to distinguish between a cold and a warm reset at the CPU level. Then both signals can be always asserted together. The core does expect pwrUp to be asserted initially because there is no true asynchronous reset. The signal is high active. 55 | 56 | 57 | Timing analysis 58 | 59 | Microcode access is one of the slowest paths on the core. But the microcode output is not needed immediately. Use the following constraints to get a more accurate timing analysis. Note that the full path might need to be modified: 60 | 61 | # Altera/Intel 62 | 63 | set_multicycle_path -start -setup -from [get_keepers fx68k:fx68k|Ir[*]] -to [get_keepers fx68k:fx68k|microAddr[*]] 2 64 | set_multicycle_path -start -hold -from [get_keepers fx68k:fx68k|Ir[*]] -to [get_keepers fx68k:fx68k|microAddr[*]] 1 65 | set_multicycle_path -start -setup -from [get_keepers fx68k:fx68k|Ir[*]] -to [get_keepers fx68k:fx68k|nanoAddr[*]] 2 66 | set_multicycle_path -start -hold -from [get_keepers fx68k:fx68k|Ir[*]] -to [get_keepers fx68k:fx68k|nanoAddr[*]] 1 67 | 68 | # For Xilinx Vivado 69 | 70 | set_multicycle_path -setup -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/nanoAddr_reg*/D] 2 71 | set_multicycle_path -setup -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/microAddr_reg*/D] 2 72 | set_multicycle_path -hold -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/nanoAddr_reg*/D] 1 73 | set_multicycle_path -hold -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/microAddr_reg*/D] 1 74 | 75 | -------------------------------------------------------------------------------- /sim/fx68x_verilator/make.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | make -j -C obj_dir -f Vfx68k.mk && obj_dir/Vfx68k 3 | -------------------------------------------------------------------------------- /sim/ini_parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // Define a structure to hold vAmigaTS configuration settings 6 | struct vAmigaTSConfig { 7 | std::string config_file_name = ""; 8 | std::string rom_path = "kick13.rom"; 9 | int screenshot_wait_time_seconds = 0; 10 | int screenshot_wait_time_seconds_offset = 0; 11 | std::string screenshot_name = ""; 12 | std::string screenshot_dir = "."; // Default to current directory 13 | std::string adf_path = "df0.adf"; 14 | std::string config_string = ""; 15 | std::string chipset = "OCS"; // use OCS as default 16 | std::string cpu_revision = "68000"; // default CPU revision 17 | }; 18 | 19 | // External variables to hold configuration data 20 | extern int g_vAmigaTS_screenshot_wait_time_seconds; 21 | extern int g_vAmigaTS_screenshot_wait_time_seconds_offset; 22 | extern std::string g_vAmigaTS_screenshot_name; 23 | extern std::string g_vAmigaTS_screenshot_dir; 24 | 25 | // Function to check and replace "_ocs.adf" or "_ecs.adf" with ".adf" 26 | void check_and_replace_adf_path(vAmigaTSConfig &config); 27 | 28 | // Function to parse command-line arguments 29 | vAmigaTSConfig parse_command_line_args(int argc, char **argv); 30 | 31 | // Function to parse the INI file 32 | void parse_ini_file(const std::string &file_path, vAmigaTSConfig &config); -------------------------------------------------------------------------------- /sim/nanomig.gtkw: -------------------------------------------------------------------------------- 1 | [*] 2 | [*] GTKWave Analyzer v3.3.116 (w)1999-2023 BSI 3 | [*] Fri Jul 12 08:05:42 2024 4 | [*] 5 | [dumpfile] "nanomig.vcd" 6 | [dumpfile_mtime] "Fri Jul 12 08:05:10 2024" 7 | [dumpfile_size] 2160783806 8 | [savefile] "nanomig.gtkw" 9 | [timestart] 3300000011530 10 | [size] 1490 1000 11 | [pos] 74 51 12 | *-23.540529 3300004998286 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 13 | [treeopen] TOP. 14 | [treeopen] TOP.nanomig. 15 | [treeopen] TOP.nanomig.MINIMIG1. 16 | [treeopen] TOP.nanomig.MINIMIG1.AGNUS1. 17 | [treeopen] TOP.nanomig.MINIMIG1.AGNUS1.bl1. 18 | [sst_width] 209 19 | [signals_width] 256 20 | [sst_expanded] 1 21 | [sst_vpaned_height] 565 22 | @28 23 | TOP.nanomig.clk 24 | TOP.nanomig.MINIMIG1.AGNUS1.clk 25 | TOP.nanomig.phi1 26 | @100028 27 | TOP.nanomig.phi2 28 | @28 29 | TOP.nanomig.reset 30 | TOP.nanomig.MINIMIG1.n_ram_bhe 31 | TOP.nanomig.MINIMIG1.n_ram_ble 32 | TOP.nanomig.MINIMIG1.BMAP1.chip0 33 | TOP.nanomig.MINIMIG1.BMAP1.kick 34 | @100022 35 | TOP.nanomig.cpu_a[23:1] 36 | @22 37 | TOP.nanomig.MINIMIG1.ram_data[15:0] 38 | @d00022 39 | TOP.nanomig.MINIMIG1.ram_address_out[18:1] 40 | @28 41 | (0)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 42 | (1)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 43 | (2)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 44 | (3)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 45 | (4)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 46 | (5)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 47 | (6)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 48 | (7)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 49 | (8)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 50 | (9)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 51 | (10)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 52 | (11)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 53 | (12)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 54 | (13)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 55 | (14)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 56 | (15)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 57 | (16)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 58 | (17)TOP.nanomig.MINIMIG1.ram_address_out[18:1] 59 | @1401200 60 | -group_end 61 | @22 62 | TOP.nanomig.MINIMIG1.ram_data_in[15:0] 63 | TOP.nanomig.MINIMIG1.ramdata_in[15:0] 64 | TOP.nanomig.cpu_din[15:0] 65 | TOP.nanomig.ram_din[15:0] 66 | @28 67 | TOP.nanomig.MINIMIG1.n_hsync 68 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.start 69 | TOP.nanomig.MINIMIG1.AGNUS1.blit_busy 70 | @23 71 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.width[10:0] 72 | @28 73 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.done 74 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.we 75 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.reqdma 76 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.ackdma 77 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.int3 78 | @100022 79 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.address_out[20:1] 80 | @22 81 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.blt_state[4:0] 82 | [color] 2 83 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltcon0[15:0] 84 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.ain[15:0] 85 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.bin[15:0] 86 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.cin[15:0] 87 | @c00022 88 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 89 | @28 90 | (0)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 91 | (1)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 92 | (2)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 93 | (3)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 94 | (4)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 95 | (5)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 96 | (6)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 97 | (7)TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.lf[7:0] 98 | @1401200 99 | -group_end 100 | @22 101 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.bltmt1.out[15:0] 102 | @100028 103 | TOP.nanomig.MINIMIG1.AGNUS1.bl1.chsel[1:0] 104 | [pattern_trace] 1 105 | [pattern_trace] 0 106 | -------------------------------------------------------------------------------- /sim/nanomig_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/nanomig_sim.png -------------------------------------------------------------------------------- /sim/nanomig_tb.v: -------------------------------------------------------------------------------- 1 | // nanomig simulation top 2 | 3 | module nanomig_tb 4 | ( 5 | input clk, // 28mhz 6 | output clk_7m, 7 | output clk7_en, 8 | output clk7n_en, 9 | input reset, 10 | 11 | // serial output, mainly for diagrom 12 | output uart_tx, 13 | 14 | // signal to e.g. trigger on disk activity 15 | output pwr_led, 16 | output fdd_led, 17 | output hdd_led, 18 | input trigger, 19 | 20 | input [5:0] chipset_config, 21 | 22 | // video 23 | output hs_n, 24 | output vs_n, 25 | output [3:0] red, 26 | output [3:0] green, 27 | output [3:0] blue, 28 | 29 | input [7:0] sdc_img_mounted, 30 | input [31:0] sdc_img_size, 31 | 32 | `ifdef SD_EMU 33 | output sdclk, 34 | output sdcmd, 35 | input sdcmd_in, 36 | output [3:0] sddat, 37 | input [3:0] sddat_in, 38 | `else 39 | output [7:0] sdc_rd, 40 | output [7:0] sdc_wr, 41 | output [31:0] sdc_sector, 42 | input sdc_busy, 43 | input sdc_done, 44 | input sdc_byte_in_strobe, 45 | input [8:0] sdc_byte_addr, 46 | input [7:0] sdc_byte_in_data, 47 | output [7:0] sdc_byte_out_data, 48 | `endif // !`ifdef SD_EMU 49 | 50 | // external ram/rom interface 51 | output [15:0] ram_data, // sram data bus 52 | input [15:0] ramdata_in, // sram data bus in 53 | output [23:1] ram_address, // sram address bus 54 | output _ram_bhe, // sram upper byte select 55 | output _ram_ble, // sram lower byte select 56 | output _ram_we, // sram write enable 57 | output _ram_oe // sram output enable 58 | ); 59 | 60 | `ifdef SD_EMU 61 | // for floppy IO the SD card itself may be included into the simulation or not 62 | wire [7:0] sdc_rd; 63 | wire [7:0] sdc_wr; 64 | wire [31:0] sdc_sector; 65 | wire sdc_busy; 66 | wire sdc_done; 67 | wire sdc_byte_in_strobe; 68 | wire [8:0] sdc_byte_addr; 69 | wire [7:0] sdc_byte_in_data; 70 | wire [7:0] sdc_byte_out_data; 71 | 72 | sd_rw #( 73 | .CLK_DIV(3'd0), // for 28 Mhz clock 74 | .SIMULATE(1'b1) 75 | ) sd_card ( 76 | .rstn(!reset), // rstn active-low, 1:working, 0:reset 77 | .clk(clk), // clock 78 | 79 | // SD card signals 80 | .sdclk(sdclk), 81 | .sdcmd(sdcmd), 82 | .sdcmd_in(sdcmd_in), 83 | .sddat(sddat), 84 | .sddat_in(sddat_in), 85 | 86 | // user read sector command interface (sync with clk) 87 | .rstart(sdc_rd), 88 | .wstart(sdc_wr), 89 | .sector(sdc_sector), 90 | .rbusy(sdc_busy), 91 | .rdone(sdc_done), 92 | 93 | // sector data output interface (sync with clk) 94 | .inbyte(sdc_byte_out_data), 95 | .outen(sdc_byte_in_strobe), // when outen=1, a byte of sector content is read out from outbyte 96 | .outaddr(sdc_byte_addr), // outaddr from 0 to 511, because the sector size is 512 97 | .outbyte(sdc_byte_in_data) // a byte of sector content 98 | ); 99 | `endif // `ifdef SD_EMU 100 | 101 | nanomig nanomig ( 102 | // system pins 103 | .clk_sys(clk), // 28.37516 MHz clock 104 | .reset(reset), 105 | .clk7_en(clk7_en), 106 | .clk7n_en(clk7n_en), 107 | 108 | .pwr_led(pwr_led), 109 | .fdd_led(fdd_led), 110 | .hdd_led(hdd_led), 111 | 112 | .chipset_config(chipset_config), 113 | .memory_config(8'b0_0_00_00_01), 114 | .floppy_config(4'h0), 115 | .ide_config(6'b000111), 116 | 117 | .hs(hs_n), 118 | .vs(vs_n), 119 | .r(red), 120 | .g(green), 121 | .b(blue), 122 | 123 | .joystick(6'b000000), 124 | 125 | // sd card interface for floppy disk emulation 126 | .sdc_img_mounted ( sdc_img_mounted ), 127 | .sdc_img_size ( sdc_img_size ), // length of image file 128 | .sdc_rd(sdc_rd), 129 | .sdc_wr(sdc_wr), 130 | .sdc_sector(sdc_sector), 131 | .sdc_busy(sdc_busy), 132 | .sdc_done(sdc_done), 133 | .sdc_byte_in_strobe(sdc_byte_in_strobe), 134 | .sdc_byte_addr(sdc_byte_addr), 135 | .sdc_byte_in_data(sdc_byte_in_data), 136 | .sdc_byte_out_data(sdc_byte_out_data), 137 | 138 | .uart_tx(uart_tx), 139 | 140 | // (s(d))ram interface 141 | .ram_data(ram_data), // sram data bus 142 | .ramdata_in(ramdata_in), // sram data bus in 143 | .chip48(48'h0), // big chip read, needed for AGA only 144 | .ram_address(ram_address), // sram address bus 145 | ._ram_bhe(_ram_bhe), // sram upper byte select 146 | ._ram_ble(_ram_ble), // sram lower byte select 147 | ._ram_we(_ram_we), // sram write enable 148 | ._ram_oe(_ram_oe) // sram output enable 149 | ); 150 | 151 | video_analyzer video_analyzer 152 | ( 153 | .clk(clk), 154 | .hs(hs_n), 155 | .vs(vs_n), 156 | .pal(), 157 | .interlace(), 158 | .vreset() 159 | ); 160 | 161 | endmodule 162 | -------------------------------------------------------------------------------- /sim/nanomig_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/nanomig_wave.png -------------------------------------------------------------------------------- /sim/screenshots/frame0200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/screenshots/frame0200.png -------------------------------------------------------------------------------- /sim/test_rom/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # 4 | 5 | all: test_rom.bin 6 | 7 | test_rom.bin: test_rom.s 8 | ./vasm-mirror/vasmm68k_mot -Fbin test_rom.s -o test_rom.bin 9 | -------------------------------------------------------------------------------- /sim/test_rom/README.md: -------------------------------------------------------------------------------- 1 | # NanoMig test rom 2 | 3 | This is a skeleton for a custom test rom to test the NanoMig in 4 | simulation (and potentially on FPGA as well). 5 | 6 | It is translated using 7 | [vasm68k](https://github.com/StarWolf3000/vasm-mirror). Which needs to 8 | be built for the m68k cpu: 9 | 10 | ``` 11 | make CPU=m68k SYNTAX=mot 12 | ``` 13 | 14 | The resulting ```vasmm68k_mot``` can be used to assemble the 15 | source code: 16 | 17 | ``` 18 | $ ./vasmm68k_mot -Fbin test_rom.s -o test_rom.bin 19 | vasm 1.9f (c) in 2002-2023 Volker Barthelmann 20 | vasm M68k/CPU32/ColdFire cpu backend 2.6c (c) 2002-2023 Frank Wille 21 | vasm motorola syntax module 3.18 (c) 2002-2023 Frank Wille 22 | vasm binary output module 2.3a (c) 2002-2023 Volker Barthelmann and Frank Wille 23 | 24 | org0001:f80000(acrwx2): 12 bytes 25 | org0002:f80030(acrwx2): 442 bytes 26 | ``` 27 | 28 | The resulting ```test_rom.bin``` can then be specified in 29 | [nanomig.cpp](../nanomig.cpp#L23) as the ```KICK``` file to boot 30 | which will then run in the simulation. 31 | 32 | ![Test ROM running](test_rom.png) 33 | -------------------------------------------------------------------------------- /sim/test_rom/test_rom.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/test_rom/test_rom.bin -------------------------------------------------------------------------------- /sim/test_rom/test_rom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/test_rom/test_rom.png -------------------------------------------------------------------------------- /sim/test_rom/test_rom.s: -------------------------------------------------------------------------------- 1 | ;; test_rom.s 2 | ;; test rom for nanomig/minimig on Tang nano 20k 3 | 4 | ;; This is just a dummy test. It initializes video 5 | ;; and outputs some increasing hex numbers on screen 6 | 7 | ;; It can be loaded into the NanoMig simulation 8 | 9 | VIDMEM EQU 2048 ; start video memory at 2048 10 | COPPER EQU $220 ; copperlist in RAM 11 | XPOS EQU $200 12 | YPOS EQU $202 13 | 14 | ;; amiga like rom header 15 | ORG $f80000 16 | 17 | bra.s start-1 ; -1? wtf ... 18 | dc.w $4ef9 ; jmp ... 19 | 20 | dc.l $f80030 21 | dc.l $f80008 22 | 23 | ORG $f80030 24 | 25 | ;; actual code starting point 26 | start: 27 | ;; wait >80ms for minimig-aga syctrl reset to be gone 28 | move #60000,d0 29 | iwlp: dbra d0,iwlp 30 | 31 | move.l #$100,sp ; use ram below $100 as stack 32 | move.b #3,$bfe201 ; LED and OVL are outputs 33 | move.b #2,$bfe001 ; switch rom overlay off 34 | 35 | bsr startcopper 36 | 37 | ;; just count ... 38 | clr.l d0 39 | prt_lp: clr.w XPOS 40 | jsr printlong 41 | addq.l #1,d0 42 | bra.s prt_lp 43 | 44 | startcopper: 45 | ;; clear screem memory 46 | move.l #(320*256)/32-1,d0 47 | move.l #VIDMEM,a0 48 | cllp: clr.l (a0)+ 49 | dbra d0,cllp 50 | 51 | ;; copy copper list to ram 52 | move.l #(copperlist_end-copperlist)/4-1,d1 53 | move.l #copperlist,a0 54 | move.l #COPPER,a1 55 | cplp: move.l (a0)+,(a1)+ 56 | dbra d1,cplp 57 | 58 | move.l #COPPER,$dff080 ; load copper list 59 | move.w $dff088,d0 ; start copper 60 | move.w #$8380,$dff096 ; init dma controller 61 | move.w #$20,$dff1dc ; PAL 62 | 63 | ;; reset cursor 64 | clr.w XPOS 65 | clr.w YPOS 66 | 67 | rts 68 | 69 | copperlist: 70 | dc.w $0100,$1200 ; enable one bitplane 71 | dc.w $0092,$003c ; display data fetch start 120 72 | dc.w $0094,$00d4 ; display data fetch end 424 73 | dc.w $008e,$2c81 ; \__ PAL 320x256 74 | dc.w $0090,$2cc1 ; / 75 | dc.w $00e0,$0000 ; bitplane 0 start hi 76 | dc.w $00e2,VIDMEM; bitplane 0 start low 77 | dc.w $0182, $000 ; pixel data black 78 | 79 | dc.w $0180, $fff ; background white 80 | dc.w $2a0f,$fffe ; wait for line $2a 81 | dc.w $0180, $0f0 ; background green 82 | dc.w $340f,$fffe ; wait for line $34 83 | dc.w $0180, $ff0 ; background yellow 84 | 85 | dc.w $ffff,$fffe ; End of copperlist 86 | copperlist_end: 87 | 88 | ;; print long given in D0 89 | printlong: 90 | swap d0 91 | jsr printword 92 | swap d0 93 | jsr printword 94 | rts 95 | 96 | printword: 97 | movem.l d0/d1,-(sp) 98 | move.w #8,d1 99 | rol.w d1,d0 100 | jsr printbyte 101 | rol.w d1,d0 102 | jsr printbyte 103 | movem.l (sp)+,d0/d1 104 | rts 105 | 106 | printbyte: 107 | movem.l d0/d1,-(sp) 108 | move d0,d1 109 | lsr #4,d0 110 | jsr printdigit 111 | move d1,d0 112 | jsr printdigit 113 | movem.l (sp)+,d0/d1 114 | rts 115 | 116 | ;; print hex digit given in D0 117 | printdigit: 118 | movem.l d0/a0-a1,-(sp) 119 | move.l #hexchars,a0 120 | and.l #15,d0 121 | lsl #3,d0 122 | add.l d0,a0 123 | move.l #VIDMEM,a1 124 | move YPOS,d0 125 | mulu #(8*40),d0 126 | add.l d0,a1 127 | add XPOS,d0 128 | ext.l d0 129 | add.l d0,a1 130 | moveq #7,d0 131 | pd0: move.b (a0)+,(a1)+ 132 | add.l #(40-1),a1 133 | dbra d0,pd0 134 | add #1,XPOS 135 | movem.l (sp)+,d0/a0-a1 136 | rts 137 | 138 | hexchars: 139 | dc.b $7C, $C6, $CE, $DE, $F6, $E6, $7C, $00 ; 0 140 | dc.b $30, $70, $30, $30, $30, $30, $FC, $00 ; 1 141 | dc.b $78, $CC, $0C, $38, $60, $CC, $FC, $00 ; 2 142 | dc.b $78, $CC, $0C, $38, $0C, $CC, $78, $00 ; 3 143 | dc.b $1C, $3C, $6C, $CC, $FE, $0C, $1E, $00 ; 4 144 | dc.b $FC, $C0, $F8, $0C, $0C, $CC, $78, $00 ; 5 145 | dc.b $38, $60, $C0, $F8, $CC, $CC, $78, $00 ; 6 146 | dc.b $FC, $CC, $0C, $18, $30, $30, $30, $00 ; 7 147 | dc.b $78, $CC, $CC, $78, $CC, $CC, $78, $00 ; 8 148 | dc.b $78, $CC, $CC, $7C, $0C, $18, $70, $00 ; 9 149 | dc.b $30, $78, $CC, $CC, $FC, $CC, $CC, $00 ; A 150 | dc.b $FC, $66, $66, $7C, $66, $66, $FC, $00 ; B 151 | dc.b $3C, $66, $C0, $C0, $C0, $66, $3C, $00 ; C 152 | dc.b $F8, $6C, $66, $66, $66, $6C, $F8, $00 ; D 153 | dc.b $FE, $62, $68, $78, $68, $62, $FE, $00 ; E 154 | dc.b $FE, $62, $68, $78, $68, $60, $F0, $00 ; F 155 | 156 | -------------------------------------------------------------------------------- /sim/vAmigaTS/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | # Default source directory if SRC_DIR is not provided 4 | #FALLBACK_DIR=~/vAmigaTS/Agnus/Blitter/bbusy 5 | #FALLBACK_DIR=~/vAmigaTS/Agnus/Blitter/bltint 6 | # maybe add wait_time_seconds_offset as parameter here? 7 | # bbusy needs 6 seconds, bltint needs 7 seconds 8 | FALLBACK_DIR=~/vAmigaTS/Agnus/Blitter/fill 9 | # this command is run in the parent directory 10 | SIMULATION_CMD=make run 11 | # this directory is located in the parent directory 12 | SCREENSHOT_DIR=$(CURDIR)/screenshots 13 | KICK_PATH=../kick13.rom 14 | 15 | # Use SRC_DIR if defined, otherwise fallback to FALLBACK_DIR 16 | SRC_DIR ?= $(FALLBACK_DIR) 17 | 18 | TMP_DIR=/tmp 19 | PARENT_DIR=.. 20 | 21 | # Run make for each .ini file in the parent directory 22 | run_all: collect_files 23 | @mkdir -p $(SCREENSHOT_DIR) # Ensure the screenshots directory exists 24 | @echo "Running simulations for each .ini file..." 25 | @for ini in $(TMP_DIR)/*.ini; do \ 26 | echo "Found .ini file: $$ini"; \ 27 | # (cd $(PARENT_DIR) && make run INI=$$ini); \ 28 | (cd $(PARENT_DIR) && $(SIMULATION_CMD) INI=$$ini SCREENSHOT_DIR=$(SCREENSHOT_DIR)); \ 29 | done 30 | 31 | # Collect all .ini and .adf files from the specified directory 32 | collect_files: 33 | @echo "Collecting .ini and .adf files from $(SRC_DIR)..." 34 | @mkdir -p $(TMP_DIR) # Ensure the temporary directory exists 35 | @-find $(SRC_DIR) -name "*.ini" -exec cp {} $(TMP_DIR) \; || echo "No .ini files found." 36 | @-find $(SRC_DIR) -name "*.adf" -exec cp {} $(TMP_DIR) \; || echo "No .adf files found." 37 | @echo "Files collected in $(TMP_DIR):" 38 | @echo "Copying kick13.rom to $(TMP_DIR)..." 39 | @cp $(KICK_PATH) $(TMP_DIR) || echo "$(KICK_PATH) not found." 40 | @ls $(TMP_DIR) 41 | 42 | # Clean up the temporary directory 43 | clean: 44 | @echo "Cleaning up..." 45 | @rm -rf $(TMP_DIR) 46 | @make clean 47 | 48 | # Default target 49 | all: run_all 50 | 51 | # End of Makefile 52 | -------------------------------------------------------------------------------- /sim/vAmigaTS/README.md: -------------------------------------------------------------------------------- 1 | # Run NanoMig Simulation with test from vAmiga Test Suite 2 | 3 | The tests from the [vAmiga Test Suite](https://github.com/dirkwhoffmann/vAmigaTS) can be used to validate the accuracy of the NanoMig Verilator simulation. 4 | 5 | For this purpose the parameters from the INI files of the vAmiga Test Suite are used to configure the NanoMig Verilator simulation. Screenshots of the NanoMig Verilator simulation are taken for comparison against the reference images provided by the vAmiga Test Suite. 6 | 7 | ## Benefit 8 | 9 | The vAmiga Test Suite has been validated against real Amiga hardware, providing a benchmark for simulation accuracy. 10 | These tests can help further improve the precision of the NanoMig simulation. 11 | 12 | ## Usage 13 | 14 | ### Running the Simulation with the Makefile 15 | 16 | This project uses a `Makefile` to automate the process of collecting tests and running the simulations. 17 | 18 | #### Key Variables in the Makefile 19 | 20 | - **`SRC_DIR`:** The directory where the vAmiga Test Suite files are located. `SRC_DIR` is passed to the Makefile as a parameter. 21 | - **`FALLBACK_DIR`:** The default directory where the vAmiga Test Suite files are located. If `SRC_DIR` is not specified, this path is used. 22 | - **`SIM_COMMAND`:** The command used to run the simulation. It defaults to `make run` in the parent directory. 23 | - **`KICK_PATH`:** The path to the `kick13.rom` file, which is necessary for the simulation. 24 | 25 | #### How to Use 26 | 27 | 1. **Prepare the Environment:** 28 | - Ensure that the vAmiga Test Suite files are located in the directory specified by `SRC_DIR` or the `FALLBACK_DIR` in the Makefile. For example under `~/vAmigaTS/` 29 | - Make sure that the `kick13.rom` file is available in the path specified by `KICK_PATH`. 30 | 31 | 2. **Run the Simulation with vAmiga Test Suite Tests:** 32 | 33 | - To use the vAmigaTS tests from the `FALLBACK_DIR`, execute the following command in your terminal: 34 | ```bash 35 | make 36 | ``` 37 | 38 | - To use the vAmigaTS tests from a specific directory, such as `~/vAmigaTS/Agnus/Blitter/bbusy`, execute the following command in your terminal: 39 | ```bash 40 | make SRC_DIR=~/vAmigaTS/Agnus/Blitter/bbusy 41 | ``` 42 | 43 | 44 | - A single test can be executed using the same approach: 45 | ```bash 46 | make SRC_DIR=~/vAmigaTS/Agnus/Blitter/bltint/bltint1 47 | ``` 48 | 49 | 50 | ## Todo 51 | - Take into account CPU revision mentioned in INI files 52 | - Take into account the amount of RAM mentioned in INI files 53 | - Test handling of directories with multiple INI files 54 | -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/README.md: -------------------------------------------------------------------------------- 1 | This directory contains screenshots of tests from the [vAmiga Test Suite](https://github.com/dirkwhoffmann/vAmigaTS), generated by the NanoMig Verilator simulation. 2 | 3 | The reference images from the vAmiga Test Suite can be found in the [vAmiga Test Suite GitHub repository](https://github.com/dirkwhoffmann/vAmigaTS) by searching for the filename of the image without the ".png" extension. 4 | For example, to find the reference image for `bbusy0.png`, you can use this search query: [https://github.com/search?q=repo%3Adirkwhoffmann%2FvAmigaTS+bbusy0](https://github.com/search?q=repo%3Adirkwhoffmann%2FvAmigaTS+bbusy0). 5 | -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint1.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint2.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint3.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint4.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint5.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint6.png -------------------------------------------------------------------------------- /sim/vAmigaTS/screenshots/bltint7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harbaum/NanoMig/3e0b61659cac6818dcd9fa379f8cce6a4906c744/sim/vAmigaTS/screenshots/bltint7.png -------------------------------------------------------------------------------- /src/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | EXT= 3 | if [ "$#" -eq 1 ]; then 4 | EXT=_$1 5 | fi 6 | 7 | # run through grc to highlight NOTEs, WARNings and ERRORs 8 | grc --config=gw_sh.grc gw_sh ./build${EXT}.tcl 9 | -------------------------------------------------------------------------------- /src/build.tcl: -------------------------------------------------------------------------------- 1 | set_device GW2AR-LV18QN88C8/I7 -name GW2AR-18C 2 | 3 | add_file nanomig.v 4 | add_file minimig-aga/amiga_clk.v 5 | add_file minimig-aga/cpu_wrapper.v 6 | add_file minimig-aga/minimig.v 7 | add_file minimig-aga/ciaa.v 8 | add_file minimig-aga/ciab.v 9 | add_file minimig-aga/cia_int.v 10 | add_file minimig-aga/cia_timera.v 11 | add_file minimig-aga/cia_timerb.v 12 | add_file minimig-aga/cia_timerd.v 13 | add_file minimig-aga/paula.v 14 | add_file minimig-aga/paula_uart.v 15 | add_file minimig-aga/paula_audio_channel.v 16 | add_file minimig-aga/paula_audio_mixer.v 17 | add_file minimig-aga/paula_audio.v 18 | add_file minimig-aga/paula_audio_volume.v 19 | add_file minimig-aga/paula_floppy_fifo.v 20 | add_file minimig-aga/paula_floppy.v 21 | add_file minimig-aga/paula_intcontroller.v 22 | add_file minimig-aga/agnus.v 23 | add_file minimig-aga/agnus_audiodma.v 24 | add_file minimig-aga/agnus_blitter_adrgen.v 25 | add_file minimig-aga/agnus_blitter_minterm.v 26 | add_file minimig-aga/agnus_diskdma.v 27 | add_file minimig-aga/agnus_beamcounter.v 28 | add_file minimig-aga/agnus_blitter_barrelshifter.v 29 | add_file minimig-aga/agnus_blitter.v 30 | add_file minimig-aga/agnus_refresh.v 31 | add_file minimig-aga/agnus_bitplanedma.v 32 | add_file minimig-aga/agnus_blitter_fill.v 33 | add_file minimig-aga/agnus_copper.v 34 | add_file minimig-aga/agnus_spritedma.v 35 | add_file minimig-aga/denise.v 36 | add_file minimig-aga/denise_bitplane_shifter.v 37 | add_file minimig-aga/denise_collision.v 38 | add_file minimig-aga/denise_colortable.v 39 | add_file minimig-aga/denise_playfields.v 40 | add_file minimig-aga/denise_sprites_shifter.v 41 | add_file minimig-aga/denise_bitplanes.v 42 | add_file minimig-aga/denise_hamgenerator.v 43 | add_file minimig-aga/denise_spritepriority.v 44 | add_file minimig-aga/denise_sprites.v 45 | add_file minimig-aga/denise_colortable_ram_mf.v 46 | add_file minimig-aga/gary.v 47 | add_file minimig-aga/gayle.v 48 | add_file minimig-aga/ide.v 49 | add_file minimig-aga/minimig_m68k_bridge.v 50 | add_file minimig-aga/minimig_bankmapper.v 51 | add_file minimig-aga/minimig_sram_bridge.v 52 | add_file minimig-aga/minimig_syscontrol.v 53 | add_file minimig-aga/userio.v 54 | add_file minimig/Amber.v 55 | add_file fx68k/fx68k.sv 56 | add_file fx68k/fx68kAlu.sv 57 | add_file fx68k/uaddrPla.sv 58 | add_file hdmi/audio_clock_regeneration_packet.sv 59 | add_file hdmi/audio_info_frame.sv 60 | add_file hdmi/audio_sample_packet.sv 61 | add_file hdmi/auxiliary_video_information_info_frame.sv 62 | add_file hdmi/hdmi.sv 63 | add_file hdmi/packet_assembler.sv 64 | add_file hdmi/packet_picker.sv 65 | add_file hdmi/serializer.sv 66 | add_file hdmi/source_product_description_info_frame.sv 67 | add_file hdmi/tmds_channel.sv 68 | add_file misc/mcu_spi.v 69 | add_file misc/sysctrl.v 70 | add_file misc/hid.v 71 | add_file misc/osd_u8g2.v 72 | add_file misc/ws2812.v 73 | add_file misc/video_analyzer.v 74 | add_file misc/sd_card.v 75 | add_file misc/sd_rw.v 76 | add_file misc/sdcmd_ctrl.v 77 | add_file misc/amiga_keymap.v 78 | add_file tang/nano20k/flash_dspi.v 79 | add_file tang/nano20k/gowin_clkdiv/gowin_clkdiv.v 80 | add_file tang/nano20k/gowin_rpll/pll_142m.v 81 | add_file tang/nano20k/gowin_dpb/sector_dpram.v 82 | add_file tang/nano20k/gowin_dpb/ide_dpram.v 83 | add_file tang/nano20k/top.sv 84 | add_file tang/nano20k/sdram.v 85 | add_file tang/nano20k/nanomig.cst 86 | add_file tang/nano20k/nanomig.sdc 87 | add_file fx68k/microrom.mem 88 | add_file fx68k/nanorom.mem 89 | add_file tg68k/TG68K_Pack.vhd 90 | add_file tg68k/TG68K.vhd 91 | add_file tg68k/TG68K_ALU.vhd 92 | add_file tg68k/TG68KdotC_Kernel.vhd 93 | add_file misc/amiga_xml.hex 94 | 95 | set_option -synthesis_tool gowinsynthesis 96 | set_option -output_base_name nanomig 97 | set_option -verilog_std sysv2017 98 | set_option -top_module top 99 | set_option -use_mspi_as_gpio 1 100 | set_option -use_sspi_as_gpio 1 101 | 102 | run all 103 | -------------------------------------------------------------------------------- /src/build_lcd.tcl: -------------------------------------------------------------------------------- 1 | set_device GW2AR-LV18QN88C8/I7 -name GW2AR-18C 2 | 3 | add_file nanomig.v 4 | add_file minimig-aga/amiga_clk.v 5 | add_file minimig-aga/cpu_wrapper.v 6 | add_file minimig-aga/minimig.v 7 | add_file minimig-aga/ciaa.v 8 | add_file minimig-aga/ciab.v 9 | add_file minimig-aga/cia_int.v 10 | add_file minimig-aga/cia_timera.v 11 | add_file minimig-aga/cia_timerb.v 12 | add_file minimig-aga/cia_timerd.v 13 | add_file minimig-aga/paula.v 14 | add_file minimig-aga/paula_uart.v 15 | add_file minimig-aga/paula_audio_channel.v 16 | add_file minimig-aga/paula_audio_mixer.v 17 | add_file minimig-aga/paula_audio.v 18 | add_file minimig-aga/paula_audio_volume.v 19 | add_file minimig-aga/paula_floppy_fifo.v 20 | add_file minimig-aga/paula_floppy.v 21 | add_file minimig-aga/paula_intcontroller.v 22 | add_file minimig-aga/agnus.v 23 | add_file minimig-aga/agnus_audiodma.v 24 | add_file minimig-aga/agnus_blitter_adrgen.v 25 | add_file minimig-aga/agnus_blitter_minterm.v 26 | add_file minimig-aga/agnus_diskdma.v 27 | add_file minimig-aga/agnus_beamcounter.v 28 | add_file minimig-aga/agnus_blitter_barrelshifter.v 29 | add_file minimig-aga/agnus_blitter.v 30 | add_file minimig-aga/agnus_refresh.v 31 | add_file minimig-aga/agnus_bitplanedma.v 32 | add_file minimig-aga/agnus_blitter_fill.v 33 | add_file minimig-aga/agnus_copper.v 34 | add_file minimig-aga/agnus_spritedma.v 35 | add_file minimig-aga/denise.v 36 | add_file minimig-aga/denise_bitplane_shifter.v 37 | add_file minimig-aga/denise_collision.v 38 | add_file minimig-aga/denise_colortable.v 39 | add_file minimig-aga/denise_playfields.v 40 | add_file minimig-aga/denise_sprites_shifter.v 41 | add_file minimig-aga/denise_bitplanes.v 42 | add_file minimig-aga/denise_hamgenerator.v 43 | add_file minimig-aga/denise_spritepriority.v 44 | add_file minimig-aga/denise_sprites.v 45 | add_file minimig-aga/denise_colortable_ram_mf.v 46 | add_file minimig-aga/gary.v 47 | add_file minimig-aga/gayle.v 48 | add_file minimig-aga/ide.v 49 | add_file minimig-aga/minimig_m68k_bridge.v 50 | add_file minimig-aga/minimig_bankmapper.v 51 | add_file minimig-aga/minimig_sram_bridge.v 52 | add_file minimig-aga/minimig_syscontrol.v 53 | add_file minimig-aga/userio.v 54 | add_file minimig/Amber.v 55 | add_file fx68k/fx68k.sv 56 | add_file fx68k/fx68kAlu.sv 57 | add_file fx68k/uaddrPla.sv 58 | add_file misc/mcu_spi.v 59 | add_file misc/sysctrl.v 60 | add_file misc/hid.v 61 | add_file misc/osd_u8g2.v 62 | add_file misc/ws2812.v 63 | add_file misc/video_analyzer.v 64 | add_file misc/sd_card.v 65 | add_file misc/sd_rw.v 66 | add_file misc/sdcmd_ctrl.v 67 | add_file misc/amiga_keymap.v 68 | add_file tang/nano20k/flash_dspi.v 69 | add_file tang/nano20k/gowin_clkdiv/gowin_clkdiv.v 70 | add_file tang/nano20k/gowin_rpll/pll_142m.v 71 | add_file tang/nano20k/gowin_dpb/sector_dpram.v 72 | add_file tang/nano20k/gowin_dpb/ide_dpram.v 73 | add_file tang/nano20k/top_lcd.sv 74 | add_file tang/nano20k/sdram.v 75 | add_file tang/nano20k/nanomig_lcd.cst 76 | add_file tang/nano20k/nanomig.sdc 77 | add_file fx68k/microrom.mem 78 | add_file fx68k/nanorom.mem 79 | add_file tg68k/TG68K_Pack.vhd 80 | add_file tg68k/TG68K.vhd 81 | add_file tg68k/TG68K_ALU.vhd 82 | add_file tg68k/TG68KdotC_Kernel.vhd 83 | add_file misc/amiga_xml.hex 84 | 85 | set_option -synthesis_tool gowinsynthesis 86 | set_option -output_base_name nanomig_lcd 87 | set_option -verilog_std sysv2017 88 | set_option -top_module top 89 | set_option -use_mspi_as_gpio 1 90 | set_option -use_sspi_as_gpio 1 91 | 92 | run all 93 | -------------------------------------------------------------------------------- /src/build_tc60k.tcl: -------------------------------------------------------------------------------- 1 | set_device GW5AT-LV60PG484AC1/I0 -name GW5AT-60B 2 | 3 | add_file nanomig.v 4 | add_file minimig-aga/amiga_clk.v 5 | add_file minimig-aga/cpu_wrapper.v 6 | add_file minimig-aga/minimig.v 7 | add_file minimig-aga/ciaa.v 8 | add_file minimig-aga/ciab.v 9 | add_file minimig-aga/cia_int.v 10 | add_file minimig-aga/cia_timera.v 11 | add_file minimig-aga/cia_timerb.v 12 | add_file minimig-aga/cia_timerd.v 13 | add_file minimig-aga/paula.v 14 | add_file minimig-aga/paula_uart.v 15 | add_file minimig-aga/paula_audio_channel.v 16 | add_file minimig-aga/paula_audio_mixer.v 17 | add_file minimig-aga/paula_audio.v 18 | add_file minimig-aga/paula_audio_volume.v 19 | add_file minimig-aga/paula_floppy_fifo.v 20 | add_file minimig-aga/paula_floppy.v 21 | add_file minimig-aga/paula_intcontroller.v 22 | add_file minimig-aga/agnus.v 23 | add_file minimig-aga/agnus_audiodma.v 24 | add_file minimig-aga/agnus_blitter_adrgen.v 25 | add_file minimig-aga/agnus_blitter_minterm.v 26 | add_file minimig-aga/agnus_diskdma.v 27 | add_file minimig-aga/agnus_beamcounter.v 28 | add_file minimig-aga/agnus_blitter_barrelshifter.v 29 | add_file minimig-aga/agnus_blitter.v 30 | add_file minimig-aga/agnus_refresh.v 31 | add_file minimig-aga/agnus_bitplanedma.v 32 | add_file minimig-aga/agnus_blitter_fill.v 33 | add_file minimig-aga/agnus_copper.v 34 | add_file minimig-aga/agnus_spritedma.v 35 | add_file minimig-aga/denise.v 36 | add_file minimig-aga/denise_bitplane_shifter.v 37 | add_file minimig-aga/denise_collision.v 38 | add_file minimig-aga/denise_colortable.v 39 | add_file minimig-aga/denise_playfields.v 40 | add_file minimig-aga/denise_sprites_shifter.v 41 | add_file minimig-aga/denise_bitplanes.v 42 | add_file minimig-aga/denise_hamgenerator.v 43 | add_file minimig-aga/denise_spritepriority.v 44 | add_file minimig-aga/denise_sprites.v 45 | add_file minimig-aga/denise_colortable_ram_mf.v 46 | add_file minimig-aga/gary.v 47 | add_file minimig-aga/gayle.v 48 | add_file minimig-aga/ide.v 49 | add_file minimig-aga/minimig_m68k_bridge.v 50 | add_file minimig-aga/minimig_bankmapper.v 51 | add_file minimig-aga/minimig_sram_bridge.v 52 | add_file minimig-aga/minimig_syscontrol.v 53 | add_file minimig-aga/userio.v 54 | add_file minimig/Amber.v 55 | add_file fx68k/fx68k.sv 56 | add_file fx68k/fx68kAlu.sv 57 | add_file fx68k/uaddrPla.sv 58 | add_file hdmi/audio_clock_regeneration_packet.sv 59 | add_file hdmi/audio_info_frame.sv 60 | add_file hdmi/audio_sample_packet.sv 61 | add_file hdmi/auxiliary_video_information_info_frame.sv 62 | add_file hdmi/hdmi.sv 63 | add_file hdmi/packet_assembler.sv 64 | add_file hdmi/packet_picker.sv 65 | add_file hdmi/serializer.sv 66 | add_file hdmi/source_product_description_info_frame.sv 67 | add_file hdmi/tmds_channel.sv 68 | add_file misc/mcu_spi.v 69 | add_file misc/sysctrl.v 70 | add_file misc/hid.v 71 | add_file misc/osd_u8g2.v 72 | add_file misc/video_analyzer.v 73 | add_file misc/sd_card.v 74 | add_file misc/sd_rw.v 75 | add_file misc/sdcmd_ctrl.v 76 | add_file misc/amiga_keymap.v 77 | add_file tang/console60k/flash_dspi.v 78 | add_file tang/console60k/gowin_clkdiv/gowin_clkdiv.v 79 | add_file tang/console60k/gowin_pll/pll_142m.v 80 | add_file tang/console60k/gowin_dpb/sector_dpram.v 81 | add_file tang/console60k/gowin_dpb/ide_dpram.v 82 | add_file tang/console60k/top.sv 83 | add_file tang/console60k/sdram.v 84 | add_file tang/console60k/nanomig.cst 85 | add_file tang/console60k/nanomig.sdc 86 | add_file fx68k/microrom.mem 87 | add_file fx68k/nanorom.mem 88 | add_file tg68k/TG68K_Pack.vhd 89 | add_file tg68k/TG68K.vhd 90 | add_file tg68k/TG68K_ALU.vhd 91 | add_file tg68k/TG68KdotC_Kernel.vhd 92 | add_file misc/amiga_xml.hex 93 | 94 | set_option -synthesis_tool gowinsynthesis 95 | set_option -output_base_name nanomig_tc60k 96 | set_option -verilog_std sysv2017 97 | set_option -top_module top 98 | set_option -use_mspi_as_gpio 1 99 | set_option -use_sspi_as_gpio 1 100 | set_option -use_done_as_gpio 1 101 | set_option -use_i2c_as_gpio 1 102 | set_option -use_cpu_as_gpio 1 103 | set_option -use_ready_as_gpio 1 104 | 105 | run all 106 | -------------------------------------------------------------------------------- /src/build_tm138k.tcl: -------------------------------------------------------------------------------- 1 | set_device GW5AST-LV138FPG676AES -name GW5AST-138B 2 | 3 | add_file nanomig.v 4 | add_file minimig-aga/amiga_clk.v 5 | add_file minimig-aga/cpu_wrapper.v 6 | add_file minimig-aga/minimig.v 7 | add_file minimig-aga/ciaa.v 8 | add_file minimig-aga/ciab.v 9 | add_file minimig-aga/cia_int.v 10 | add_file minimig-aga/cia_timera.v 11 | add_file minimig-aga/cia_timerb.v 12 | add_file minimig-aga/cia_timerd.v 13 | add_file minimig-aga/paula.v 14 | add_file minimig-aga/paula_uart.v 15 | add_file minimig-aga/paula_audio_channel.v 16 | add_file minimig-aga/paula_audio_mixer.v 17 | add_file minimig-aga/paula_audio.v 18 | add_file minimig-aga/paula_audio_volume.v 19 | add_file minimig-aga/paula_floppy_fifo.v 20 | add_file minimig-aga/paula_floppy.v 21 | add_file minimig-aga/paula_intcontroller.v 22 | add_file minimig-aga/agnus.v 23 | add_file minimig-aga/agnus_audiodma.v 24 | add_file minimig-aga/agnus_blitter_adrgen.v 25 | add_file minimig-aga/agnus_blitter_minterm.v 26 | add_file minimig-aga/agnus_diskdma.v 27 | add_file minimig-aga/agnus_beamcounter.v 28 | add_file minimig-aga/agnus_blitter_barrelshifter.v 29 | add_file minimig-aga/agnus_blitter.v 30 | add_file minimig-aga/agnus_refresh.v 31 | add_file minimig-aga/agnus_bitplanedma.v 32 | add_file minimig-aga/agnus_blitter_fill.v 33 | add_file minimig-aga/agnus_copper.v 34 | add_file minimig-aga/agnus_spritedma.v 35 | add_file minimig-aga/denise.v 36 | add_file minimig-aga/denise_bitplane_shifter.v 37 | add_file minimig-aga/denise_collision.v 38 | add_file minimig-aga/denise_colortable.v 39 | add_file minimig-aga/denise_playfields.v 40 | add_file minimig-aga/denise_sprites_shifter.v 41 | add_file minimig-aga/denise_bitplanes.v 42 | add_file minimig-aga/denise_hamgenerator.v 43 | add_file minimig-aga/denise_spritepriority.v 44 | add_file minimig-aga/denise_sprites.v 45 | add_file minimig-aga/denise_colortable_ram_mf.v 46 | add_file minimig-aga/gary.v 47 | add_file minimig-aga/gayle.v 48 | add_file minimig-aga/ide.v 49 | add_file minimig-aga/minimig_m68k_bridge.v 50 | add_file minimig-aga/minimig_bankmapper.v 51 | add_file minimig-aga/minimig_sram_bridge.v 52 | add_file minimig-aga/minimig_syscontrol.v 53 | add_file minimig-aga/userio.v 54 | add_file minimig/Amber.v 55 | add_file fx68k/fx68k.sv 56 | add_file fx68k/fx68kAlu.sv 57 | add_file fx68k/uaddrPla.sv 58 | add_file hdmi/audio_clock_regeneration_packet.sv 59 | add_file hdmi/audio_info_frame.sv 60 | add_file hdmi/audio_sample_packet.sv 61 | add_file hdmi/auxiliary_video_information_info_frame.sv 62 | add_file hdmi/hdmi.sv 63 | add_file hdmi/packet_assembler.sv 64 | add_file hdmi/packet_picker.sv 65 | add_file hdmi/serializer.sv 66 | add_file hdmi/source_product_description_info_frame.sv 67 | add_file hdmi/tmds_channel.sv 68 | add_file misc/mcu_spi.v 69 | add_file misc/sysctrl.v 70 | add_file misc/hid.v 71 | add_file misc/osd_u8g2.v 72 | add_file misc/ws2812.v 73 | add_file misc/video_analyzer.v 74 | add_file misc/sd_card.v 75 | add_file misc/sd_rw.v 76 | add_file misc/sdcmd_ctrl.v 77 | add_file misc/amiga_keymap.v 78 | add_file tang/mega138k/flash_dspi.v 79 | add_file tang/mega138k/gowin_clkdiv/gowin_clkdiv.v 80 | add_file tang/mega138k/gowin_pll/pll_142m.v 81 | add_file tang/mega138k/gowin_dpb/sector_dpram.v 82 | add_file tang/mega138k/gowin_dpb/ide_dpram.v 83 | add_file tang/mega138k/top.sv 84 | add_file tang/mega138k/sdram.v 85 | add_file tang/mega138k/nanomig.cst 86 | add_file tang/mega138k/nanomig.sdc 87 | add_file fx68k/microrom.mem 88 | add_file fx68k/nanorom.mem 89 | add_file tg68k/TG68K_Pack.vhd 90 | add_file tg68k/TG68K.vhd 91 | add_file tg68k/TG68K_ALU.vhd 92 | add_file tg68k/TG68KdotC_Kernel.vhd 93 | add_file misc/amiga_xml.hex 94 | 95 | set_option -synthesis_tool gowinsynthesis 96 | set_option -output_base_name nanomig_tm138k 97 | set_option -verilog_std sysv2017 98 | set_option -top_module top 99 | set_option -use_mspi_as_gpio 1 100 | set_option -use_sspi_as_gpio 1 101 | set_option -use_done_as_gpio 1 102 | set_option -use_cpu_as_gpio 1 103 | set_option -use_ready_as_gpio 1 104 | 105 | run all 106 | -------------------------------------------------------------------------------- /src/build_tp25k.tcl: -------------------------------------------------------------------------------- 1 | set_device GW5A-LV25MG121NC1/I0 -name GW5A-25A 2 | 3 | add_file nanomig.v 4 | add_file minimig-aga/amiga_clk.v 5 | add_file minimig-aga/cpu_wrapper.v 6 | add_file minimig-aga/minimig.v 7 | add_file minimig-aga/ciaa.v 8 | add_file minimig-aga/ciab.v 9 | add_file minimig-aga/cia_int.v 10 | add_file minimig-aga/cia_timera.v 11 | add_file minimig-aga/cia_timerb.v 12 | add_file minimig-aga/cia_timerd.v 13 | add_file minimig-aga/paula.v 14 | add_file minimig-aga/paula_uart.v 15 | add_file minimig-aga/paula_audio_channel.v 16 | add_file minimig-aga/paula_audio_mixer.v 17 | add_file minimig-aga/paula_audio.v 18 | add_file minimig-aga/paula_audio_volume.v 19 | add_file minimig-aga/paula_floppy_fifo.v 20 | add_file minimig-aga/paula_floppy.v 21 | add_file minimig-aga/paula_intcontroller.v 22 | add_file minimig-aga/agnus.v 23 | add_file minimig-aga/agnus_audiodma.v 24 | add_file minimig-aga/agnus_blitter_adrgen.v 25 | add_file minimig-aga/agnus_blitter_minterm.v 26 | add_file minimig-aga/agnus_diskdma.v 27 | add_file minimig-aga/agnus_beamcounter.v 28 | add_file minimig-aga/agnus_blitter_barrelshifter.v 29 | add_file minimig-aga/agnus_blitter.v 30 | add_file minimig-aga/agnus_refresh.v 31 | add_file minimig-aga/agnus_bitplanedma.v 32 | add_file minimig-aga/agnus_blitter_fill.v 33 | add_file minimig-aga/agnus_copper.v 34 | add_file minimig-aga/agnus_spritedma.v 35 | add_file minimig-aga/denise.v 36 | add_file minimig-aga/denise_bitplane_shifter.v 37 | add_file minimig-aga/denise_collision.v 38 | add_file minimig-aga/denise_colortable.v 39 | add_file minimig-aga/denise_playfields.v 40 | add_file minimig-aga/denise_sprites_shifter.v 41 | add_file minimig-aga/denise_bitplanes.v 42 | add_file minimig-aga/denise_hamgenerator.v 43 | add_file minimig-aga/denise_spritepriority.v 44 | add_file minimig-aga/denise_sprites.v 45 | add_file minimig-aga/denise_colortable_ram_mf.v 46 | add_file minimig-aga/gary.v 47 | add_file minimig-aga/gayle.v 48 | add_file minimig-aga/ide.v 49 | add_file minimig-aga/minimig_m68k_bridge.v 50 | add_file minimig-aga/minimig_bankmapper.v 51 | add_file minimig-aga/minimig_sram_bridge.v 52 | add_file minimig-aga/minimig_syscontrol.v 53 | add_file minimig-aga/userio.v 54 | add_file minimig/Amber.v 55 | add_file fx68k/fx68k.sv 56 | add_file fx68k/fx68kAlu.sv 57 | add_file fx68k/uaddrPla.sv 58 | add_file hdmi/audio_clock_regeneration_packet.sv 59 | add_file hdmi/audio_info_frame.sv 60 | add_file hdmi/audio_sample_packet.sv 61 | add_file hdmi/auxiliary_video_information_info_frame.sv 62 | add_file hdmi/hdmi.sv 63 | add_file hdmi/packet_assembler.sv 64 | add_file hdmi/packet_picker.sv 65 | add_file hdmi/serializer.sv 66 | add_file hdmi/source_product_description_info_frame.sv 67 | add_file hdmi/tmds_channel.sv 68 | add_file misc/mcu_spi.v 69 | add_file misc/sysctrl.v 70 | add_file misc/hid.v 71 | add_file misc/osd_u8g2.v 72 | add_file misc/video_analyzer.v 73 | add_file misc/sd_card.v 74 | add_file misc/sd_rw.v 75 | add_file misc/sdcmd_ctrl.v 76 | add_file misc/amiga_keymap.v 77 | add_file tang/primer25k/flash_dspi.v 78 | add_file tang/primer25k/gowin_clkdiv/gowin_clkdiv.v 79 | add_file tang/primer25k/gowin_pll/pll_142m.v 80 | add_file tang/primer25k/gowin_dpb/sector_dpram.v 81 | add_file tang/primer25k/gowin_dpb/ide_dpram.v 82 | add_file tang/primer25k/top.sv 83 | add_file tang/primer25k/sdram.v 84 | add_file tang/primer25k/nanomig.cst 85 | add_file tang/primer25k/nanomig.sdc 86 | add_file fx68k/microrom.mem 87 | add_file fx68k/nanorom.mem 88 | add_file tg68k/TG68K_Pack.vhd 89 | add_file tg68k/TG68K.vhd 90 | add_file tg68k/TG68K_ALU.vhd 91 | add_file tg68k/TG68KdotC_Kernel.vhd 92 | add_file misc/amiga_xml.hex 93 | 94 | set_option -synthesis_tool gowinsynthesis 95 | set_option -output_base_name nanomig_tp25k 96 | set_option -verilog_std sysv2017 97 | set_option -top_module top 98 | set_option -use_mspi_as_gpio 1 99 | set_option -use_sspi_as_gpio 1 100 | set_option -use_done_as_gpio 1 101 | set_option -use_cpu_as_gpio 1 102 | set_option -use_i2c_as_gpio 1 103 | set_option -use_ready_as_gpio 1 104 | 105 | run all 106 | -------------------------------------------------------------------------------- /src/fx68k/README.md: -------------------------------------------------------------------------------- 1 | # fx68k 2 | FX68K 68000 cycle accurate SystemVerilog core 3 | 4 | Copyright (c) 2018 by Jorge Cwik 5 | fx68k@fxatari.com 6 | 7 | FX68K is a 68000 cycle exact compatible core. At least in theory, it should be impossible to distinguish functionally from a real 68K processor. 8 | 9 | On Cyclone families it uses just over 5,100 LEs and about 5KB internal ram, reaching a max effective clock frequency close to 40MHz. Some optimizations are still possible to implement and increase the performance. 10 | 11 | The core is fully synchronous. Considerable effort was made to avoid any asynchronous logic. 12 | 13 | Written in SystemVerilog. 14 | 15 | The timing of the external bus signals is exactly as the original processor. The only feature that is not implemented yet is bus retry using the external HALT input signal. 16 | 17 | It was designed to replace an actual chip on a real board. This wasn't yet tested however and not all necessary output enable control signals are fully implemented. 18 | -------------------------------------------------------------------------------- /src/gw_sh.grc: -------------------------------------------------------------------------------- 1 | # NOTE lines 2 | regexp=^NOTE.* 3 | colour=green 4 | - 5 | # WARNing lines 6 | regexp=^WARN.* 7 | colour=yellow 8 | - 9 | # ERROR lines 10 | regexp=^ERROR.* 11 | colour=red 12 | -------------------------------------------------------------------------------- /src/hdmi/audio_clock_regeneration_packet.sv: -------------------------------------------------------------------------------- 1 | // Implementation of HDMI audio clock regeneration packet 2 | // By Sameer Puri https://github.com/sameer 3 | 4 | // See HDMI 1.4b Section 5.3.3 5 | module audio_clock_regeneration_packet 6 | #( 7 | parameter real VIDEO_RATE = 25.2E6, 8 | parameter int AUDIO_RATE = 48e3 9 | ) 10 | ( 11 | input logic clk_pixel, 12 | input logic clk_audio, 13 | output logic clk_audio_counter_wrap, 14 | output logic [23:0] header, 15 | output logic [55:0] sub [3:0] 16 | ); 17 | 18 | // See Section 7.2.3, values derived from "Other" row in Tables 7-1, 7-2, 7-3. 19 | localparam bit [19:0] N = AUDIO_RATE % 125 == 0 ? 20'(16 * AUDIO_RATE / 125) : AUDIO_RATE % 225 == 0 ? 20'(32 * AUDIO_RATE / 225) : 20'(AUDIO_RATE * 16 / 125); 20 | 21 | localparam int CLK_AUDIO_COUNTER_WIDTH = $clog2(N / 128); 22 | localparam bit [CLK_AUDIO_COUNTER_WIDTH-1:0] CLK_AUDIO_COUNTER_END = CLK_AUDIO_COUNTER_WIDTH'(N / 128 - 1); 23 | logic [CLK_AUDIO_COUNTER_WIDTH-1:0] clk_audio_counter = CLK_AUDIO_COUNTER_WIDTH'(0); 24 | logic internal_clk_audio_counter_wrap = 1'd0; 25 | always_ff @(posedge clk_audio) 26 | begin 27 | if (clk_audio_counter == CLK_AUDIO_COUNTER_END) 28 | begin 29 | clk_audio_counter <= CLK_AUDIO_COUNTER_WIDTH'(0); 30 | internal_clk_audio_counter_wrap <= !internal_clk_audio_counter_wrap; 31 | end 32 | else 33 | clk_audio_counter <= clk_audio_counter + 1'd1; 34 | end 35 | 36 | logic [1:0] clk_audio_counter_wrap_synchronizer_chain = 2'd0; 37 | always_ff @(posedge clk_pixel) 38 | clk_audio_counter_wrap_synchronizer_chain <= {internal_clk_audio_counter_wrap, clk_audio_counter_wrap_synchronizer_chain[1]}; 39 | 40 | localparam bit [19:0] CYCLE_TIME_STAMP_COUNTER_IDEAL = 20'(int'(VIDEO_RATE * int'(N) / 128 / AUDIO_RATE)); 41 | localparam int CYCLE_TIME_STAMP_COUNTER_WIDTH = $clog2(20'(int'(real'(CYCLE_TIME_STAMP_COUNTER_IDEAL) * 1.1))); // Account for 10% deviation in audio clock 42 | 43 | logic [19:0] cycle_time_stamp = 20'd0; 44 | logic [CYCLE_TIME_STAMP_COUNTER_WIDTH-1:0] cycle_time_stamp_counter = CYCLE_TIME_STAMP_COUNTER_WIDTH'(0); 45 | always_ff @(posedge clk_pixel) 46 | begin 47 | if (clk_audio_counter_wrap_synchronizer_chain[1] ^ clk_audio_counter_wrap_synchronizer_chain[0]) 48 | begin 49 | cycle_time_stamp_counter <= CYCLE_TIME_STAMP_COUNTER_WIDTH'(0); 50 | cycle_time_stamp <= {(20-CYCLE_TIME_STAMP_COUNTER_WIDTH)'(0), cycle_time_stamp_counter + CYCLE_TIME_STAMP_COUNTER_WIDTH'(1)}; 51 | clk_audio_counter_wrap <= !clk_audio_counter_wrap; 52 | end 53 | else 54 | cycle_time_stamp_counter <= cycle_time_stamp_counter + CYCLE_TIME_STAMP_COUNTER_WIDTH'(1); 55 | end 56 | 57 | // "An HDMI Sink shall ignore bytes HB1 and HB2 of the Audio Clock Regeneration Packet header." 58 | `ifdef MODEL_TECH 59 | assign header = {8'd0, 8'd0, 8'd1}; 60 | `else 61 | assign header = {8'dX, 8'dX, 8'd1}; 62 | `endif 63 | 64 | // "The four Subpackets each contain the same Audio Clock regeneration Subpacket." 65 | genvar i; 66 | generate 67 | for (i = 0; i < 4; i++) 68 | begin: same_packet 69 | assign sub[i] = {N[7:0], N[15:8], {4'd0, N[19:16]}, cycle_time_stamp[7:0], cycle_time_stamp[15:8], {4'd0, cycle_time_stamp[19:16]}, 8'd0}; 70 | end 71 | endgenerate 72 | 73 | endmodule 74 | -------------------------------------------------------------------------------- /src/hdmi/audio_info_frame.sv: -------------------------------------------------------------------------------- 1 | // Implementation of HDMI audio info frame 2 | // By Sameer Puri https://github.com/sameer 3 | 4 | // See Section 8.2.2 5 | module audio_info_frame 6 | #( 7 | parameter bit [2:0] AUDIO_CHANNEL_COUNT = 3'd1, // 2 channels. See CEA-861-D table 17 for details. 8 | parameter bit [7:0] CHANNEL_ALLOCATION = 8'h00, // Channel 0 = Front Left, Channel 1 = Front Right (0-indexed) 9 | parameter bit DOWN_MIX_INHIBITED = 1'b0, // Permitted or no information about any assertion of this. The DM_INH field is to be set only for DVD-Audio applications. 10 | parameter bit [3:0] LEVEL_SHIFT_VALUE = 4'd0, // 4-bit unsigned number from 0dB up to 15dB, used for downmixing. 11 | parameter bit [1:0] LOW_FREQUENCY_EFFECTS_PLAYBACK_LEVEL = 2'b00 // No information, LFE = bass-only info < 120Hz, used in Dolby Surround. 12 | ) 13 | ( 14 | output logic [23:0] header, 15 | output logic [55:0] sub [3:0] 16 | ); 17 | 18 | // NOTE—HDMI requires the coding type, sample size and sample frequency fields to be set to 0 ("Refer to Stream Header") as these items are carried in the audio stream 19 | localparam bit [3:0] AUDIO_CODING_TYPE = 4'd0; // Refer to stream header. 20 | localparam bit [2:0] SAMPLING_FREQUENCY = 3'd0; // Refer to stream header. 21 | localparam bit [1:0] SAMPLE_SIZE = 2'd0; // Refer to stream header. 22 | 23 | localparam bit [4:0] LENGTH = 5'd10; 24 | localparam bit [7:0] VERSION = 8'd1; 25 | localparam bit [6:0] TYPE = 7'd4; 26 | 27 | assign header = {{3'b0, LENGTH}, VERSION, {1'b1, TYPE}}; 28 | 29 | // PB0-PB6 = sub0 30 | // PB7-13 = sub1 31 | // PB14-20 = sub2 32 | // PB21-27 = sub3 33 | logic [7:0] packet_bytes [27:0]; 34 | 35 | assign packet_bytes[0] = 8'd1 + ~(header[23:16] + header[15:8] + header[7:0] + packet_bytes[5] + packet_bytes[4] + packet_bytes[3] + packet_bytes[2] + packet_bytes[1]); 36 | assign packet_bytes[1] = {AUDIO_CODING_TYPE, 1'b0, AUDIO_CHANNEL_COUNT}; 37 | assign packet_bytes[2] = {3'd0, SAMPLING_FREQUENCY, SAMPLE_SIZE}; 38 | assign packet_bytes[3] = 8'd0; 39 | assign packet_bytes[4] = CHANNEL_ALLOCATION; 40 | assign packet_bytes[5] = {DOWN_MIX_INHIBITED, LEVEL_SHIFT_VALUE, 1'b0, LOW_FREQUENCY_EFFECTS_PLAYBACK_LEVEL}; 41 | 42 | genvar i; 43 | generate 44 | for (i = 6; i < 28; i++) 45 | begin: pb_reserved 46 | assign packet_bytes[i] = 8'd0; 47 | end 48 | for (i = 0; i < 4; i++) 49 | begin: pb_to_sub 50 | assign sub[i] = {packet_bytes[6 + i*7], packet_bytes[5 + i*7], packet_bytes[4 + i*7], packet_bytes[3 + i*7], packet_bytes[2 + i*7], packet_bytes[1 + i*7], packet_bytes[0 + i*7]}; 51 | end 52 | endgenerate 53 | endmodule 54 | -------------------------------------------------------------------------------- /src/hdmi/packet_assembler.sv: -------------------------------------------------------------------------------- 1 | // Implementation of HDMI packet ECC calculation. 2 | // By Sameer Puri https://github.com/sameer 3 | 4 | module packet_assembler ( 5 | input logic clk_pixel, 6 | input logic reset, 7 | input logic data_island_period, 8 | input logic [23:0] header, // See Table 5-8 Packet Types 9 | input logic [55:0] sub [3:0], 10 | output logic [8:0] packet_data, // See Figure 5-4 Data Island Packet and ECC Structure 11 | output logic [4:0] counter 12 | ); 13 | 14 | // 32 pixel wrap-around counter. See Section 5.2.3.4 for further information. 15 | always_ff @(posedge clk_pixel) 16 | begin 17 | if (reset) 18 | counter <= 5'd0; 19 | else if (data_island_period) 20 | counter <= counter + 5'd1; 21 | end 22 | // BCH packets 0 to 3 are transferred two bits at a time, see Section 5.2.3.4 for further information. 23 | wire [5:0] counter_t2 = {counter, 1'b0}; 24 | wire [5:0] counter_t2_p1 = {counter, 1'b1}; 25 | 26 | // Initialize parity bits to 0 27 | logic [7:0] parity [4:0] = '{8'd0, 8'd0, 8'd0, 8'd0, 8'd0}; 28 | 29 | wire [63:0] bch [3:0]; 30 | assign bch[0] = {parity[0], sub[0]}; 31 | assign bch[1] = {parity[1], sub[1]}; 32 | assign bch[2] = {parity[2], sub[2]}; 33 | assign bch[3] = {parity[3], sub[3]}; 34 | wire [31:0] bch4 = {parity[4], header}; 35 | assign packet_data = {bch[3][counter_t2_p1], bch[2][counter_t2_p1], bch[1][counter_t2_p1], bch[0][counter_t2_p1], bch[3][counter_t2], bch[2][counter_t2], bch[1][counter_t2], bch[0][counter_t2], bch4[counter]}; 36 | 37 | // See Figure 5-5 Error Correction Code generator. Generalization of a CRC with binary BCH. 38 | // See https://web.archive.org/web/20190520020602/http://hamsterworks.co.nz/mediawiki/index.php/Minimal_HDMI#Computing_the_ECC for an explanation of the implementation. 39 | // See https://en.wikipedia.org/wiki/BCH_code#Systematic_encoding:_The_message_as_a_prefix for further information. 40 | function automatic [7:0] next_ecc; 41 | input [7:0] ecc, next_bch_bit; 42 | begin 43 | next_ecc = (ecc >> 1) ^ ((ecc[0] ^ next_bch_bit) ? 8'b10000011 : 8'd0); 44 | end 45 | endfunction 46 | 47 | logic [7:0] parity_next [4:0]; 48 | 49 | // The parity needs to be calculated 2 bits at a time for blocks 0 to 3. 50 | // There's 56 bits being sent 2 bits at a time over TMDS channels 1 & 2, so the parity bits wouldn't be ready in time otherwise. 51 | logic [7:0] parity_next_next [3:0]; 52 | 53 | genvar i; 54 | generate 55 | for(i = 0; i < 5; i++) 56 | begin: parity_calc 57 | if (i == 4) 58 | assign parity_next[i] = next_ecc(parity[i], header[counter]); 59 | else 60 | begin 61 | assign parity_next[i] = next_ecc(parity[i], sub[i][counter_t2]); 62 | assign parity_next_next[i] = next_ecc(parity_next[i], sub[i][counter_t2_p1]); 63 | end 64 | end 65 | endgenerate 66 | 67 | always_ff @(posedge clk_pixel) 68 | begin 69 | if (reset) 70 | parity <= '{8'd0, 8'd0, 8'd0, 8'd0, 8'd0}; 71 | else if (data_island_period) 72 | begin 73 | if (counter < 5'd28) // Compute ECC only on subpacket data, not on itself 74 | begin 75 | parity[3:0] <= parity_next_next; 76 | if (counter < 5'd24) // Header only has 24 bits, whereas subpackets have 56 and 56 / 2 = 28. 77 | parity[4] <= parity_next[4]; 78 | end 79 | else if (counter == 5'd31) 80 | parity <= '{8'd0, 8'd0, 8'd0, 8'd0, 8'd0}; // Reset ECC for next packet 81 | end 82 | else 83 | parity <= '{8'd0, 8'd0, 8'd0, 8'd0, 8'd0}; 84 | end 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /src/hdmi/source_product_description_info_frame.sv: -------------------------------------------------------------------------------- 1 | // Implementation of HDMI SPD InfoFrame packet. 2 | // By Sameer Puri https://github.com/sameer 3 | 4 | // See CEA-861-D Section 6.5 page 72 (84 in PDF) 5 | module source_product_description_info_frame 6 | #( 7 | parameter bit [8*8-1:0] VENDOR_NAME = 0, 8 | parameter bit [8*16-1:0] PRODUCT_DESCRIPTION = 0, 9 | parameter bit [7:0] SOURCE_DEVICE_INFORMATION = 0 10 | ) 11 | ( 12 | output logic [23:0] header, 13 | output logic [55:0] sub [3:0] 14 | ); 15 | 16 | localparam bit [4:0] LENGTH = 5'd25; 17 | localparam bit [7:0] VERSION = 8'd1; 18 | localparam bit [6:0] TYPE = 7'd3; 19 | 20 | assign header = {{3'b0, LENGTH}, VERSION, {1'b1, TYPE}}; 21 | 22 | // PB0-PB6 = sub0 23 | // PB7-13 = sub1 24 | // PB14-20 = sub2 25 | // PB21-27 = sub3 26 | logic [7:0] packet_bytes [27:0]; 27 | 28 | assign packet_bytes[0] = 8'd1 + ~(header[23:16] + header[15:8] + header[7:0] + packet_bytes[25] + packet_bytes[24] + packet_bytes[23] + packet_bytes[22] + packet_bytes[21] + packet_bytes[20] + packet_bytes[19] + packet_bytes[18] + packet_bytes[17] + packet_bytes[16] + packet_bytes[15] + packet_bytes[14] + packet_bytes[13] + packet_bytes[12] + packet_bytes[11] + packet_bytes[10] + packet_bytes[9] + packet_bytes[8] + packet_bytes[7] + packet_bytes[6] + packet_bytes[5] + packet_bytes[4] + packet_bytes[3] + packet_bytes[2] + packet_bytes[1]); 29 | 30 | 31 | byte vendor_name [0:7]; 32 | byte product_description [0:15]; 33 | 34 | genvar i; 35 | generate 36 | for (i = 0; i < 8; i++) 37 | begin: vendor_to_bytes 38 | assign vendor_name[i] = VENDOR_NAME[(7-i+1)*8-1:(7-i)*8]; 39 | end 40 | for (i = 0; i < 16; i++) 41 | begin: product_to_bytes 42 | assign product_description[i] = PRODUCT_DESCRIPTION[(15-i+1)*8-1:(15-i)*8]; 43 | end 44 | 45 | for (i = 1; i < 9; i++) 46 | begin: pb_vendor 47 | assign packet_bytes[i] = vendor_name[i - 1] == 8'h30 ? 8'h00 : vendor_name[i - 1]; 48 | end 49 | for (i = 9; i < LENGTH; i++) 50 | begin: pb_product 51 | assign packet_bytes[i] = product_description[i - 9] == 8'h30 ? 8'h00 : product_description[i - 9]; 52 | end 53 | assign packet_bytes[LENGTH] = SOURCE_DEVICE_INFORMATION; 54 | for (i = 26; i < 28; i++) 55 | begin: pb_reserved 56 | assign packet_bytes[i] = 8'd0; 57 | end 58 | for (i = 0; i < 4; i++) 59 | begin: pb_to_sub 60 | assign sub[i] = {packet_bytes[6 + i*7], packet_bytes[5 + i*7], packet_bytes[4 + i*7], packet_bytes[3 + i*7], packet_bytes[2 + i*7], packet_bytes[1 + i*7], packet_bytes[0 + i*7]}; 61 | end 62 | endgenerate 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /src/impl/nanomig_lcd_process_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACKGROUND_PROGRAMMING" : "off", 3 | "COMPRESS" : false, 4 | "CPU" : false, 5 | "CRC_CHECK" : true, 6 | "Clock_Route_Order" : 0, 7 | "Convert_SDP32_36_to_SDP16_18" : true, 8 | "Correct_Hold_Violation" : true, 9 | "DONE" : false, 10 | "DOWNLOAD_SPEED" : "default", 11 | "Disable_Insert_Pad" : false, 12 | "ENABLE_CTP" : false, 13 | "ENABLE_MERGE_MODE" : false, 14 | "ENCRYPTION_KEY" : false, 15 | "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000", 16 | "ERROR_DECTION_AND_CORRECTION" : false, 17 | "ERROR_DECTION_ONLY" : false, 18 | "ERROR_INJECTION" : false, 19 | "EXTERNAL_MASTER_CONFIG_CLOCK" : false, 20 | "Enable_DSRM" : false, 21 | "FORMAT" : "binary", 22 | "FREQUENCY_DIVIDER" : "", 23 | "Generate_Constraint_File_of_Ports" : false, 24 | "Generate_IBIS_File" : false, 25 | "Generate_Plain_Text_Timing_Report" : false, 26 | "Generate_Post_PNR_Simulation_Model_File" : false, 27 | "Generate_Post_Place_File" : false, 28 | "Generate_SDF_File" : false, 29 | "Generate_VHDL_Post_PNR_Simulation_Model_File" : false, 30 | "Global_Freq" : "default", 31 | "GwSyn_Loop_Limit" : 2000, 32 | "HOTBOOT" : false, 33 | "I2C" : false, 34 | "I2C_SLAVE_ADDR" : "00", 35 | "INCREMENTAL_PLACE_AND_ROUTING" : "0", 36 | "INCREMENTAL_PLACE_ONLY" : "0", 37 | "IncludePath" : [ 38 | 39 | ], 40 | "Incremental_Compile" : "", 41 | "Initialize_Primitives" : false, 42 | "JTAG" : false, 43 | "MODE_IO" : false, 44 | "MSPI" : true, 45 | "MSPI_JUMP" : false, 46 | "MULTIBOOT_ADDRESS_WIDTH" : "24", 47 | "MULTIBOOT_MODE" : "Normal", 48 | "MULTIBOOT_SPI_FLASH_ADDRESS" : "00000000", 49 | "MULTIJUMP_ADDRESS_WIDTH" : "24", 50 | "MULTIJUMP_MODE" : "Normal", 51 | "MULTIJUMP_SPI_FLASH_ADDRESS" : "000000", 52 | "Multi_Boot" : true, 53 | "OUTPUT_BASE_NAME" : "nanomig_lcd", 54 | "POWER_ON_RESET_MONITOR" : true, 55 | "PRINT_BSRAM_VALUE" : true, 56 | "PROGRAM_DONE_BYPASS" : false, 57 | "PlaceInRegToIob" : true, 58 | "PlaceIoRegToIob" : true, 59 | "PlaceOutRegToIob" : true, 60 | "Place_Option" : "0", 61 | "Process_Configuration_Verion" : "1.0", 62 | "Promote_Physical_Constraint_Warning_to_Error" : true, 63 | "READY" : false, 64 | "RECONFIG_N" : false, 65 | "Ram_RW_Check" : false, 66 | "Replicate_Resources" : false, 67 | "Report_Auto-Placed_Io_Information" : false, 68 | "Route_Maxfan" : 23, 69 | "Route_Option" : "0", 70 | "Run_Timing_Driven" : true, 71 | "SECURE_MODE" : false, 72 | "SECURITY_BIT" : true, 73 | "SEU_HANDLER" : false, 74 | "SEU_HANDLER_CHECKSUM" : false, 75 | "SEU_HANDLER_MODE" : "auto", 76 | "SSPI" : true, 77 | "STOP_SEU_HANDLER" : false, 78 | "Show_All_Warnings" : false, 79 | "Synthesize_tool" : "GowinSyn", 80 | "TclPre" : "", 81 | "TopModule" : "top", 82 | "USERCODE" : "default", 83 | "Unused_Pin" : "As_input_tri_stated_with_pull_up", 84 | "VCC" : "1.0", 85 | "VCCAUX" : 3.3, 86 | "VCCX" : "3.3", 87 | "VHDL_Standard" : "VHDL_Std_1993", 88 | "Verilog_Standard" : "Vlg_Std_Sysv2017", 89 | "WAKE_UP" : "0", 90 | "show_all_warnings" : false, 91 | "turn_off_bg" : false 92 | } -------------------------------------------------------------------------------- /src/impl/nanomig_process_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACKGROUND_PROGRAMMING" : "off", 3 | "COMPRESS" : false, 4 | "CPU" : false, 5 | "CRC_CHECK" : true, 6 | "Clock_Route_Order" : 0, 7 | "Convert_SDP32_36_to_SDP16_18" : true, 8 | "Correct_Hold_Violation" : true, 9 | "DONE" : false, 10 | "DOWNLOAD_SPEED" : "default", 11 | "Disable_Insert_Pad" : false, 12 | "ENABLE_CTP" : false, 13 | "ENABLE_MERGE_MODE" : false, 14 | "ENCRYPTION_KEY" : false, 15 | "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000", 16 | "ERROR_DECTION_AND_CORRECTION" : false, 17 | "ERROR_DECTION_ONLY" : false, 18 | "ERROR_INJECTION" : false, 19 | "EXTERNAL_MASTER_CONFIG_CLOCK" : false, 20 | "Enable_DSRM" : false, 21 | "FORMAT" : "binary", 22 | "FREQUENCY_DIVIDER" : "1", 23 | "Generate_Constraint_File_of_Ports" : false, 24 | "Generate_IBIS_File" : false, 25 | "Generate_Plain_Text_Timing_Report" : false, 26 | "Generate_Post_PNR_Simulation_Model_File" : false, 27 | "Generate_Post_Place_File" : false, 28 | "Generate_SDF_File" : false, 29 | "Generate_VHDL_Post_PNR_Simulation_Model_File" : false, 30 | "Global_Freq" : "default", 31 | "GwSyn_Loop_Limit" : 2000, 32 | "HOTBOOT" : false, 33 | "I2C" : false, 34 | "I2C_SLAVE_ADDR" : "00", 35 | "INCREMENTAL_PLACE_AND_ROUTING" : "0", 36 | "INCREMENTAL_PLACE_ONLY" : "0", 37 | "IncludePath" : [ 38 | 39 | ], 40 | "Incremental_Compile" : "", 41 | "Initialize_Primitives" : false, 42 | "JTAG" : false, 43 | "MODE_IO" : false, 44 | "MSPI" : true, 45 | "MSPI_JUMP" : false, 46 | "MULTIBOOT_ADDRESS_WIDTH" : "24", 47 | "MULTIBOOT_MODE" : "Normal", 48 | "MULTIBOOT_SPI_FLASH_ADDRESS" : "00000000", 49 | "MULTIJUMP_ADDRESS_WIDTH" : "24", 50 | "MULTIJUMP_MODE" : "Normal", 51 | "MULTIJUMP_SPI_FLASH_ADDRESS" : "000000", 52 | "Multi_Boot" : true, 53 | "OUTPUT_BASE_NAME" : "nanomig", 54 | "POWER_ON_RESET_MONITOR" : true, 55 | "PRINT_BSRAM_VALUE" : true, 56 | "PROGRAM_DONE_BYPASS" : false, 57 | "PlaceInRegToIob" : true, 58 | "PlaceIoRegToIob" : true, 59 | "PlaceOutRegToIob" : true, 60 | "Place_Option" : "0", 61 | "Process_Configuration_Verion" : "1.0", 62 | "Promote_Physical_Constraint_Warning_to_Error" : true, 63 | "READY" : false, 64 | "RECONFIG_N" : false, 65 | "Ram_RW_Check" : false, 66 | "Replicate_Resources" : false, 67 | "Report_Auto-Placed_Io_Information" : false, 68 | "Route_Maxfan" : 23, 69 | "Route_Option" : "0", 70 | "Run_Timing_Driven" : true, 71 | "SECURE_MODE" : false, 72 | "SECURITY_BIT" : true, 73 | "SEU_HANDLER" : false, 74 | "SEU_HANDLER_CHECKSUM" : false, 75 | "SEU_HANDLER_MODE" : "auto", 76 | "SSPI" : true, 77 | "STOP_SEU_HANDLER" : false, 78 | "Show_All_Warnings" : false, 79 | "Synthesize_tool" : "GowinSyn", 80 | "TclPre" : "", 81 | "TopModule" : "top", 82 | "USERCODE" : "default", 83 | "Unused_Pin" : "As_input_tri_stated_with_pull_up", 84 | "VCC" : "1.0", 85 | "VCCAUX" : 3.3, 86 | "VCCX" : "3.3", 87 | "VHDL_Standard" : "VHDL_Std_1993", 88 | "Verilog_Standard" : "Vlg_Std_Sysv2017", 89 | "WAKE_UP" : "0", 90 | "show_all_warnings" : false, 91 | "turn_off_bg" : false 92 | } -------------------------------------------------------------------------------- /src/impl/nanomig_tm138k_process_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACKGROUND_PROGRAMMING" : "off", 3 | "COMPRESS" : false, 4 | "CPU" : true, 5 | "CRC_CHECK" : true, 6 | "Clock_Route_Order" : 0, 7 | "Convert_SDP32_36_to_SDP16_18" : true, 8 | "Correct_Hold_Violation" : true, 9 | "DONE" : true, 10 | "DOWNLOAD_SPEED" : "default", 11 | "Disable_Insert_Pad" : false, 12 | "ENABLE_CTP" : false, 13 | "ENABLE_MERGE_MODE" : false, 14 | "ENCRYPTION_KEY" : false, 15 | "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000", 16 | "ERROR_DECTION_AND_CORRECTION" : false, 17 | "ERROR_DECTION_ONLY" : false, 18 | "ERROR_INJECTION" : false, 19 | "EXTERNAL_MASTER_CONFIG_CLOCK" : false, 20 | "Enable_DSRM" : false, 21 | "FORMAT" : "binary", 22 | "FREQUENCY_DIVIDER" : "1", 23 | "Generate_Constraint_File_of_Ports" : false, 24 | "Generate_IBIS_File" : false, 25 | "Generate_Plain_Text_Timing_Report" : false, 26 | "Generate_Post_PNR_Simulation_Model_File" : false, 27 | "Generate_Post_Place_File" : false, 28 | "Generate_SDF_File" : false, 29 | "Generate_VHDL_Post_PNR_Simulation_Model_File" : false, 30 | "Global_Freq" : "default", 31 | "GwSyn_Loop_Limit" : 2000, 32 | "HOTBOOT" : false, 33 | "I2C" : false, 34 | "I2C_SLAVE_ADDR" : "00", 35 | "INCREMENTAL_PLACE_AND_ROUTING" : "0", 36 | "INCREMENTAL_PLACE_ONLY" : "0", 37 | "IncludePath" : [ 38 | 39 | ], 40 | "Incremental_Compile" : "", 41 | "Initialize_Primitives" : false, 42 | "JTAG" : false, 43 | "MODE_IO" : false, 44 | "MSPI" : true, 45 | "MSPI_JUMP" : false, 46 | "MULTIBOOT_ADDRESS_WIDTH" : "24", 47 | "MULTIBOOT_MODE" : "Normal", 48 | "MULTIBOOT_SPI_FLASH_ADDRESS" : "000000", 49 | "MULTIJUMP_ADDRESS_WIDTH" : "24", 50 | "MULTIJUMP_MODE" : "Normal", 51 | "MULTIJUMP_SPI_FLASH_ADDRESS" : "000000", 52 | "Multi_Boot" : false, 53 | "OUTPUT_BASE_NAME" : "nanomig_tm138k", 54 | "POWER_ON_RESET_MONITOR" : true, 55 | "PRINT_BSRAM_VALUE" : true, 56 | "PROGRAM_DONE_BYPASS" : false, 57 | "PlaceInRegToIob" : false, 58 | "PlaceIoRegToIob" : false, 59 | "PlaceOutRegToIob" : false, 60 | "Place_Option" : "3", 61 | "Process_Configuration_Verion" : "1.0", 62 | "Promote_Physical_Constraint_Warning_to_Error" : true, 63 | "READY" : true, 64 | "RECONFIG_N" : false, 65 | "Ram_RW_Check" : false, 66 | "Replicate_Resources" : false, 67 | "Report_Auto-Placed_Io_Information" : false, 68 | "Route_Maxfan" : 23, 69 | "Route_Option" : "2", 70 | "Run_Timing_Driven" : true, 71 | "SECURE_MODE" : false, 72 | "SECURITY_BIT" : true, 73 | "SEU_HANDLER" : false, 74 | "SEU_HANDLER_CHECKSUM" : false, 75 | "SEU_HANDLER_MODE" : "auto", 76 | "SSPI" : true, 77 | "STOP_SEU_HANDLER" : false, 78 | "Show_All_Warnings" : false, 79 | "Synthesize_tool" : "GowinSyn", 80 | "TclPre" : "", 81 | "TopModule" : "top", 82 | "USERCODE" : "default", 83 | "Unused_Pin" : "As_input_tri_stated_with_pull_up", 84 | "VCC" : "0.9", 85 | "VCCAUX" : "3.3", 86 | "VCCX" : "1.8", 87 | "VHDL_Standard" : "VHDL_Std_1993", 88 | "Verilog_Standard" : "Vlg_Std_Sysv2017", 89 | "WAKE_UP" : "0", 90 | "show_all_warnings" : false, 91 | "turn_off_bg" : false 92 | } -------------------------------------------------------------------------------- /src/impl/nanomig_tp25k_process_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACKGROUND_PROGRAMMING" : "off", 3 | "COMPRESS" : false, 4 | "CPU" : true, 5 | "CRC_CHECK" : true, 6 | "Clock_Route_Order" : 0, 7 | "Convert_SDP32_36_to_SDP16_18" : true, 8 | "Correct_Hold_Violation" : true, 9 | "DONE" : true, 10 | "DOWNLOAD_SPEED" : "default", 11 | "Disable_Insert_Pad" : false, 12 | "ENABLE_CTP" : false, 13 | "ENABLE_MERGE_MODE" : false, 14 | "ENCRYPTION_KEY" : false, 15 | "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000", 16 | "ERROR_DECTION_AND_CORRECTION" : false, 17 | "ERROR_DECTION_ONLY" : false, 18 | "ERROR_INJECTION" : false, 19 | "EXTERNAL_MASTER_CONFIG_CLOCK" : false, 20 | "Enable_DSRM" : false, 21 | "FORMAT" : "binary", 22 | "FREQUENCY_DIVIDER" : "1", 23 | "Generate_Constraint_File_of_Ports" : false, 24 | "Generate_IBIS_File" : false, 25 | "Generate_Plain_Text_Timing_Report" : false, 26 | "Generate_Post_PNR_Simulation_Model_File" : false, 27 | "Generate_Post_Place_File" : false, 28 | "Generate_SDF_File" : false, 29 | "Generate_VHDL_Post_PNR_Simulation_Model_File" : false, 30 | "Global_Freq" : "default", 31 | "GwSyn_Loop_Limit" : 2000, 32 | "HOTBOOT" : false, 33 | "I2C" : true, 34 | "I2C_SLAVE_ADDR" : "00", 35 | "INCREMENTAL_PLACE_AND_ROUTING" : "0", 36 | "INCREMENTAL_PLACE_ONLY" : "0", 37 | "IncludePath" : [ 38 | 39 | ], 40 | "Incremental_Compile" : "", 41 | "Initialize_Primitives" : false, 42 | "JTAG" : false, 43 | "MODE_IO" : false, 44 | "MSPI" : true, 45 | "MSPI_JUMP" : false, 46 | "MULTIBOOT_ADDRESS_WIDTH" : "24", 47 | "MULTIBOOT_MODE" : "Normal", 48 | "MULTIBOOT_SPI_FLASH_ADDRESS" : "000000", 49 | "MULTIJUMP_ADDRESS_WIDTH" : "24", 50 | "MULTIJUMP_MODE" : "Normal", 51 | "MULTIJUMP_SPI_FLASH_ADDRESS" : "000000", 52 | "Multi_Boot" : false, 53 | "OUTPUT_BASE_NAME" : "nanomig_tp25k", 54 | "POWER_ON_RESET_MONITOR" : true, 55 | "PRINT_BSRAM_VALUE" : true, 56 | "PROGRAM_DONE_BYPASS" : false, 57 | "PlaceInRegToIob" : false, 58 | "PlaceIoRegToIob" : false, 59 | "PlaceOutRegToIob" : false, 60 | "Place_Option" : "3", 61 | "Process_Configuration_Verion" : "1.0", 62 | "Promote_Physical_Constraint_Warning_to_Error" : true, 63 | "READY" : true, 64 | "RECONFIG_N" : false, 65 | "Ram_RW_Check" : false, 66 | "Replicate_Resources" : false, 67 | "Report_Auto-Placed_Io_Information" : false, 68 | "Route_Maxfan" : 23, 69 | "Route_Option" : "2", 70 | "Run_Timing_Driven" : true, 71 | "SECURE_MODE" : false, 72 | "SECURITY_BIT" : true, 73 | "SEU_HANDLER" : false, 74 | "SEU_HANDLER_CHECKSUM" : false, 75 | "SEU_HANDLER_MODE" : "auto", 76 | "SSPI" : true, 77 | "STOP_SEU_HANDLER" : false, 78 | "Show_All_Warnings" : false, 79 | "Synthesize_tool" : "GowinSyn", 80 | "TclPre" : "", 81 | "TopModule" : "top", 82 | "USERCODE" : "default", 83 | "Unused_Pin" : "As_input_tri_stated_with_pull_up", 84 | "VCC" : "0.9", 85 | "VCCAUX" : "3.3", 86 | "VCCX" : "", 87 | "VHDL_Standard" : "VHDL_Std_1993", 88 | "Verilog_Standard" : "Vlg_Std_Sysv2017", 89 | "WAKE_UP" : "0", 90 | "show_all_warnings" : false, 91 | "turn_off_bg" : false 92 | } -------------------------------------------------------------------------------- /src/minimig-aga/agnus_blitter_adrgen.v: -------------------------------------------------------------------------------- 1 | // Blitter address generator 2 | // It can increment or decrement selected pointer register or add or substract any selected modulo register 3 | 4 | module agnus_blitter_adrgen 5 | ( 6 | input clk, // bus clock 7 | input clk7_en, 8 | input reset, // reset 9 | input [1:0] ptrsel, // pointer register selection 10 | input [1:0] modsel, // modulo register selection 11 | input enaptr, // enable pointer selection and update 12 | input incptr, // increase selected pointer register 13 | input decptr, // decrease selected pointer register 14 | input addmod, // add selected modulo register to selected pointer register 15 | input submod, // substract selected modulo register from selected pointer register 16 | output sign_out, // sign output (used for line mode) 17 | input [15:0] data_in, // bus data in 18 | input [8:1] reg_address_in, // register address input 19 | output [20:1] address_out // generated address out 20 | ); 21 | 22 | //register names and addresses 23 | parameter BLTAMOD = 9'h064; 24 | parameter BLTBMOD = 9'h062; 25 | parameter BLTCMOD = 9'h060; 26 | parameter BLTDMOD = 9'h066; 27 | parameter BLTAPTH = 9'h050; 28 | parameter BLTAPTL = 9'h052; 29 | parameter BLTBPTH = 9'h04c; 30 | parameter BLTBPTL = 9'h04e; 31 | parameter BLTCPTH = 9'h048; 32 | parameter BLTCPTL = 9'h04a; 33 | parameter BLTDPTH = 9'h054; 34 | parameter BLTDPTL = 9'h056; 35 | 36 | //channel select codes 37 | parameter CHA = 2'b10; // channel A 38 | parameter CHB = 2'b01; // channel B 39 | parameter CHC = 2'b00; // channel C 40 | parameter CHD = 2'b11; // channel D 41 | 42 | //local signals 43 | wire [1:0] bltptr_sel; // blitter pointer select 44 | wire [20:1] bltptr_in; // blitter pointer registers input 45 | reg [20:16] bltpth [3:0]; // blitter pointer register bank (high) 46 | wire [20:16] bltpth_out; // blitter pointer register bank output (high) 47 | reg [15:1] bltptl [3:0]; // blitter pointer register bank (low) 48 | wire [15:1] bltptl_out; // blitter pointer register bank output (low) 49 | wire [20:1] bltptr_out; // blitter pointer register bank output 50 | 51 | wire [1:0] bltmod_sel; // blitter modulo register select 52 | reg [15:1] bltmod [3:0]; // blitter modulo register bank 53 | wire [15:1] bltmod_out; // blitter modulo register bank output 54 | 55 | reg [20:1] newptr; // new pointer value 56 | reg [20:1] t_newptr; // temporary pointer value 57 | 58 | //-------------------------------------------------------------------------------------- 59 | 60 | //pointer register bank 61 | 62 | assign bltptr_in[20:1] = enaptr ? newptr[20:1] : {data_in[4:0], data_in[15:1]}; 63 | 64 | assign bltptr_sel = enaptr ? ptrsel : {reg_address_in[4],reg_address_in[2]}; 65 | 66 | always @(posedge clk) 67 | if (clk7_en) begin 68 | if (enaptr || reg_address_in[8:1]==BLTAPTH[8:1] || reg_address_in[8:1]==BLTBPTH[8:1] || reg_address_in[8:1]==BLTCPTH[8:1] || reg_address_in[8:1]==BLTDPTH[8:1]) 69 | bltpth[bltptr_sel] <= bltptr_in[20:16]; 70 | end 71 | 72 | assign bltpth_out = bltpth[bltptr_sel]; 73 | 74 | always @(posedge clk) 75 | if (clk7_en) begin 76 | if (enaptr || reg_address_in[8:1]==BLTAPTL[8:1] || reg_address_in[8:1]==BLTBPTL[8:1] || reg_address_in[8:1]==BLTCPTL[8:1] || reg_address_in[8:1]==BLTDPTL[8:1]) 77 | bltptl[bltptr_sel] <= bltptr_in[15:1]; 78 | end 79 | 80 | assign bltptl_out = bltptl[bltptr_sel]; 81 | 82 | assign bltptr_out = {bltpth_out, bltptl_out}; 83 | 84 | assign address_out = bltptr_out; 85 | 86 | //-------------------------------------------------------------------------------------- 87 | 88 | //modulo register bank 89 | 90 | assign bltmod_sel = enaptr ? modsel : reg_address_in[2:1]; 91 | 92 | always @(posedge clk) 93 | if (clk7_en) begin 94 | if (reg_address_in[8:3]==BLTAMOD[8:3]) 95 | bltmod[bltmod_sel] <= data_in[15:1]; 96 | end 97 | assign bltmod_out = bltmod[modsel]; 98 | 99 | //-------------------------------------------------------------------------------------- 100 | 101 | // pointer arithmetic unit 102 | 103 | // increment or decrement selected pointer 104 | always @(*) 105 | if (incptr && !decptr) 106 | t_newptr = bltptr_out + 20'h1; // increment selected pointer 107 | else if (!incptr && decptr) 108 | t_newptr = bltptr_out - 20'h1; // decrement selected pointer 109 | else 110 | t_newptr = bltptr_out; 111 | 112 | // add or substract modulo 113 | always @(*) 114 | if (addmod && !submod) 115 | newptr = t_newptr + {{5{bltmod_out[15]}},bltmod_out[15:1]}; // add modulo (sign extended) 116 | else if (!addmod && submod) 117 | newptr = t_newptr - {{5{bltmod_out[15]}},bltmod_out[15:1]}; // substract modulo (sign extended) 118 | else 119 | newptr = t_newptr; 120 | 121 | //sign output 122 | assign sign_out = newptr[15]; // used in line mode as the sign of Bresenham's error accumulator (channel A pointer acts as an accumulator) 123 | 124 | 125 | endmodule 126 | 127 | -------------------------------------------------------------------------------- /src/minimig-aga/agnus_blitter_barrelshifter.v: -------------------------------------------------------------------------------- 1 | //Blitter barrel shifter 2 | //This module can shift 0-15 positions to the right (normal mode) or to the left (descending mode). 3 | //Multipliers are used to save logic. 4 | 5 | 6 | module agnus_blitter_barrelshifter 7 | ( 8 | input desc, // select descending mode (shift to the left) 9 | input [3:0] shift, // shift value (0 to 15) 10 | input [15:0] new_val, // barrel shifter data in 11 | input [15:0] old_val, // barrel shifter data in 12 | output [15:0] out // barrel shifter data out 13 | ); 14 | 15 | wire [35:0] shifted_new; // shifted new data 16 | wire [35:0] shifted_old; // shifted old data 17 | reg [17:0] shift_onehot; // one-hot shift value for multipliers 18 | 19 | //one-hot shift value encoding 20 | always @(desc or shift) 21 | case ({desc,shift[3:0]}) 22 | 5'h00 : shift_onehot = 18'h10000; 23 | 5'h01 : shift_onehot = 18'h08000; 24 | 5'h02 : shift_onehot = 18'h04000; 25 | 5'h03 : shift_onehot = 18'h02000; 26 | 5'h04 : shift_onehot = 18'h01000; 27 | 5'h05 : shift_onehot = 18'h00800; 28 | 5'h06 : shift_onehot = 18'h00400; 29 | 5'h07 : shift_onehot = 18'h00200; 30 | 5'h08 : shift_onehot = 18'h00100; 31 | 5'h09 : shift_onehot = 18'h00080; 32 | 5'h0A : shift_onehot = 18'h00040; 33 | 5'h0B : shift_onehot = 18'h00020; 34 | 5'h0C : shift_onehot = 18'h00010; 35 | 5'h0D : shift_onehot = 18'h00008; 36 | 5'h0E : shift_onehot = 18'h00004; 37 | 5'h0F : shift_onehot = 18'h00002; 38 | 5'h10 : shift_onehot = 18'h00001; 39 | 5'h11 : shift_onehot = 18'h00002; 40 | 5'h12 : shift_onehot = 18'h00004; 41 | 5'h13 : shift_onehot = 18'h00008; 42 | 5'h14 : shift_onehot = 18'h00010; 43 | 5'h15 : shift_onehot = 18'h00020; 44 | 5'h16 : shift_onehot = 18'h00040; 45 | 5'h17 : shift_onehot = 18'h00080; 46 | 5'h18 : shift_onehot = 18'h00100; 47 | 5'h19 : shift_onehot = 18'h00200; 48 | 5'h1A : shift_onehot = 18'h00400; 49 | 5'h1B : shift_onehot = 18'h00800; 50 | 5'h1C : shift_onehot = 18'h01000; 51 | 5'h1D : shift_onehot = 18'h02000; 52 | 5'h1E : shift_onehot = 18'h04000; 53 | 5'h1F : shift_onehot = 18'h08000; 54 | endcase 55 | 56 | /* 57 | MULT18X18 multiplier_1 58 | ( 59 | .dataa({2'b00,new_val[15:0]}), // 18-bit multiplier input 60 | .datab(shift_onehot), // 18-bit multiplier input 61 | .result(shifted_new) // 36-bit multiplier output 62 | ); 63 | */ 64 | assign shifted_new = ({2'b00,new_val[15:0]})*shift_onehot; 65 | 66 | /* 67 | MULT18X18 multiplier_2 68 | ( 69 | .dataa({2'b00,old_val[15:0]}), // 18-bit multiplier input 70 | .datab(shift_onehot), // 18-bit multiplier input 71 | .result(shifted_old) // 36-bit multiplier output 72 | ); 73 | */ 74 | assign shifted_old = ({2'b00,old_val[15:0]})*shift_onehot; 75 | 76 | assign out = desc ? shifted_new[15:0] | shifted_old[31:16] : shifted_new[31:16] | shifted_old[15:0]; 77 | 78 | 79 | endmodule 80 | 81 | -------------------------------------------------------------------------------- /src/minimig-aga/agnus_blitter_fill.v: -------------------------------------------------------------------------------- 1 | //Blitter fill logic 2 | //The fill logic module has 2 modes,inclusive fill and exclusive fill. 3 | //Both share the same xor operation but in inclusive fill mode, 4 | //the output of the xor-filler is or-ed with the input data. 5 | 6 | 7 | module agnus_blitter_fill 8 | ( 9 | input ife, //inclusive fill enable 10 | input efe, //exclusive fill enable 11 | input fci, //fill carry input 12 | output fco, //fill carry output 13 | input [15:0]in, //data in 14 | output reg [15:0]out //data out 15 | ); 16 | 17 | //local signals 18 | reg [15:0]carry; 19 | 20 | //generate all fill carry's 21 | integer j; 22 | always @(fci or in[0])//least significant bit 23 | carry[0] = fci ^ in[0]; 24 | always @(in or carry)//rest of bits 25 | for (j=1;j<=15;j=j+1) 26 | carry[j] = carry[j-1] ^ in[j]; 27 | 28 | //fill carry output 29 | assign fco = carry[15]; 30 | 31 | //fill data output 32 | always @(ife or efe or carry or in) 33 | if (efe)//exclusive fill 34 | out[15:0] = carry[15:0]; 35 | else if (ife)//inclusive fill 36 | out[15:0] = carry[15:0] | in[15:0]; 37 | else//bypass,no filling 38 | out[15:0] = in[15:0]; 39 | 40 | 41 | endmodule 42 | 43 | -------------------------------------------------------------------------------- /src/minimig-aga/agnus_blitter_minterm.v: -------------------------------------------------------------------------------- 1 | //Blitter minterm function generator 2 | //The minterm function generator takes , and 3 | //and checks every logic combination against the LF control byte. 4 | //If a combination is marked as 1 in the LF byte,the ouput will 5 | //also be 1,else the output is 0. 6 | 7 | module agnus_blitter_minterm 8 | ( 9 | input [7:0] lf, //LF control byte 10 | input [15:0] ain, //A channel in 11 | input [15:0] bin, //B channel in 12 | input [15:0] cin, //C channel in 13 | output [15:0] out //function generator output 14 | ); 15 | 16 | reg [15:0] mt0; //minterm 0 17 | reg [15:0] mt1; //minterm 1 18 | reg [15:0] mt2; //minterm 2 19 | reg [15:0] mt3; //minterm 3 20 | reg [15:0] mt4; //minterm 4 21 | reg [15:0] mt5; //minterm 5 22 | reg [15:0] mt6; //minterm 6 23 | reg [15:0] mt7; //minterm 7 24 | 25 | //Minterm generator for each bit. The code inside the loop 26 | //describes one bit. The loop is 'unrolled' by the 27 | //synthesizer to cover all 16 bits in the word. 28 | integer j; 29 | always @(ain or bin or cin or lf) 30 | for (j=15; j>=0; j=j-1) 31 | begin 32 | mt0[j] = ~ain[j] & ~bin[j] & ~cin[j] & lf[0]; 33 | mt1[j] = ~ain[j] & ~bin[j] & cin[j] & lf[1]; 34 | mt2[j] = ~ain[j] & bin[j] & ~cin[j] & lf[2]; 35 | mt3[j] = ~ain[j] & bin[j] & cin[j] & lf[3]; 36 | mt4[j] = ain[j] & ~bin[j] & ~cin[j] & lf[4]; 37 | mt5[j] = ain[j] & ~bin[j] & cin[j] & lf[5]; 38 | mt6[j] = ain[j] & bin[j] & ~cin[j] & lf[6]; 39 | mt7[j] = ain[j] & bin[j] & cin[j] & lf[7]; 40 | end 41 | 42 | //Generate function generator output by or-ing all 43 | //minterms together. 44 | assign out = mt0 | mt1 | mt2 | mt3 | mt4 | mt5 | mt6 | mt7; 45 | 46 | 47 | endmodule 48 | 49 | -------------------------------------------------------------------------------- /src/minimig-aga/agnus_diskdma.v: -------------------------------------------------------------------------------- 1 | //disk dma engine 2 | //DMA cycle allocation is as specified in the HRM 3 | //optionally 4 refresh slots are used for higher transfer speed 4 | 5 | module agnus_diskdma 6 | ( 7 | input clk, //bus clock 8 | input clk7_en, 9 | output dma, //true if disk dma engine uses it's cycle 10 | input dmal, //Paula requests dma 11 | input dmas, //Paula special dma 12 | input speed, 13 | input [8:0] hpos, //horizontal beam counter (advanced by 4 CCKs) 14 | output wr, //write (disk dma writes to memory) 15 | input [8:1] reg_address_in, //register address inputs 16 | output [8:1] reg_address_out, //register address outputs 17 | input [15:0] data_in, //bus data in 18 | output reg [20:1] address_out //chip address out current disk dma pointer 19 | ); 20 | //register names and adresses 21 | parameter DSKPTH = 9'h020; 22 | parameter DSKPTL = 9'h022; 23 | parameter DSKDAT = 9'h026; 24 | parameter DSKDATR = 9'h008; 25 | 26 | //local signals 27 | wire [20:1] address_outnew; //new disk dma pointer 28 | reg dmaslot; //indicates if the current slot can be used to transfer data 29 | 30 | //-------------------------------------------------------------------------------------- 31 | 32 | //dma cycle allocation 33 | //nominally disk DMA uses 3 slots: 08, 0A and 0C 34 | //refresh slots: 00, 02, 04 and 06 are used for higher transfer speed 35 | //hint: Agnus hpos counter is advanced by 4 CCK cycles 36 | always @(*) 37 | case (hpos[8:1]) 38 | 8'h04: dmaslot = speed; 39 | 8'h06: dmaslot = speed; 40 | 8'h08: dmaslot = speed; 41 | 8'h0A: dmaslot = speed; 42 | 8'h0C: dmaslot = 1; 43 | 8'h0E: dmaslot = 1; 44 | 8'h10: dmaslot = 1; 45 | default: dmaslot = 0; 46 | endcase 47 | 48 | //dma request 49 | assign dma = dmal & dmaslot & hpos[0]; 50 | //write signal 51 | assign wr = ~dmas; 52 | 53 | //-------------------------------------------------------------------------------------- 54 | 55 | //address_out input multiplexer and ALU 56 | assign address_outnew[20:1] = dma ? address_out[20:1]+1'b1 : {data_in[4:0],data_in[15:1]}; 57 | 58 | //disk pointer control 59 | always @(posedge clk) 60 | if (clk7_en) begin 61 | if (dma || (reg_address_in[8:1] == DSKPTH[8:1])) 62 | address_out[20:16] <= address_outnew[20:16];//high 5 bits 63 | end 64 | 65 | always @(posedge clk) 66 | if (clk7_en) begin 67 | if (dma || (reg_address_in[8:1] == DSKPTL[8:1])) 68 | address_out[15:1] <= address_outnew[15:1];//low 15 bits 69 | end 70 | 71 | //-------------------------------------------------------------------------------------- 72 | 73 | //register address output 74 | assign reg_address_out[8:1] = wr ? DSKDATR[8:1] : DSKDAT[8:1]; 75 | 76 | //-------------------------------------------------------------------------------------- 77 | 78 | 79 | endmodule 80 | 81 | -------------------------------------------------------------------------------- /src/minimig-aga/agnus_refresh.v: -------------------------------------------------------------------------------- 1 | // refresh dma channel (for compatibility) 2 | 3 | 4 | module agnus_refresh 5 | ( 6 | input [8:0] hpos, 7 | output reg dma 8 | ); 9 | 10 | //dma request 11 | always @(hpos) 12 | case (hpos) 13 | 9'b0000_0100_1 : dma = 1'b1; 14 | 9'b0000_0110_1 : dma = 1'b1; 15 | 9'b0000_1000_1 : dma = 1'b1; 16 | 9'b0000_1010_1 : dma = 1'b1; 17 | default : dma = 1'b0; 18 | endcase 19 | 20 | 21 | endmodule 22 | 23 | -------------------------------------------------------------------------------- /src/minimig-aga/amiga_clk.v: -------------------------------------------------------------------------------- 1 | /* amiga_clk.v */ 2 | /* 2012, rok.krajnc@gmail.com */ 3 | 4 | module amiga_clk 5 | ( 6 | input clk_28, // 28MHz output clock ( 28.375160MHz) 7 | output clk7_en, // 7MHz output clock enable (on 28MHz clock domain) 8 | output clk7n_en, // 7MHz negedge output clock enable (on 28MHz clock domain) 9 | output reg c1, // clk28m clock domain signal synchronous with clk signal 10 | output reg c3, // clk28m clock domain signal synchronous with clk signal delayed by 90 degrees 11 | output reg cck, // colour clock output (3.54 MHz) 12 | output [9:0] eclk, // 0.709379 MHz clock enable output (clk domain pulse) 13 | input reset_n 14 | ); 15 | 16 | //// generated clocks //// 17 | 18 | // 7MHz 19 | reg [1:0] clk7_cnt = 2'b10; 20 | reg clk7_en_reg = 1'b1; 21 | reg clk7n_en_reg = 1'b1; 22 | reg [9:0] shifter; 23 | always @ (posedge clk_28, negedge reset_n) begin 24 | if (!reset_n) begin 25 | clk7_cnt <= 2'b10; 26 | clk7_en_reg <= 1'b1; 27 | clk7n_en_reg <= 1'b1; 28 | cck <= 1; 29 | shifter <= 1; 30 | end else begin 31 | clk7_cnt <= clk7_cnt + 2'b01; 32 | clk7_en_reg <= (clk7_cnt == 2'b00); 33 | clk7n_en_reg <= (clk7_cnt == 2'b10); 34 | if(clk7_cnt == 2'b01) begin 35 | cck <= ~cck; 36 | shifter <= {shifter[8:0],shifter[9]}; 37 | if(!shifter) shifter <= 1; 38 | end 39 | end 40 | end 41 | 42 | wire clk_7 = clk7_cnt[1]; 43 | assign clk7_en = clk7_en_reg; 44 | assign clk7n_en = clk7n_en_reg; 45 | 46 | // amiga clocks & clock enables 47 | // __ __ __ __ __ 48 | // clk_28 __/ \__/ \__/ \__/ \__/ 49 | // ___________ __ 50 | // clk_7 __/ \___________/ 51 | // ___________ __ 52 | // c1 __/ \___________/ <- clk28m domain 53 | // ___________ 54 | // c3 ________/ \________ <- clk28m domain 55 | // 56 | 57 | // clk_28 clock domain signal synchronous with clk signal delayed by 90 degrees 58 | always @(posedge clk_28) c3 <= clk_7; 59 | 60 | // clk28m clock domain signal synchronous with clk signal 61 | always @(posedge clk_28) c1 <= ~c3; 62 | 63 | // 0.709379 MHz clock enable output (clk domain pulse) 64 | assign eclk = shifter; 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /src/minimig-aga/cia_int.v: -------------------------------------------------------------------------------- 1 | module cia_int 2 | ( 3 | input clk, // clock 4 | input clk7_en, 5 | input wr, // write enable 6 | input reset, // reset 7 | input icrs, // intterupt control register select 8 | input ta, // ta (set TA bit in ICR register) 9 | input tb, // tb (set TB bit in ICR register) 10 | input alrm, // alrm (set ALRM bit ICR register) 11 | input flag, // flag (set FLG bit in ICR register) 12 | input ser, // ser (set SP bit in ICR register) 13 | input [7:0] data_in, // bus data in 14 | output [7:0] data_out, // bus data out 15 | output irq // intterupt out 16 | ); 17 | 18 | reg [4:0] icr = 5'd0; // interrupt register 19 | reg [4:0] icrmask = 5'd0; // interrupt mask register 20 | 21 | // reading of interrupt data register 22 | assign data_out[7:0] = icrs && !wr ? {irq,2'b00,icr[4:0]} : 8'b0000_0000; 23 | 24 | // writing of interrupt mask register 25 | always @(posedge clk) 26 | if (clk7_en) begin 27 | if (reset) 28 | icrmask[4:0] <= 5'b0_0000; 29 | else if (icrs && wr) 30 | begin 31 | if (data_in[7]) 32 | icrmask[4:0] <= icrmask[4:0] | data_in[4:0]; 33 | else 34 | icrmask[4:0] <= icrmask[4:0] & (~data_in[4:0]); 35 | end 36 | end 37 | 38 | // register new interrupts and/or changes by user reads 39 | always @(posedge clk) 40 | if (clk7_en) begin 41 | if (reset)// synchronous reset 42 | icr[4:0] <= 5'b0_0000; 43 | else if (icrs && !wr) 44 | begin// clear latched intterupts on read 45 | icr[0] <= ta; // timer a 46 | icr[1] <= tb; // timer b 47 | icr[2] <= alrm; // timer tod 48 | icr[3] <= ser; // external ser input 49 | icr[4] <= flag; // external flag input 50 | end 51 | else 52 | begin// keep latched intterupts 53 | icr[0] <= icr[0] | ta; // timer a 54 | icr[1] <= icr[1] | tb; // timer b 55 | icr[2] <= icr[2] | alrm; // timer tod 56 | icr[3] <= icr[3] | ser; // external ser input 57 | icr[4] <= icr[4] | flag; // external flag input 58 | end 59 | end 60 | 61 | // generate irq output (interrupt request) 62 | assign irq = (icrmask[0] & icr[0]) 63 | | (icrmask[1] & icr[1]) 64 | | (icrmask[2] & icr[2]) 65 | | (icrmask[3] & icr[3]) 66 | | (icrmask[4] & icr[4]); 67 | 68 | 69 | endmodule 70 | 71 | -------------------------------------------------------------------------------- /src/minimig-aga/cia_timera.v: -------------------------------------------------------------------------------- 1 | module cia_timera 2 | ( 3 | input clk, // clock 4 | input clk7_en, 5 | input wr, // write enable 6 | input reset, // reset 7 | input tlo, // timer low byte select 8 | input thi, // timer high byte select 9 | input tcr, // timer control register 10 | input [7:0] data_in, // bus data in 11 | output [7:0] data_out, // bus data out 12 | input eclk, // count enable 13 | output tmra_ovf, // timer A underflow 14 | output spmode, // serial port mode 15 | output irq // intterupt out 16 | ); 17 | 18 | reg [15:0] tmr; // timer 19 | reg [7:0] tmlh; // timer latch high byte 20 | reg [7:0] tmll; // timer latch low byte 21 | reg [6:0] tmcr; // timer control register 22 | reg forceload; // force load strobe 23 | wire oneshot; // oneshot mode 24 | wire start; // timer start (enable) 25 | reg thi_load; // load tmr after writing thi in one-shot mode 26 | wire reload; // reload timer counter 27 | wire zero; // timer counter is zero 28 | wire underflow; // timer is going to underflow 29 | wire count; // count enable signal 30 | 31 | // count enable signal 32 | assign count = eclk; 33 | 34 | // writing timer control register 35 | always @(posedge clk) 36 | if (clk7_en) begin 37 | if (reset) // synchronous reset 38 | tmcr[6:0] <= 7'd0; 39 | else if (tcr && wr) // load control register, bit 4(strobe) is always 0 40 | tmcr[6:0] <= {data_in[6:5],1'b0,data_in[3:0]}; 41 | else if (thi_load && oneshot) // start timer if thi is written in one-shot mode 42 | tmcr[0] <= 1'd1; 43 | else if (underflow && oneshot) // stop timer in one-shot mode 44 | tmcr[0] <= 1'd0; 45 | end 46 | 47 | always @(posedge clk) 48 | if (clk7_en) begin 49 | forceload <= tcr & wr & data_in[4]; // force load strobe 50 | end 51 | 52 | assign oneshot = tmcr[3]; // oneshot alias 53 | assign start = tmcr[0]; // start alias 54 | assign spmode = tmcr[6]; // serial port mode (0-input, 1-output) 55 | 56 | // timer A latches for high and low byte 57 | always @(posedge clk) 58 | if (clk7_en) begin 59 | if (reset) 60 | tmll[7:0] <= 8'b1111_1111; 61 | else if (tlo && wr) 62 | tmll[7:0] <= data_in[7:0]; 63 | end 64 | 65 | always @(posedge clk) 66 | if (clk7_en) begin 67 | if (reset) 68 | tmlh[7:0] <= 8'b1111_1111; 69 | else if (thi && wr) 70 | tmlh[7:0] <= data_in[7:0]; 71 | end 72 | 73 | // thi is written in one-shot mode so tmr must be reloaded 74 | always @(posedge clk) 75 | if (clk7_en) begin 76 | thi_load <= thi & wr & (~start | oneshot); 77 | end 78 | 79 | // timer counter reload signal 80 | assign reload = thi_load | forceload | underflow; 81 | 82 | // timer counter 83 | always @(posedge clk) 84 | if (clk7_en) begin 85 | if (reset) 86 | tmr[15:0] <= 16'hFF_FF; 87 | else if (reload) 88 | tmr[15:0] <= {tmlh[7:0],tmll[7:0]}; 89 | else if (start && count) 90 | tmr[15:0] <= tmr[15:0] - 16'd1; 91 | end 92 | 93 | // timer counter equals zero 94 | assign zero = ~|tmr; 95 | 96 | // timer counter is going to underflow 97 | assign underflow = zero & start & count; 98 | 99 | // Timer A underflow signal for Timer B 100 | assign tmra_ovf = underflow; 101 | 102 | // timer underflow interrupt request 103 | assign irq = underflow; 104 | 105 | // data output 106 | assign data_out[7:0] = ({8{~wr&tlo}} & tmr[7:0]) 107 | | ({8{~wr&thi}} & tmr[15:8]) 108 | | ({8{~wr&tcr}} & {1'b0,tmcr[6:0]}); 109 | 110 | 111 | endmodule 112 | 113 | -------------------------------------------------------------------------------- /src/minimig-aga/cia_timerb.v: -------------------------------------------------------------------------------- 1 | module cia_timerb 2 | ( 3 | input clk, // clock 4 | input clk7_en, 5 | input wr, // write enable 6 | input reset, // reset 7 | input tlo, // timer low byte select 8 | input thi, // timer high byte select 9 | input tcr, // timer control register 10 | input [7:0] data_in, // bus data in 11 | output [7:0] data_out, // bus data out 12 | input eclk, // count enable 13 | input tmra_ovf, // timer A underflow 14 | output irq // intterupt out 15 | ); 16 | 17 | reg [15:0] tmr; // timer 18 | reg [7:0] tmlh; // timer latch high byte 19 | reg [7:0] tmll; // timer latch low byte 20 | reg [6:0] tmcr; // timer control register 21 | reg forceload; // force load strobe 22 | wire oneshot; // oneshot mode 23 | wire start; // timer start (enable) 24 | reg thi_load; // load tmr after writing thi in one-shot mode 25 | wire reload; // reload timer counter 26 | wire zero; // timer counter is zero 27 | wire underflow; // timer is going to underflow 28 | wire count; // count enable signal 29 | 30 | // Timer B count signal source 31 | assign count = tmcr[6] ? tmra_ovf : eclk; 32 | 33 | // writing timer control register 34 | always @(posedge clk) 35 | if (clk7_en) begin 36 | if (reset) // synchronous reset 37 | tmcr[6:0] <= 7'd0; 38 | else if (tcr && wr) // load control register, bit 4(strobe) is always 0 39 | tmcr[6:0] <= {data_in[6:5],1'b0,data_in[3:0]}; 40 | else if (thi_load && oneshot) // start timer if thi is written in one-shot mode 41 | tmcr[0] <= 1'd1; 42 | else if (underflow && oneshot) // stop timer in one-shot mode 43 | tmcr[0] <= 1'd0; 44 | end 45 | 46 | always @(posedge clk) 47 | if (clk7_en) begin 48 | forceload <= tcr & wr & data_in[4]; // force load strobe 49 | end 50 | 51 | assign oneshot = tmcr[3]; // oneshot alias 52 | assign start = tmcr[0]; // start alias 53 | 54 | // timer B latches for high and low byte 55 | always @(posedge clk) 56 | if (clk7_en) begin 57 | if (reset) 58 | tmll[7:0] <= 8'b1111_1111; 59 | else if (tlo && wr) 60 | tmll[7:0] <= data_in[7:0]; 61 | end 62 | 63 | always @(posedge clk) 64 | if (clk7_en) begin 65 | if (reset) 66 | tmlh[7:0] <= 8'b1111_1111; 67 | else if (thi && wr) 68 | tmlh[7:0] <= data_in[7:0]; 69 | end 70 | 71 | // thi is written in one-shot mode so tmr must be reloaded 72 | always @(posedge clk) 73 | if (clk7_en) begin 74 | thi_load <= thi & wr & (~start | oneshot); 75 | end 76 | 77 | // timer counter reload signal 78 | assign reload = thi_load | forceload | underflow; 79 | 80 | // timer counter 81 | always @(posedge clk) 82 | if (clk7_en) begin 83 | if (reset) 84 | tmr[15:0] <= 16'hFF_FF; 85 | else if (reload) 86 | tmr[15:0] <= {tmlh[7:0],tmll[7:0]}; 87 | else if (start && count) 88 | tmr[15:0] <= tmr[15:0] - 16'd1; 89 | end 90 | 91 | // timer counter equals zero 92 | assign zero = ~|tmr; 93 | 94 | // timer counter is going to underflow 95 | assign underflow = zero & start & count; 96 | 97 | // timer underflow interrupt request 98 | assign irq = underflow; 99 | 100 | // data output 101 | assign data_out[7:0] = ({8{~wr&tlo}} & tmr[7:0]) 102 | | ({8{~wr&thi}} & tmr[15:8]) 103 | | ({8{~wr&tcr}} & {1'b0,tmcr[6:0]}); 104 | 105 | 106 | endmodule 107 | 108 | -------------------------------------------------------------------------------- /src/minimig-aga/cia_timerd.v: -------------------------------------------------------------------------------- 1 | // timer D 2 | //---------------------------------------------------------------------------------- 3 | //---------------------------------------------------------------------------------- 4 | 5 | 6 | module cia_timerd 7 | ( 8 | input clk, // clock 9 | input clk7_en, 10 | input wr, // write enable 11 | input reset, // reset 12 | input tlo, // timer low byte select 13 | input tme, // timer mid byte select 14 | input thi, // timer high byte select 15 | input tcr, // timer control register 16 | input [7:0] data_in, // bus data in 17 | output reg [7:0] data_out, // bus data out 18 | input count, // count enable 19 | output irq // intterupt out 20 | ); 21 | 22 | reg latch_ena; // timer d output latch enable 23 | reg count_ena; // timer d count enable 24 | reg crb7; // bit 7 of control register B 25 | reg [23:0] tod; // timer d 26 | reg [23:0] alarm; // alarm 27 | reg [23:0] tod_latch; // timer d latch 28 | reg count_del; // delayed count signal for interrupt requesting 29 | 30 | // timer D output latch control 31 | always @(posedge clk) 32 | if (clk7_en) begin 33 | if (reset) 34 | latch_ena <= 1'd1; 35 | else if (!wr) 36 | begin 37 | if (thi && !crb7) // if MSB read and ALARM is not selected, hold data for subsequent reads 38 | latch_ena <= 1'd0; 39 | else if (tlo) // if LSB read, update data every clock 40 | latch_ena <= 1'd1; 41 | end 42 | end 43 | 44 | always @(posedge clk) 45 | if (clk7_en) begin 46 | if (latch_ena) 47 | tod_latch[23:0] <= tod[23:0]; 48 | end 49 | 50 | // timer D and crb7 read 51 | always @(*) 52 | if (!wr) 53 | begin 54 | if (thi) // high byte of timer D 55 | data_out[7:0] = tod_latch[23:16]; 56 | else if (tme) // medium byte of timer D (latched) 57 | data_out[7:0] = tod_latch[15:8]; 58 | else if (tlo) // low byte of timer D (latched) 59 | data_out[7:0] = tod_latch[7:0]; 60 | else if (tcr) // bit 7 of crb 61 | data_out[7:0] = {crb7,7'b000_0000}; 62 | else 63 | data_out[7:0] = 8'd0; 64 | end 65 | else 66 | data_out[7:0] = 8'd0; 67 | 68 | // timer D count enable control 69 | always @(posedge clk) 70 | if (clk7_en) begin 71 | if (reset) 72 | count_ena <= 1'd1; 73 | else if (wr && !crb7) // crb7==0 enables writing to TOD counter 74 | begin 75 | if (thi/* || tme*/) // stop counting 76 | count_ena <= 1'd0; 77 | else if (tlo) // write to LSB starts counting again 78 | count_ena <= 1'd1; 79 | end 80 | end 81 | 82 | // timer D counter 83 | always @(posedge clk) 84 | if (clk7_en) begin 85 | if (reset) // synchronous reset 86 | begin 87 | tod[23:0] <= 24'd0; 88 | end 89 | else if (wr && !crb7) // crb7==0 enables writing to TOD counter 90 | begin 91 | if (tlo) 92 | tod[7:0] <= data_in[7:0]; 93 | if (tme) 94 | tod[15:8] <= data_in[7:0]; 95 | if (thi) 96 | tod[23:16] <= data_in[7:0]; 97 | end 98 | else if (count_ena && count) 99 | tod[23:0] <= tod[23:0] + 24'd1; 100 | end 101 | 102 | // alarm write 103 | always @(posedge clk) 104 | if (clk7_en) begin 105 | if (reset) // synchronous reset 106 | begin 107 | alarm[7:0] <= 8'b1111_1111; 108 | alarm[15:8] <= 8'b1111_1111; 109 | alarm[23:16] <= 8'b1111_1111; 110 | end 111 | else if (wr && crb7) // crb7==1 enables writing to ALARM 112 | begin 113 | if (tlo) 114 | alarm[7:0] <= data_in[7:0]; 115 | if (tme) 116 | alarm[15:8] <= data_in[7:0]; 117 | if (thi) 118 | alarm[23:16] <= data_in[7:0]; 119 | end 120 | end 121 | 122 | // crb7 write 123 | always @(posedge clk) 124 | if (clk7_en) begin 125 | if (reset) 126 | crb7 <= 1'd0; 127 | else if (wr && tcr) 128 | crb7 <= data_in[7]; 129 | end 130 | 131 | // delayed count enable signal 132 | always @(posedge clk) 133 | if (clk7_en) begin 134 | count_del <= count & count_ena; 135 | end 136 | 137 | // alarm interrupt request 138 | assign irq = (tod[23:0]==alarm[23:0] && count_del) ? 1'b1 : 1'b0; 139 | 140 | 141 | endmodule 142 | 143 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_colortable.v: -------------------------------------------------------------------------------- 1 | // this is the 32 colour colour table 2 | // because this module also supports EHB (extra half brite) mode, 3 | // it actually has a 6bit colour select input 4 | // the 6th bit selects EHB colour while the lower 5 bit select the actual colour register 5 | 6 | 7 | module denise_colortable 8 | ( 9 | input wire clk, // 28MHz clock 10 | input wire clk7_en, // 7MHz clock enable 11 | input wire [ 9-1:1] reg_address_in, // register adress inputs 12 | input wire [ 12-1:0] data_in, // bus data in 13 | input wire rdram, // read the color table instead of writing to it 14 | input wire [ 8-1:0] select, // colour select input 15 | input wire [ 8-1:0] bplxor, // clut address xor value 16 | input wire [ 3-1:0] bank, // color bank select 17 | input wire loct, // 12-bit palette select 18 | input wire ehb_en, // EHB enable 19 | output reg [ 24-1:0] rgb // RGB output 20 | ); 21 | 22 | 23 | // register names and adresses 24 | parameter COLORBASE = 9'h180; // colour table base address 25 | 26 | // select xor 27 | wire [ 8-1:0] select_xored = select;// ^ bplxor; 28 | 29 | // color ram 30 | wire [ 8-1:0] wr_adr = {bank[2:0], reg_address_in[5:1]}; 31 | wire wr_en = (reg_address_in[8:6] == COLORBASE[8:6]) && clk7_en && !rdram; 32 | wire [12-1:0] wr_dat = data_in[11:0]; 33 | wire [ 2-1:0] wr_ws = loct ? 2'b01 : 2'b11; 34 | wire [ 8-1:0] rd_adr = rdram ? wr_adr : ehb_en ? {3'b000, select_xored[4:0]} : select_xored; 35 | wire [24-1:0] rd_dat; 36 | reg ehb_sel; 37 | 38 | // color lut 39 | denise_colortable_ram_mf clut 40 | ( 41 | .clock (clk ), 42 | .wraddress (wr_adr ), 43 | .wren (wr_en ), 44 | .ena_a (wr_ws ), 45 | .data (wr_dat ), 46 | .rdaddress (rd_adr ), 47 | .q (rd_dat ) 48 | ); 49 | 50 | // register half-brite bit 51 | always @ (posedge clk) begin 52 | ehb_sel <= #1 select_xored[5]; 53 | end 54 | 55 | // pack color values 56 | wire [12-1:0] color_hi = rd_dat[12-1+12:0+12]; 57 | wire [12-1:0] color_lo = rd_dat[12-1+ 0:0+ 0]; 58 | wire [24-1:0] color = {color_hi[11:8], color_lo[11:8], color_hi[7:4], color_lo[7:4], color_hi[3:0], color_lo[3:0]}; 59 | 60 | // extra half brite mode shifter 61 | always @ (*) begin 62 | if (ehb_sel && ehb_en) // half bright, shift every component 1 position to the right 63 | rgb = {1'b0,color[23:17],1'b0,color[15:9],1'b0,color[7:1]}; 64 | else // normal colour select 65 | rgb = color; 66 | end 67 | 68 | 69 | endmodule 70 | 71 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_colortable_ram_mf.v: -------------------------------------------------------------------------------- 1 | // colortable ram 2 | 3 | module denise_colortable_ram_mf ( 4 | input [1:0] ena_a, 5 | input clock, 6 | input [11:0] data, 7 | input [7:0] rdaddress, 8 | input [7:0] wraddress, 9 | input wren, 10 | output reg [23:0] q 11 | ); 12 | 13 | reg [11:0] ram0[255:0]; 14 | reg [11:0] ram1[255:0]; 15 | 16 | always @(posedge clock) begin 17 | if(wren) begin 18 | if(ena_a[0]) ram0[wraddress] <= data; 19 | if(ena_a[1]) ram1[wraddress] <= data; 20 | end 21 | 22 | q <= { ram1[rdaddress], ram0[rdaddress] }; 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_hamgenerator.v: -------------------------------------------------------------------------------- 1 | // this module handles the hold and modify mode (HAM) 2 | // the module has its own colour pallete bank, this is to let 3 | // the sprites run simultaneously with a HAM playfield 4 | 5 | 6 | module denise_hamgenerator 7 | ( 8 | input wire clk, // 28MHz clock 9 | input wire clk7_en, // 7MHz clock enable 10 | input wire [ 9-1:1] reg_address_in, // register adress inputs 11 | input wire [ 12-1:0] data_in, // bus data in 12 | input wire [ 8-1:0] select, // colour select input 13 | input wire [ 8-1:0] bplxor, // clut address xor value 14 | input wire [ 3-1:0] bank, // color bank select 15 | input wire loct, // 12-bit pallete select 16 | input wire ham8, // HAM8 mode 17 | output reg [ 24-1:0] rgb // RGB output 18 | ); 19 | 20 | 21 | // register names and adresses 22 | parameter COLORBASE = 9'h180; // colour table base address 23 | 24 | // select xor 25 | wire [ 8-1:0] select_xored = select ^ bplxor; 26 | 27 | // color ram 28 | wire [ 8-1:0] wr_adr = {bank[2:0], reg_address_in[5:1]}; 29 | wire wr_en = (reg_address_in[8:6] == COLORBASE[8:6]) && clk7_en; 30 | wire [12-1:0] wr_dat = data_in[11:0]; 31 | wire [ 2-1:0] wr_ws = loct ? 2'b01 : 2'b11; 32 | wire [ 8-1:0] rd_adr = ham8 ? {2'b00, select_xored[7:2]} : select_xored; 33 | wire [24-1:0] rd_dat; 34 | reg [24-1:0] rgb_prev; 35 | reg [ 8-1:0] select_r; 36 | 37 | // color lut 38 | denise_colortable_ram_mf clut 39 | ( 40 | .clock (clk ), 41 | .wraddress (wr_adr ), 42 | .wren (wr_en ), 43 | .ena_a (wr_ws ), 44 | .data (wr_dat ), 45 | .rdaddress (rd_adr ), 46 | .q (rd_dat ) 47 | ); 48 | 49 | // pack color values 50 | wire [12-1:0] color_hi = rd_dat[12-1+12:0+12]; 51 | wire [12-1:0] color_lo = rd_dat[12-1+ 0:0+ 0]; 52 | wire [24-1:0] color = {color_hi[11:8], color_lo[11:8], color_hi[7:4], color_lo[7:4], color_hi[3:0], color_lo[3:0]}; 53 | 54 | // register previous rgb value 55 | always @ (posedge clk) begin 56 | rgb_prev <= #1 rgb; 57 | end 58 | 59 | // register previous select 60 | always @ (posedge clk) begin 61 | select_r <= #1 select_xored; 62 | end 63 | 64 | // HAM instruction decoder/processor 65 | always @ (*) begin 66 | if (ham8) begin 67 | case (select_r[1:0]) 68 | 2'b00: // load rgb output with colour from table 69 | rgb = color; 70 | 2'b01: // hold green and red, modify blue 71 | rgb = {rgb_prev[23:8],select_r[7:2],rgb_prev[1:0]}; 72 | 2'b10: // hold green and blue, modify red 73 | rgb = {select_r[7:2],rgb_prev[17:16],rgb_prev[15:0]}; 74 | 2'b11: // hold blue and red, modify green 75 | rgb = {rgb_prev[23:16],select_r[7:2],rgb_prev[9:8],rgb_prev[7:0]}; 76 | default: 77 | rgb = color; 78 | endcase 79 | end else begin 80 | case (select_r[5:4]) 81 | 2'b00: // load rgb output with colour from table 82 | rgb = color; 83 | 2'b01: // hold green and red, modify blue 84 | rgb = {rgb_prev[23:8],select_r[3:0],select_r[3:0]}; 85 | 2'b10: // hold green and blue, modify red 86 | rgb = {select_r[3:0],select_r[3:0],rgb_prev[15:0]}; 87 | 2'b11: // hold blue and red, modify green 88 | rgb = {rgb_prev[23:16],select_r[3:0],select_r[3:0],rgb_prev[7:0]}; 89 | default: 90 | rgb = color; 91 | endcase 92 | end 93 | end 94 | 95 | 96 | endmodule 97 | 98 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_playfields.v: -------------------------------------------------------------------------------- 1 | //This is the playfield engine. 2 | //It takes the raw bitplane data and generates a 3 | //single or dual playfield 4 | //it also generated the nplayfield valid data signals which are needed 5 | //by the main video priority logic in Denise 6 | 7 | 8 | module denise_playfields 9 | ( 10 | input aga, 11 | input [8:1] bpldata, //raw bitplane data in 12 | input dblpf, //double playfield select 13 | input [2:0] pf2of, // playfield 2 offset into color table 14 | input [6:0] bplcon2, //bplcon2 (playfields priority) 15 | output reg [2:1] nplayfield, //playfield 1,2 valid data 16 | output reg [7:0] plfdata //playfield data out 17 | ); 18 | 19 | //local signals 20 | wire pf2pri; //playfield 2 priority over playfield 1 21 | wire [2:0] pf2p; //playfield 2 priority code 22 | reg [7:0] pf2of_val; // playfield 2 offset value 23 | 24 | assign pf2pri = bplcon2[6]; 25 | assign pf2p = bplcon2[5:3]; 26 | 27 | always @ (*) begin 28 | case(pf2of) 29 | 3'd0 : pf2of_val = 8'd0; 30 | 3'd1 : pf2of_val = 8'd2; 31 | 3'd2 : pf2of_val = 8'd4; 32 | 3'd3 : pf2of_val = 8'd8; 33 | 3'd4 : pf2of_val = 8'd16; 34 | 3'd5 : pf2of_val = 8'd32; 35 | 3'd6 : pf2of_val = 8'd64; 36 | 3'd7 : pf2of_val = 8'd128; 37 | endcase 38 | end 39 | 40 | //generate playfield 1,2 data valid signals 41 | always @(*) 42 | begin 43 | if (dblpf) //dual playfield 44 | begin 45 | if (bpldata[7] || bpldata[5] || bpldata[3] || bpldata[1]) //detect data valid for playfield 1 46 | nplayfield[1] = 1; 47 | else 48 | nplayfield[1] = 0; 49 | 50 | if (bpldata[8] || bpldata[6] || bpldata[4] || bpldata[2]) //detect data valid for playfield 2 51 | nplayfield[2] = 1; 52 | else 53 | nplayfield[2] = 0; 54 | end 55 | else //single playfield is always playfield 2 56 | begin 57 | nplayfield[1] = 0; 58 | if (bpldata[8:1]!=8'b000000) 59 | nplayfield[2] = 1; 60 | else 61 | nplayfield[2] = 0; 62 | end 63 | end 64 | 65 | //playfield 1 and 2 priority logic 66 | always @(*) 67 | begin 68 | if (dblpf) //dual playfield 69 | begin 70 | if (pf2pri) //playfield 2 (2,4,6) has priority 71 | begin 72 | if (nplayfield[2]) 73 | if (aga) 74 | plfdata[7:0] = {4'b0000,bpldata[8],bpldata[6],bpldata[4],bpldata[2]} + pf2of_val; 75 | else 76 | plfdata[7:0] = {4'b0000,1'b1,bpldata[6],bpldata[4],bpldata[2]}; 77 | else if (nplayfield[1]) 78 | plfdata[7:0] = {4'b0000,bpldata[7],bpldata[5],bpldata[3],bpldata[1]}; 79 | else //both planes transparant, select background color 80 | plfdata[7:0] = 8'b00000000; 81 | end 82 | else //playfield 1 (1,3,5) has priority 83 | begin 84 | if (nplayfield[1]) 85 | plfdata[7:0] = {4'b0000,bpldata[7],bpldata[5],bpldata[3],bpldata[1]}; 86 | else if (nplayfield[2]) 87 | if (aga) 88 | plfdata[7:0] = {4'b0000,bpldata[8],bpldata[6],bpldata[4],bpldata[2]} + pf2of_val; 89 | else 90 | plfdata[7:0] = {4'b0000,1'b1,bpldata[6],bpldata[4],bpldata[2]}; 91 | else //both planes transparent, select background color 92 | plfdata[7:0] = 8'b00000000; 93 | end 94 | end 95 | else //normal single playfield (playfield 2 only) 96 | //OCS/ECS undocumented feature when bpu=5 and pf2pri>5 (Swiv score display) 97 | if ((pf2p>5) && bpldata[5] && !aga) 98 | plfdata[7:0] = {8'b00010000}; 99 | else 100 | plfdata[7:0] = bpldata[8:1]; 101 | end 102 | 103 | 104 | endmodule 105 | 106 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_spritepriority.v: -------------------------------------------------------------------------------- 1 | // sprite priority logic module 2 | // this module checks the playfields and sprites video status and 3 | // determines if playfield or sprite data must be sent to the video output 4 | // sprite/playfield priority is configurable through the bplcon2 bits 5 | module denise_spritepriority 6 | ( 7 | input [5:0] bplcon2, // playfields vs sprites priority setting 8 | input [2:1] nplayfield, // playfields video status 9 | input [7:0] nsprite, // sprites video status 10 | output reg sprsel // sprites select signal output 11 | ); 12 | 13 | // local signals 14 | reg [2:0] sprcode; // sprite code 15 | wire [3:0] sprgroup; // grouped sprites 16 | wire pf1front; // playfield 1 is on front of sprites 17 | wire pf2front; // playfield 2 is on front of sprites 18 | 19 | // group sprites together 20 | assign sprgroup[0] = (nsprite[1:0]==2'd0) ? 1'b0 : 1'b1; 21 | assign sprgroup[1] = (nsprite[3:2]==2'd0) ? 1'b0 : 1'b1; 22 | assign sprgroup[2] = (nsprite[5:4]==2'd0) ? 1'b0 : 1'b1; 23 | assign sprgroup[3] = (nsprite[7:6]==2'd0) ? 1'b0 : 1'b1; 24 | 25 | // sprites priority encoder 26 | always @(*) 27 | if (sprgroup[0]) 28 | sprcode = 3'd1; 29 | else if (sprgroup[1]) 30 | sprcode = 3'd2; 31 | else if (sprgroup[2]) 32 | sprcode = 3'd3; 33 | else if (sprgroup[3]) 34 | sprcode = 3'd4; 35 | else 36 | sprcode = 3'd7; 37 | 38 | // check if playfields are in front of sprites 39 | assign pf1front = sprcode[2:0]>bplcon2[2:0] ? 1'b1 : 1'b0; 40 | assign pf2front = sprcode[2:0]>bplcon2[5:3] ? 1'b1 : 1'b0; 41 | 42 | // generate final playfield/sprite select signal 43 | always @(*) 44 | begin 45 | if (sprcode[2:0]==3'd7) // if no valid sprite data, always select playfields 46 | sprsel = 1'b0; 47 | else if (pf1front && nplayfield[1]) // else if pf1 in front and valid data, select playfields 48 | sprsel = 1'b0; 49 | else if (pf2front && nplayfield[2]) // else if pf2 in front and valid data, select playfields 50 | sprsel = 1'b0; 51 | else // else select sprites 52 | sprsel = 1'b1; 53 | end 54 | 55 | endmodule 56 | 57 | -------------------------------------------------------------------------------- /src/minimig-aga/denise_sprites_shifter.v: -------------------------------------------------------------------------------- 1 | // this is the sprite parallel to serial converter 2 | // clk is 7.09379 MHz (low resolution pixel clock) 3 | // the sprdata assign circuitry is constructed differently from the hardware 4 | // as described in the amiga hardware reference manual 5 | // this is to make sure that the horizontal start position of a sprite 6 | // aligns with the bitplane/playfield start position 7 | 8 | 9 | module denise_sprites_shifter 10 | ( 11 | input clk, // 28MHz clock 12 | input clk7_en, 13 | input clk7n_en, // 7MHz clock enable 14 | input reset, // reset 15 | input aen, // address enable 16 | input [1:0] address, // register address input 17 | input [8:0] hpos, // horizontal beam counter 18 | input [15:0] fmode, 19 | input shift, 20 | input [48-1:0] chip48, 21 | input [15:0] data_in, // bus data in 22 | output [1:0] sprdata, // serialized sprite data out 23 | output reg attach // sprite is attached 24 | ); 25 | 26 | // register names and adresses 27 | parameter POS = 2'b00; 28 | parameter CTL = 2'b01; 29 | parameter DATA = 2'b10; 30 | parameter DATB = 2'b11; 31 | 32 | // local signals 33 | reg [63:0] datla; // data register A 34 | reg [63:0] datlb; // data register B 35 | reg [63:0] shifta; // shift register A 36 | reg [63:0] shiftb; // shift register B 37 | reg [8:0] hstart; // horizontal start value 38 | reg armed; // sprite "armed" signal 39 | reg load; // load shift register signal 40 | reg load_del; 41 | 42 | //-------------------------------------------------------------------------------------- 43 | 44 | reg [15:0] data16; 45 | always @(posedge clk) if (clk7_en) data16 <= data_in; 46 | 47 | // switch data according to fmode 48 | reg [64-1:0] spr_fmode_dat; 49 | 50 | always @ (*) begin 51 | case(fmode[3:2]) 52 | 2'b00 : spr_fmode_dat = {data16, 48'h000000000000}; 53 | 2'b11 : spr_fmode_dat = {data16, chip48[47:0]}; 54 | default : spr_fmode_dat = {data16, chip48[47:32], 32'h00000000}; 55 | endcase 56 | end 57 | 58 | // generate armed signal 59 | always @(posedge clk) 60 | if (clk7_en) begin 61 | if (reset) // reset disables sprite 62 | armed <= 0; 63 | else if (aen && address==CTL) // writing CTL register disables sprite 64 | armed <= 0; 65 | else if (aen && address==DATA) // writing data register A arms sprite 66 | armed <= 1; 67 | end 68 | 69 | //-------------------------------------------------------------------------------------- 70 | 71 | // generate load signal 72 | always @(posedge clk) 73 | if (clk7_en) begin 74 | load <= armed && (hpos[7:0] == hstart[7:0]) && (fmode[15] || (hpos[8] == hstart[8])) ? 1'b1 : 1'b0; 75 | end 76 | 77 | //always @(posedge clk) 78 | // if (clk7_en) begin 79 | // load_del <= load; // AMR - delaying this screws up the scoreboard in hybris. 80 | // end 81 | 82 | //-------------------------------------------------------------------------------------- 83 | 84 | // POS register 85 | always @(posedge clk) 86 | if (clk7_en) begin 87 | if (aen && address==POS) 88 | hstart[8:1] <= data_in[7:0]; 89 | end 90 | 91 | // CTL register 92 | always @(posedge clk) 93 | if (clk7_en) begin 94 | if (aen && address==CTL) 95 | {attach,hstart[0]} <= {data_in[7],data_in[0]}; 96 | end 97 | 98 | // data register A 99 | always @(posedge clk) begin 100 | reg st; 101 | if(clk7_en && aen && address==DATA) st <= 1; 102 | if(st & clk7n_en) begin 103 | st <= 0; 104 | datla <= spr_fmode_dat; 105 | end 106 | end 107 | 108 | // data register B 109 | always @(posedge clk) begin 110 | reg st; 111 | if(clk7_en && aen && address==DATB) st <= 1; 112 | if(st & clk7n_en) begin 113 | st <= 0; 114 | datlb <= spr_fmode_dat; 115 | end 116 | end 117 | 118 | //-------------------------------------------------------------------------------------- 119 | 120 | // sprite shift register 121 | always @(posedge clk) 122 | if (clk7_en && load) // AMR - load_del) // load new data into shift register 123 | begin 124 | shifta[63:0] <= datla[63:0]; 125 | shiftb[63:0] <= datlb[63:0]; 126 | end 127 | else if (shift) 128 | begin 129 | shifta[63:0] <= {shifta[62:0],1'b0}; 130 | shiftb[63:0] <= {shiftb[62:0],1'b0}; 131 | end 132 | 133 | // assign serialized output data 134 | // AMR - register the output data to delay it by one clk7, compensating for removing load_del 135 | // Fixed highres sprites by pipelining shifter output. 136 | reg [7:0] sprdata_r; 137 | always @(posedge clk) 138 | sprdata_r <= {shiftb[63],shifta[63],sprdata_r[7:2]}; // Ugly - are we masking a copper timing problem here? 139 | 140 | assign sprdata[1:0] = sprdata_r[1:0]; // {shiftb[63],shifta[63]}; 141 | //-------------------------------------------------------------------------------------- 142 | 143 | endmodule 144 | 145 | -------------------------------------------------------------------------------- /src/minimig-aga/minimig_bankmapper.v: -------------------------------------------------------------------------------- 1 | //This module maps physical 512KB blocks of every memory chip to different memory ranges in Amiga 2 | // 3 | // Since we currently have 8M for non-fastram, this was simplified to 4 | // use the full address for mapping. We only use this part to signal 5 | // that ram access should occur and to emulate the mirroring behaviour 6 | // of the lower 2M when less than 2M chipram is selected. Moreover we 7 | // use sel_kick downstream, because there is no boot overlay 8 | // information in the address alone. 9 | 10 | module minimig_bankmapper 11 | ( 12 | input chip0, // chip ram select: 1st 512 KB block 13 | input chip1, // chip ram select: 2nd 512 KB block 14 | input chip2, // chip ram select: 3rd 512 KB block 15 | input chip3, // chip ram select: 4th 512 KB block 16 | input slow0, // slow ram select: 1st 512 KB block 17 | input slow1, // slow ram select: 2nd 512 KB block 18 | input slow2, // slow ram select: 3rd 512 KB block 19 | input kick, // Kickstart ROM address range select 20 | input kick1mb, // 1MB Kickstart 'upper' half 21 | input kick256kmirror, // mirror f8-fb to fc-ff in a1k mode 22 | input cart, // Action Reply memory range select 23 | input [1:0] memory_config, // memory configuration 24 | output [7:0] bank // bank select 25 | ); 26 | 27 | assign bank = bank_r; 28 | 29 | reg [7:0] bank_r; 30 | 31 | always @(*) begin 32 | bank_r[7:4] = { kick,kick256kmirror , chip3 | chip2 | chip1 | chip0, kick1mb | slow0 | slow1 | slow2 | cart} ; 33 | case (memory_config) 34 | 0: bank_r[3:0] = { 1'b0, 1'b0, 1'b0, chip3 | chip2 | chip1 | chip0 }; // 0.5M CHIP 35 | 1: bank_r[3:0] = { 1'b0, 1'b0, chip3 | chip1, chip2 | chip0 }; // 1.0M CHIP 36 | 2: bank_r[3:0] = { 1'b0, chip2, chip1, chip0 }; // 1.5M CHIP 37 | 3: bank_r[3:0] = { chip3, chip2, chip1, chip0 }; // 2.0M CHIP 38 | endcase 39 | end 40 | 41 | endmodule 42 | 43 | -------------------------------------------------------------------------------- /src/minimig-aga/minimig_sram_bridge.v: -------------------------------------------------------------------------------- 1 | // This module interfaces the minimig's synchronous bus to the asynchronous sram 2 | // on the Minimig rev1.0 board 3 | // 4 | // JB: 5 | // 2008-09-23 - generation of write strobes moved to clk28m clock domain 6 | 7 | 8 | module minimig_sram_bridge 9 | ( 10 | //clocks 11 | input clk, // 28 MHz system clock 12 | input c1, // clock enable signal 13 | input c3, // clock enable signal 14 | 15 | //chipset internal port 16 | input [7:0] bank, // memory bank select (512KB) 17 | input [23:1] address_in, // bus address 18 | input [15:0] data_in, // bus data in 19 | output [15:0] data_out, // bus data out 20 | input rd, // bus read 21 | input hwr, // bus high byte write 22 | input lwr, // bus low byte write 23 | 24 | //RAM external signals 25 | output _bhe, // sram upper byte 26 | output _ble, // sram lower byte 27 | output _we, // sram write enable 28 | output _oe, // sram output enable 29 | output [22:1] address, // sram address bus 30 | output [15:0] data, // sram data das 31 | input [15:0] ramdata_in // sram data das in 32 | ); 33 | 34 | /* basic timing diagram 35 | 36 | phase : Q0 : Q1 : Q2 : Q3 : Q0 : Q1 : Q2 : Q3 : Q0 : Q1 : 37 | : : : : : : : : : : : 38 | ___________ ___________ ___________ 39 | clk ___/ \___________/ \___________/ \_____ (7.09 MHz - dedicated clock) 40 | 41 | : : : : : : : : : : : 42 | __ __ __ __ __ __ __ __ __ __ __ 43 | clk28m ___/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ (28.36 MHz - dedicated clock) 44 | : : : : : : : : : : : 45 | ___________ ___________ ___________ 46 | c1 ___/ \___________/ \___________/ \_____ (7.09 MHz) 47 | : : : : : : : : : : : 48 | ___________ ___________ ___________ 49 | c3 _________/ \___________/ \___________/ (7.09 MHz) 50 | : : : : : : : : : : : 51 | _________ _____ _____ 52 | _ce \_________________/ \_________________/ \___________ (ram chip enable) 53 | : : : : : : : : : : : 54 | _______________ ___________ ___________ 55 | _we \___________/ \___________/ \_____ (ram write strobe) 56 | : : : : : : : : : : : 57 | _________ _____ _____ 58 | _oe \_________________/ \_________________/ \___________ (ram output enable) 59 | : : : : : : : : : : : 60 | */ 61 | 62 | // generate enable signal if any of the banks is selected 63 | wire enable = |bank[7:0]; // indicates memory access cycle 64 | 65 | assign _we = (!hwr && !lwr) | !enable; 66 | assign _oe = !rd | !enable; 67 | assign _bhe = !hwr | !enable; 68 | assign _ble = !lwr | !enable; 69 | 70 | assign address[17:1] = address_in[17:1]; 71 | assign address[22:18] = bank[6] ? 5'b111_11 : //access f8-fb and !ovl and !halt, map to fc-ff 72 | (bank[7] ? {4'b111_1, address_in[18]} : //access to f8-ff or ovl 73 | (bank[5] ? {2'b0, bank[3]|bank[2], bank[3]|bank[1],address_in[18]} : 74 | address_in[22:18])); //chipram access 75 | 76 | assign data_out[15:0] = (enable && rd) ? ramdata_in[15:0] : 16'b0000000000000000; 77 | assign data[15:0] = data_in[15:0]; 78 | 79 | endmodule 80 | -------------------------------------------------------------------------------- /src/minimig-aga/minimig_syscontrol.v: -------------------------------------------------------------------------------- 1 | //syscontrol handles the startup of the FGPA, 2 | //after fpga config, it automatically does a global system reset and asserts boot. 3 | //the boot signal puts gary in a special mode so that the bootrom 4 | //is mapped into the system memory map. The firmware in the bootrom 5 | //then loads the kickstart via the diskcontroller into the kickstart ram area. 6 | //When kickstart has been loaded, the bootrom asserts bootdone by selecting both cia's at once. 7 | //This resets the system for a second time but it also de-asserts boot. 8 | //Thus, the system now boots as a regular amiga. 9 | //Subsequent resets by asserting mrst will not assert boot again. 10 | // 11 | // JB: 12 | // 2008-07-11 - reset to bootloader 13 | // 2009-03-13 - shorter reset 14 | // 2009-08-17 - reset generator modification 15 | 16 | 17 | module minimig_syscontrol 18 | ( 19 | input clk, //bus clock 20 | input clk7_en, 21 | input cnt, //pulses for counting 22 | input mrst, //master/user reset input 23 | output reset //global synchronous system reset 24 | ); 25 | 26 | reg reset_R = 1'b1; 27 | assign reset = reset_R; 28 | reg [2:0] rst_cnt = 0; //reset timer SHOULD BE CLEARED BY CONFIG 29 | 30 | //reset timer and mrst control 31 | always @(posedge clk) begin 32 | if (clk7_en) begin 33 | if (mrst) rst_cnt <= 0; 34 | else if (~rst_cnt[2] && cnt) rst_cnt <= rst_cnt + 3'd1; 35 | reset_R <= ~rst_cnt[2]; 36 | end 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /src/minimig-aga/paula_audio_mixer.v: -------------------------------------------------------------------------------- 1 | // stereo volume control 2 | // channel 0&3 --> left 3 | // channel 1&2 --> right 4 | 5 | 6 | module paula_audio_mixer ( 7 | input clk, //bus clock 8 | input clk7_en, 9 | input [7:0] sample0, //sample 0 input 10 | input [7:0] sample1, //sample 1 input 11 | input [7:0] sample2, //sample 2 input 12 | input [7:0] sample3, //sample 3 input 13 | input [6:0] vol0, //volume 0 input 14 | input [6:0] vol1, //volume 1 input 15 | input [6:0] vol2, //volume 2 input 16 | input [6:0] vol3, //volume 3 input 17 | output reg [14:0]ldatasum, //left DAC data 18 | output reg [14:0]rdatasum //right DAC data 19 | ); 20 | 21 | // volume control 22 | wire [14-1:0] msample0, msample1, msample2, msample3; 23 | // when volume MSB is set, volume is always maximum 24 | paula_audio_volume sv0 25 | ( 26 | .sample(sample0), 27 | .volume({ (vol0[6] | vol0[5]), 28 | (vol0[6] | vol0[4]), 29 | (vol0[6] | vol0[3]), 30 | (vol0[6] | vol0[2]), 31 | (vol0[6] | vol0[1]), 32 | (vol0[6] | vol0[0]) }), 33 | .out(msample0) 34 | ); 35 | 36 | paula_audio_volume sv1 37 | ( 38 | .sample(sample1), 39 | .volume({ (vol1[6] | vol1[5]), 40 | (vol1[6] | vol1[4]), 41 | (vol1[6] | vol1[3]), 42 | (vol1[6] | vol1[2]), 43 | (vol1[6] | vol1[1]), 44 | (vol1[6] | vol1[0]) }), 45 | .out(msample1) 46 | ); 47 | 48 | paula_audio_volume sv2 49 | ( 50 | .sample(sample2), 51 | .volume({ (vol2[6] | vol2[5]), 52 | (vol2[6] | vol2[4]), 53 | (vol2[6] | vol2[3]), 54 | (vol2[6] | vol2[2]), 55 | (vol2[6] | vol2[1]), 56 | (vol2[6] | vol2[0]) }), 57 | .out(msample2) 58 | ); 59 | 60 | paula_audio_volume sv3 61 | ( 62 | .sample(sample3), 63 | .volume({ (vol3[6] | vol3[5]), 64 | (vol3[6] | vol3[4]), 65 | (vol3[6] | vol3[3]), 66 | (vol3[6] | vol3[2]), 67 | (vol3[6] | vol3[1]), 68 | (vol3[6] | vol3[0]) }), 69 | .out(msample3) 70 | ); 71 | 72 | 73 | // channel muxing 74 | // !!! this is 28MHz clock !!! 75 | always @ (posedge clk) begin 76 | ldatasum <= #1 {msample0[13], msample0} + {msample3[13], msample3}; 77 | rdatasum <= #1 {msample1[13], msample1} + {msample2[13], msample2}; 78 | end 79 | 80 | 81 | endmodule 82 | 83 | -------------------------------------------------------------------------------- /src/minimig-aga/paula_audio_volume.v: -------------------------------------------------------------------------------- 1 | //this module multiplies a signed 8 bit sample with an unsigned 6 bit volume setting 2 | //it produces a 14bit signed result 3 | 4 | 5 | module paula_audio_volume 6 | ( 7 | input [7:0] sample, //signed sample input 8 | input [5:0] volume, //unsigned volume input 9 | output [13:0] out //signed product out 10 | ); 11 | 12 | wire [13:0] sesample; //sign extended sample 13 | wire [13:0] sevolume; //sign extended volume 14 | 15 | //sign extend input parameters 16 | assign sesample[13:0] = {{6{sample[7]}},sample[7:0]}; 17 | assign sevolume[13:0] = {8'b00000000,volume[5:0]}; 18 | 19 | //multiply, synthesizer should infer multiplier here 20 | assign out[13:0] = {sesample[13:0] * sevolume[13:0]}; 21 | 22 | 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /src/minimig-aga/paula_floppy_fifo.v: -------------------------------------------------------------------------------- 1 | //2048 words deep, 16 bits wide, fifo 2 | //data is written into the fifo when wr=1 3 | //reading is more or less asynchronous if you read during the rising edge of clk 4 | //because the output data is updated at the falling edge of the clk 5 | //when rd=1, the next data word is selected 6 | 7 | 8 | module paula_floppy_fifo 9 | ( 10 | input clk, //bus clock 11 | input clk7_en, 12 | input reset, //reset 13 | input [15:0] in, //data in 14 | output reg [15:0] out, //data out 15 | input rd, //read from fifo 16 | input wr, //write to fifo 17 | output reg empty, //fifo is empty 18 | output full, //fifo is full 19 | output [11:0] cnt // number of entries in FIFO 20 | ); 21 | 22 | //local signals and registers 23 | reg [15:0] mem [2047:0]; // 2048 words by 16 bit wide fifo memory (for 2 MFM-encoded sectors) 24 | reg [11:0] in_ptr; //fifo input pointer 25 | reg [11:0] out_ptr; //fifo output pointer 26 | wire equal; //lower 11 bits of in_ptr and out_ptr are equal 27 | 28 | 29 | // count of FIFO entries 30 | assign cnt = in_ptr - out_ptr; 31 | 32 | //main fifo memory (implemented using synchronous block ram) 33 | always @(posedge clk) begin 34 | if (clk7_en) begin 35 | if (wr) 36 | mem[in_ptr[10:0]] <= in; 37 | end 38 | end 39 | 40 | always @(posedge clk) begin 41 | if (clk7_en) begin 42 | out=mem[out_ptr[10:0]]; 43 | end 44 | end 45 | 46 | //fifo write pointer control 47 | always @(posedge clk) begin 48 | if (clk7_en) begin 49 | if (reset) 50 | in_ptr[11:0] <= 0; 51 | else if(wr) 52 | in_ptr[11:0] <= in_ptr[11:0] + 12'd1; 53 | end 54 | end 55 | 56 | // fifo read pointer control 57 | always @(posedge clk) begin 58 | if (clk7_en) begin 59 | if (reset) 60 | out_ptr[11:0] <= 0; 61 | else if (rd) 62 | out_ptr[11:0] <= out_ptr[11:0] + 12'd1; 63 | end 64 | end 65 | 66 | // check lower 11 bits of pointer to generate equal signal 67 | assign equal = (in_ptr[10:0]==out_ptr[10:0]) ? 1'b1 : 1'b0; 68 | 69 | // assign output flags, empty is delayed by one clock to handle ram delay 70 | always @(posedge clk) begin 71 | if (clk7_en) begin 72 | if (equal && (in_ptr[11]==out_ptr[11])) 73 | empty <= 1'b1; 74 | else 75 | empty <= 1'b0; 76 | end 77 | end 78 | 79 | assign full = (equal && (in_ptr[11]!=out_ptr[11])) ? 1'b1 : 1'b0; 80 | 81 | 82 | endmodule 83 | 84 | -------------------------------------------------------------------------------- /src/misc/amiga.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 101 | 102 | -------------------------------------------------------------------------------- /src/misc/hid.v: -------------------------------------------------------------------------------- 1 | /* 2 | hid.v 3 | 4 | hid (keyboard, mouse etc) interface to the IO MCU 5 | */ 6 | 7 | module hid ( 8 | input clk, 9 | input reset, 10 | 11 | input data_in_strobe, 12 | input data_in_start, 13 | input [7:0] data_in, 14 | output reg [7:0] data_out, 15 | 16 | // input local db9 port events to be sent to MCU to e.g. 17 | // be able to control the OSD via joystick connected 18 | // to the FPGA 19 | input [5:0] db9_port, 20 | output reg irq, 21 | input iack, 22 | 23 | // output HID data received from USB 24 | output reg [2:0] mouse_buttons, // mouse buttons 25 | output reg kbd_mouse_level, 26 | output reg [1:0] kbd_mouse_type, 27 | output reg [7:0] kbd_mouse_data, 28 | 29 | output reg [7:0] joystick0, 30 | output reg [7:0] joystick1 31 | ); 32 | 33 | reg [3:0] state; 34 | reg [7:0] command; 35 | reg [7:0] device; // used for joystick 36 | 37 | reg irq_enable; 38 | reg [5:0] db9_portD; 39 | reg [5:0] db9_portD2; 40 | 41 | wire [6:0] amiga_keycode; 42 | keymap keymap ( 43 | .code ( data_in[6:0] ), 44 | .amiga ( amiga_keycode ) 45 | ); 46 | 47 | // process mouse events 48 | always @(posedge clk) begin 49 | if(reset) begin 50 | state <= 4'd0; 51 | irq <= 1'b0; 52 | irq_enable <= 1'b0; 53 | kbd_mouse_level <= 1'b0; 54 | end else begin 55 | db9_portD <= db9_port; 56 | db9_portD2 <= db9_portD; 57 | 58 | // monitor db9 port for changes and raise interrupt 59 | if(irq_enable) begin 60 | if(db9_portD2 != db9_portD) begin 61 | // irq_enable prevents further interrupts until 62 | // the db9 state has actually been read by the MCU 63 | irq <= 1'b1; 64 | irq_enable <= 1'b0; 65 | end 66 | end 67 | 68 | if(iack) irq <= 1'b0; // iack clears interrupt 69 | 70 | if(data_in_strobe) begin 71 | if(data_in_start) begin 72 | state <= 4'd0; 73 | command <= data_in; 74 | end else begin 75 | if(state != 4'd15) state <= state + 4'd1; 76 | 77 | // CMD 0: status data 78 | if(command == 8'd0) begin 79 | // return some dummy data for now ... 80 | if(state == 4'd0) data_out <= 8'h01; // hid version 1 81 | if(state == 4'd1) data_out <= 8'h00; // subversion 0 82 | end 83 | 84 | // CMD 1: keyboard data 85 | // this Amiga variant of hid.v does not maintain a matrix. Instead 86 | // it just sends events 87 | if(command == 8'd1) begin 88 | if(state == 4'd0 && amiga_keycode != 7'h7f) begin 89 | kbd_mouse_level <= !kbd_mouse_level; 90 | kbd_mouse_type <= 2'd2; 91 | kbd_mouse_data <= { data_in[7], amiga_keycode }; 92 | end 93 | end 94 | 95 | // CMD 2: mouse data 96 | if(command == 8'd2) begin 97 | // we need to be careful here. The receiver runs on the 7Mhz clock 98 | // and we need to make sure that these two subsequent events don't come 99 | // too fast 100 | if(state == 4'd0) mouse_buttons <= data_in[2:0]; 101 | if(state == 4'd1) begin 102 | kbd_mouse_level <= !kbd_mouse_level; 103 | kbd_mouse_type <= 2'd0; 104 | kbd_mouse_data <= data_in; 105 | end 106 | if(state == 4'd2) begin 107 | kbd_mouse_level <= !kbd_mouse_level; 108 | kbd_mouse_type <= 2'd1; 109 | kbd_mouse_data <= data_in; 110 | end 111 | end 112 | 113 | // CMD 3: receive digital joystick data 114 | if(command == 8'd3) begin 115 | if(state == 4'd0) device <= data_in; 116 | if(state == 4'd1) begin 117 | if(device == 8'd0) joystick0 <= data_in; 118 | if(device == 8'd1) joystick1 <= data_in; 119 | end 120 | end 121 | 122 | // CMD 4: send digital joystick data to MCU 123 | if(command == 8'd4) begin 124 | if(state == 4'd0) irq_enable <= 1'b1; // (re-)enable interrupt 125 | data_out <= {2'b00, db9_portD }; 126 | end 127 | 128 | end 129 | end 130 | end 131 | end 132 | 133 | endmodule 134 | -------------------------------------------------------------------------------- /src/misc/mcu_spi.v: -------------------------------------------------------------------------------- 1 | /* 2 | mcu_spi.v 3 | 4 | SPI version of MCU interface 5 | */ 6 | 7 | module mcu_spi ( 8 | input clk, 9 | input reset, 10 | 11 | // SPI interface to MCU 12 | input spi_io_ss, 13 | input spi_io_clk, 14 | input spi_io_din, 15 | output reg spi_io_dout, 16 | 17 | // byte interface to the various core components 18 | output mcu_sys_strobe, // byte strobe for system control target 19 | output mcu_hid_strobe, // byte strobe for HID target 20 | output mcu_osd_strobe, // byte strobe for OSD target 21 | output mcu_sdc_strobe, // byte strobe for SD card target 22 | output mcu_start, 23 | input [7:0] mcu_sys_din, 24 | input [7:0] mcu_hid_din, 25 | input [7:0] mcu_osd_din, 26 | input [7:0] mcu_sdc_din, 27 | output [7:0] mcu_dout 28 | ); 29 | 30 | // SPI runs in MODE1 31 | // -> idle state of data is low 32 | // -> data is setup on rising clock edge 33 | // -> data is read on falling clock edge 34 | 35 | // bit/byte counter 36 | reg [3:0] spi_cnt; 37 | 38 | reg [7:0] spi_data_in; 39 | reg [6:0] spi_sr_in; 40 | reg spi_data_in_ready; 41 | 42 | // read data on falling edge of spi clock 43 | always @(negedge spi_io_clk or posedge spi_io_ss) begin 44 | if(spi_io_ss) begin 45 | spi_cnt <= 4'd0; 46 | end else begin 47 | // lower 3 bits cound bits, upper 8 bits count bytes 48 | spi_cnt <= spi_cnt + 4'd1; 49 | 50 | // shift bit in 51 | spi_sr_in <= { spi_sr_in[5:0], spi_io_din }; 52 | 53 | // byte ready? 54 | if(spi_cnt[2:0] == 3'd7) begin 55 | // latch byte and raise ready flag 56 | spi_data_in <= { spi_sr_in, spi_io_din }; 57 | spi_data_in_ready <= 1'b1; 58 | end 59 | 60 | // Clear data ready at bit 3. If the reading side 61 | // runs at 32 Mhz, this will work up to 64 MHz 62 | // SPI clock. At higher clocks the word width must 63 | // be increased. 64 | if(spi_cnt[2:0] == 3'd3) 65 | spi_data_in_ready <= 1'b0; 66 | end 67 | end // always @ (negedge spi_io_clk or posedge spi_io_ss) 68 | 69 | // bring received byte into local clock domain 70 | 71 | 72 | reg spi_in_strobe; 73 | reg [7:0] spi_target; 74 | assign mcu_sys_strobe = spi_in_strobe && spi_target == 8'd0; 75 | assign mcu_hid_strobe = spi_in_strobe && spi_target == 8'd1; 76 | assign mcu_osd_strobe = spi_in_strobe && spi_target == 8'd2; 77 | assign mcu_sdc_strobe = spi_in_strobe && spi_target == 8'd3; 78 | 79 | reg [7:0] spi_in_data; 80 | assign mcu_start = spi_in_cnt == 2; 81 | assign mcu_dout = spi_in_data; 82 | 83 | reg [3:0] spi_in_cnt; 84 | 85 | always @(posedge clk) begin 86 | reg [1:0] spi_data_in_readyD; 87 | spi_data_in_readyD <= { spi_data_in_readyD[0], spi_data_in_ready }; 88 | 89 | if(spi_io_ss) 90 | spi_in_cnt <= 4'd0; 91 | 92 | if(spi_data_in_readyD == 2'b01) begin 93 | // incoming SPI byte is now in local clock domain 94 | 95 | // first byte is target id. Else send external trigger 96 | if(spi_in_cnt == 4'd0) 97 | spi_target <= spi_data_in; 98 | else begin 99 | spi_in_strobe <= 1'b1; 100 | spi_in_data <= spi_data_in; 101 | end 102 | 103 | if(spi_in_cnt != 4'd15) 104 | spi_in_cnt <= spi_in_cnt + 4'd1; 105 | end else 106 | spi_in_strobe <= 1'b0; 107 | end 108 | 109 | wire [7:0] in_byte = 110 | (spi_target == 8'd0)?mcu_sys_din: 111 | (spi_target == 8'd1)?mcu_hid_din: 112 | (spi_target == 8'd2)?mcu_osd_din: 113 | (spi_target == 8'd3)?mcu_sdc_din: 114 | 8'h00; 115 | 116 | // setup data on rising edge of spi clock 117 | always @(posedge spi_io_clk or posedge spi_io_ss) begin 118 | if(spi_io_ss) begin 119 | // ... 120 | end else begin 121 | spi_io_dout <= in_byte[~spi_cnt[2:0]]; 122 | end 123 | end 124 | 125 | endmodule // osd_u8g2 126 | -------------------------------------------------------------------------------- /src/misc/video_analyzer.v: -------------------------------------------------------------------------------- 1 | // 2 | // video_analyzer.v 3 | // 4 | // try to derive video parameters from hs/vs/de 5 | // 6 | 7 | module video_analyzer 8 | ( 9 | // system interface 10 | input clk, 11 | input hs, 12 | input vs, 13 | output reg pal, // pal mode detected 14 | output reg short_frame, // short frame has two lines less 15 | output reg interlace, // interlace modes have one line less 16 | output reg vreset 17 | ); 18 | 19 | 20 | // generate a reset signal in the upper left corner of active video used 21 | // to synchonize the HDMI video generation to the Amiga 22 | reg vsD, hsD; 23 | reg [12:0] hcnt; // signal ranges 0..2047 24 | reg [12:0] hcntL; 25 | reg [10:0] vcnt; // signal ranges 0..625 26 | reg [10:0] vcntL; 27 | reg changed; 28 | 29 | always @(posedge clk) begin 30 | // ---- hsync processing ----- 31 | hsD <= hs; 32 | 33 | // begin of hsync, falling edge 34 | if(!hs && hsD) begin 35 | // check if line length has changed during last cycle 36 | hcntL <= hcnt; 37 | if(hcntL != hcnt) 38 | changed <= 1'b1; 39 | 40 | hcnt <= 0; 41 | end else 42 | hcnt <= hcnt + 13'd1; 43 | 44 | if(!hs && hsD) begin 45 | // ---- vsync processing ----- 46 | vsD <= vs; 47 | // begin of vsync, falling edge 48 | if(!vs && vsD) begin 49 | // check if image height has changed during last cycle 50 | vcntL <= vcnt; 51 | if(vcntL != vcnt) begin 52 | if(vcnt == 11'd523) begin 53 | pal <= 1'b0; // NTSC 54 | short_frame <= 1'b1; 55 | end 56 | if(vcnt == 11'd524 || vcnt == 11'd525) begin 57 | pal <= 1'b0; // NTSC 58 | short_frame <= 1'b0; 59 | end 60 | if(vcnt == 11'd623) begin 61 | pal <= 1'b1; // PAL 62 | short_frame <= 1'b1; 63 | end 64 | if(vcnt == 11'd624 || vcnt == 11'd625) begin 65 | pal <= 1'b1; // PAL 66 | short_frame <= 1'b0; 67 | end 68 | 69 | interlace <= !vcnt[0]; 70 | 71 | changed <= 1'b1; 72 | end 73 | 74 | vcnt <= 0; 75 | end else 76 | vcnt <= vcnt + 11'd1; 77 | end 78 | 79 | // the reset signal is sent to the HDMI generator. On reset the 80 | // HDMI re-adjusts its counters to the start of the visible screen 81 | // area 82 | 83 | vreset <= 1'b0; 84 | // account for back porches to adjust image position within the 85 | // HDMI frame 86 | if( hcnt == 120 && vcnt == 36 && changed) begin 87 | vreset <= 1'b1; 88 | changed <= 1'b0; 89 | end 90 | end 91 | 92 | endmodule 93 | -------------------------------------------------------------------------------- /src/misc/ws2812.v: -------------------------------------------------------------------------------- 1 | module ws2812 ( 2 | input clk, // input clock source 3 | input reset, // clock not stable enough 4 | input [23:0] color, // requested color 5 | output reg data // output to the interface of WS2812 6 | ); 7 | 8 | parameter WS2812_NUM = 0 ; // LED number of WS2812 (starts from 0) 9 | parameter WS2812_WIDTH = 24 ; // WS2812 data bit width 10 | parameter CLK_FRE = 28_375_160 ; // CLK frequency (mHZ) 11 | 12 | parameter DELAY_1_HIGH = (CLK_FRE / 1_000_000 * 0.85 ) - 1; //≈850ns±150ns 1 high level time 13 | parameter DELAY_1_LOW = (CLK_FRE / 1_000_000 * 0.40 ) - 1; //≈400ns±150ns 1 low level time 14 | parameter DELAY_0_HIGH = (CLK_FRE / 1_000_000 * 0.40 ) - 1; //≈400ns±150ns 0 high level time 15 | parameter DELAY_0_LOW = (CLK_FRE / 1_000_000 * 0.85 ) - 1; //≈850ns±150ns 0 low level time 16 | parameter DELAY_RESET = (CLK_FRE / 10 ) - 1; //0.1s reset time >50us 17 | 18 | parameter IDLE = 0; //state machine statement 19 | parameter DATA_SEND = 1; 20 | parameter BIT_SEND_HIGH = 2; 21 | parameter BIT_SEND_LOW = 3; 22 | 23 | parameter INIT_DATA = 24'b1111; // initial pattern 24 | 25 | reg [ 1:0] state = 0; // synthesis preserve - main state machine control 26 | reg [ 8:0] bit_send = 0; // number of bits sent - increase for larger led strips/matrix 27 | reg [ 8:0] data_send = 0; // number of data sent - increase for larger led strips/matrix 28 | reg [31:0] clk_count = 0; // delay control 29 | reg WS2812_data_valid = 0; 30 | reg [23:0] WS2812_data = 0; // WS2812 color data 31 | 32 | always@(posedge clk) begin 33 | if(reset) 34 | WS2812_data_valid <= 1'b0; 35 | else begin 36 | case (state) 37 | IDLE:begin 38 | data <= 0; 39 | if (clk_count < DELAY_RESET) begin 40 | clk_count <= clk_count + 1; 41 | end 42 | else begin 43 | clk_count <= 0; 44 | if (WS2812_data != color || !WS2812_data_valid) begin 45 | WS2812_data_valid <= 1'b1; 46 | WS2812_data <= color; 47 | state <= DATA_SEND; 48 | end 49 | end 50 | end 51 | 52 | DATA_SEND: 53 | if (data_send > WS2812_NUM && bit_send == WS2812_WIDTH)begin 54 | clk_count <= 0; 55 | data_send <= 0; 56 | bit_send <= 0; 57 | state <= IDLE; 58 | end 59 | else if (bit_send < WS2812_WIDTH) begin 60 | state <= BIT_SEND_HIGH; 61 | end 62 | else begin 63 | data_send <= data_send + 9'd1; 64 | bit_send <= 0; 65 | state <= BIT_SEND_HIGH; 66 | end 67 | 68 | BIT_SEND_HIGH:begin 69 | data <= 1; 70 | 71 | if (WS2812_data[bit_send]) 72 | if (clk_count < DELAY_1_HIGH) 73 | clk_count <= clk_count + 1; 74 | else begin 75 | clk_count <= 0; 76 | state <= BIT_SEND_LOW; 77 | end 78 | else 79 | if (clk_count < DELAY_0_HIGH) 80 | clk_count <= clk_count + 1; 81 | else begin 82 | clk_count <= 0; 83 | state <= BIT_SEND_LOW; 84 | end 85 | end 86 | 87 | BIT_SEND_LOW:begin 88 | data <= 0; 89 | 90 | if (WS2812_data[bit_send]) 91 | if (clk_count < DELAY_1_LOW) 92 | clk_count <= clk_count + 1; 93 | else begin 94 | clk_count <= 0; 95 | 96 | bit_send <= bit_send + 9'd1; 97 | state <= DATA_SEND; 98 | end 99 | else 100 | if (clk_count < DELAY_0_LOW) 101 | clk_count <= clk_count + 1; 102 | else begin 103 | clk_count <= 0; 104 | 105 | bit_send <= bit_send + 9'd1; 106 | state <= DATA_SEND; 107 | end 108 | end 109 | endcase // case (state) 110 | end 111 | end // always@ (posedge clk) 112 | 113 | endmodule 114 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_clkdiv/gowin_clkdiv.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=gowin_clkdiv 4 | module=Gowin_CLKDIV 5 | target_device=gw5a25a-002 6 | type=clock_clkdiv 7 | version=1.0 8 | 9 | [Config] 10 | Calibration=false 11 | Division_Factor=5 12 | Language=0 13 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_clkdiv/gowin_clkdiv.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name Gowin_CLKDIV 9 | -file_name gowin_clkdiv 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_clkdiv/ 11 | -type CLKDIV 12 | -file_type vlg 13 | -division_factor 5 14 | -calib false -------------------------------------------------------------------------------- /src/tang/console60k/gowin_clkdiv/gowin_clkdiv.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5A-LV25MG121NC1/I0 6 | //Device: GW5A-25 7 | //Device Version: A 8 | //Created Time: Sat Jan 4 14:37:40 2025 9 | 10 | module Gowin_CLKDIV (clkout, hclkin, resetn); 11 | 12 | output clkout; 13 | input hclkin; 14 | input resetn; 15 | 16 | wire gw_gnd; 17 | 18 | assign gw_gnd = 1'b0; 19 | 20 | CLKDIV clkdiv_inst ( 21 | .CLKOUT(clkout), 22 | .HCLKIN(hclkin), 23 | .RESETN(resetn), 24 | .CALIB(gw_gnd) 25 | ); 26 | 27 | defparam clkdiv_inst.DIV_MODE = "5"; 28 | 29 | endmodule //Gowin_CLKDIV 30 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_dpb/ide_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=ide_dpram 4 | module=ide_dpram 5 | target_device=gw5a25a-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=4096 13 | DEPTH_B=4096 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=16 20 | WIDTH_B=16 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_dpb/ide_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name ide_dpram 9 | -file_name ide_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5A-25A 15 | -depth_0 4096 16 | -depth_1 4096 17 | -width_0 16 18 | -width_1 16 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/console60k/gowin_dpb/sector_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=sector_dpram 4 | module=sector_dpram 5 | target_device=gw5a25a-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=512 13 | DEPTH_B=512 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=8 20 | WIDTH_B=8 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_dpb/sector_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name sector_dpram 9 | -file_name sector_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5A-25A 15 | -depth_0 512 16 | -depth_1 512 17 | -width_0 8 18 | -width_1 8 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/console60k/gowin_dpb/sector_dpram.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5A-LV25MG121NC1/I0 6 | //Device: GW5A-25 7 | //Device Version: A 8 | //Created Time: Sat Jan 4 14:41:33 2025 9 | 10 | module sector_dpram (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb); 11 | 12 | output [7:0] douta; 13 | output [7:0] doutb; 14 | input clka; 15 | input ocea; 16 | input cea; 17 | input reseta; 18 | input wrea; 19 | input clkb; 20 | input oceb; 21 | input ceb; 22 | input resetb; 23 | input wreb; 24 | input [8:0] ada; 25 | input [7:0] dina; 26 | input [8:0] adb; 27 | input [7:0] dinb; 28 | 29 | wire [7:0] dpb_inst_0_douta_w; 30 | wire [7:0] dpb_inst_0_doutb_w; 31 | wire gw_gnd; 32 | 33 | assign gw_gnd = 1'b0; 34 | 35 | DPB dpb_inst_0 ( 36 | .DOA({dpb_inst_0_douta_w[7:0],douta[7:0]}), 37 | .DOB({dpb_inst_0_doutb_w[7:0],doutb[7:0]}), 38 | .CLKA(clka), 39 | .OCEA(ocea), 40 | .CEA(cea), 41 | .RESETA(reseta), 42 | .WREA(wrea), 43 | .CLKB(clkb), 44 | .OCEB(oceb), 45 | .CEB(ceb), 46 | .RESETB(resetb), 47 | .WREB(wreb), 48 | .BLKSELA({gw_gnd,gw_gnd,gw_gnd}), 49 | .BLKSELB({gw_gnd,gw_gnd,gw_gnd}), 50 | .ADA({gw_gnd,gw_gnd,ada[8:0],gw_gnd,gw_gnd,gw_gnd}), 51 | .DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:0]}), 52 | .ADB({gw_gnd,gw_gnd,adb[8:0],gw_gnd,gw_gnd,gw_gnd}), 53 | .DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:0]}) 54 | ); 55 | 56 | defparam dpb_inst_0.READ_MODE0 = 1'b0; 57 | defparam dpb_inst_0.READ_MODE1 = 1'b0; 58 | defparam dpb_inst_0.WRITE_MODE0 = 2'b00; 59 | defparam dpb_inst_0.WRITE_MODE1 = 2'b00; 60 | defparam dpb_inst_0.BIT_WIDTH_0 = 8; 61 | defparam dpb_inst_0.BIT_WIDTH_1 = 8; 62 | defparam dpb_inst_0.BLK_SEL_0 = 3'b000; 63 | defparam dpb_inst_0.BLK_SEL_1 = 3'b000; 64 | defparam dpb_inst_0.RESET_MODE = "SYNC"; 65 | 66 | endmodule //sector_dpram 67 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_pll/pll_142m.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=pll_142m 4 | module=pll_142m 5 | target_device=gw5a25a-002 6 | type=clock_plladv 7 | version=1.0 8 | 9 | [Config] 10 | AdvancedMode=false 11 | ClkfbDivideFactorStatic=true 12 | ClkfbDivideFactorStaticValue=1 13 | ClkfbInternal=true 14 | ClkfboutExpectedFrequency=400 15 | ClkfboutTolerance=0.0 16 | ClkfboutVCODivideFactorStatic=true 17 | ClkfboutVCODivideFactorStaticValue=17 18 | ClkfboutVCOFractionalDivideFactorStaticValue=0 19 | ClkinClockFrequency=50 20 | ClkinDividerFactorStatic=true 21 | ClkinDividerFactorStaticValue=1 22 | ClkinDividerReset=false 23 | Clkou1BPhaseStatic=true 24 | Clkou2BPhaseStatic=true 25 | Clkou3BPhaseStatic=true 26 | Clkout0Bypass=false 27 | Clkout0DutyCycleDynamic=false 28 | Clkout0DutyCycleDynamicValue=0 29 | Clkout0DutyCycleStatic=true 30 | Clkout0DutyTrimStatic=true 31 | Clkout0DutyTrimStaticFalling=false 32 | Clkout0DutyTrimStaticRising=true 33 | Clkout0DutyTrimStaticStep=0 34 | Clkout0ExpectedFrequency=141.875 35 | Clkout0PhaseDynamic=false 36 | Clkout0PhaseStatic=true 37 | Clkout0PhaseStaticValue=0 38 | Clkout0Tolerance=0.2 39 | Clkout0VCODivideFactorStatic=true 40 | Clkout0VCODivideFactorStaticValue=6 41 | Clkout0VCOFractionalDivideFactorStaticValue=0 42 | Clkout1Bypass=false 43 | Clkout1DutyCycleDynamic=false 44 | Clkout1DutyCycleDynamicValue=0 45 | Clkout1DutyCycleStatic=true 46 | Clkout1DutyTrimStatic=true 47 | Clkout1DutyTrimStaticFalling=false 48 | Clkout1DutyTrimStaticRising=true 49 | Clkout1DutyTrimStaticStep=0 50 | Clkout1ExpectedFrequency=400 51 | Clkout1PhaseDynamic=false 52 | Clkout1PhaseStaticValue=0 53 | Clkout1Tolerance=0.0 54 | Clkout1VCODivideFactorStatic=true 55 | Clkout1VCODivideFactorStaticValue=8 56 | Clkout2Bypass=false 57 | Clkout2DutyCycleDynamic=false 58 | Clkout2DutyCycleDynamicValue=0 59 | Clkout2DutyCycleStatic=true 60 | Clkout2DutyTrimStatic=true 61 | Clkout2DutyTrimStaticFalling=false 62 | Clkout2DutyTrimStaticRising=true 63 | Clkout2DutyTrimStaticStep=0 64 | Clkout2ExpectedFrequency=400 65 | Clkout2PhaseDynamic=false 66 | Clkout2PhaseStaticValue=0 67 | Clkout2Tolerance=0.0 68 | Clkout2VCODivideFactorStatic=true 69 | Clkout2VCODivideFactorStaticValue=8 70 | Clkout3Bypass=false 71 | Clkout3DutyCycleDynamic=false 72 | Clkout3DutyCycleDynamicValue=0 73 | Clkout3DutyCycleStatic=true 74 | Clkout3DutyTrimStatic=true 75 | Clkout3DutyTrimStaticFalling=false 76 | Clkout3DutyTrimStaticRising=true 77 | Clkout3DutyTrimStaticStep=0 78 | Clkout3ExpectedFrequency=400 79 | Clkout3PhaseDynamic=false 80 | Clkout3PhaseStaticValue=0 81 | Clkout3Tolerance=0.0 82 | Clkout3VCODivideFactorStatic=true 83 | Clkout3VCODivideFactorStaticValue=8 84 | Clkout4Bypass=false 85 | Clkout4DutyCycleDynamic=false 86 | Clkout4DutyCycleDynamicValue=0 87 | Clkout4DutyCycleStatic=true 88 | Clkout4ExpectedFrequency=400 89 | Clkout4PhaseDynamic=false 90 | Clkout4PhaseStatic=true 91 | Clkout4PhaseStaticValue=0 92 | Clkout4Tolerance=0.0 93 | Clkout4VCODivideFactorStatic=true 94 | Clkout4VCODivideFactorStaticValue=8 95 | Clkout5Bypass=false 96 | Clkout5DutyCycleDynamic=false 97 | Clkout5DutyCycleDynamicValue=0 98 | Clkout5DutyCycleStatic=true 99 | Clkout5ExpectedFrequency=400 100 | Clkout5PhaseDynamic=false 101 | Clkout5PhaseStatic=true 102 | Clkout5PhaseStaticValue=0 103 | Clkout5Tolerance=0.0 104 | Clkout5VCODivideFactorStatic=true 105 | Clkout5VCODivideFactorStaticValue=8 106 | Clkout6Bypass=false 107 | Clkout6DutyCycleDynamic=false 108 | Clkout6DutyCycleDynamicValue=0 109 | Clkout6DutyCycleStatic=true 110 | Clkout6ExpectedFrequency=400 111 | Clkout6PhaseDynamic=false 112 | Clkout6PhaseStatic=true 113 | Clkout6PhaseStaticValue=0 114 | Clkout6Tolerance=0.0 115 | Clkout6VCODivideFactorStatic=true 116 | Clkout6VCODivideFactorStaticValue=8 117 | ClkoutDividerReset=false 118 | EnableCascade=false 119 | EnableClkfbout=false 120 | EnableClkout0Divider=false 121 | EnableClkout1=false 122 | EnableClkout1Divider=false 123 | EnableClkout2=false 124 | EnableClkout2Divider=false 125 | EnableClkout3=false 126 | EnableClkout3Divider=false 127 | EnableClkout4=false 128 | EnableClkout4Divider=false 129 | EnableClkout5=false 130 | EnableClkout5Divider=false 131 | EnableClkout6=false 132 | EnableClkout6Divider=false 133 | EnableLock=true 134 | EnableSsc=false 135 | GeneralMode=true 136 | ICPSELStatic=true 137 | ICPSELStaticValue=X 138 | LANG=0 139 | LPFCAPStaticValue=C0 140 | LPFRESStaticValue=X 141 | LPFSELStatic=true 142 | PLLPowerDown=false 143 | PLLReset=false 144 | clkfbExternal=false 145 | clkfbExternalValue= 146 | -------------------------------------------------------------------------------- /src/tang/console60k/gowin_pll/pll_142m.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name pll_142m 9 | -file_name pll_142m 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_pll/ 11 | -type PLL_ADV 12 | -file_type vlg 13 | -ssc false 14 | -rst false 15 | -rst_pwd false 16 | -rst_i false 17 | -rst_o false 18 | -fclkin 50 19 | -idiv_sel 1 20 | -clkfb_sel 0 21 | -fbdiv_sel 1 22 | -en_lock true 23 | -dyn_dpa_en false 24 | -clkout0_bypass false 25 | -odiv0_sel 6 26 | -odiv0_frac_sel 0 27 | -clkout0_dt_dir 1 28 | -clkout0_dt_step 0 29 | -dyn_pe0_sel false 30 | -clkout0_pe_coarse 0 31 | -clkout0_pe_fine 0 32 | -de0_en false 33 | -clkout0_dt_dir 1 34 | -clkout0_dt_step 0 35 | -en_clkout1 false 36 | -en_clkout2 false 37 | -en_clkout3 false 38 | -en_clkout4 false 39 | -en_clkout5 false 40 | -en_clkout6 false 41 | -en_clkfbout false 42 | -mdiv_sel 17 43 | -mdiv_frac_sel 0 -------------------------------------------------------------------------------- /src/tang/console60k/nanomig.sdc: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 GOWIN Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: Timing Constraints file 4 | //Tool Version: V1.9.9 5 | //Created Time: 2024-02-23 19:02:18 6 | // create_clock -name clk_hdmi -period 6.25 -waveform {0 3.125} [get_nets {video2hdmi/clk_pixel_x5}] -add 7 | // create_clock -name clk_flash -period 10 -waveform {0 5} [get_nets {flash_clk}] 8 | create_clock -name clk_spi -period 10 -waveform {0 5} [get_ports {mspi_clk}] -add 9 | create_clock -name clk_32 -period 31 -waveform {0 15} [get_ports {O_sdram_clk}] -add 10 | create_clock -name clk_osc -period 20 -waveform {0 10} [get_ports {clk}] -add 11 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_clkdiv/gowin_clkdiv.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=gowin_clkdiv 4 | module=Gowin_CLKDIV 5 | target_device=gw5ast138b-002 6 | type=clock_clkdiv 7 | version=1.0 8 | 9 | [Config] 10 | Calibration=false 11 | Division_Factor=5 12 | Language=0 13 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_clkdiv/gowin_clkdiv.mod: -------------------------------------------------------------------------------- 1 | -series GW5AST 2 | -device GW5AST-138 3 | -device_version B 4 | -package FCPBGA676A 5 | -part_number GW5AST-LV138FPG676AES 6 | 7 | 8 | -mod_name Gowin_CLKDIV 9 | -file_name gowin_clkdiv 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/mega138k/gowin_clkdiv/ 11 | -type CLKDIV 12 | -file_type vlg 13 | -division_factor 5 14 | -calib false -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_clkdiv/gowin_clkdiv.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5AST-LV138FPG676AES 6 | //Device: GW5AST-138 7 | //Device Version: B 8 | //Created Time: Thu Jan 2 17:10:44 2025 9 | 10 | module Gowin_CLKDIV (clkout, hclkin, resetn); 11 | 12 | output clkout; 13 | input hclkin; 14 | input resetn; 15 | 16 | wire gw_gnd; 17 | 18 | assign gw_gnd = 1'b0; 19 | 20 | CLKDIV clkdiv_inst ( 21 | .CLKOUT(clkout), 22 | .HCLKIN(hclkin), 23 | .RESETN(resetn), 24 | .CALIB(gw_gnd) 25 | ); 26 | 27 | defparam clkdiv_inst.DIV_MODE = "5"; 28 | 29 | endmodule //Gowin_CLKDIV 30 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_dpb/ide_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=ide_dpram 4 | module=ide_dpram 5 | target_device=gw5ast138b-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=4096 13 | DEPTH_B=4096 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=16 20 | WIDTH_B=16 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_dpb/ide_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5AST 2 | -device GW5AST-138 3 | -device_version B 4 | -package FCPBGA676A 5 | -part_number GW5AST-LV138FPG676AES 6 | 7 | 8 | -mod_name ide_dpram 9 | -file_name ide_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/src/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5AST-138B 15 | -depth_0 4096 16 | -depth_1 4096 17 | -width_0 16 18 | -width_1 16 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_dpb/sector_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=sector_dpram 4 | module=sector_dpram 5 | target_device=gw5ast138b-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=512 13 | DEPTH_B=512 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=8 20 | WIDTH_B=8 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_dpb/sector_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5AST 2 | -device GW5AST-138 3 | -device_version B 4 | -package FCPBGA676A 5 | -part_number GW5AST-LV138FPG676AES 6 | 7 | 8 | -mod_name sector_dpram 9 | -file_name sector_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/mega138k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5AST-138B 15 | -depth_0 512 16 | -depth_1 512 17 | -width_0 8 18 | -width_1 8 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_dpb/sector_dpram.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5AST-LV138FPG676AES 6 | //Device: GW5AST-138 7 | //Device Version: B 8 | //Created Time: Thu Jan 2 17:13:10 2025 9 | 10 | module sector_dpram (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb); 11 | 12 | output [7:0] douta; 13 | output [7:0] doutb; 14 | input clka; 15 | input ocea; 16 | input cea; 17 | input reseta; 18 | input wrea; 19 | input clkb; 20 | input oceb; 21 | input ceb; 22 | input resetb; 23 | input wreb; 24 | input [8:0] ada; 25 | input [7:0] dina; 26 | input [8:0] adb; 27 | input [7:0] dinb; 28 | 29 | wire [7:0] dpb_inst_0_douta_w; 30 | wire [7:0] dpb_inst_0_doutb_w; 31 | wire gw_gnd; 32 | 33 | assign gw_gnd = 1'b0; 34 | 35 | DPB dpb_inst_0 ( 36 | .DOA({dpb_inst_0_douta_w[7:0],douta[7:0]}), 37 | .DOB({dpb_inst_0_doutb_w[7:0],doutb[7:0]}), 38 | .CLKA(clka), 39 | .OCEA(ocea), 40 | .CEA(cea), 41 | .RESETA(reseta), 42 | .WREA(wrea), 43 | .CLKB(clkb), 44 | .OCEB(oceb), 45 | .CEB(ceb), 46 | .RESETB(resetb), 47 | .WREB(wreb), 48 | .BLKSELA({gw_gnd,gw_gnd,gw_gnd}), 49 | .BLKSELB({gw_gnd,gw_gnd,gw_gnd}), 50 | .ADA({gw_gnd,gw_gnd,ada[8:0],gw_gnd,gw_gnd,gw_gnd}), 51 | .DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:0]}), 52 | .ADB({gw_gnd,gw_gnd,adb[8:0],gw_gnd,gw_gnd,gw_gnd}), 53 | .DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:0]}) 54 | ); 55 | 56 | defparam dpb_inst_0.READ_MODE0 = 1'b0; 57 | defparam dpb_inst_0.READ_MODE1 = 1'b0; 58 | defparam dpb_inst_0.WRITE_MODE0 = 2'b00; 59 | defparam dpb_inst_0.WRITE_MODE1 = 2'b00; 60 | defparam dpb_inst_0.BIT_WIDTH_0 = 8; 61 | defparam dpb_inst_0.BIT_WIDTH_1 = 8; 62 | defparam dpb_inst_0.BLK_SEL_0 = 3'b000; 63 | defparam dpb_inst_0.BLK_SEL_1 = 3'b000; 64 | defparam dpb_inst_0.RESET_MODE = "SYNC"; 65 | 66 | endmodule //sector_dpram 67 | -------------------------------------------------------------------------------- /src/tang/mega138k/gowin_pll/pll_142m.mod: -------------------------------------------------------------------------------- 1 | -series GW5AST 2 | -device GW5AST-138 3 | -device_version B 4 | -package FCPBGA676A 5 | -part_number GW5AST-LV138FPG676AES 6 | 7 | 8 | -mod_name pll_142m 9 | -file_name pll_142m 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/mega138k/gowin_pll/ 11 | -type PLL_ADV 12 | -file_type vlg 13 | -ssc false 14 | -clock_en false 15 | -rst false 16 | -rst_pwd false 17 | -rst_i false 18 | -rst_o false 19 | -fclkin 50 20 | -dyn_idiv_sel false 21 | -idiv_sel 1 22 | -clkfb_sel 0 23 | -dyn_fbdiv_sel false 24 | -fbdiv_sel 1 25 | -en_lock true 26 | -dyn_dpa_en false 27 | -clkout0_bypass false 28 | -dyn_odiv0_sel false 29 | -odiv0_sel 6 30 | -odiv0_frac_sel 0 31 | -dyn_dt0_sel false 32 | -clkout0_dt_dir 1 33 | -clkout0_dt_step 0 34 | -dyn_pe0_sel false 35 | -clkout0_pe_coarse 0 36 | -clkout0_pe_fine 0 37 | -de0_en false 38 | -dyn_dt0_sel false 39 | -clkout0_dt_dir 1 40 | -clkout0_dt_step 0 41 | -en_clkout1 false 42 | -en_clkout2 false 43 | -en_clkout3 false 44 | -en_clkout4 false 45 | -en_clkout5 false 46 | -en_clkout6 false 47 | -en_clkfbout false 48 | -dyn_mdiv_sel false 49 | -mdiv_sel 17 50 | -mdiv_frac_sel 0 -------------------------------------------------------------------------------- /src/tang/mega138k/nanomig.sdc: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 GOWIN Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: Timing Constraints file 4 | //Tool Version: V1.9.9 5 | //Created Time: 2024-02-23 19:02:18 6 | // create_clock -name clk_hdmi -period 6.25 -waveform {0 3.125} [get_nets {video2hdmi/clk_pixel_x5}] -add 7 | // create_clock -name clk_flash -period 10 -waveform {0 5} [get_nets {flash_clk}] 8 | create_clock -name clk_spi -period 10 -waveform {0 5} [get_ports {mspi_clk}] -add 9 | create_clock -name clk_32 -period 31 -waveform {0 15} [get_ports {O_sdram_clk}] -add 10 | create_clock -name clk_osc -period 20 -waveform {0 10} [get_ports {clk}] -add 11 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_clkdiv/gowin_clkdiv.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=gowin_clkdiv 4 | module=Gowin_CLKDIV 5 | target_device=gw1nr9c-004 6 | type=clock_clkdiv 7 | version=1.0 8 | 9 | [Config] 10 | Calibration=false 11 | Division_Factor=5 12 | Language=0 13 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_clkdiv/gowin_clkdiv.mod: -------------------------------------------------------------------------------- 1 | -series GW1NR 2 | -device GW1NR-9C 3 | -package QFN88P 4 | -part_number GW1NR-LV9QN88PC6/I5 5 | 6 | 7 | -mod_name Gowin_CLKDIV 8 | -file_name gowin_clkdiv 9 | -path D:/verilog_wb/gowin/picotiny/src/gowin_clkdiv/ 10 | -type CLKDIV 11 | -file_type vlg 12 | -division_factor 5 13 | -calib false -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_clkdiv/gowin_clkdiv.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2021 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //GOWIN Version: V1.9.8 5 | //Part Number: GW1NR-LV9QN88PC6/I5 6 | //Device: GW1NR-9C 7 | //Created Time: Fri Nov 12 13:46:33 2021 8 | 9 | module Gowin_CLKDIV (clkout, hclkin, resetn); 10 | 11 | output clkout; 12 | input hclkin; 13 | input resetn; 14 | 15 | wire gw_gnd; 16 | 17 | assign gw_gnd = 1'b0; 18 | 19 | CLKDIV clkdiv_inst ( 20 | .CLKOUT(clkout), 21 | .HCLKIN(hclkin), 22 | .RESETN(resetn), 23 | .CALIB(gw_gnd) 24 | ); 25 | 26 | defparam clkdiv_inst.DIV_MODE = "5"; 27 | defparam clkdiv_inst.GSREN = "false"; 28 | 29 | endmodule //Gowin_CLKDIV 30 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_dpb/ide_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=ide_dpram 4 | module=ide_dpram 5 | target_device=gw2ar18c-000 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=4096 13 | DEPTH_B=4096 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=16 20 | WIDTH_B=16 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_dpb/ide_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW2AR 2 | -device GW2AR-18 3 | -device_version C 4 | -package QFN88 5 | -part_number GW2AR-LV18QN88C8/I7 6 | 7 | 8 | -mod_name ide_dpram 9 | -file_name ide_dpram 10 | -path /home/tharbaum/tmp/private_stuff/mistlite/nanomig/src/tang/nano20k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW2AR-18C 15 | -depth_0 4096 16 | -depth_1 4096 17 | -width_0 16 18 | -width_1 16 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_dpb/sector_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=sector_dpram 4 | module=sector_dpram 5 | target_device=gw2ar18c-000 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=512 13 | DEPTH_B=512 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=8 20 | WIDTH_B=8 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_dpb/sector_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW2AR 2 | -device GW2AR-18 3 | -device_version C 4 | -package QFN88 5 | -part_number GW2AR-LV18QN88C8/I7 6 | 7 | 8 | -mod_name sector_dpram 9 | -file_name sector_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/atarist/tangnano20k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW2AR-18C 15 | -depth_0 512 16 | -depth_1 512 17 | -width_0 8 18 | -width_1 8 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_dpb/sector_dpram.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2023 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.9 5 | //Part Number: GW2AR-LV18QN88C8/I7 6 | //Device: GW2AR-18 7 | //Device Version: C 8 | //Created Time: Tue Jan 2 16:32:52 2024 9 | 10 | module sector_dpram (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb); 11 | 12 | output [7:0] douta; 13 | output [7:0] doutb; 14 | input clka; 15 | input ocea; 16 | input cea; 17 | input reseta; 18 | input wrea; 19 | input clkb; 20 | input oceb; 21 | input ceb; 22 | input resetb; 23 | input wreb; 24 | input [8:0] ada; 25 | input [7:0] dina; 26 | input [8:0] adb; 27 | input [7:0] dinb; 28 | 29 | wire [7:0] dpb_inst_0_douta_w; 30 | wire [7:0] dpb_inst_0_doutb_w; 31 | wire gw_gnd; 32 | 33 | assign gw_gnd = 1'b0; 34 | 35 | DPB dpb_inst_0 ( 36 | .DOA({dpb_inst_0_douta_w[7:0],douta[7:0]}), 37 | .DOB({dpb_inst_0_doutb_w[7:0],doutb[7:0]}), 38 | .CLKA(clka), 39 | .OCEA(ocea), 40 | .CEA(cea), 41 | .RESETA(reseta), 42 | .WREA(wrea), 43 | .CLKB(clkb), 44 | .OCEB(oceb), 45 | .CEB(ceb), 46 | .RESETB(resetb), 47 | .WREB(wreb), 48 | .BLKSELA({gw_gnd,gw_gnd,gw_gnd}), 49 | .BLKSELB({gw_gnd,gw_gnd,gw_gnd}), 50 | .ADA({gw_gnd,gw_gnd,ada[8:0],gw_gnd,gw_gnd,gw_gnd}), 51 | .DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:0]}), 52 | .ADB({gw_gnd,gw_gnd,adb[8:0],gw_gnd,gw_gnd,gw_gnd}), 53 | .DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:0]}) 54 | ); 55 | 56 | defparam dpb_inst_0.READ_MODE0 = 1'b0; 57 | defparam dpb_inst_0.READ_MODE1 = 1'b0; 58 | defparam dpb_inst_0.WRITE_MODE0 = 2'b00; 59 | defparam dpb_inst_0.WRITE_MODE1 = 2'b00; 60 | defparam dpb_inst_0.BIT_WIDTH_0 = 8; 61 | defparam dpb_inst_0.BIT_WIDTH_1 = 8; 62 | defparam dpb_inst_0.BLK_SEL_0 = 3'b000; 63 | defparam dpb_inst_0.BLK_SEL_1 = 3'b000; 64 | defparam dpb_inst_0.RESET_MODE = "SYNC"; 65 | 66 | endmodule //sector_dpram 67 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_rpll/pll_142m.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=pll_142m 4 | module=pll_142m 5 | target_device=gw2ar18c-000 6 | type=clock_rpll 7 | version=1.0 8 | 9 | [Config] 10 | CKLOUTD3=false 11 | CLKFB_SOURCE=0 12 | CLKIN_FREQ=27 13 | CLKOUTD=false 14 | CLKOUTP=false 15 | CLKOUT_BYPASS=false 16 | CLKOUT_DIVIDE_DYN=true 17 | CLKOUT_FREQ=141.75 18 | CLKOUT_TOLERANCE=0 19 | DYNAMIC=true 20 | LANG=0 21 | LOCK_EN=true 22 | MODE_GENERAL=true 23 | PLL_PWD=false 24 | RESET_PLL=false 25 | -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_rpll/pll_142m.mod: -------------------------------------------------------------------------------- 1 | -series GW2AR 2 | -device GW2AR-18 3 | -device_version C 4 | -package QFN88 5 | -part_number GW2AR-LV18QN88C8/I7 6 | 7 | 8 | -mod_name pll_142m 9 | -file_name pll_142m 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/nano20k/gowin_rpll/ 11 | -type PLL 12 | -rPll true 13 | -file_type vlg 14 | -dev_type GW2AR-18C 15 | -dyn_idiv_sel false 16 | -idiv_sel 4 17 | -dyn_fbdiv_sel false 18 | -fbdiv_sel 21 19 | -dyn_odiv_sel false 20 | -odiv_sel 4 21 | -dyn_da_en true 22 | -rst_sig false 23 | -rst_sig_p false 24 | -fclkin 27 25 | -clkfb_sel 0 26 | -en_lock true 27 | -clkout_bypass false 28 | -clkout_ft_dir 1 29 | -en_clkoutp false 30 | -clkoutp_bypass false 31 | -en_clkoutd false 32 | -clkoutd_bypass false 33 | -en_clkoutd3 false -------------------------------------------------------------------------------- /src/tang/nano20k/gowin_rpll/pll_142m.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.9.02 5 | //Part Number: GW2AR-LV18QN88C8/I7 6 | //Device: GW2AR-18 7 | //Device Version: C 8 | //Created Time: Fri May 3 17:37:31 2024 9 | 10 | module pll_142m (clkout, lock, clkin); 11 | 12 | output clkout; 13 | output lock; 14 | input clkin; 15 | 16 | wire clkoutp_o; 17 | wire clkoutd_o; 18 | wire clkoutd3_o; 19 | wire gw_gnd; 20 | 21 | assign gw_gnd = 1'b0; 22 | 23 | rPLL rpll_inst ( 24 | .CLKOUT(clkout), 25 | .LOCK(lock), 26 | .CLKOUTP(clkoutp_o), 27 | .CLKOUTD(clkoutd_o), 28 | .CLKOUTD3(clkoutd3_o), 29 | .RESET(gw_gnd), 30 | .RESET_P(gw_gnd), 31 | .CLKIN(clkin), 32 | .CLKFB(gw_gnd), 33 | .FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}), 34 | .IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}), 35 | .ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}), 36 | .PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}), 37 | .DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}), 38 | .FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd}) 39 | ); 40 | 41 | defparam rpll_inst.FCLKIN = "27"; 42 | defparam rpll_inst.DYN_IDIV_SEL = "false"; 43 | defparam rpll_inst.IDIV_SEL = 3; 44 | defparam rpll_inst.DYN_FBDIV_SEL = "false"; 45 | defparam rpll_inst.FBDIV_SEL = 20; 46 | defparam rpll_inst.DYN_ODIV_SEL = "false"; 47 | defparam rpll_inst.ODIV_SEL = 4; 48 | defparam rpll_inst.PSDA_SEL = "0000"; 49 | defparam rpll_inst.DYN_DA_EN = "true"; 50 | defparam rpll_inst.DUTYDA_SEL = "1000"; 51 | defparam rpll_inst.CLKOUT_FT_DIR = 1'b1; 52 | defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1; 53 | defparam rpll_inst.CLKOUT_DLY_STEP = 0; 54 | defparam rpll_inst.CLKOUTP_DLY_STEP = 0; 55 | defparam rpll_inst.CLKFB_SEL = "internal"; 56 | defparam rpll_inst.CLKOUT_BYPASS = "false"; 57 | defparam rpll_inst.CLKOUTP_BYPASS = "false"; 58 | defparam rpll_inst.CLKOUTD_BYPASS = "false"; 59 | defparam rpll_inst.DYN_SDIV_SEL = 2; 60 | defparam rpll_inst.CLKOUTD_SRC = "CLKOUT"; 61 | defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT"; 62 | defparam rpll_inst.DEVICE = "GW2AR-18C"; 63 | 64 | endmodule //pll_142m 65 | -------------------------------------------------------------------------------- /src/tang/nano20k/nanomig.cst: -------------------------------------------------------------------------------- 1 | 2 | // digital video 3 | IO_LOC "tmds_clk_p" 33,34; 4 | IO_PORT "tmds_clk_p" PULL_MODE=NONE DRIVE=8; 5 | IO_LOC "tmds_d_p[0]" 35,36; 6 | IO_PORT "tmds_d_p[0]" PULL_MODE=NONE DRIVE=8; 7 | IO_LOC "tmds_d_p[1]" 37,38; 8 | IO_PORT "tmds_d_p[1]" PULL_MODE=NONE DRIVE=8; 9 | IO_LOC "tmds_d_p[2]" 39,40; 10 | IO_PORT "tmds_d_p[2]" PULL_MODE=NONE DRIVE=8; 11 | 12 | // the six on-board leds 13 | IO_LOC "leds_n[5]" 20; 14 | IO_PORT "leds_n[5]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 15 | IO_LOC "leds_n[4]" 19; 16 | IO_PORT "leds_n[4]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 17 | IO_LOC "leds_n[3]" 18; 18 | IO_PORT "leds_n[3]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 19 | IO_LOC "leds_n[2]" 17; 20 | IO_PORT "leds_n[2]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 21 | IO_LOC "leds_n[1]" 16; 22 | IO_PORT "leds_n[1]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 23 | IO_LOC "leds_n[0]" 15; 24 | IO_PORT "leds_n[0]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 25 | 26 | // ws2812 led 27 | IO_LOC "ws2812" 79; 28 | IO_PORT "ws2812" DRIVE=8 IO_TYPE=LVCMOS33; 29 | 30 | // SPI flash 31 | IO_LOC "mspi_wp" 57; 32 | IO_PORT "mspi_wp" PULL_MODE=DOWN IO_TYPE=LVCMOS33; 33 | IO_LOC "mspi_clk" 59; 34 | IO_PORT "mspi_clk" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 35 | IO_LOC "mspi_cs" 60; 36 | IO_PORT "mspi_cs" PULL_MODE=UP IO_TYPE=LVCMOS33; 37 | IO_LOC "mspi_di" 61; 38 | IO_PORT "mspi_di" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 39 | IO_LOC "mspi_do" 62; 40 | IO_PORT "mspi_do" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 41 | IO_LOC "mspi_hold" 63; 42 | IO_PORT "mspi_hold" PULL_MODE=NONE IO_TYPE=LVCMOS33; 43 | 44 | // SD card 45 | IO_LOC "sd_clk" 83; 46 | IO_PORT "sd_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; 47 | IO_LOC "sd_cmd" 82; // MOSI 48 | IO_PORT "sd_cmd" PULL_MODE=NONE IO_TYPE=LVCMOS33; 49 | IO_LOC "sd_dat[0]" 84; // MISO 50 | IO_PORT "sd_dat[0]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 51 | IO_LOC "sd_dat[1]" 85; 52 | IO_PORT "sd_dat[1]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 53 | IO_LOC "sd_dat[2]" 80; 54 | IO_PORT "sd_dat[2]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 55 | IO_LOC "sd_dat[3]" 81; 56 | IO_PORT "sd_dat[3]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 57 | 58 | // generic IO pins to use for e.g. db9 mouse or joystick 59 | IO_LOC "io[0]" 27; 60 | IO_PORT "io[0]" PULL_MODE=UP IO_TYPE=LVCMOS33; 61 | IO_LOC "io[1]" 28; 62 | IO_PORT "io[1]" PULL_MODE=UP IO_TYPE=LVCMOS33; 63 | IO_LOC "io[2]" 25; 64 | IO_PORT "io[2]" PULL_MODE=UP IO_TYPE=LVCMOS33; 65 | IO_LOC "io[3]" 26; 66 | IO_PORT "io[3]" PULL_MODE=UP IO_TYPE=LVCMOS33; 67 | IO_LOC "io[4]" 29; 68 | IO_PORT "io[4]" PULL_MODE=UP IO_TYPE=LVCMOS33; 69 | IO_LOC "io[5]" 30; 70 | IO_PORT "io[5]" PULL_MODE=UP IO_TYPE=LVCMOS33; 71 | IO_LOC "io[6]" 31; 72 | IO_PORT "io[6]" PULL_MODE=UP IO_TYPE=LVCMOS33; 73 | IO_LOC "io[7]" 77; 74 | IO_PORT "io[7]" PULL_MODE=UP IO_TYPE=LVCMOS33; 75 | 76 | // connection to the external BL616/M0S 77 | IO_LOC "m0s[0]" 42; 78 | IO_PORT "m0s[0]" PULL_MODE=UP IO_TYPE=LVCMOS33; 79 | IO_LOC "m0s[1]" 41; 80 | IO_PORT "m0s[1]" PULL_MODE=UP IO_TYPE=LVCMOS33; 81 | IO_LOC "m0s[2]" 56; 82 | IO_PORT "m0s[2]" PULL_MODE=UP IO_TYPE=LVCMOS33; 83 | IO_LOC "m0s[3]" 54; 84 | IO_PORT "m0s[3]" PULL_MODE=UP IO_TYPE=LVCMOS33; 85 | IO_LOC "m0s[4]" 51; 86 | IO_PORT "m0s[4]" PULL_MODE=UP IO_TYPE=LVCMOS33; 87 | IO_LOC "m0s[5]" 48; 88 | IO_PORT "m0s[5]" PULL_MODE=UP IO_TYPE=LVCMOS33; 89 | 90 | // connections to the internal BL616 controller 91 | IO_LOC "spi_csn" 86; 92 | IO_PORT "spi_csn" PULL_MODE=UP IO_TYPE=LVCMOS33; 93 | IO_LOC "spi_sclk" 13; 94 | IO_PORT "spi_sclk" PULL_MODE=UP IO_TYPE=LVCMOS33; 95 | IO_LOC "spi_dat" 76; 96 | IO_PORT "spi_dat" PULL_MODE=UP IO_TYPE=LVCMOS33; 97 | IO_LOC "spi_dir" 75; 98 | IO_PORT "spi_dir" PULL_MODE=UP IO_TYPE=LVCMOS33; 99 | 100 | // two on-board buttons 101 | IO_LOC "user" 88; 102 | IO_PORT "user" IO_TYPE=LVCMOS33 PULL_MODE=DOWN; 103 | IO_LOC "reset" 87; 104 | IO_PORT "reset" IO_TYPE=LVCMOS33 PULL_MODE=DOWN; 105 | 106 | // MIDI 107 | IO_LOC "midi_out" 71; 108 | IO_PORT "midi_out" IO_TYPE=LVCMOS33 DRIVE=8 PULL_MODE=NONE; 109 | IO_LOC "midi_in" 72; 110 | IO_PORT "midi_in" IO_TYPE=LVCMOS33 PULL_MODE=DOWN; 111 | 112 | // re-used JTAG pins as spi_dat (above) is not really 113 | // usable as there are resistors and capacistors that 114 | // limit the max data rate 115 | // IO_LOC "jtag_tck" 6; 116 | // IO_PORT "jtag_tck" IO_TYPE=LVCMOS33 PULL_MODE=UP; 117 | 118 | IO_LOC "clk" 4; 119 | IO_PORT "clk" PULL_MODE=UP; 120 | -------------------------------------------------------------------------------- /src/tang/nano20k/nanomig.sdc: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 GOWIN Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: Timing Constraints file 4 | //Tool Version: V1.9.9.03 5 | //Created Time: 2024-05-24 22:03:19 6 | // create_clock -name clk_7m -period 142.045 -waveform {0 71.022} [get_nets {clk_cnt[1]}] 7 | // create_clock -name clk_28m -period 35.511 -waveform {0 17.755} [get_nets {clk_sys}] 8 | create_clock -name clk_hdmi -period 7 -waveform {0 3} [get_nets {clk_pixel_x5}] -add 9 | create_clock -name clk_osc -period 37 -waveform {0 18} [get_ports {clk}] -add 10 | create_clock -name clk_spi -period 14.085 -waveform {0 7.04} [get_ports {mspi_clk}] -add 11 | -------------------------------------------------------------------------------- /src/tang/nano20k/nanomig_lcd.cst: -------------------------------------------------------------------------------- 1 | // the six on-board leds 2 | IO_LOC "leds_n[5]" 20; 3 | IO_PORT "leds_n[5]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 4 | IO_LOC "leds_n[4]" 19; 5 | IO_PORT "leds_n[4]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 6 | IO_LOC "leds_n[3]" 18; 7 | IO_PORT "leds_n[3]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 8 | IO_LOC "leds_n[2]" 17; 9 | IO_PORT "leds_n[2]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 10 | IO_LOC "leds_n[1]" 16; 11 | IO_PORT "leds_n[1]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 12 | IO_LOC "leds_n[0]" 15; 13 | IO_PORT "leds_n[0]" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 14 | 15 | // ws2812 led 16 | IO_LOC "ws2812" 79; 17 | IO_PORT "ws2812" DRIVE=8 IO_TYPE=LVCMOS33; 18 | 19 | // SPI flash 20 | IO_LOC "mspi_wp" 57; 21 | IO_PORT "mspi_wp" PULL_MODE=DOWN IO_TYPE=LVCMOS33; 22 | IO_LOC "mspi_clk" 59; 23 | IO_PORT "mspi_clk" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 24 | IO_LOC "mspi_cs" 60; 25 | IO_PORT "mspi_cs" PULL_MODE=UP IO_TYPE=LVCMOS33; 26 | IO_LOC "mspi_di" 61; 27 | IO_PORT "mspi_di" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 28 | IO_LOC "mspi_do" 62; 29 | IO_PORT "mspi_do" PULL_MODE=NONE DRIVE=8 IO_TYPE=LVCMOS33; 30 | IO_LOC "mspi_hold" 63; 31 | IO_PORT "mspi_hold" PULL_MODE=NONE IO_TYPE=LVCMOS33; 32 | 33 | // SD card 34 | IO_LOC "sd_clk" 83; 35 | IO_PORT "sd_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; 36 | IO_LOC "sd_cmd" 82; // MOSI 37 | IO_PORT "sd_cmd" PULL_MODE=NONE IO_TYPE=LVCMOS33; 38 | IO_LOC "sd_dat[0]" 84; // MISO 39 | IO_PORT "sd_dat[0]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 40 | IO_LOC "sd_dat[1]" 85; 41 | IO_PORT "sd_dat[1]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 42 | IO_LOC "sd_dat[2]" 80; 43 | IO_PORT "sd_dat[2]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 44 | IO_LOC "sd_dat[3]" 81; 45 | IO_PORT "sd_dat[3]" PULL_MODE=NONE IO_TYPE=LVCMOS33; 46 | 47 | // internal LCD 48 | IO_LOC "lcd_dclk" 77; 49 | IO_PORT "lcd_dclk" IO_TYPE=LVCMOS33; 50 | IO_LOC "lcd_hs" 25; 51 | IO_PORT "lcd_hs" IO_TYPE=LVCMOS33; 52 | IO_LOC "lcd_vs" 26; 53 | IO_PORT "lcd_vs" IO_TYPE=LVCMOS33; 54 | IO_LOC "lcd_de" 48; 55 | IO_PORT "lcd_bl" PULL_MODE=DOWN IO_TYPE=LVCMOS33; 56 | IO_LOC "lcd_bl" 49; 57 | IO_PORT "lcd_de" IO_TYPE=LVCMOS33; 58 | IO_LOC "lcd_r[0]" 42; 59 | IO_PORT "lcd_r[0]" IO_TYPE=LVCMOS33 DRIVE=24; 60 | IO_LOC "lcd_r[1]" 41; 61 | IO_PORT "lcd_r[1]" IO_TYPE=LVCMOS33 DRIVE=24; 62 | IO_LOC "lcd_r[2]" 40; 63 | IO_PORT "lcd_r[2]" IO_TYPE=LVCMOS33 DRIVE=24; 64 | IO_LOC "lcd_r[3]" 39; 65 | IO_PORT "lcd_r[3]" IO_TYPE=LVCMOS33 DRIVE=24; 66 | IO_LOC "lcd_r[4]" 38; 67 | IO_PORT "lcd_r[4]" IO_TYPE=LVCMOS33 DRIVE=24; 68 | 69 | IO_LOC "lcd_g[0]" 37; 70 | IO_PORT "lcd_g[0]" IO_TYPE=LVCMOS33 DRIVE=24; 71 | IO_LOC "lcd_g[1]" 36; 72 | IO_PORT "lcd_g[1]" IO_TYPE=LVCMOS33 DRIVE=24; 73 | IO_LOC "lcd_g[2]" 35; 74 | IO_PORT "lcd_g[2]" IO_TYPE=LVCMOS33 DRIVE=24; 75 | IO_LOC "lcd_g[3]" 34; 76 | IO_PORT "lcd_g[3]" IO_TYPE=LVCMOS33 DRIVE=24; 77 | IO_LOC "lcd_g[4]" 33; 78 | IO_PORT "lcd_g[4]" IO_TYPE=LVCMOS33 DRIVE=24; 79 | IO_LOC "lcd_g[5]" 32; 80 | IO_PORT "lcd_g[5]" IO_TYPE=LVCMOS33 DRIVE=24; 81 | 82 | IO_LOC "lcd_b[0]" 31; 83 | IO_PORT "lcd_b[0]" IO_TYPE=LVCMOS33 DRIVE=24; 84 | IO_LOC "lcd_b[1]" 30; 85 | IO_PORT "lcd_b[1]" IO_TYPE=LVCMOS33 DRIVE=24; 86 | IO_LOC "lcd_b[2]" 29; 87 | IO_PORT "lcd_b[2]" IO_TYPE=LVCMOS33 DRIVE=24; 88 | IO_LOC "lcd_b[3]" 28; 89 | IO_PORT "lcd_b[3]" IO_TYPE=LVCMOS33 DRIVE=24; 90 | IO_LOC "lcd_b[4]" 27; 91 | IO_PORT "lcd_b[4]" IO_TYPE=LVCMOS33 DRIVE=24; 92 | 93 | // companion interface 94 | IO_LOC "m0s[0]" 71; 95 | IO_PORT "m0s[0]" PULL_MODE=UP IO_TYPE=LVCMOS33; 96 | IO_LOC "m0s[1]" 72; 97 | IO_PORT "m0s[1]" PULL_MODE=UP IO_TYPE=LVCMOS33; 98 | IO_LOC "m0s[2]" 73; 99 | IO_PORT "m0s[2]" PULL_MODE=UP IO_TYPE=LVCMOS33; 100 | IO_LOC "m0s[3]" 74; 101 | IO_PORT "m0s[3]" PULL_MODE=UP IO_TYPE=LVCMOS33; 102 | IO_LOC "m0s[4]" 75; 103 | IO_PORT "m0s[4]" PULL_MODE=UP IO_TYPE=LVCMOS33; 104 | 105 | // audio amplifier 106 | IO_LOC "pa_en" 51; 107 | IO_PORT "pa_en" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 108 | IO_LOC "hp_din" 54; 109 | IO_PORT "hp_din" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 110 | IO_LOC "hp_ws" 55; 111 | IO_PORT "hp_ws" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 112 | IO_LOC "hp_bck" 56; 113 | IO_PORT "hp_bck" PULL_MODE=UP DRIVE=8 IO_TYPE=LVCMOS33; 114 | 115 | // two on-board buttons 116 | IO_LOC "user" 88; 117 | IO_PORT "user" IO_TYPE=LVCMOS33 PULL_MODE=UP; 118 | IO_LOC "reset" 87; 119 | IO_PORT "reset" IO_TYPE=LVCMOS33 PULL_MODE=UP; 120 | 121 | IO_LOC "clk" 4; 122 | IO_PORT "clk" PULL_MODE=UP; 123 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_clkdiv/gowin_clkdiv.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=gowin_clkdiv 4 | module=Gowin_CLKDIV 5 | target_device=gw5a25a-002 6 | type=clock_clkdiv 7 | version=1.0 8 | 9 | [Config] 10 | Calibration=false 11 | Division_Factor=5 12 | Language=0 13 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_clkdiv/gowin_clkdiv.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name Gowin_CLKDIV 9 | -file_name gowin_clkdiv 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_clkdiv/ 11 | -type CLKDIV 12 | -file_type vlg 13 | -division_factor 5 14 | -calib false -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_clkdiv/gowin_clkdiv.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5A-LV25MG121NC1/I0 6 | //Device: GW5A-25 7 | //Device Version: A 8 | //Created Time: Sat Jan 4 14:37:40 2025 9 | 10 | module Gowin_CLKDIV (clkout, hclkin, resetn); 11 | 12 | output clkout; 13 | input hclkin; 14 | input resetn; 15 | 16 | wire gw_gnd; 17 | 18 | assign gw_gnd = 1'b0; 19 | 20 | CLKDIV clkdiv_inst ( 21 | .CLKOUT(clkout), 22 | .HCLKIN(hclkin), 23 | .RESETN(resetn), 24 | .CALIB(gw_gnd) 25 | ); 26 | 27 | defparam clkdiv_inst.DIV_MODE = "5"; 28 | 29 | endmodule //Gowin_CLKDIV 30 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_dpb/ide_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=ide_dpram 4 | module=ide_dpram 5 | target_device=gw5a25a-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=4096 13 | DEPTH_B=4096 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=16 20 | WIDTH_B=16 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_dpb/ide_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name ide_dpram 9 | -file_name ide_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5A-25A 15 | -depth_0 4096 16 | -depth_1 4096 17 | -width_0 16 18 | -width_1 16 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_dpb/sector_dpram.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=sector_dpram 4 | module=sector_dpram 5 | target_device=gw5a25a-002 6 | type=ram_dpb 7 | version=1.0 8 | 9 | [Config] 10 | Area=true 11 | BYTE_SIZE=0 12 | DEPTH_A=512 13 | DEPTH_B=512 14 | LANG=0 15 | READ_A=0 16 | READ_B=0 17 | RESET_MODE=true 18 | Speed=false 19 | WIDTH_A=8 20 | WIDTH_B=8 21 | WRITE_A=0 22 | WRITE_B=0 23 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_dpb/sector_dpram.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name sector_dpram 9 | -file_name sector_dpram 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_dpb/ 11 | -type RAM_DP 12 | -file_type vlg 13 | -bram_b true 14 | -dev_type GW5A-25A 15 | -depth_0 512 16 | -depth_1 512 17 | -width_0 8 18 | -width_1 8 19 | -read_mode_0 bypass 20 | -read_mode_1 bypass 21 | -write_mode_0 normal 22 | -write_mode_1 normal 23 | -speed false 24 | -reset_mode sync -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_dpb/sector_dpram.v: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 Gowin Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: IP file 4 | //Tool Version: V1.9.11 5 | //Part Number: GW5A-LV25MG121NC1/I0 6 | //Device: GW5A-25 7 | //Device Version: A 8 | //Created Time: Sat Jan 4 14:41:33 2025 9 | 10 | module sector_dpram (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb); 11 | 12 | output [7:0] douta; 13 | output [7:0] doutb; 14 | input clka; 15 | input ocea; 16 | input cea; 17 | input reseta; 18 | input wrea; 19 | input clkb; 20 | input oceb; 21 | input ceb; 22 | input resetb; 23 | input wreb; 24 | input [8:0] ada; 25 | input [7:0] dina; 26 | input [8:0] adb; 27 | input [7:0] dinb; 28 | 29 | wire [7:0] dpb_inst_0_douta_w; 30 | wire [7:0] dpb_inst_0_doutb_w; 31 | wire gw_gnd; 32 | 33 | assign gw_gnd = 1'b0; 34 | 35 | DPB dpb_inst_0 ( 36 | .DOA({dpb_inst_0_douta_w[7:0],douta[7:0]}), 37 | .DOB({dpb_inst_0_doutb_w[7:0],doutb[7:0]}), 38 | .CLKA(clka), 39 | .OCEA(ocea), 40 | .CEA(cea), 41 | .RESETA(reseta), 42 | .WREA(wrea), 43 | .CLKB(clkb), 44 | .OCEB(oceb), 45 | .CEB(ceb), 46 | .RESETB(resetb), 47 | .WREB(wreb), 48 | .BLKSELA({gw_gnd,gw_gnd,gw_gnd}), 49 | .BLKSELB({gw_gnd,gw_gnd,gw_gnd}), 50 | .ADA({gw_gnd,gw_gnd,ada[8:0],gw_gnd,gw_gnd,gw_gnd}), 51 | .DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:0]}), 52 | .ADB({gw_gnd,gw_gnd,adb[8:0],gw_gnd,gw_gnd,gw_gnd}), 53 | .DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:0]}) 54 | ); 55 | 56 | defparam dpb_inst_0.READ_MODE0 = 1'b0; 57 | defparam dpb_inst_0.READ_MODE1 = 1'b0; 58 | defparam dpb_inst_0.WRITE_MODE0 = 2'b00; 59 | defparam dpb_inst_0.WRITE_MODE1 = 2'b00; 60 | defparam dpb_inst_0.BIT_WIDTH_0 = 8; 61 | defparam dpb_inst_0.BIT_WIDTH_1 = 8; 62 | defparam dpb_inst_0.BLK_SEL_0 = 3'b000; 63 | defparam dpb_inst_0.BLK_SEL_1 = 3'b000; 64 | defparam dpb_inst_0.RESET_MODE = "SYNC"; 65 | 66 | endmodule //sector_dpram 67 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_pll/pll_142m.ipc: -------------------------------------------------------------------------------- 1 | [General] 2 | ipc_version=4 3 | file=pll_142m 4 | module=pll_142m 5 | target_device=gw5a25a-002 6 | type=clock_plladv 7 | version=1.0 8 | 9 | [Config] 10 | AdvancedMode=false 11 | ClkfbDivideFactorStatic=true 12 | ClkfbDivideFactorStaticValue=1 13 | ClkfbInternal=true 14 | ClkfboutExpectedFrequency=400 15 | ClkfboutTolerance=0.0 16 | ClkfboutVCODivideFactorStatic=true 17 | ClkfboutVCODivideFactorStaticValue=17 18 | ClkfboutVCOFractionalDivideFactorStaticValue=0 19 | ClkinClockFrequency=50 20 | ClkinDividerFactorStatic=true 21 | ClkinDividerFactorStaticValue=1 22 | ClkinDividerReset=false 23 | Clkou1BPhaseStatic=true 24 | Clkou2BPhaseStatic=true 25 | Clkou3BPhaseStatic=true 26 | Clkout0Bypass=false 27 | Clkout0DutyCycleDynamic=false 28 | Clkout0DutyCycleDynamicValue=0 29 | Clkout0DutyCycleStatic=true 30 | Clkout0DutyTrimStatic=true 31 | Clkout0DutyTrimStaticFalling=false 32 | Clkout0DutyTrimStaticRising=true 33 | Clkout0DutyTrimStaticStep=0 34 | Clkout0ExpectedFrequency=141.875 35 | Clkout0PhaseDynamic=false 36 | Clkout0PhaseStatic=true 37 | Clkout0PhaseStaticValue=0 38 | Clkout0Tolerance=0.2 39 | Clkout0VCODivideFactorStatic=true 40 | Clkout0VCODivideFactorStaticValue=6 41 | Clkout0VCOFractionalDivideFactorStaticValue=0 42 | Clkout1Bypass=false 43 | Clkout1DutyCycleDynamic=false 44 | Clkout1DutyCycleDynamicValue=0 45 | Clkout1DutyCycleStatic=true 46 | Clkout1DutyTrimStatic=true 47 | Clkout1DutyTrimStaticFalling=false 48 | Clkout1DutyTrimStaticRising=true 49 | Clkout1DutyTrimStaticStep=0 50 | Clkout1ExpectedFrequency=400 51 | Clkout1PhaseDynamic=false 52 | Clkout1PhaseStaticValue=0 53 | Clkout1Tolerance=0.0 54 | Clkout1VCODivideFactorStatic=true 55 | Clkout1VCODivideFactorStaticValue=8 56 | Clkout2Bypass=false 57 | Clkout2DutyCycleDynamic=false 58 | Clkout2DutyCycleDynamicValue=0 59 | Clkout2DutyCycleStatic=true 60 | Clkout2DutyTrimStatic=true 61 | Clkout2DutyTrimStaticFalling=false 62 | Clkout2DutyTrimStaticRising=true 63 | Clkout2DutyTrimStaticStep=0 64 | Clkout2ExpectedFrequency=400 65 | Clkout2PhaseDynamic=false 66 | Clkout2PhaseStaticValue=0 67 | Clkout2Tolerance=0.0 68 | Clkout2VCODivideFactorStatic=true 69 | Clkout2VCODivideFactorStaticValue=8 70 | Clkout3Bypass=false 71 | Clkout3DutyCycleDynamic=false 72 | Clkout3DutyCycleDynamicValue=0 73 | Clkout3DutyCycleStatic=true 74 | Clkout3DutyTrimStatic=true 75 | Clkout3DutyTrimStaticFalling=false 76 | Clkout3DutyTrimStaticRising=true 77 | Clkout3DutyTrimStaticStep=0 78 | Clkout3ExpectedFrequency=400 79 | Clkout3PhaseDynamic=false 80 | Clkout3PhaseStaticValue=0 81 | Clkout3Tolerance=0.0 82 | Clkout3VCODivideFactorStatic=true 83 | Clkout3VCODivideFactorStaticValue=8 84 | Clkout4Bypass=false 85 | Clkout4DutyCycleDynamic=false 86 | Clkout4DutyCycleDynamicValue=0 87 | Clkout4DutyCycleStatic=true 88 | Clkout4ExpectedFrequency=400 89 | Clkout4PhaseDynamic=false 90 | Clkout4PhaseStatic=true 91 | Clkout4PhaseStaticValue=0 92 | Clkout4Tolerance=0.0 93 | Clkout4VCODivideFactorStatic=true 94 | Clkout4VCODivideFactorStaticValue=8 95 | Clkout5Bypass=false 96 | Clkout5DutyCycleDynamic=false 97 | Clkout5DutyCycleDynamicValue=0 98 | Clkout5DutyCycleStatic=true 99 | Clkout5ExpectedFrequency=400 100 | Clkout5PhaseDynamic=false 101 | Clkout5PhaseStatic=true 102 | Clkout5PhaseStaticValue=0 103 | Clkout5Tolerance=0.0 104 | Clkout5VCODivideFactorStatic=true 105 | Clkout5VCODivideFactorStaticValue=8 106 | Clkout6Bypass=false 107 | Clkout6DutyCycleDynamic=false 108 | Clkout6DutyCycleDynamicValue=0 109 | Clkout6DutyCycleStatic=true 110 | Clkout6ExpectedFrequency=400 111 | Clkout6PhaseDynamic=false 112 | Clkout6PhaseStatic=true 113 | Clkout6PhaseStaticValue=0 114 | Clkout6Tolerance=0.0 115 | Clkout6VCODivideFactorStatic=true 116 | Clkout6VCODivideFactorStaticValue=8 117 | ClkoutDividerReset=false 118 | EnableCascade=false 119 | EnableClkfbout=false 120 | EnableClkout0Divider=false 121 | EnableClkout1=false 122 | EnableClkout1Divider=false 123 | EnableClkout2=false 124 | EnableClkout2Divider=false 125 | EnableClkout3=false 126 | EnableClkout3Divider=false 127 | EnableClkout4=false 128 | EnableClkout4Divider=false 129 | EnableClkout5=false 130 | EnableClkout5Divider=false 131 | EnableClkout6=false 132 | EnableClkout6Divider=false 133 | EnableLock=true 134 | EnableSsc=false 135 | GeneralMode=true 136 | ICPSELStatic=true 137 | ICPSELStaticValue=X 138 | LANG=0 139 | LPFCAPStaticValue=C0 140 | LPFRESStaticValue=X 141 | LPFSELStatic=true 142 | PLLPowerDown=false 143 | PLLReset=false 144 | clkfbExternal=false 145 | clkfbExternalValue= 146 | -------------------------------------------------------------------------------- /src/tang/primer25k/gowin_pll/pll_142m.mod: -------------------------------------------------------------------------------- 1 | -series GW5A 2 | -device GW5A-25 3 | -device_version A 4 | -package MBGA121N 5 | -part_number GW5A-LV25MG121NC1/I0 6 | 7 | 8 | -mod_name pll_142m 9 | -file_name pll_142m 10 | -path /home/harbaum/projekte/private_stuff/mistlite/nanomig/src/tang/primer25k/gowin_pll/ 11 | -type PLL_ADV 12 | -file_type vlg 13 | -ssc false 14 | -rst false 15 | -rst_pwd false 16 | -rst_i false 17 | -rst_o false 18 | -fclkin 50 19 | -idiv_sel 1 20 | -clkfb_sel 0 21 | -fbdiv_sel 1 22 | -en_lock true 23 | -dyn_dpa_en false 24 | -clkout0_bypass false 25 | -odiv0_sel 6 26 | -odiv0_frac_sel 0 27 | -clkout0_dt_dir 1 28 | -clkout0_dt_step 0 29 | -dyn_pe0_sel false 30 | -clkout0_pe_coarse 0 31 | -clkout0_pe_fine 0 32 | -de0_en false 33 | -clkout0_dt_dir 1 34 | -clkout0_dt_step 0 35 | -en_clkout1 false 36 | -en_clkout2 false 37 | -en_clkout3 false 38 | -en_clkout4 false 39 | -en_clkout5 false 40 | -en_clkout6 false 41 | -en_clkfbout false 42 | -mdiv_sel 17 43 | -mdiv_frac_sel 0 -------------------------------------------------------------------------------- /src/tang/primer25k/nanomig.sdc: -------------------------------------------------------------------------------- 1 | //Copyright (C)2014-2024 GOWIN Semiconductor Corporation. 2 | //All rights reserved. 3 | //File Title: Timing Constraints file 4 | //Tool Version: V1.9.9 5 | //Created Time: 2024-02-23 19:02:18 6 | // create_clock -name clk_hdmi -period 6.25 -waveform {0 3.125} [get_nets {video2hdmi/clk_pixel_x5}] -add 7 | // create_clock -name clk_flash -period 10 -waveform {0 5} [get_nets {flash_clk}] 8 | create_clock -name clk_spi -period 10 -waveform {0 5} [get_ports {mspi_clk}] -add 9 | create_clock -name clk_32 -period 31 -waveform {0 15} [get_ports {O_sdram_clk}] -add 10 | create_clock -name clk_osc -period 20 -waveform {0 10} [get_ports {clk}] -add 11 | --------------------------------------------------------------------------------