diff --git a/Makefile b/Makefile index 4b26756..618c3ca 100644 --- a/Makefile +++ b/Makefile @@ -3,14 +3,16 @@ DOCKER=docker #DOCKER=podman PWD = $(shell pwd) +USBDEVICE ?= /dev/bus/usb DOCKERARGS = run --rm -v $(PWD):/src -w /src VERILATORARGS = run --name verilator --hostname verilator --rm -it --entrypoint= -v $(PWD):/work -w /work -YOSYS = $(DOCKER) $(DOCKERARGS) ghdl/synth:beta yosys -NEXTPNR = $(DOCKER) $(DOCKERARGS) ghdl/synth:nextpnr-ecp5 nextpnr-ecp5 -ECPPACK = $(DOCKER) $(DOCKERARGS) ghdl/synth:trellis ecppack -OPENOCD = $(DOCKER) $(DOCKERARGS) --device /dev/bus/usb ghdl/synth:prog openocd -VERILATOR = $(DOCKER) $(VERILATORARGS) verilator/verilator +YOSYS = $(DOCKER) $(DOCKERARGS) ghdl/synth:beta yosys +NEXTPNR = $(DOCKER) $(DOCKERARGS) ghdl/synth:nextpnr-ecp5 nextpnr-ecp5 +ECPPACK = $(DOCKER) $(DOCKERARGS) ghdl/synth:trellis ecppack +OPENOCD_DEF = $(DOCKER) $(DOCKERARGS) --privileged --device $(USBDEVICE):/dev/bus/usb ghdl/synth:prog openocd +OPENOCD_ULX3S = $(DOCKER) $(DOCKERARGS) --privileged --device $(USBDEVICE):/dev/bus/usb alpin3/ulx3s openocd +VERILATOR = $(DOCKER) $(VERILATORARGS) verilator/verilator # Uncomment to use local tools for synthesis #YOSYS = yosys @@ -34,6 +36,7 @@ LPF=constraints/ecp5-evn.lpf PLL=pll/pll_ehxplll.v PACKAGE=CABGA381 NEXTPNR_FLAGS=--um5g-85k --freq 12 +OPENOCD=$(OPENOCD_DEF) OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg else ifeq ($(ECP5_BOARD),ulx3s) @@ -42,6 +45,7 @@ LPF=constraints/ecp5-ulx3s.lpf PLL=pll/pll_ehxplll_25MHz.v PACKAGE=CABGA381 NEXTPNR_FLAGS=--85k --freq 25 +OPENOCD=$(OPENOCD_ULX3S) OPENOCD_JTAG_CONFIG=openocd/ft231x.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5U-85F.cfg else ifeq ($(ECP5_BOARD),orangecrab) @@ -50,6 +54,7 @@ LPF=constraints/orange-crab.lpf PLL=pll/pll_bypass.v PACKAGE=CSFBGA285 NEXTPNR_FLAGS=--um5g-85k --freq 50 +OPENOCD=$(OPENOCD_DEF) OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg else ifeq ($(ECP5_BOARD),colorlight) @@ -58,6 +63,7 @@ LPF=constraints/colorlight_5A-75B.lpf PLL=pll/pll_ehxplll_25MHz.v PACKAGE=CABGA256 NEXTPNR_FLAGS=--25k --freq 25 +OPENOCD=$(OPENOCD_DEF) OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5U-25F.cfg else @@ -90,10 +96,10 @@ dockerlator: chiselwatt # Mask exit code from verilator on Make @$(VERILATOR) bash || true -synth: test-vars chiselwatt.bit +synth: check-board-vars chiselwatt.bit -test-vars: - @test -n "$(LPF)" || (echo "If synthesizing, use \"synth\" target with ECP5_BOARD variable to either \"evn\", \"ulx3s\", \"orangecrab\", \"colorlight\"\n" ; exit 1) +check-board-vars: + @test -n "$(LPF)" || (echo "If synthesizing or programming, use \"synth\" or \"prog\" targets with ECP5_BOARD variable to either \"evn\", \"ulx3s\", \"orangecrab\", \"colorlight\"\n" ; exit 1) chiselwatt.json: insns.hex $(verilog_files) $(PLL) toplevel.v $(YOSYS) -p "read_verilog -sv $(verilog_files) $(PLL) toplevel.v; synth_ecp5 -json $@ -top toplevel" @@ -106,8 +112,8 @@ chiselwatt.bit: chiselwatt_out.config chiselwatt.svf: chiselwatt.bit -prog: chiselwatt.svf - $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit" +prog: check-board-vars chiselwatt.svf + $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf chiselwatt.svf; exit" clean: @rm -f Core.fir firrtl_black_box_resource_files.f Core.v Core.anno.json MemoryBlackBox.v diff --git a/README.md b/README.md index 30414d6..014259d 100644 --- a/README.md +++ b/README.md @@ -108,9 +108,17 @@ and to program the FPGA: ```sh make ECP5_BOARD=evn prog + +# or if your USB device has a different path, pass it on USBDEVICE, like: + +make ECP5_BOARD=evn USBDEVICE=/dev/tty.usbserial-120001 prog ``` -If you connect to the serial port of the FPGA at 115200 8n1, you should see "Hello World" +Programming using OpenOCD on Docker does not work on Docker Desktop for Mac since the container is run in a Linux VM and can not see the physical devices connected to the MacOS. + +For the ULX3S board, the current OpenOCD does not support ft232 protocol so to program it, download [ujprog](https://github.com/emard/ulx3s-bin/tree/master/usb-jtag) for your platform and program using `./ujprog chiselwatt.bit` or to persist in the flash, `./ujprog -j FLASH chiselwatt.bit`. + +After programming, if you connect to the serial port of the FPGA at 115200 8n1, you should see "Hello World" and after that all input will be echoed to the output. On Linux, picocom can be used. Another option below is a simple python script. diff --git a/chiselwatt.core b/chiselwatt.core index d8ded00..9208402 100644 --- a/chiselwatt.core +++ b/chiselwatt.core @@ -31,6 +31,11 @@ filesets: - constraints/ecp5-evn.lpf : {file_type : LPF} - pll/pll_ehxplll.v : {file_type : verilogSource} + ecp5-ulx3s: + files: + - constraints/ecp5-ulx3s.lpf : {file_type : LPF} + - pll/pll_ehxplll_25MHz.v : {file_type : verilogSource} + targets: cmod_a7-35: default_tool: vivado @@ -69,6 +74,13 @@ targets: diamond: {part: LFE5U-85F-8BG381I} toplevel : toplevel + ecp5-ulx3s: + default_tool: diamond + filesets: [core, ecp5-ulx3s] + tools: + diamond: {part: LFE5U-85F-8BG381I} + toplevel : toplevel + parameters: RESET_LOW: datatype : bool diff --git a/constraints/ecp5-ulx3s.lpf b/constraints/ecp5-ulx3s.lpf index 44685bb..77c9469 100644 --- a/constraints/ecp5-ulx3s.lpf +++ b/constraints/ecp5-ulx3s.lpf @@ -2,14 +2,14 @@ LOCATE COMP "clock" SITE "G2"; IOBUF PORT "clock" PULLMODE=NONE IO_TYPE=LVCMOS33; FREQUENCY PORT "clock" 25 MHZ; -LOCATE COMP "reset" SITE "D7"; +LOCATE COMP "reset" SITE "D6"; IOBUF PORT "reset" PULLMODE=UP IO_TYPE=LVCMOS33; -LOCATE COMP "io_tx" SITE "M1"; -LOCATE COMP "io_rx" SITE "L4"; +LOCATE COMP "io_tx" SITE "L4"; +LOCATE COMP "io_rx" SITE "M1"; -IOBUF PORT "io_tx" IO_TYPE=LVCMOS33; -IOBUF PORT "io_rx" IO_TYPE=LVCMOS33; +IOBUF PORT "io_tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "io_rx" PULLMODE=UP IO_TYPE=LVCMOS33; LOCATE COMP "io_terminate" SITE "B2"; LOCATE COMP "io_ledB" SITE "C2"; diff --git a/openocd/ecp5-ulx3s.cfg b/openocd/ecp5-ulx3s.cfg index 42988bb..dfb2685 100644 --- a/openocd/ecp5-ulx3s.cfg +++ b/openocd/ecp5-ulx3s.cfg @@ -1,18 +1,16 @@ -# this supports Radiona ULX3S EXP5 Board - -# file: ecp5.ocd telnet_port 4444 gdb_port 3333 # JTAG TAPs +#12k +# jtag newtap lfe5 tap -expected-id 0x21111043 -irlen 8 -irmask 0xFF -ircapture 0x5 +#25k +#jtag newtap lfe5 tap -expected-id 0x41111043 -irlen 8 -irmask 0xFF -ircapture 0x5 +#45k +#jtag newtap lfe5 tap -expected-id 0x41112043 -irlen 8 -irmask 0xFF -ircapture 0x5 +#85k jtag newtap lfe5 tap -expected-id 0x41113043 -irlen 8 -irmask 0xFF -ircapture 0x5 -# -expected-id should match ECP5 CHIP_ID: -# 12F: 0x21111043 -# 25F: 0x41111043 -# 45F: 0x41112043 -# 85F: 0x41113043 - init scan_chain svf -tap lfe5.tap -quiet -progress chiselwatt.svf diff --git a/openocd/ft231x.cfg b/openocd/ft231x.cfg index 198f31d..253b450 100644 --- a/openocd/ft231x.cfg +++ b/openocd/ft231x.cfg @@ -1,14 +1,11 @@ -# this supports Radiona ULX3s ECP5 Board - -# file: ft231x.ocd interface ft232r ft232r_vid_pid 0x0403 0x6015 -# ft232r_serial_desc 123456 +# ULX3S specific GPIO setting ft232r_tck_num DSR ft232r_tms_num DCD ft232r_tdi_num RI ft232r_tdo_num CTS +# trst/srst are not used but must have different values than above ft232r_trst_num RTS ft232r_srst_num DTR -ft232r_restore_serial 0x15 adapter_khz 1000 \ No newline at end of file