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:
parent
cbc583de13
commit
c06e4697dc
13
.gitignore
vendored
13
.gitignore
vendored
@ -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
|
||||||
@ -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
139
Makefile
@ -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
|
||||||
|
|
||||||
|
|||||||
96
README.md
96
README.md
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user