1
0
mirror of https://github.com/antonblanchard/chiselwatt.git synced 2026-01-11 23:53:33 +00:00

Restructured Makefile and Readme for multi-boards

Added a couple of improvements to the Makefile and Readme:

* Restructured the Makefile to support multiple boards based on variable
* Verilator build is also done in Docker container with local option
* Restructured Readme to reflect changes in the Makefile
* Support for running the verilator chiselwatt binary in a Docker
container in case the OS is not Linux.

Signed-off-by: Carlos de Paula <me@carlosedp.com>
This commit is contained in:
Carlos de Paula 2020-03-25 11:01:00 -03:00
parent cbc583de13
commit c06e4697dc
4 changed files with 148 additions and 103 deletions

13
.gitignore vendored
View File

@ -6,3 +6,16 @@ test_run_dir/
*.anno.json *.anno.json
*.fir *.fir
*.vcd *.vcd
insns.hex
firrtl_black_box_resource_files.f
chiselwatt_out.config
chiselwatt.svf
chiselwatt.json
chiselwatt.bit
chiselwatt
MemoryBlackBox.v
Core.v
Core.fir
Core.anno.json
LoadStoreInsns.hex
MemoryBlackBoxInsns.hex

View File

@ -6,4 +6,5 @@ services: docker
before_install: docker pull verilator/verilator:latest before_install: docker pull verilator/verilator:latest
script: script:
docker run --rm -t -v `pwd`:/build -w /build --entrypoint /bin/bash verilator/verilator:latest -c "apt update && apt install -y default-jre-headless python3-pexpect curl && make && make check && ./scripts/test_micropython_long.py" # Unset the VERILATOR variable so the container won't fail when running inside another container in Travis
docker run --rm -t -v `pwd`:/build -w /build --entrypoint /bin/bash verilator/verilator:latest -c "apt update && apt install -y default-jre-headless python3-pexpect curl && make VERILATOR= && make VERILATOR= check && ./scripts/test_micropython_long.py"

139
Makefile
View File

@ -1,4 +1,23 @@
all: chiselwatt # Use Docker images for synthesis and verilator
DOCKER=docker
#DOCKER=podman
PWD = $(shell pwd)
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
# Uncomment to use local tools for synthesis
#YOSYS = yosys
#NEXTPNR = nextpnr-ecp5
#ECPPACK = ecppack
#OPENOCD = openocd
#VERILATOR = verilator
scala_files = $(wildcard src/main/scala/*scala) scala_files = $(wildcard src/main/scala/*scala)
@ -6,60 +25,10 @@ verilog_files = Core.v MemoryBlackBox.v
verilator_binary = chiselwatt verilator_binary = chiselwatt
$(verilog_files): $(scala_files)
scripts/mill chiselwatt.run
$(verilator_binary): $(verilog_files) chiselwatt.cpp uart.c
# Warnings disabled until we fix the Chisel issues
#verilator -O3 -Wall --assert --cc Core.v --exe chiselwatt.cpp uart.c #--trace
verilator -O3 --assert --cc Core.v --exe chiselwatt.cpp uart.c -o $@ #--trace
make -C obj_dir -f VCore.mk
@cp -f obj_dir/chiselwatt chiselwatt
clean:
@rm -f Core.fir firrtl_black_box_resource_files.f Core.v Core.anno.json MemoryBlackBox.v
@rm -rf obj_dir test_run_dir target project
@rm -f chiselwatt
@rm -f *.bit *.json *.svf *.config
@rm -f LoadStoreInsns.hex MemoryBlackBoxInsns.hex
scala_tests: $(verilator_binary)
scripts/mill chiselwatt.test
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out))) tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
check: scala_tests $(tests) # Define board parameters
ifeq ($(ECP5_BOARD),evn)
$(tests): $(verilator_binary)
@./scripts/run_test.sh $@
# Use local tools for synthesis
#YOSYS = yosys
#NEXTPNR = nextpnr-ecp5
#ECPPACK = ecppack
#OPENOCD = openocd
# Use Docker images for synthesis
DOCKER=docker
#DOCKER=podman
#
PWD = $(shell pwd)
DOCKERARGS = run --rm -v $(PWD):/src -w /src
#
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
# OrangeCrab with ECP85
#LPF=constraints/orange-crab.lpf
#PLL=pll/pll_bypass.v
#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 # ECP5-EVN
LPF=constraints/ecp5-evn.lpf LPF=constraints/ecp5-evn.lpf
PLL=pll/pll_ehxplll.v PLL=pll/pll_ehxplll.v
@ -67,16 +36,56 @@ PACKAGE=CABGA381
NEXTPNR_FLAGS=--um5g-85k --freq 12 NEXTPNR_FLAGS=--um5g-85k --freq 12
OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
else ifeq ($(ECP5_BOARD),orangecrab)
# OrangeCrab with ECP85
LPF=constraints/orange-crab.lpf
PLL=pll/pll_bypass.v
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
else ifeq ($(ECP5_BOARD),colorlight)
# Colorlight 5A-75B # Colorlight 5A-75B
#LPF=constraints/colorlight_5A-75B.lpf LPF=constraints/colorlight_5A-75B.lpf
#PLL=pll/pll_ehxplll_25MHz.v PLL=pll/pll_ehxplll_25MHz.v
#PACKAGE=CABGA256 PACKAGE=CABGA256
#NEXTPNR_FLAGS=--25k --freq 25 NEXTPNR_FLAGS=--25k --freq 25
#OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
#OPENOCD_DEVICE_CONFIG=openocd/LFE5U-25F.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5U-25F.cfg
else
endif
synth: chiselwatt.bit # Targets
all: chiselwatt
$(verilog_files): $(scala_files)
scripts/mill chiselwatt.run
$(verilator_binary): $(verilog_files) chiselwatt.cpp uart.c
# Warnings disabled until we fix the Chisel issues
#$(VERILATOR) verilator -O3 -Wall --assert --cc Core.v --exe chiselwatt.cpp uart.c #--trace
$(VERILATOR) verilator -O3 --assert --cc Core.v --exe chiselwatt.cpp uart.c -o $@ #--trace
$(VERILATOR) make -C obj_dir -f VCore.mk
@cp -f obj_dir/chiselwatt chiselwatt
scala_tests: $(verilator_binary)
scripts/mill chiselwatt.test
check: scala_tests $(tests)
$(tests): $(verilator_binary)
@./scripts/run_test.sh $@
dockerlator: chiselwatt
@echo "To execute chiselwatt Verilator binary, run ./chiselwatt at the prompt."
# Mask exit code from verilator on Make
@$(VERILATOR) bash || true
synth: test-vars chiselwatt.bit
test-vars:
@test -n "$(LPF)" || (echo "If synthesizing, use \"synth\" target with ECP5_BOARD variable to either \"evn\", \"orangecrab\", \"colorlight\"\n" ; exit 1)
chiselwatt.json: insns.hex $(verilog_files) $(PLL) toplevel.v chiselwatt.json: insns.hex $(verilog_files) $(PLL) toplevel.v
$(YOSYS) -p "read_verilog -sv $(verilog_files) $(PLL) toplevel.v; synth_ecp5 -json $@ -top toplevel" $(YOSYS) -p "read_verilog -sv $(verilog_files) $(PLL) toplevel.v; synth_ecp5 -json $@ -top toplevel"
@ -92,5 +101,13 @@ chiselwatt.svf: chiselwatt.bit
prog: chiselwatt.svf prog: chiselwatt.svf
$(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit" $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit"
clean:
@rm -f Core.fir firrtl_black_box_resource_files.f Core.v Core.anno.json MemoryBlackBox.v
@rm -rf obj_dir test_run_dir target project
@rm -f chiselwatt
@rm -f *.bit *.json *.svf *.config
@rm -f LoadStoreInsns.hex MemoryBlackBoxInsns.hex
.PHONY: clean prog .PHONY: clean prog
.PRECIOUS: chiselwatt.json chiselwatt_out.config chiselwatt.bit .PRECIOUS: chiselwatt.json chiselwatt_out.config chiselwatt.bit

View File

@ -4,32 +4,39 @@ A tiny POWER Open ISA soft processor written in Chisel.
## Simulation using verilator ## Simulation using verilator
* Chiselwatt uses `verilator` for simulation. Either install this from your * Chiselwatt uses `verilator` for simulation. It is built by default and run in
distro or build it. On Fedora you can install the distro version using: a Docker container. To build with local verilator install, edit `Makefile`.
* First build chiselwatt:
```sh ```sh
$ sudo dnf install verilator git clone https://github.com/antonblanchard/chiselwatt
``` cd chiselwatt
make
* Next build chiselwatt:
```sh
$ git clone https://github.com/antonblanchard/chiselwatt
$ cd chiselwatt
$ make
``` ```
* A micropython image is included in the repo. To use it, link the memory image * A micropython image is included in the repo. To use it, link the memory image
into chiselwatt: into chiselwatt:
```sh ```sh
$ ln -s micropython/firmware.hex insns.hex ln -s micropython/firmware.hex insns.hex
``` ```
* Now run chiselwatt: * Now run chiselwatt:
```sh ```sh
$ ./chiselwatt ./chiselwatt
```
* If your operating system is not Linux, run chiselwatt inside a container:
```sh
make dockerlator
# Inside the container prompt, run:
./chiselwatt
# type "exit" to exit the container
exit
``` ```
## Building micropython from scratch ## Building micropython from scratch
@ -42,11 +49,11 @@ example below I installed it in usr/local/powerpc64le-power8--glibc--bleeding-ed
and the tools begin with `powerpc64-linux-*`: and the tools begin with `powerpc64-linux-*`:
```sh ```sh
$ git clone https://github.com/micropython/micropython.git git clone https://github.com/micropython/micropython.git
$ cd micropython cd micropython
$ cd ports/powerpc cd ports/powerpc
$ make CROSS_COMPILE=/usr/local/powerpc64le-power8--glibc--bleeding-edge-2018.11-1/bin/powerpc64le-linux- -j$(nproc) make CROSS_COMPILE=/usr/local/powerpc64le-power8--glibc--bleeding-edge-2018.11-1/bin/powerpc64le-linux- -j$(nproc)
$ cd ../../../ cd ../../../
``` ```
* Build chiselwatt, import the the micropython image and run it. We use * Build chiselwatt, import the the micropython image and run it. We use
@ -54,24 +61,22 @@ bin2hex.py to convert a binary file into a series of 64 bit hex values
expected by the tools: expected by the tools:
```sh ```sh
$ cd chiselwatt cd chiselwatt
$ make make
$ scripts/bin2hex.py ../micropython/ports/powerpc/build/firmware.bin > insns.hex scripts/bin2hex.py ../micropython/ports/powerpc/build/firmware.bin > insns.hex
$ ./chiselwatt ./chiselwatt
``` ```
## Synthesis using Open Source tools (yosys/nextpnr) ## Synthesis using Open Source tools (yosys/nextpnr)
Synthesis on FPGAs is supported with yosys/nextpnr. At the moment the tools support Synthesis on FPGAs is supported with yosys/nextpnr. At the moment the tools support
Lattice ECP5 FPGAs. It uses Docker images, so no software other than Docker needs Lattice ECP5 FPGAs. The build process uses Docker images, so no software other than Docker needs
to be installed. If you prefer podman you can use that too, just adjust it in to be installed. If you prefer podman you can use that too, just adjust it in
`Makefile`, `DOCKER=podman`. `Makefile`, `DOCKER=podman`.
Edit `Makefile` to configure your FPGA, JTAG device etc.
### hello_world ### hello_world
hello_world should run everywhere, so start with it. Edit `src/main/scala/Core.scala` The `hello_world` example should run everywhere, so start with it. Edit `src/main/scala/Core.scala`
and set memory to 16 kB (`16*1024`): and set memory to 16 kB (`16*1024`):
``` ```
@ -81,19 +86,27 @@ chisel3.Driver.execute(Array[String](), () => new Core(64, 16*1024, "insns.hex",
Then link in the hello_world image: Then link in the hello_world image:
```sh ```sh
$ ln -s hello_world/hello_world.hex insns.hex ln -s hello_world/hello_world.hex insns.hex
``` ```
To build: ### Building and programming the FPGA
The `Makefile` currently supports the following FPGA boards by defining the `ECP5_BOARD` parameter on make:
* Lattice [ECP5 Evaluation Board](http://www.latticesemi.com/ecp5-evaluation) - `evn`
* Greg Davill [Orangecrab](https://github.com/gregdavill/OrangeCrab) - `orangecrab`
* Q3k [Colorlight](https://github.com/q3k/chubby75/tree/master/5a-75b) - `colorlight`
For example, to build for the Evaluation Board, run:
```sh ```sh
$ make chiselwatt.bit make ECP5_BOARD=evn synth`
``` ```
and to program the FPGA: and to program the FPGA:
```sh ```sh
$ make prog make ECP5_BOARD=evn prog
``` ```
If you connect to the serial port of the FPGA at 115200 8n1, you should see "Hello World" If you connect to the serial port of the FPGA at 115200 8n1, you should see "Hello World"
@ -103,7 +116,8 @@ Another option below is a simple python script.
### Micropython ### Micropython
Unfortunately due to an issue in yosys/nextpnr, dual port RAMs are not Unfortunately due to an issue in yosys/nextpnr, dual port RAMs are not
working. More details can be found in https://github.com/YosysHQ/yosys/issues/1101. working. More details can be found in <https://github.com/YosysHQ/yosys/issues/1101>.
This means we use twice as much block RAM as you would expect. This also means This means we use twice as much block RAM as you would expect. This also means
Micropython won't fit on an ECP5 85F, because the ~400kB of available BRAM is halved Micropython won't fit on an ECP5 85F, because the ~400kB of available BRAM is halved
to ~200k. Micropython requires 384 kB. to ~200k. Micropython requires 384 kB.
@ -117,25 +131,24 @@ chisel3.Driver.execute(Array[String](), () => new Core(64, 384*1024, "insns.hex"
Then link in the micropython image: Then link in the micropython image:
```sh ```sh
$ ln -s micropython/firmware.hex insns.hex ln -s micropython/firmware.hex insns.hex
``` ```
To build: For example, to build for the Orangecrab, run:
```sh ```sh
$ make chiselwatt.bit make ECP5_BOARD=orangecrab synth`
``` ```
and to program the FPGA: and to program the FPGA:
```sh ```sh
$ make prog make ECP5_BOARD=orangecrab prog
``` ```
## Simple Python script for reading USB serial port ## Simple Python script for reading USB serial port
```python ```python
#!/usr/bin/python #!/usr/bin/python
import serial import serial
@ -158,8 +171,9 @@ while 1:
## Issues ## Issues
Now that it is functional, we have a number of things to add Now that it is functional, we have a number of things to add:
- A few instructions
- Wishbone interconnect * A few instructions
- Caches * Wishbone interconnect
- Pipelining and bypassing * Caches
* Pipelining and bypassing