Initial support for ghdl synthesis

A first pass at ghdl synthesis using yosys and nextpnr. It runs hello world
or micropython if the FPGA has enough block RAM (eg ECP5 85F). The hello
world testcase also loops UART rx to tx in software (ie not a hardware
loopback).

It uses Docker images, so no software needs to be installed. If you prefer
podman you can use that too. Edit Makefile.synth to configure your FPGA,
JTAG device etc.

To build:

make -f Makefile.synth

and to program:

make -f Makefile.synth prog

A few issues:

We need to add PLL support. Right now Microwatt runs at whatever the
external clock frequency is and the baud rate gets scaled by how far off
50MHz it is. This means on the ecp5-evn with a 12 MHz clock rate the baud
rate is a quite strange 27650 (115200 * 50 / 12). On my OrangeCrab with a
50MHz clock the UART is 115200.

It uses a large amount of resources, way more than it should. There are
still some ghdl/yosys issues to be sorted out.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
pull/142/head
Anton Blanchard 5 years ago committed by Anton Blanchard
parent 21a40c2ba6
commit db937403ec

@ -0,0 +1,77 @@
# Use local tools
#GHDLSYNTH = ghdl.so
#YOSYS = yosys
#NEXTPNR = nextpnr-ecp5
#ECPPACK = ecppack
#OPENOCD = openocd

# Use Docker images
DOCKER=docker
#DOCKER=podman
#
PWD = $(shell pwd)
DOCKERARGS = run --rm -v $(PWD):/src -w /src
#
GHDLSYNTH = ghdl
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


# Hello world
GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=8192 -gRAM_INIT_FILE=hello_world/hello_world.hex

# Micropython
#GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=393216 -gRAM_INIT_FILE=micropython/firmware.hex


# OrangeCrab with ECP85
#GHDL_TARGET_GENERICS=-gRESET_LOW=true -gCLK_INPUT=50000000 -gCLK_FREQUENCY=50000000
#LPF=constraints/orange-crab.lpf
#PACKAGE=CSFBGA285
#NEXTPNR_FLAGS=--um5g-85k --freq 50
#OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
#OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg

# ECP5-EVN
GHDL_TARGET_GENERICS=-gRESET_LOW=true -gCLK_INPUT=12000000 -gCLK_FREQUENCY=12000000
LPF=constraints/ecp5-evn.lpf
PACKAGE=CABGA381
NEXTPNR_FLAGS=--um5g-85k --freq 12
OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg

VHDL_FILES = wishbone_types.vhdl utils.vhdl fpga/main_bram.vhdl
VHDL_FILES += wishbone_bram_wrapper.vhdl decode_types.vhdl common.vhdl
VHDL_FILES += fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd wishbone_arbiter.vhdl
VHDL_FILES += dmi_dtm_dummy.vhdl wishbone_debug_master.vhdl helpers.vhdl
VHDL_FILES += loadstore1.vhdl crhelpers.vhdl writeback.vhdl ppc_fx_insns.vhdl
VHDL_FILES += countzero.vhdl insn_helpers.vhdl rotator.vhdl logical.vhdl
VHDL_FILES += execute1.vhdl fetch1.vhdl gpr_hazard.vhdl cr_hazard.vhdl
VHDL_FILES += control.vhdl decode2.vhdl cr_file.vhdl cache_ram.vhdl plru.vhdl
VHDL_FILES += dcache.vhdl core_debug.vhdl multiply.vhdl icache.vhdl fetch2.vhdl
VHDL_FILES += register_file.vhdl decode1.vhdl divider.vhdl core.vhdl soc.vhdl
VHDL_FILES += fpga/soc_reset.vhdl fpga/clk_gen_bypass.vhd fpga/toplevel.vhdl

all: microwatt.bit

microwatt.json: $(VHDL_FILES)
$(YOSYS) -m $(GHDLSYNTH) -p "ghdl --std=08 $(GHDL_IMAGE_GENERICS) $(GHDL_TARGET_GENERICS) $(VHDL_FILES) -e toplevel; synth_ecp5 -json $@"

microwatt_out.config: microwatt.json $(LPF)
$(NEXTPNR) --json $< --lpf $(LPF) --textcfg $@ $(NEXTPNR_FLAGS) --package $(PACKAGE)

microwatt.bit: microwatt_out.config
$(ECPPACK) --svf microwatt.svf $< $@

microwatt.svf: microwatt.bit

prog: microwatt.svf
$(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit"

clean:
@rm -f work-obj08.cf *.bit *.json *.svf *.config

.PHONY: clean prog
.PRECIOUS: microwatt.json microwatt_out.config microwatt.bit

@ -0,0 +1,19 @@
LOCATE COMP "ext_clk" SITE "A10";
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;

LOCATE COMP "ext_rst" SITE "P4";
IOBUF PORT "rst" IO_TYPE=LVCMOS33;

LOCATE COMP "uart0_txd" SITE "P3";
LOCATE COMP "uart0_rxd" SITE "P2";

IOBUF PORT "uart0_txd" IO_TYPE=LVCMOS33;
IOBUF PORT "uart0_rxd" IO_TYPE=LVCMOS33;

LOCATE COMP "led_a" SITE "A13";
LOCATE COMP "led_b" SITE "A12";
LOCATE COMP "led_c" SITE "B19";

IOBUF PORT "led_a" IO_TYPE=LVCMOS25;
IOBUF PORT "led_b" IO_TYPE=LVCMOS25;
IOBUF PORT "led_c" IO_TYPE=LVCMOS25;

@ -0,0 +1,19 @@
LOCATE COMP "ext_clk" SITE "A9";
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;

LOCATE COMP "ext_rst" SITE "J2";
IOBUF PORT "ext_rst" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;

LOCATE COMP "uart0_txd" SITE "N17";
LOCATE COMP "uart0_rxd" SITE "M18";

IOBUF PORT "uart0_txd" IO_TYPE=LVCMOS25;
IOBUF PORT "uart0_rxd" IO_TYPE=LVCMOS25;

LOCATE COMP "led_a" SITE "V17";
LOCATE COMP "led_b" SITE "T17";
LOCATE COMP "led_c" SITE "J3";

IOBUF PORT "led_a" IO_TYPE=LVCMOS25;
IOBUF PORT "led_b" IO_TYPE=LVCMOS25;
IOBUF PORT "led_c" IO_TYPE=LVCMOS25;

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41111043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41112043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41113043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01111043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01112043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01113043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81111043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043

@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043

@ -0,0 +1,13 @@
# this supports ECP5 Evaluation Board

interface ftdi
ftdi_device_desc "Lattice ECP5 Evaluation Board"
ftdi_vid_pid 0x0403 0x6010
# channel 1 does not have any functionality
ftdi_channel 0
# just TCK TDI TDO TMS, no reset
ftdi_layout_init 0xfff8 0xfffb
reset_config none

# default speed
adapter_khz 5000

@ -0,0 +1,17 @@
#
# Olimex ARM-USB-TINY-H
#
# http://www.olimex.com/dev/arm-usb-tiny-h.html
#

interface ftdi
ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
ftdi_vid_pid 0x15ba 0x002a

ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800

# default speed
adapter_khz 5000
Loading…
Cancel
Save