diff --git a/j1b/ulx3s/Makefile b/j1b/ulx3s/Makefile new file mode 100644 index 0000000..31c11b6 --- /dev/null +++ b/j1b/ulx3s/Makefile @@ -0,0 +1,28 @@ +# ******* project, board and chip name ******* +PROJECT = swapforth +BOARD = ulx3s +# 12 25 45 85 +FPGA_SIZE = 85 + +# ******* design files ******* +CONSTRAINTS = ulx3s_v20_segpdi.lpf +TOP_MODULE = ulx3s_top +PREFIX = ../verilog +TOP_MODULE_FILE = $(PREFIX)/$(TOP_MODULE).v + +VERILOG_FILES = \ +$(TOP_MODULE_FILE) \ +$(PREFIX)/j1.v \ +$(PREFIX)/ram.v \ +$(PREFIX)/uart.v \ +$(PREFIX)/stack.v \ + +# *.vhd those files will be converted to *.v files with vhdl2vl (warning overwriting/deleting) +VHDL_FILES = \ + +YOSYS_OPTIONS = -abc9 +NEXTPNR_OPTIONS = --timing-allow-fail + +SCRIPTS = scripts +include $(SCRIPTS)/trellis_path.mk +include $(SCRIPTS)/trellis_main.mk diff --git a/j1b/ulx3s/README.md b/j1b/ulx3s/README.md new file mode 100644 index 0000000..262c787 --- /dev/null +++ b/j1b/ulx3s/README.md @@ -0,0 +1,18 @@ +The ULX3S board is based upon the Lattice ECP5 FPGA. It's a it's a prototype +board with lots of features in a small form factor. For more info, see +https://ulx3s.github.io. + +Currently the only tested toolchain is Trellis (or rather the tools associated +with Trellis). + +As with the other supported platforms, have the Trellis tools installed, and run +make in this directory to create a bitstream. Run fujprog to install it over +USB: + + fujprog ulx3s_85f_swapforth.bit + +Now you can use `shell.py` in the parent directory to attach to the Forth +process over UART. The Verilator bootstrap process will also work for ULX3S. + +Currently only J1b itself and UART are supported. Support for low-hanging fruit +like GPIOs, buttons and LEDs should follow shortly. diff --git a/j1b/ulx3s/makefile.diamond b/j1b/ulx3s/makefile.diamond new file mode 100644 index 0000000..2cb63d3 --- /dev/null +++ b/j1b/ulx3s/makefile.diamond @@ -0,0 +1,31 @@ +# ******* project, board and chip name ******* +PROJECT = swapforth_hex +BOARD = ulx3s +# 12 25 45 85 +FPGA_SIZE = 12 +FPGA_PACKAGE = 6bg381c +# config flash: 1:SPI (standard), 4:QSPI (quad) +FLASH_SPI = 4 +# chip: is25lp032d is25lp128f s25fl164k +FLASH_CHIP = is25lp128f + +# ******* design files ******* +CONSTRAINTS = ulx3s_v20_segpdi.lpf +TOP_MODULE = ulx3s_top +PREFIX = ../verilog +TOP_MODULE_FILE = $(PREFIX)/$(TOP_MODULE).v + +VERILOG_FILES = \ +$(TOP_MODULE_FILE) \ +$(PREFIX)/j1.v \ +$(PREFIX)/ram.v \ +$(PREFIX)/uart.v \ +$(PREFIX)/stack.v \ + +# *.vhd those files will be converted to *.v files with vhdl2vl (warning overwriting/deleting) +VHDL_FILES = \ + +SCRIPTS = ../../../../scripts/ +include $(SCRIPTS)/trellis_path.mk +include $(SCRIPTS)/diamond_path.mk +include $(SCRIPTS)/diamond_main.mk diff --git a/j1b/ulx3s/scripts/diamond_main.mk b/j1b/ulx3s/scripts/diamond_main.mk new file mode 100644 index 0000000..6b17b54 --- /dev/null +++ b/j1b/ulx3s/scripts/diamond_main.mk @@ -0,0 +1,285 @@ +# ******* project, board and chip name ******* +PROJECT ?= project +BOARD ?= board +FPGA_SIZE ?= 12 +FPGA_CHIP ?= lfe5u-$(FPGA_SIZE)f +FPGA_PACKAGE ?= 6bg381c +# config flash: 1:SPI (standard), 4:QSPI (quad) +FLASH_SPI ?= 1 +# chip: is25lp032d is25lp128f s25fl164k +FLASH_CHIP ?= is25lp032d + +# ******* design files ******* +CONSTRAINTS ?= board_constraints.lpf +STRATEGY ?= $(SCRIPTS)/ulx3s.sty +TOP_MODULE ?= top +TOP_MODULE_FILE ?= $(TOP_MODULE).v +VERILOG_FILES ?= $(TOP_MODULE_FILE) +VHDL_FILES ?= +SBX_FILES ?= + +# ******* tools installation paths ******* +# include $(SCRIPTS)/trellis_path.mk +# https://github.com/ldoolitt/vhd2vl +#VHDL2VL ?= /mt/scratch/tmp/openfpga/vhd2vl/src/vhd2vl +# https://github.com/YosysHQ/yosys +#YOSYS ?= /mt/scratch/tmp/openfpga/yosys/yosys +# https://github.com/YosysHQ/nextpnr +#NEXTPNR-ECP5 ?= /mt/scratch/tmp/openfpga/nextpnr/nextpnr-ecp5 +# https://github.com/SymbiFlow/prjtrellis +#TRELLIS ?= /mt/scratch/tmp/openfpga/prjtrellis + +ifeq ($(FPGA_CHIP), lfe5u-12f) + CHIP_ID=0x21111043 + MASK_FILE=LFE5U-45F.msk +endif +ifeq ($(FPGA_CHIP), lfe5u-25f) + CHIP_ID=0x41111043 + MASK_FILE=LFE5U-45F.msk +endif +ifeq ($(FPGA_CHIP), lfe5u-45f) + CHIP_ID=0x41112043 + MASK_FILE=LFE5U-45F.msk +endif +ifeq ($(FPGA_CHIP), lfe5u-85f) + CHIP_ID=0x41113043 + MASK_FILE=LFE5U-85F.msk +endif + +#ifeq ($(FPGA_SIZE), 12) +# FPGA_K=25 +# IDCODE_CHIPID=--idcode $(CHIP_ID) +#else + FPGA_K=$(FPGA_SIZE) + IDCODE_CHIPID= +#endif + +FPGA_CHIP_EQUIVALENT ?= lfe5u-$(FPGA_K)f + +# open source synthesis tools +ECPPLL ?= $(TRELLIS)/libtrellis/ecppll +ECPPACK ?= $(TRELLIS)/libtrellis/ecppack +TRELLISDB ?= $(TRELLIS)/database +LIBTRELLIS ?= $(TRELLIS)/libtrellis +BIT2SVF ?= $(TRELLIS)/tools/bit_to_svf.py +#BASECFG ?= $(TRELLIS)/misc/basecfgs/empty_$(FPGA_CHIP_EQUIVALENT).config +# yosys options, sometimes those can be used: -noccu2 -nomux -nodram +YOSYS_OPTIONS ?= + +# clock generator +CLK0_NAME ?= clk0 +CLK0_FILE_NAME ?= clocks/$(CLK0_NAME).v +CLK0_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK1_NAME ?= clk1 +CLK1_FILE_NAME ?= clocks/$(CLK1_NAME).v +CLK1_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK2_NAME ?= clk2 +CLK2_FILE_NAME ?= clocks/$(CLK2_NAME).v +CLK2_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK3_NAME ?= clk3 +CLK3_FILE_NAME ?= clocks/$(CLK3_NAME).v +CLK3_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 + +# closed source synthesis tools +# include $(SCRIPTS)/diamond_path.mk +#DIAMOND_BASE ?= /usr/local/diamond +ifneq ($(wildcard $(DIAMOND_BASE)),) + DIAMOND_BIN := $(shell find ${DIAMOND_BASE}/ -maxdepth 2 -name bin | sort -rn | head -1) + DIAMONDC := $(shell find ${DIAMOND_BIN}/ -name diamondc) + DDTCMD := $(shell find ${DIAMOND_BIN}/ -name ddtcmd) + MASK_PATH := $(shell find ${DIAMOND_BASE}/ -maxdepth 5 -name xpga -type d)/ecp5 +endif + +#PROJ_FILE := $(shell ls *.ldf | head -1) +#PROJ_NAME := $(shell fgrep default_implementation ${PROJ_FILE} | cut -d'"' -f 4) +#IMPL_NAME := $(shell fgrep default_implementation ${PROJ_FILE} | cut -d'"' -f 8) +#IMPL_DIR := $(shell fgrep default_strategy ${PROJ_FILE} | cut -d'"' -f 4) + +# programming tools +UJPROG ?= fujprog +OPENFPGALOADER ?= openFPGALoader +OPENFPGALOADER_OPTIONS ?= --board ulx3s +FLEAFPGA_JTAG ?= FleaFPGA-JTAG +OPENOCD ?= openocd +OPENOCD_INTERFACE ?= $(SCRIPTS)/ft231x.ocd +DFU_UTIL ?= dfu-util +TINYFPGASP ?= tinyfpgasp + +# helper scripts directory +SCRIPTS ?= scripts + +# rest of the include makefile +FPGA_CHIP_UPPERCASE := $(shell echo $(FPGA_CHIP) | tr '[:lower:]' '[:upper:]') +FPGA_PACKAGE_UPPERCASE := $(shell echo $(FPGA_PACKAGE) | tr '[:lower:]' '[:upper:]') + +BITSTREAM ?= $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +#BITSTREAM ?= $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash_$(FLASH_CHIP).vme + +all: $(BITSTREAM) + +# VHDL to VERILOG conversion +#%.v: %.vhd +# $(VHDL2VL) $< $@ + +#*.v: *.vhdl +# $(VHDL2VL) $< $@ + +#$(PROJECT).ys: makefile +# $(SCRIPTS)/ysgen.sh $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) > $@ +# echo "hierarchy -top ${TOP_MODULE}" >> $@ +# echo "synth_ecp5 -noccu2 -nomux -nodram -json ${PROJECT}.json" >> $@ + +#$(PROJECT).json: $(PROJECT).ys $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) +# $(YOSYS) $(PROJECT).ys + +$(PROJECT).json: $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) + $(YOSYS) \ + -p "hierarchy -top ${TOP_MODULE}" \ + -p "synth_ecp5 ${YOSYS_OPTIONS} -json ${PROJECT}.json" \ + $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config: $(PROJECT).json $(BASECFG) + $(NEXTPNR-ECP5) --$(FPGA_K)k --json $(PROJECT).json --lpf $(CONSTRAINTS) --basecfg $(BASECFG) --textcfg $@ + +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config +# LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPACK) $(IDCODE_CHIPID) --db $(TRELLISDB) --input $< --bit $@ + +# generate LDF project file for diamond +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).ldf: $(SCRIPTS)/project.ldf $(SCRIPTS)/ldf.xsl $(SCRIPTS)/$(BOARD)_sram.xcf + xsltproc \ + --stringparam FPGA_DEVICE $(FPGA_CHIP_UPPERCASE)-$(FPGA_PACKAGE_UPPERCASE) \ + --stringparam CONSTRAINTS_FILE $(CONSTRAINTS) \ + --stringparam STRATEGY_FILE $(STRATEGY) \ + --stringparam XCF_FILE $(SCRIPTS)/$(BOARD)_sram.xcf \ + --stringparam TOP_MODULE $(TOP_MODULE) \ + --stringparam TOP_MODULE_FILE $(TOP_MODULE_FILE) \ + --stringparam VHDL_FILES "$(VHDL_FILES)" \ + --stringparam VERILOG_FILES "$(VERILOG_FILES)" \ + --stringparam SBX_FILES "$(SBX_FILES)" \ + $(SCRIPTS)/ldf.xsl $(SCRIPTS)/project.ldf > $@ + +project/project_project.bit: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).ldf $(VERILOG_FILES) $(VHDL_FILES) + echo prj_project open $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).ldf \; prj_run Export -task Bitgen | ${DIAMONDC} + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit: project/project_project.bit + ln -sf project/project_project.bit $@ + +$(CLK0_FILE_NAME): + LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPLL) $(CLK0_OPTIONS) --file $@ + +$(CLK1_FILE_NAME): + LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPLL) $(CLK1_OPTIONS) --file $@ + +$(CLK2_FILE_NAME): + LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPLL) $(CLK2_OPTIONS) --file $@ + +$(CLK3_FILE_NAME): + LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPLL) $(CLK3_OPTIONS) --file $@ + +# generate sram programming XCF file for DDTCMD +$(BOARD)_$(FPGA_SIZE)f.xcf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(SCRIPTS)/$(BOARD)_sram.xcf $(SCRIPTS)/xcf.xsl + xsltproc \ + --stringparam FPGA_CHIP $(FPGA_CHIP_UPPERCASE) \ + --stringparam CHIP_ID $(CHIP_ID) \ + --stringparam BITSTREAM_FILE $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit \ + $(SCRIPTS)/xcf.xsl $(SCRIPTS)/$(BOARD)_sram.xcf > $@ + +# run DDTCMD to generate sram VME file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + LANG=C ${DDTCMD} -oft -fullvme -if $(BOARD)_$(FPGA_SIZE)f.xcf -nocompress -noheader -of $@ + +# run DDTCMD to generate SVF file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + LANG=C ${DDTCMD} -oft -svfsingle -revd -maxdata 8 -if $(BOARD)_$(FPGA_SIZE)f.xcf -of $@ + +# run DDTCMD to generate flash MCS file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash.mcs: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + LANG=C ${DDTCMD} -dev $(FPGA_CHIP_UPPERCASE) \ + -if $< -oft -int -quad $(FPGA_SPI) -of $@ + +# generate flash programming XCF file for DDTCMD +$(BOARD)_$(FPGA_SIZE)f_flash_$(FLASH_CHIP).xcf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(SCRIPTS)/$(BOARD)_flash_$(FLASH_CHIP).xcf $(SCRIPTS)/xcf.xsl + xsltproc \ + --stringparam FPGA_CHIP $(FPGA_CHIP_UPPERCASE) \ + --stringparam CHIP_ID $(CHIP_ID) \ + --stringparam MASK_FILE $(MASK_PATH)/$(MASK_FILE) \ + --stringparam BITSTREAM_FILE $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash.mcs \ + $(SCRIPTS)/xcf.xsl $(SCRIPTS)/$(BOARD)_flash_$(FLASH_CHIP).xcf > $@ + +# run DDTCMD to generate flash VME file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash_$(FLASH_CHIP).vme: $(BOARD)_$(FPGA_SIZE)f_flash_$(FLASH_CHIP).xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash.mcs + LANG=C ${DDTCMD} -oft -fullvme -if $(BOARD)_$(FPGA_SIZE)f_flash_$(FLASH_CHIP).xcf -nocompress -noheader -of $@ + +# generate SVF file by prjtrellis python script +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +# $(BIT2SVF) $< $@ + +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config +# LD_LIBRARY_PATH=$(LIBTRELLIS) $(ECPPACK) $(IDCODE_CHIPID) --db $(TRELLISDB) $< --freq 62.0 --svf-rowsize 8000 --svf $@ + +# program SRAM with ujrprog (temporary) +prog: program +program: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) $< + +# program SRAM with OPENFPGALOADER +prog_ofl: program_ofl +program_ofl: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(OPENFPGALOADER) $(OPENFPGALOADER_OPTIONS) $< + +# program SRAM with FleaFPGA-JTAG (temporary) +program_flea: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme + $(FLEAFPGA_JTAG) $< + +# program FLASH over US1 port with ujprog (permanently) +flash: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) -j flash $< + +# program FLASH uver US1 with FleaFPGA-JTAG (permanent) +flash_flea: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash_$(FLASH_CHIP).vme + $(FLEAFPGA_JTAG) $< + +# program FLASH over US2 port with DFU bootloader (permanently) +flash_dfu: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(DFU_UTIL) -a 0 -D $< + $(DFU_UTIL) -a 0 -e + +# program FLASH over US2 port with tinyfpgasp bootloader (permanently) +flash_tiny: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(TINYFPGASP) -w $< + +# generate chip-specific openocd programming file +$(BOARD)_$(FPGA_SIZE)f.ocd: $(SCRIPTS)/ecp5-ocd.sh + $(SCRIPTS)/ecp5-ocd.sh $(CHIP_ID) $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf > $@ + +# program SRAM with OPENOCD +prog_ocd: program_ocd +program_ocd: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf $(BOARD)_$(FPGA_SIZE)f.ocd + $(OPENOCD) --file=$(OPENOCD_INTERFACE) --file=$(BOARD)_$(FPGA_SIZE)f.ocd + +JUNK = *~ +#JUNK += $(PROJECT).ys +JUNK += $(PROJECT).json +JUNK += $(VHDL_TO_VERILOG_FILES) +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).ldf +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf +JUNK += $(BOARD)_$(FPGA_SIZE)f.xcf +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash.mcs +JUNK += $(BOARD)_$(FPGA_SIZE)f_flash_$(FLASH_CHIP).xcf +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT)_flash_$(FLASH_CHIP).vme +JUNK += $(BOARD)_$(FPGA_SIZE)f.ocd +JUNK += $(CLK0_FILE_NAME) $(CLK1_FILE_NAME) $(CLK2_FILE_NAME) $(CLK3_FILE_NAME) +# diamond junk +JUNK += ${IMPL_DIR} .recovery ._Real_._Math_.vhd *.sty reportview.xml +JUNK += dummy_sym.sort project_tcl.html promote.xml .run_manager.ini +JUNK += generate_core.tcl generate_ngd.tcl msg_file.log + +JUNK_DIR = project +JUNK_DIR += project_tcr.dir + +clean: + rm -rf $(JUNK_DIR) + rm -f $(JUNK) diff --git a/j1b/ulx3s/scripts/diamond_path.mk b/j1b/ulx3s/scripts/diamond_path.mk new file mode 100644 index 0000000..89418c3 --- /dev/null +++ b/j1b/ulx3s/scripts/diamond_path.mk @@ -0,0 +1,6 @@ +# the path of your diamond installation +DIAMOND_BASE ?= /usr/local/diamond + +# it is a directory that looks like this: +# ls /usr/local/diamond +# 3.7_x64 diff --git a/j1b/ulx3s/scripts/trellis_main.mk b/j1b/ulx3s/scripts/trellis_main.mk new file mode 100644 index 0000000..99b046c --- /dev/null +++ b/j1b/ulx3s/scripts/trellis_main.mk @@ -0,0 +1,231 @@ +# ******* project, board and chip name ******* +PROJECT ?= project +BOARD ?= board +FPGA_PREFIX ?= +# 12 25 45 85 um-85 um5g-85 +FPGA_SIZE ?= 12 +FPGA_CHIP ?= lfe5u-$(FPGA_SIZE)f +FPGA_PACKAGE ?= CABGA381 +# 2.4 4.8 9.7 19.4 38.8 62.0 +FLASH_READ_MHZ ?= 62.0 +# fast-read dual-spi qspi +FLASH_READ_MODE ?= fast-read + +# ******* design files ******* +CONSTRAINTS ?= board_constraints.lpf +TOP_MODULE ?= top +VERILOG_FILES ?= $(TOP_MODULE).v +# implicit list of *.vhd VHDL files to be converted to verilog *.v +# files here are list as *.v but user should +# edit original source which has *.vhd extension (vhdl_blink.vhd) +VHDL_FILES ?= + +# ******* tools installation paths ******* +# https://github.com/ldoolitt/vhd2vl +#VHDL2VL ?= /mt/scratch/tmp/openfpga/vhd2vl/src/vhd2vl +# https://github.com/YosysHQ/yosys +#YOSYS ?= /mt/scratch/tmp/openfpga/yosys/yosys +# https://github.com/YosysHQ/nextpnr +#NEXTPNR-ECP5 ?= /mt/scratch/tmp/openfpga/nextpnr/nextpnr-ecp5 +# https://github.com/SymbiFlow/prjtrellis +#TRELLIS ?= /mt/scratch/tmp/openfpga/prjtrellis + +# open source synthesis tools +TRELLISDB ?= $(TRELLIS)/database +LIBTRELLIS ?= $(TRELLIS)/libtrellis +ECPPLL ?= LANG=C ecppll # LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(TRELLIS)/libtrellis/ecppll +ECPPACK ?= LANG=C ecppack # LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(TRELLIS)/libtrellis/ecppack --db $(TRELLISDB) +BIT2SVF ?= $(TRELLIS)/tools/bit_to_svf.py +#BASECFG ?= $(TRELLIS)/misc/basecfgs/empty_$(FPGA_CHIP_EQUIVALENT).config +# yosys options, sometimes those can be used: -noccu2 -nomux -nodram +YOSYS_OPTIONS ?= +# nextpnr options +NEXTPNR_OPTIONS ?= + +ifeq ($(FPGA_CHIP), lfe5u-12f) + CHIP_ID=0x21111043 +endif +ifeq ($(FPGA_CHIP), lfe5u-25f) + CHIP_ID=0x41111043 +endif +ifeq ($(FPGA_CHIP), lfe5u-45f) + CHIP_ID=0x41112043 +endif +ifeq ($(FPGA_CHIP), lfe5u-85f) + CHIP_ID=0x41113043 +endif + +#ifeq ($(FPGA_SIZE), 12) +# FPGA_K=$(FPGA_PREFIX)25 +# IDCODE_CHIPID=--idcode $(CHIP_ID) +#else + FPGA_K=$(FPGA_PREFIX)$(FPGA_SIZE) + IDCODE_CHIPID= +#endif + + +FPGA_CHIP_EQUIVALENT ?= lfe5u-$(FPGA_K)f + +# clock generator +CLK0_NAME ?= clk0 +CLK0_FILE_NAME ?= clocks/$(CLK0_NAME).v +CLK0_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK1_NAME ?= clk1 +CLK1_FILE_NAME ?= clocks/$(CLK1_NAME).v +CLK1_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK2_NAME ?= clk2 +CLK2_FILE_NAME ?= clocks/$(CLK2_NAME).v +CLK2_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK3_NAME ?= clk3 +CLK3_FILE_NAME ?= clocks/$(CLK3_NAME).v +CLK3_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 + +# closed source synthesis tools +#DIAMOND_BASE := /usr/local/diamond +ifneq ($(wildcard $(DIAMOND_BASE)),) + DIAMOND_BIN := $(shell find ${DIAMOND_BASE}/ -maxdepth 2 -name bin | sort -rn | head -1) + DIAMONDC := $(shell find ${DIAMOND_BIN}/ -name diamondc) + DDTCMD := $(shell find ${DIAMOND_BIN}/ -name ddtcmd) +endif + +# programming tools +UJPROG ?= fujprog +OPENFPGALOADER ?= openFPGALoader +OPENFPGALOADER_OPTIONS ?= --board ulx3s +FLEAFPGA_JTAG ?= FleaFPGA-JTAG +OPENOCD ?= openocd +OPENOCD_INTERFACE ?= $(SCRIPTS)/ft231x.ocd +DFU_UTIL ?= dfu-util +TINYFPGASP ?= tinyfpgasp + +# helper scripts directory +SCRIPTS ?= scripts + +# rest of the include makefile +FPGA_CHIP_UPPERCASE := $(shell echo $(FPGA_CHIP) | tr '[:lower:]' '[:upper:]') + + +#all: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf +all: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf + +# VHDL to VERILOG conversion +# convert all *.vhd filenames to .v extension +VHDL_TO_VERILOG_FILES = $(VHDL_FILES:.vhd=.v) +# implicit conversion rule +%.v: %.vhd + $(VHDL2VL) $< $@ + +#*.v: *.vhdl +# $(VHDL2VL) $< $@ + +#$(PROJECT).ys: makefile +# $(SCRIPTS)/ysgen.sh $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) > $@ +# echo "hierarchy -top ${TOP_MODULE}" >> $@ +# echo "synth_ecp5 -noccu2 -nomux -nodram -json ${PROJECT}.json" >> $@ + +#$(PROJECT).json: $(PROJECT).ys $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) +# $(YOSYS) $(PROJECT).ys + +$(PROJECT).json: $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) + $(YOSYS) \ + -p "read -sv $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES)" \ + -p "hierarchy -top ${TOP_MODULE}" \ + -p "synth_ecp5 ${YOSYS_OPTIONS} -json ${PROJECT}.json" + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config: $(PROJECT).json $(BASECFG) + $(NEXTPNR-ECP5) $(NEXTPNR_OPTIONS) --$(FPGA_K)k --package $(FPGA_PACKAGE) --json $(PROJECT).json --lpf $(CONSTRAINTS) --textcfg $@ + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config + $(ECPPACK) $(IDCODE_CHIPID) --compress --freq $(FLASH_READ_MHZ) --input $< --bit $@ +# $(ECPPACK) $(IDCODE_CHIPID) --compress --freq $(FLASH_READ_MHZ) --spimode $(FLASH_READ_MODE) --input $< --bit $@ + +$(CLK0_FILE_NAME): + $(ECPPLL) $(CLK0_OPTIONS) --file $@ + +$(CLK1_FILE_NAME): + $(ECPPLL) $(CLK1_OPTIONS) --file $@ + +$(CLK2_FILE_NAME): + $(ECPPLL) $(CLK2_OPTIONS) --file $@ + +$(CLK3_FILE_NAME): + $(ECPPLL) $(CLK3_OPTIONS) --file $@ + +# generate XCF programming file for DDTCMD +$(BOARD)_$(FPGA_SIZE)f.xcf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(SCRIPTS)/$(BOARD)_sram.xcf $(SCRIPTS)/xcf.xsl $(DTD_FILE) + xsltproc \ + --stringparam FPGA_CHIP $(FPGA_CHIP_UPPERCASE) \ + --stringparam CHIP_ID $(CHIP_ID) \ + --stringparam BITSTREAM_FILE $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit \ + $(SCRIPTS)/xcf.xsl $(SCRIPTS)/$(BOARD)_sram.xcf > $@ + +# run DDTCMD to generate VME file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + LANG=C ${DDTCMD} -oft -fullvme -if $(BOARD)_$(FPGA_SIZE)f.xcf -nocompress -noheader -of $@ + +# run DDTCMD to generate SVF file +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +# LANG=C ${DDTCMD} -oft -svfsingle -revd -maxdata 8 -if $(BOARD)_$(FPGA_SIZE)f.xcf -of $@ + +# generate SVF file by prjtrellis python script +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +# $(BIT2SVF) $< $@ + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config + $(ECPPACK) $(IDCODE_CHIPID) $< --compress --freq $(FLASH_READ_MHZ) --svf-rowsize 800000 --svf $@ +# $(ECPPACK) $(IDCODE_CHIPID) $< --compress --freq $(FLASH_READ_MHZ) --spimode $(FLASH_READ_MODE) --svf-rowsize 800000 --svf $@ + +# program SRAM with ujrprog (temporary) +prog: program +program: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) $< + +# program SRAM with OPENFPGALOADER +prog_ofl: program_ofl +program_ofl: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(OPENFPGALOADER) $(OPENFPGALOADER_OPTIONS) $< + +# program SRAM with FleaFPGA-JTAG (temporary) +program_flea: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme + $(FLEAFPGA_JTAG) $< + +# program FLASH over US1 port with ujprog (permanently) +flash: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) -j flash $< + +# program FLASH over US1 port with openFPGALoader (permanently) +flash_ofl: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(OPENFPGALOADER) $(OPENFPGALOADER_OPTIONS) -f $< + +# program FLASH over US2 port with DFU bootloader (permanently) +flash_dfu: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(DFU_UTIL) -a 0 -D $< + $(DFU_UTIL) -a 0 -e + +# program FLASH over US2 port with tinyfpgasp bootloader (permanently) +flash_tiny: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(TINYFPGASP) -w $< + +# generate chip-specific openocd programming file +$(BOARD)_$(FPGA_SIZE)f.ocd: $(SCRIPTS)/ecp5-ocd.sh + $(SCRIPTS)/ecp5-ocd.sh $(CHIP_ID) $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf > $@ + +# program SRAM with OPENOCD +prog_ocd: program_ocd +program_ocd: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf $(BOARD)_$(FPGA_SIZE)f.ocd + $(OPENOCD) --file=$(OPENOCD_INTERFACE) --file=$(BOARD)_$(FPGA_SIZE)f.ocd + +JUNK = *~ +#JUNK += $(PROJECT).ys +JUNK += $(PROJECT).json +JUNK += $(VHDL_TO_VERILOG_FILES) +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf +JUNK += $(BOARD)_$(FPGA_SIZE)f.xcf +JUNK += $(BOARD)_$(FPGA_SIZE)f.ocd +JUNK += $(CLK0_FILE_NAME) $(CLK1_FILE_NAME) $(CLK2_FILE_NAME) $(CLK3_FILE_NAME) + +clean: + rm -f $(JUNK) diff --git a/j1b/ulx3s/scripts/trellis_main_sv.mk b/j1b/ulx3s/scripts/trellis_main_sv.mk new file mode 100644 index 0000000..7da4e27 --- /dev/null +++ b/j1b/ulx3s/scripts/trellis_main_sv.mk @@ -0,0 +1,207 @@ +# ******* project, board and chip name ******* +PROJECT ?= project +BOARD ?= board +FPGA_PREFIX ?= +FPGA_SIZE ?= 12 +FPGA_CHIP ?= lfe5u-$(FPGA_SIZE)f +FPGA_PACKAGE ?= CABGA381 + +# ******* design files ******* +CONSTRAINTS ?= board_constraints.lpf +TOP_MODULE ?= top +VERILOG_FILES ?= +SYSTEMVERILOG_FILES ?= +# implicit list of *.vhd VHDL files to be converted to verilog *.v +# files here are list as *.v but user should +# edit original source which has *.vhd extension (vhdl_blink.vhd) +VHDL_FILES ?= + +# ******* tools installation paths ******* +# https://github.com/ldoolitt/vhd2vl +#VHDL2VL ?= /mt/scratch/tmp/openfpga/vhd2vl/src/vhd2vl +# https://github.com/YosysHQ/yosys +#YOSYS ?= /mt/scratch/tmp/openfpga/yosys/yosys +# https://github.com/YosysHQ/nextpnr +#NEXTPNR-ECP5 ?= /mt/scratch/tmp/openfpga/nextpnr/nextpnr-ecp5 +# https://github.com/SymbiFlow/prjtrellis +#TRELLIS ?= /mt/scratch/tmp/openfpga/prjtrellis + +# open source synthesis tools +TRELLISDB ?= $(TRELLIS)/database +LIBTRELLIS ?= $(TRELLIS)/libtrellis +ECPPLL ?= LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(TRELLIS)/libtrellis/ecppll +ECPPACK ?= LANG=C LD_LIBRARY_PATH=$(LIBTRELLIS) $(TRELLIS)/libtrellis/ecppack --db $(TRELLISDB) +BIT2SVF ?= $(TRELLIS)/tools/bit_to_svf.py +#BASECFG ?= $(TRELLIS)/misc/basecfgs/empty_$(FPGA_CHIP_EQUIVALENT).config +# yosys options, sometimes those can be used: -noccu2 -nomux -nodram +YOSYS_OPTIONS ?= +# nextpnr options +NEXTPNR_OPTIONS ?= + +ifeq ($(FPGA_CHIP), lfe5u-12f) + CHIP_ID=0x21111043 +endif +ifeq ($(FPGA_CHIP), lfe5u-25f) + CHIP_ID=0x41111043 +endif +ifeq ($(FPGA_CHIP), lfe5u-45f) + CHIP_ID=0x41112043 +endif +ifeq ($(FPGA_CHIP), lfe5u-85f) + CHIP_ID=0x41113043 +endif + +ifeq ($(FPGA_SIZE), 12) + FPGA_K=$(FPGA_PREFIX)25 + IDCODE_CHIPID=--idcode $(CHIP_ID) +else + FPGA_K=$(FPGA_PREFIX)$(FPGA_SIZE) + IDCODE_CHIPID= +endif + +FPGA_CHIP_EQUIVALENT ?= lfe5u-$(FPGA_K)f + + +# clock generator +CLK0_NAME ?= clk0 +CLK0_FILE_NAME ?= clocks/$(CLK0_NAME).v +CLK0_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK1_NAME ?= clk1 +CLK1_FILE_NAME ?= clocks/$(CLK1_NAME).v +CLK1_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK2_NAME ?= clk2 +CLK2_FILE_NAME ?= clocks/$(CLK2_NAME).v +CLK2_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 +CLK3_NAME ?= clk3 +CLK3_FILE_NAME ?= clocks/$(CLK3_NAME).v +CLK3_OPTIONS ?= --input 25 --output 100 --s1 50 --p1 0 --s2 25 --p2 0 --s3 125 --p3 0 + +# closed source synthesis tools +#DIAMOND_BASE := /usr/local/diamond +ifneq ($(wildcard $(DIAMOND_BASE)),) + DIAMOND_BIN := $(shell find ${DIAMOND_BASE}/ -maxdepth 2 -name bin | sort -rn | head -1) + DIAMONDC := $(shell find ${DIAMOND_BIN}/ -name diamondc) + DDTCMD := $(shell find ${DIAMOND_BIN}/ -name ddtcmd) +endif + +# programming tools +TINYFPGASP ?= tinyfpgasp +FLEAFPGA_JTAG ?= FleaFPGA-JTAG +OPENOCD ?= openocd +OPENOCD_INTERFACE ?= $(SCRIPTS)/ft231x.ocd +UJPROG ?= ujprog + +# helper scripts directory +SCRIPTS ?= scripts + +# rest of the include makefile +FPGA_CHIP_UPPERCASE := $(shell echo $(FPGA_CHIP) | tr '[:lower:]' '[:upper:]') + + +#all: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf +all: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf + +# VHDL to VERILOG conversion +# convert all *.vhd filenames to .v extension +VHDL_TO_VERILOG_FILES = $(VHDL_FILES:.vhd=.v) +# implicit conversion rule +%.v: %.vhd + $(VHDL2VL) $< $@ + +#*.v: *.vhdl +# $(VHDL2VL) $< $@ + +#$(PROJECT).ys: makefile +# $(SCRIPTS)/ysgen.sh $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) > $@ +# echo "hierarchy -top ${TOP_MODULE}" >> $@ +# echo "synth_ecp5 -noccu2 -nomux -nodram -json ${PROJECT}.json" >> $@ + +#$(PROJECT).json: $(PROJECT).ys $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES) +# $(YOSYS) $(PROJECT).ys + +$(PROJECT).json: $(VERILOG_FILES) $(SYSTEMVERILOG_FILES) $(VHDL_TO_VERILOG_FILES) + $(YOSYS) \ + -p "read -vlog2k $(VERILOG_FILES) $(VHDL_TO_VERILOG_FILES)" \ + -p "read -sv $(SYSTEMVERILOG_FILES)" \ + -p "hierarchy -top ${TOP_MODULE}" \ + -p "synth_ecp5 ${YOSYS_OPTIONS} -json ${PROJECT}.json" + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config: $(PROJECT).json $(BASECFG) + $(NEXTPNR-ECP5) $(NEXTPNR_OPTIONS) --$(FPGA_K)k --package $(FPGA_PACKAGE) --json $(PROJECT).json --lpf $(CONSTRAINTS) --textcfg $@ + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config + $(ECPPACK) $(IDCODE_CHIPID) --compress --input $< --bit $@ + +$(CLK0_FILE_NAME): + $(ECPPLL) $(CLK0_OPTIONS) --file $@ + +$(CLK1_FILE_NAME): + $(ECPPLL) $(CLK1_OPTIONS) --file $@ + +$(CLK2_FILE_NAME): + $(ECPPLL) $(CLK2_OPTIONS) --file $@ + +$(CLK3_FILE_NAME): + $(ECPPLL) $(CLK3_OPTIONS) --file $@ + +# generate XCF programming file for DDTCMD +$(BOARD)_$(FPGA_SIZE)f.xcf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit $(SCRIPTS)/$(BOARD)_sram.xcf $(SCRIPTS)/xcf.xsl $(DTD_FILE) + xsltproc \ + --stringparam FPGA_CHIP $(FPGA_CHIP_UPPERCASE) \ + --stringparam CHIP_ID $(CHIP_ID) \ + --stringparam BITSTREAM_FILE $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit \ + $(SCRIPTS)/xcf.xsl $(SCRIPTS)/$(BOARD)_sram.xcf > $@ + +# run DDTCMD to generate VME file +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + LANG=C ${DDTCMD} -oft -fullvme -if $(BOARD)_$(FPGA_SIZE)f.xcf -nocompress -noheader -of $@ + +# run DDTCMD to generate SVF file +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f.xcf $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +# LANG=C ${DDTCMD} -oft -svfsingle -revd -maxdata 8 -if $(BOARD)_$(FPGA_SIZE)f.xcf -of $@ + +# generate SVF file by prjtrellis python script +#$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +# $(BIT2SVF) $< $@ + +$(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config + $(ECPPACK) $(IDCODE_CHIPID) $< --freq 62.0 --svf-rowsize 800000 --svf $@ + +# program SRAM with ujrprog (temporary) +program: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) $< + +# program SRAM with FleaFPGA-JTAG (temporary) +program_flea: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme + $(FLEAFPGA_JTAG) $< + +# program FLASH over US1 port with ujprog bootloader (permanently) +flash: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(UJPROG) -j flash $< + +# program FLASH over US2 port with tinyfpgasp bootloader (permanently) +flash_tiny: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit + $(TINYFPGASP) -w $< + +# generate chip-specific openocd programming file +$(BOARD)_$(FPGA_SIZE)f.ocd: makefile $(SCRIPTS)/ecp5-ocd.sh + $(SCRIPTS)/ecp5-ocd.sh $(CHIP_ID) $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf > $@ + +# program SRAM with OPENOCD +program_ocd: $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf $(BOARD)_$(FPGA_SIZE)f.ocd + $(OPENOCD) --file=$(OPENOCD_INTERFACE) --file=$(BOARD)_$(FPGA_SIZE)f.ocd + +JUNK = *~ +#JUNK += $(PROJECT).ys +JUNK += $(PROJECT).json +JUNK += $(VHDL_TO_VERILOG_FILES) +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).config +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).bit +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).vme +JUNK += $(BOARD)_$(FPGA_SIZE)f_$(PROJECT).svf +JUNK += $(BOARD)_$(FPGA_SIZE)f.xcf +JUNK += $(BOARD)_$(FPGA_SIZE)f.ocd +JUNK += $(CLK0_FILE_NAME) $(CLK1_FILE_NAME) $(CLK2_FILE_NAME) $(CLK3_FILE_NAME) + +clean: + rm -f $(JUNK) diff --git a/j1b/ulx3s/scripts/trellis_path.mk b/j1b/ulx3s/scripts/trellis_path.mk new file mode 100644 index 0000000..28ddf37 --- /dev/null +++ b/j1b/ulx3s/scripts/trellis_path.mk @@ -0,0 +1,12 @@ +# ******* tools installation paths ******* +# https://github.com/SymbiFlow/prjtrellis +TRELLIS ?= /mt/scratch/tmp/openfpga/prjtrellis +# https://github.com/ldoolitt/vhd2vl +VHDL2VL ?= vhd2vl +# https://github.com/YosysHQ/yosys +YOSYS ?= yosys +# https://github.com/YosysHQ/nextpnr +NEXTPNR-ECP5 ?= nextpnr-ecp5 +# trellis ecppack +ECPPACK ?= LANG=C ecppack +ECPPLL ?= LANG=C ecppll diff --git a/j1b/ulx3s/ulx3s_v20_segpdi.lpf b/j1b/ulx3s/ulx3s_v20_segpdi.lpf new file mode 100644 index 0000000..6379d18 --- /dev/null +++ b/j1b/ulx3s/ulx3s_v20_segpdi.lpf @@ -0,0 +1,457 @@ +BLOCK RESETPATHS; +BLOCK ASYNCPATHS; +## ULX3S v2.x.x and v3.0.x + +# The clock "usb" and "gpdi" sheet +LOCATE COMP "clk_25mhz" SITE "G2"; +IOBUF PORT "clk_25mhz" PULLMODE=NONE IO_TYPE=LVCMOS33; +FREQUENCY PORT "clk_25mhz" 25 MHZ; + +# JTAG and SPI FLASH voltage 3.3V and options to boot from SPI flash +# write to FLASH possible any time from JTAG: +SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=ENABLE SLAVE_PARALLEL_PORT=DISABLE; +# write to FLASH possible from user bitstream: +# SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; + +## USBSERIAL FTDI-FPGA serial port "usb" sheet +LOCATE COMP "ftdi_rxd" SITE "L4"; # FPGA transmits to ftdi +LOCATE COMP "ftdi_txd" SITE "M1"; # FPGA receives from ftdi +LOCATE COMP "ftdi_nrts" SITE "M3"; # FPGA receives +LOCATE COMP "ftdi_ndtr" SITE "N1"; # FPGA receives +LOCATE COMP "ftdi_txden" SITE "L3"; # FPGA receives +IOBUF PORT "ftdi_rxd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "ftdi_txd" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_nrts" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_ndtr" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_txden" PULLMODE=UP IO_TYPE=LVCMOS33; + +## LED indicators "blinkey" and "gpio" sheet +LOCATE COMP "led[7]" SITE "H3"; +LOCATE COMP "led[6]" SITE "E1"; +LOCATE COMP "led[5]" SITE "E2"; +LOCATE COMP "led[4]" SITE "D1"; +LOCATE COMP "led[3]" SITE "D2"; +LOCATE COMP "led[2]" SITE "C1"; +LOCATE COMP "led[1]" SITE "C2"; +LOCATE COMP "led[0]" SITE "B2"; +IOBUF PORT "led[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +## Pushbuttons "blinkey", "flash", "power", "gpdi" sheet +LOCATE COMP "btn[0]" SITE "D6"; # BTN_PWRn (inverted logic) +LOCATE COMP "btn[1]" SITE "R1"; # FIRE1 +LOCATE COMP "btn[2]" SITE "T1"; # FIRE2 +LOCATE COMP "btn[3]" SITE "R18"; # UP W1->R18 +LOCATE COMP "btn[4]" SITE "V1"; # DOWN +LOCATE COMP "btn[5]" SITE "U1"; # LEFT +LOCATE COMP "btn[6]" SITE "H16"; # RIGHT Y2->H16 +IOBUF PORT "btn[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[3]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[4]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[5]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "btn[6]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; + +## DIP switch "blinkey", "gpio" sheet +LOCATE COMP "sw[0]" SITE "E8"; # SW1 +LOCATE COMP "sw[1]" SITE "D8"; # SW2 +LOCATE COMP "sw[2]" SITE "D7"; # SW3 +LOCATE COMP "sw[3]" SITE "E7"; # SW4 +IOBUF PORT "sw[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sw[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sw[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sw[3]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; + +## SPI OLED DISPLAY SSD1331 (Color) or SSD1306 (B/W) "blinkey", "usb" sheet +LOCATE COMP "oled_clk" SITE "P4"; +LOCATE COMP "oled_mosi" SITE "P3"; +LOCATE COMP "oled_dc" SITE "P1"; +LOCATE COMP "oled_resn" SITE "P2"; +LOCATE COMP "oled_csn" SITE "N2"; +IOBUF PORT "oled_clk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_dc" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_resn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SPI Flash chip "flash" sheet +LOCATE COMP "flash_csn" SITE "R2"; +LOCATE COMP "flash_clk" SITE "U3"; +LOCATE COMP "flash_mosi" SITE "W2"; +LOCATE COMP "flash_miso" SITE "V2"; +LOCATE COMP "flash_holdn" SITE "W1"; +LOCATE COMP "flash_wpn" SITE "Y2"; +#LOCATE COMP "flash_csspin" SITE "AJ3"; +#LOCATE COMP "flash_initn" SITE "AG4"; +#LOCATE COMP "flash_done" SITE "AJ4"; +#LOCATE COMP "flash_programn" SITE "AH4"; +#LOCATE COMP "flash_cfg_select[0]" SITE "AM4"; +#LOCATE COMP "flash_cfg_select[1]" SITE "AL4"; +#LOCATE COMP "flash_cfg_select[2]" SITE "AK4"; +IOBUF PORT "flash_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_clk" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_miso" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_holdn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_wpn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_csspin" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_initn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_done" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; + +## SD card "sdcard", "usb" sheet +LOCATE COMP "sd_clk" SITE "H2"; # sd_clk WiFi_GPIO14 +LOCATE COMP "sd_cmd" SITE "J1"; # sd_cmd_di (MOSI) WiFi GPIO15 +LOCATE COMP "sd_d[0]" SITE "J3"; # sd_dat0_do (MISO) WiFi GPIO2 +LOCATE COMP "sd_d[1]" SITE "H1"; # sd_dat1_irq WiFi GPIO4 +LOCATE COMP "sd_d[2]" SITE "K1"; # sd_dat2 WiFi_GPIO12 +LOCATE COMP "sd_d[3]" SITE "K2"; # sd_dat3_csn WiFi_GPIO13 +LOCATE COMP "sd_wp" SITE "P5"; # not connected +LOCATE COMP "sd_cdn" SITE "N5"; # not connected +IOBUF PORT "sd_clk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_cmd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; # WiFi GPIO12 pulldown bootstrapping requirement +IOBUF PORT "sd_d[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_wp" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_cdn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## ADC SPI (MAX11123) "analog", "ram" sheet +LOCATE COMP "adc_csn" SITE "R17"; +LOCATE COMP "adc_mosi" SITE "R16"; +LOCATE COMP "adc_miso" SITE "U16"; +LOCATE COMP "adc_sclk" SITE "P17"; +IOBUF PORT "adc_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_miso" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_sclk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## Audio 4-bit DAC "analog", "gpio" sheet +# 4-bit mode can drive down to 75 ohm load impedance. +# Lower impedance leads to IO overload, +# FPGA will stop working and need reboot. +# For standard 17 ohm earphones on PCB v1.7: +# use bits 2,3 as input (High-Z) and drive only bits 0,1. +# PCB v2.1.2 can use full 4 bits and 16mA drive for 17 ohm earphones. +LOCATE COMP "audio_l[3]" SITE "B3"; # JACK TIP (left audio) +LOCATE COMP "audio_l[2]" SITE "C3"; +LOCATE COMP "audio_l[1]" SITE "D3"; +LOCATE COMP "audio_l[0]" SITE "E4"; +LOCATE COMP "audio_r[3]" SITE "C5"; # JACK RING1 (right audio) +LOCATE COMP "audio_r[2]" SITE "D5"; +LOCATE COMP "audio_r[1]" SITE "B5"; +LOCATE COMP "audio_r[0]" SITE "A3"; +LOCATE COMP "audio_v[3]" SITE "E5"; # JACK RING2 (video or digital audio) +LOCATE COMP "audio_v[2]" SITE "F5"; +LOCATE COMP "audio_v[1]" SITE "F2"; +LOCATE COMP "audio_v[0]" SITE "H5"; +IOBUF PORT "audio_l[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; + +## WiFi ESP-32 "wifi", "usb", "flash" sheet +# other pins are shared with GP/GN, SD card and JTAG +LOCATE COMP "wifi_en" SITE "F1"; # enable/reset WiFi +LOCATE COMP "wifi_rxd" SITE "K3"; # FPGA transmits to WiFi +LOCATE COMP "wifi_txd" SITE "K4"; # FPGA receives from WiFi +LOCATE COMP "wifi_gpio0" SITE "L2"; +LOCATE COMP "wifi_gpio5" SITE "N4"; # WIFI LED +LOCATE COMP "wifi_gpio16" SITE "L1"; # Serial1 RX +LOCATE COMP "wifi_gpio17" SITE "N3"; # Serial1 TX +# LOCATE COMP "prog_done" SITE "Y3"; # not GPIO, always active +IOBUF PORT "wifi_en" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_rxd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_txd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio0" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio5" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio16" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio17" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +# IOBUF PORT "prog_done" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## PCB antenna 433 MHz (may be also used for FM) "usb" sheet +LOCATE COMP "ant_433mhz" SITE "G1"; +IOBUF PORT "ant_433mhz" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +## Second USB port "US2" going directly into FPGA "usb", "ram" sheet +LOCATE COMP "usb_fpga_dp" SITE "E16"; # single ended or differential input only +LOCATE COMP "usb_fpga_dn" SITE "F16"; +IOBUF PORT "usb_fpga_dp" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16; +IOBUF PORT "usb_fpga_dn" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16; +LOCATE COMP "usb_fpga_bd_dp" SITE "D15"; # single-ended bidirectional +LOCATE COMP "usb_fpga_bd_dn" SITE "E15"; +IOBUF PORT "usb_fpga_bd_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "usb_fpga_bd_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "usb_fpga_pu_dp" SITE "B12"; # pull up/down control +LOCATE COMP "usb_fpga_pu_dn" SITE "C12"; +IOBUF PORT "usb_fpga_pu_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "usb_fpga_pu_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; + +## JTAG ESP-32 "usb" sheet +# connected to FT231X and ESP-32 +# commented out because those are dedicated pins, not directly useable as GPIO +# but could be used by some vendor-specific JTAG bridging (boundary scan) module +#LOCATE COMP "jtag_tdi" SITE "R5"; # FTDI_nRI FPGA receives +#LOCATE COMP "jtag_tdo" SITE "V4"; # FTDI_nCTS FPGA transmits +#LOCATE COMP "jtag_tck" SITE "T5"; # FTDI_nDSR FPGA receives +#LOCATE COMP "jtag_tms" SITE "U5"; # FTDI_nDCD FPGA receives +#IOBUF PORT "jtag_tdi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tdo" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tck" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tms" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SDRAM "ram" sheet +LOCATE COMP "sdram_clk" SITE "F19"; +LOCATE COMP "sdram_cke" SITE "F20"; +LOCATE COMP "sdram_csn" SITE "P20"; +LOCATE COMP "sdram_wen" SITE "T20"; +LOCATE COMP "sdram_rasn" SITE "R20"; +LOCATE COMP "sdram_casn" SITE "T19"; +LOCATE COMP "sdram_a[0]" SITE "M20"; +LOCATE COMP "sdram_a[1]" SITE "M19"; +LOCATE COMP "sdram_a[2]" SITE "L20"; +LOCATE COMP "sdram_a[3]" SITE "L19"; +LOCATE COMP "sdram_a[4]" SITE "K20"; +LOCATE COMP "sdram_a[5]" SITE "K19"; +LOCATE COMP "sdram_a[6]" SITE "K18"; +LOCATE COMP "sdram_a[7]" SITE "J20"; +LOCATE COMP "sdram_a[8]" SITE "J19"; +LOCATE COMP "sdram_a[9]" SITE "H20"; +LOCATE COMP "sdram_a[10]" SITE "N19"; +LOCATE COMP "sdram_a[11]" SITE "G20"; +LOCATE COMP "sdram_a[12]" SITE "G19"; +LOCATE COMP "sdram_ba[0]" SITE "P19"; +LOCATE COMP "sdram_ba[1]" SITE "N20"; +LOCATE COMP "sdram_dqm[0]" SITE "U19"; +LOCATE COMP "sdram_dqm[1]" SITE "E20"; +LOCATE COMP "sdram_d[0]" SITE "J16"; +LOCATE COMP "sdram_d[1]" SITE "L18"; +LOCATE COMP "sdram_d[2]" SITE "M18"; +LOCATE COMP "sdram_d[3]" SITE "N18"; +LOCATE COMP "sdram_d[4]" SITE "P18"; +LOCATE COMP "sdram_d[5]" SITE "T18"; +LOCATE COMP "sdram_d[6]" SITE "T17"; +LOCATE COMP "sdram_d[7]" SITE "U20"; +LOCATE COMP "sdram_d[8]" SITE "E19"; +LOCATE COMP "sdram_d[9]" SITE "D20"; +LOCATE COMP "sdram_d[10]" SITE "D19"; +LOCATE COMP "sdram_d[11]" SITE "C20"; +LOCATE COMP "sdram_d[12]" SITE "E18"; +LOCATE COMP "sdram_d[13]" SITE "F18"; +LOCATE COMP "sdram_d[14]" SITE "J18"; +LOCATE COMP "sdram_d[15]" SITE "J17"; +IOBUF PORT "sdram_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_cke" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_csn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_wen" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_rasn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_casn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_a[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_ba[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_ba[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_dqm[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_dqm[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_d[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +# GPDI differential interface (Video) "gpdi" sheet +LOCATE COMP "gpdi_dp[0]" SITE "A16"; # Blue + +LOCATE COMP "gpdi_dn[0]" SITE "B16"; # Blue - +LOCATE COMP "gpdi_dp[1]" SITE "A14"; # Green + +LOCATE COMP "gpdi_dn[1]" SITE "C14"; # Green - +LOCATE COMP "gpdi_dp[2]" SITE "A12"; # Red + +LOCATE COMP "gpdi_dn[2]" SITE "A13"; # Red - +LOCATE COMP "gpdi_dp[3]" SITE "A17"; # Clock + +LOCATE COMP "gpdi_dn[3]" SITE "B18"; # Clock - +LOCATE COMP "gpdi_ethp" SITE "A19"; # Ethernet + +LOCATE COMP "gpdi_ethn" SITE "B20"; # Ethernet - +LOCATE COMP "gpdi_cec" SITE "A18"; +LOCATE COMP "gpdi_sda" SITE "B19"; # I2C shared with RTC +LOCATE COMP "gpdi_scl" SITE "E12"; # I2C shared with RTC C12->E12 +IOBUF PORT "gpdi_dp[0]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dn[0]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dp[1]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dn[1]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dp[2]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dn[2]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dp[3]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_dn[3]" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_ethp" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_ethn" IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_cec" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_sda" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_scl" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +# GPIO (default single-ended) "gpio", "ram", "gpdi" sheet +# Pins enumerated gp[0-27], gn[0-27]. +# With differential mode enabled on Lattice, +# gp[] (+) are used, gn[] (-) are ignored from design +# as they handle inverted signal by default. +# To enable differential, rename LVCMOS33->LVCMOS33D +LOCATE COMP "gp[0]" SITE "B11"; # J1_5+ GP0 +LOCATE COMP "gn[0]" SITE "C11"; # J1_5- GN0 +LOCATE COMP "gp[1]" SITE "A10"; # J1_7+ GP1 +LOCATE COMP "gn[1]" SITE "A11"; # J1_7- GN1 +LOCATE COMP "gp[2]" SITE "A9"; # J1_9+ GP2 +LOCATE COMP "gn[2]" SITE "B10"; # J1_9- GN2 +LOCATE COMP "gp[3]" SITE "B9"; # J1_11+ GP3 +LOCATE COMP "gn[3]" SITE "C10"; # J1_11- GN3 +LOCATE COMP "gp[4]" SITE "A7"; # J1_13+ GP4 +LOCATE COMP "gn[4]" SITE "A8"; # J1_13- GN4 +LOCATE COMP "gp[5]" SITE "C8"; # J1_15+ GP5 +LOCATE COMP "gn[5]" SITE "B8"; # J1_15- GN5 +LOCATE COMP "gp[6]" SITE "C6"; # J1_17+ GP6 +LOCATE COMP "gn[6]" SITE "C7"; # J1_17- GN6 +IOBUF PORT "gp[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[2]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[2]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[4]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[4]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[5]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[5]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[6]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[6]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[7]" SITE "A6"; # J1_23+ GP7 +LOCATE COMP "gn[7]" SITE "B6"; # J1_23- GN7 +LOCATE COMP "gp[8]" SITE "A4"; # J1_25+ GP8 +LOCATE COMP "gn[8]" SITE "A5"; # J1_25- GN8 +LOCATE COMP "gp[9]" SITE "A2"; # J1_27+ GP9 +LOCATE COMP "gn[9]" SITE "B1"; # J1_27- GN9 +LOCATE COMP "gp[10]" SITE "C4"; # J1_29+ GP10 WIFI_GPIO27 +LOCATE COMP "gn[10]" SITE "B4"; # J1_29- GN10 +LOCATE COMP "gp[11]" SITE "F4"; # J1_31+ GP11 WIFI_GPIO25 +LOCATE COMP "gn[11]" SITE "E3"; # J1_31- GN11 WIFI_GPIO26 +LOCATE COMP "gp[12]" SITE "G3"; # J1_33+ GP12 WIFI_GPIO32 +LOCATE COMP "gn[12]" SITE "F3"; # J1_33- GN12 WIFI_GPIO33 +LOCATE COMP "gp[13]" SITE "H4"; # J1_35+ GP13 WIFI_GPIO34 +LOCATE COMP "gn[13]" SITE "G5"; # J1_35- GN13 WIFI_GPIO35 +IOBUF PORT "gp[7]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[7]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[8]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[8]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[9]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[9]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[10]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[10]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[11]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[11]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[12]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[12]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[13]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[13]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[14]" SITE "U18"; # J2_5+ GP14 +LOCATE COMP "gn[14]" SITE "U17"; # J2_5- GN14 +LOCATE COMP "gp[15]" SITE "N17"; # J2_7+ GP15 +LOCATE COMP "gn[15]" SITE "P16"; # J2_7- GN15 +LOCATE COMP "gp[16]" SITE "N16"; # J2_9+ GP16 +LOCATE COMP "gn[16]" SITE "M17"; # J2_9- GN16 +LOCATE COMP "gp[17]" SITE "L16"; # J2_11+ GP17 +LOCATE COMP "gn[17]" SITE "L17"; # J2_11- GN17 +LOCATE COMP "gp[18]" SITE "H18"; # J2_13+ GP18 +LOCATE COMP "gn[18]" SITE "H17"; # J2_13- GN18 +LOCATE COMP "gp[19]" SITE "F17"; # J2_15+ GP19 +LOCATE COMP "gn[19]" SITE "G18"; # J2_15- GN19 +LOCATE COMP "gp[20]" SITE "D18"; # J2_17+ GP20 +LOCATE COMP "gn[20]" SITE "E17"; # J2_17- GN20 +IOBUF PORT "gp[14]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[14]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[15]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[15]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[16]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[16]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[17]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[17]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[18]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[18]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[19]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[19]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[20]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[20]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[21]" SITE "C18"; # J2_23+ GP21 +LOCATE COMP "gn[21]" SITE "D17"; # J2_23- GN21 +LOCATE COMP "gp[22]" SITE "B15"; # J2_25+ GP22 D15->B15 +LOCATE COMP "gn[22]" SITE "C15"; # J2_25- GN22 E15->C15 +LOCATE COMP "gp[23]" SITE "B17"; # J2_27+ GP23 +LOCATE COMP "gn[23]" SITE "C17"; # J2_27- GN23 +LOCATE COMP "gp[24]" SITE "C16"; # J2_29+ GP24 +LOCATE COMP "gn[24]" SITE "D16"; # J2_29- GN24 +LOCATE COMP "gp[25]" SITE "D14"; # J2_31+ GP25 B15->D14 +LOCATE COMP "gn[25]" SITE "E14"; # J2_31- GN25 C15->E14 +LOCATE COMP "gp[26]" SITE "B13"; # J2_33+ GP26 +LOCATE COMP "gn[26]" SITE "C13"; # J2_33- GN26 +LOCATE COMP "gp[27]" SITE "D13"; # J2_35+ GP27 +LOCATE COMP "gn[27]" SITE "E13"; # J2_35- GN27 +IOBUF PORT "gp[21]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[21]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[22]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[22]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[23]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[23]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[24]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[24]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[25]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[25]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[26]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[26]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[27]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[27]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## PROGRAMN (reload bitstream from FLASH, exit from bootloader) +# PCB v2.0.5 and higher +LOCATE COMP "user_programn" SITE "M4"; +IOBUF PORT "user_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SHUTDOWN "power", "ram" sheet (connected from PCB v1.7.5) +# on PCB v1.7 shutdown is not connected to FPGA +LOCATE COMP "shutdown" SITE "G16"; # FPGA receives +IOBUF PORT "shutdown" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; diff --git a/j1b/verilog/ram.v b/j1b/verilog/ram.v new file mode 100644 index 0000000..6c5edb9 --- /dev/null +++ b/j1b/verilog/ram.v @@ -0,0 +1,83 @@ +`default_nettype none + +module bram_tdp #( + parameter DATA = 72, + parameter ADDR = 10 +) ( + // Port A + input wire a_clk, + input wire a_wr, + input wire [ADDR-1:0] a_addr, + input wire [DATA-1:0] a_din, + output reg [DATA-1:0] a_dout, + + // Port B + input wire b_clk, + input wire b_wr, + input wire [ADDR-1:0] b_addr, + input wire [DATA-1:0] b_din, + output reg [DATA-1:0] b_dout +); + +// Shared memory +reg [DATA-1:0] mem [(2**ADDR)-1:0]; + initial begin + $readmemh("../build/nuc.hex", mem); + end + +// Port A +always @(posedge a_clk) begin + a_dout <= mem[a_addr]; + if(a_wr) begin + a_dout <= a_din; + mem[a_addr] <= a_din; + end +end + +// Port B +always @(posedge b_clk) begin + b_dout <= mem[b_addr]; + if(b_wr) begin + b_dout <= b_din; + mem[b_addr] <= b_din; + end +end + +endmodule + +// A 32Kbyte RAM (8192x32) with two ports: +// port a, 32 bits read/write +// port b, 16 bits read-only, lower 16K only + +module ram16k( + input wire clk, + + input wire[15:0] a_addr, + output wire[31:0] a_q, + input wire[31:0] a_d, + input wire a_wr, + + input wire[12:0] b_addr, + output wire[15:0] b_q); + + wire [31:0] insn32; + + bram_tdp #(.DATA(32), .ADDR(13)) nram ( + .a_clk(clk), + .a_wr(a_wr), + .a_addr(a_addr[14:2]), + .a_din(a_d), + .a_dout(a_q), + + .b_clk(clk), + .b_wr(1'b0), + .b_addr({1'b0, b_addr[12:1]}), + .b_din(32'd0), + .b_dout(insn32)); + + reg ba_; + always @(posedge clk) + ba_ <= b_addr[0]; + assign b_q = ba_ ? insn32[31:16] : insn32[15:0]; + +endmodule diff --git a/j1b/verilog/ulx3s_top.v b/j1b/verilog/ulx3s_top.v new file mode 100644 index 0000000..321ec80 --- /dev/null +++ b/j1b/verilog/ulx3s_top.v @@ -0,0 +1,141 @@ +`default_nettype none + +module ulx3s_top( + input wire clk_25mhz, + input wire [6:0] btn, + output wire [7:0] led, + + input wire ftdi_txd, + output wire ftdi_rxd, + + output wire wifi_gpio0 + ); + + // Tie GPIO0, keep board from rebooting + assign wifi_gpio0 = 1'b1; + + // no leds on for now + assign led = 0; + + wire resetq = btn[0]; + + localparam MHZ = 25; + wire fclk = clk_25mhz; + + reg [63:0] counter; + always @(posedge fclk) + counter <= counter + 64'd1; + + reg [31:0] ms; + reg [17:0] subms; + localparam [17:0] lim = (MHZ * 1000) - 1; + always @(posedge fclk) begin + subms <= (subms == lim) ? 18'd0 : (subms + 18'd1); + if (subms == lim) + ms <= ms + 32'd1; + end + + // ------------------------------------------------------------------------ + + wire uart0_valid, uart0_busy; + wire [7:0] uart0_data; + wire uart0_rd, uart0_wr; + reg [31:0] uart_baud = 32'd115200; + wire UART0_RX; + buart #(.CLKFREQ(MHZ * 1000000)) _uart0 ( + .clk(fclk), + .resetq(resetq), + .baud(uart_baud), + .rx(ftdi_txd), + .tx(ftdi_rxd), + .rd(uart0_rd), + .wr(uart0_wr), + .valid(uart0_valid), + .busy(uart0_busy), + .tx_data(dout_[7:0]), + .rx_data(uart0_data)); + + wire [15:0] mem_addr; + wire [31:0] mem_din; + wire mem_wr; + wire [31:0] dout; + reg [31:0] din; + + wire [12:0] code_addr; + wire [15:0] insn; + + wire io_rd, io_wr; + + j1 _j1 ( + .clk(fclk), + .resetq(resetq), + + .io_rd(io_rd), + .io_wr(io_wr), + .mem_addr(mem_addr), + .mem_wr(mem_wr), + .mem_din(mem_din), + .dout(dout), + .io_din(din), + + .code_addr(code_addr), + .insn(insn) + ); + + ram16k ram(.clk(fclk), + .a_addr(mem_addr), + .a_q(mem_din), + .a_wr(mem_wr), + .a_d(dout), + .b_addr(code_addr), + .b_q(insn)); + + reg io_wr_, io_rd_; + reg [15:0] mem_addr_; + reg [31:0] dout_; + always @(posedge fclk) + {io_wr_, io_rd_, mem_addr_, dout_} <= {io_wr, io_rd, mem_addr, dout}; + + /* READ WRITE + 00xx GPIO rd GPIO wr + 01xx GPIO direction + + 1008 baudrate baudrate + 1000 UART RX UART TX + 2000 UART status + + 1010 master freq snapshot clock + 1014 clock[31:0] + 1018 clock[63:32] + 101c millisecond uptime + + */ + + reg [63:0] counter_; + + always @(posedge fclk) begin + casez (mem_addr) + 16'h1008: din <= uart_baud; + 16'h1000: din <= {24'd0, uart0_data}; + 16'h2000: din <= {30'd0, uart0_valid, !uart0_busy}; + + 16'h1010: din <= MHZ * 1000000; + 16'h1014: din <= counter_[31:0]; + 16'h1018: din <= counter_[63:32]; + 16'h101c: din <= ms; + + default: din <= 32'bx; + endcase + + if (io_wr_) begin + casez (mem_addr_) + 16'h1008: uart_baud <= dout_; + 16'h1010: counter_ <= counter; + endcase + end + end + + assign uart0_wr = io_wr_ & (mem_addr_ == 16'h1000); + assign uart0_rd = io_rd_ & (mem_addr_ == 16'h1000); + +endmodule diff --git a/j1b/verilog/xilinx-top.v b/j1b/verilog/xilinx-top.v index 8d92f44..6e4b1e4 100644 --- a/j1b/verilog/xilinx-top.v +++ b/j1b/verilog/xilinx-top.v @@ -1,88 +1,5 @@ `default_nettype none -module bram_tdp #( - parameter DATA = 72, - parameter ADDR = 10 -) ( - // Port A - input wire a_clk, - input wire a_wr, - input wire [ADDR-1:0] a_addr, - input wire [DATA-1:0] a_din, - output reg [DATA-1:0] a_dout, - - // Port B - input wire b_clk, - input wire b_wr, - input wire [ADDR-1:0] b_addr, - input wire [DATA-1:0] b_din, - output reg [DATA-1:0] b_dout -); - -// Shared memory -reg [DATA-1:0] mem [(2**ADDR)-1:0]; - initial begin - $readmemh("../build/nuc.hex", mem); - end - -// Port A -always @(posedge a_clk) begin - a_dout <= mem[a_addr]; - if(a_wr) begin - a_dout <= a_din; - mem[a_addr] <= a_din; - end -end - -// Port B -always @(posedge b_clk) begin - b_dout <= mem[b_addr]; - if(b_wr) begin - b_dout <= b_din; - mem[b_addr] <= b_din; - end -end - -endmodule - -// A 32Kbyte RAM (8192x32) with two ports: -// port a, 32 bits read/write -// port b, 16 bits read-only, lower 16K only - -module ram16k( - input wire clk, - - input wire[15:0] a_addr, - output wire[31:0] a_q, - input wire[31:0] a_d, - input wire a_wr, - - input wire[12:0] b_addr, - output wire[15:0] b_q); - - wire [31:0] insn32; - - bram_tdp #(.DATA(32), .ADDR(13)) nram ( - .a_clk(clk), - .a_wr(a_wr), - .a_addr(a_addr[14:2]), - .a_din(a_d), - .a_dout(a_q), - - .b_clk(clk), - .b_wr(1'b0), - .b_addr({1'b0, b_addr[12:1]}), - .b_din(32'd0), - .b_dout(insn32)); - - reg ba_; - always @(posedge clk) - ba_ <= b_addr[0]; - assign b_q = ba_ ? insn32[31:16] : insn32[15:0]; - -endmodule - - module top( input wire CLK, input wire DUO_SW1, diff --git a/j1b/xilinx/Makefile b/j1b/xilinx/Makefile index 23db1a6..5360868 100644 --- a/j1b/xilinx/Makefile +++ b/j1b/xilinx/Makefile @@ -6,7 +6,14 @@ part = xc6slx9-2-tqg144 top_module = top flashsize = 2048 -vfiles = ../verilog/xilinx-top.v ../verilog/uart.v ../verilog/j1.v ../verilog/stack.v # ../verilog/vga.v +vfiles = \ +../verilog/xilinx-top.v \ +../verilog/j1.v \ +../verilog/ram.v \ +../verilog/uart.v \ +../verilog/stack.v \ +# ../verilog/vga.v \ + ifiles = ../build/nuc.hex include xilinx.mk