diff --git a/Containerfile b/Containerfile index 8594aa8..363da31 100644 --- a/Containerfile +++ b/Containerfile @@ -32,9 +32,9 @@ RUN apk add yosys WORKDIR /home/root/aur-install # Install prjxray librairies -RUN git clone https://github.com/supersurviveur/prjxray.git && \ +RUN git clone https://github.com/supersurviveur/prjxray.git --depth 1 && \ cd prjxray && \ - git submodule update --init && \ + git submodule update --init --depth 1 && \ # include fasm2frames in python package mv utils/fasm2frames.py prjxray/ && \ sed -E 's/(fasm2frames=)utils/\1prjxray/' -i setup.py && \ @@ -44,7 +44,7 @@ RUN git clone https://github.com/supersurviveur/prjxray.git && \ -DCMAKE_INSTALL_PREFIX='/usr' \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -Wno-dev && \ - cmake --build build && \ + cmake --build build -j$(nproc) && \ python -m build --wheel --no-isolation --skip-dependency-check && \ python -m installer dist/*.whl && \ python -m build third_party/fasm --wheel --no-isolation --skip-dependency-check && \ @@ -53,9 +53,8 @@ RUN git clone https://github.com/supersurviveur/prjxray.git && \ # prjxray dependency not available on apk RUN pip install textx --break-system-packages -# RUN fasm2frames # Install the zynq7 prjxray database -RUN git clone https://github.com/f4pga/prjxray-db.git && \ +RUN git clone https://github.com/f4pga/prjxray-db.git --depth 1 && \ cd prjxray-db && \ install -dm 755 /usr/share/xray/database && \ cp -r zynq7 /usr/share/xray/database/ && \ @@ -63,9 +62,9 @@ RUN git clone https://github.com/f4pga/prjxray-db.git && \ rm /usr/share/xray/database/zynq7/xc7z020 -rf # Install nextpnr-himbaechel -RUN git clone https://github.com/YosysHQ/nextpnr && \ +RUN git clone https://github.com/YosysHQ/nextpnr --depth 1 && \ cd nextpnr && \ - git submodule update --remote --init himbaechel/uarch/xilinx/meta && \ + git submodule update --remote --init --depth 1 himbaechel/uarch/xilinx/meta && \ cmake -S "." -B build \ -DARCH=himbaechel \ -DHIMBAECHEL_UARCH=xilinx \ @@ -76,21 +75,12 @@ RUN git clone https://github.com/YosysHQ/nextpnr && \ -DCMAKE_BUILD_TYPE=None \ -DCMAKE_INSTALL_PREFIX=/usr \ -DUSE_OPENMP=ON && \ - make -C build - -# This part is specific to djtgcfg but it doesn't detect the card over USB (missing driver ?) -# # Install djtgcfg -# # Install avahi (djtcfg dependency) -# RUN apk add avahi -# RUN git clone https://aur.archlinux.org/digilent.adept.runtime.git && \ -# cd digilent.adept.runtime && makepkg -si --noconfirm --needed -# RUN git clone https://aur.archlinux.org/digilent.adept.utilities.git && \ -# cd digilent.adept.utilities && makepkg -si --noconfirm --needed + make -C build -j$(nproc) # Install sv2v -RUN git clone https://github.com/zachjs/sv2v && \ +RUN git clone https://github.com/zachjs/sv2v --depth 1 && \ cd sv2v && \ - make + make -j$(nproc) COPY copy_bin_deps.sh /usr/bin/ RUN chmod +x /usr/bin/copy_bin_deps.sh @@ -104,17 +94,13 @@ RUN copy_bin_deps.sh /home/root/aur-install/prjxray/build/tools/xc7frames2bit RUN copy_bin_deps.sh /home/root/aur-install/sv2v/bin/sv2v RUN cp /usr/bin/fasm2frames /dependencies/usr/bin/ -# djtgcfg -# RUN copy_bin_deps.sh /usr/bin/djtgcfg -# RUN copy_bin_deps.sh /usr/bin/dftdrvdtch - # Final image FROM alpine:edge # Install dependencies available in apk RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ apk update && \ - apk add abc py3-yaml py3-simplejson py3-intervaltree py3-arpeggio + apk add abc py3-yaml py3-simplejson py3-intervaltree py3-arpeggio openfpgaloader # Get dependencies back COPY --from=builder /dependencies / @@ -130,13 +116,6 @@ COPY --from=builder /usr/lib/python3.12/site-packages/prjxray /usr/lib/python3.1 COPY --from=builder /usr/lib/python3.12/site-packages/fasm /usr/lib/python3.12/site-packages/fasm COPY --from=builder /usr/lib/python3.12/site-packages/textx /usr/lib/python3.12/site-packages/textx -# This part is specific to djtgcfg but it doesn't detect the card over USB (missing driver ?) -# COPY --from=builder /usr/share/digilent /usr/share/digilent -# COPY --from=builder /etc/digilent-adept.conf /etc/digilent-adept.conf -# COPY --from=builder /etc/ld.so.conf.d/digilent-adept-libraries.conf /etc/ld.so.conf.d/digilent-adept-libraries.conf -# Generate ld configuration for digilent programs -# RUN ldconfig - WORKDIR /root/code CMD ["/bin/bash -c \"$@\""] diff --git a/README.md b/README.md new file mode 100644 index 0000000..5e9a85a --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +This repository contains a podman image whichs contains all necessary tools to generate and flash bitstream file from a SystemVerilog program. +It is build for the xilinx zybo zynq7 `xc7z010` card, but it can probably be easily edited to support another card. + +# Installation + +You will need [podman](https://podman.io/) to run the image. + +## Use the pre-built image + +You can directly use the pre-build image present in the repo + +```bash +zstd -d fmn.tar.zst +podman load --input fmn.tar +``` + +## Build the image from source + +You can build the image yourself by using this command: + +```bash +podman build -t fmn_alpine . +``` + +It will first create an image which will build every tools, and then create the final image containing only needed binaries and libraries. + +For information, it takes around 5.63GB space and 10 minutes to build on my device. + +# Tools + +- [sv2v](https://github.com/zachjs/sv2v) : Convert SystemVerilog to Verilog. +- [yosys](https://github.com/YosysHQ/yosys) : Do RTL synthesis from verilog files. +- [nextpnr-himbaechel](https://github.com/YosysHQ/nextpnr) : placing and routing tool. +- [fasm2frames](https://github.com/f4pga/prjxray) : Convert fasm files to frames files. +- [xc7frames2bit](https://github.com/f4pga/prjxray) : Convert frames files to bitstream. +- [openFPGALoader](https://github.com/trabucayre/openFPGALoader) : Flash a bitstream on a FPGA card. + +The image also contains some [databases](https://github.com/f4pga/prjxray-db) needed for prjxray tools to work. + +# Usage + +See the small [example](./example/). diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..c3533ef --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,6 @@ +abc.history +adder.v +out.bin +out.fasm +out.frames +synthesis.json diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..b229b31 --- /dev/null +++ b/example/README.md @@ -0,0 +1,48 @@ +# Example + +This directory shows how to flash a system verilog program (A full-adder) on a Zybo `xc7z010clg400-1` card. + +## Build + +Firstly, the system verilog file needs to be converted to verilog in order to use it with yosys : + +```bash +podman run --mount=type=bind,source=.,target=/root/code fmn_alpine sv2v adder.sv -w adder.v +``` + +The mount parameter is used to provide to podman the current directory. + +Then, yosys can achieve the RTL synthesis of the program : + +```bash +podman run --mount=type=bind,source=.,target=/root/code fmn_alpine yosys adder.v -p "synth_xilinx; write_json synthesis.json" +``` + +Nextpnr can now place and route each components using the xdc constraints file : + +```bash +podman run --mount=type=bind,source=.,target=/root/code fmn_alpine nextpnr-himbaechel --json synthesis.json -o xdc=adder.xdc -o fasm=out.fasm --device xc7z010clg400-1 +``` + +Now the fasm file can be converted in a frames file and then in a bitstream : + +```bash +podman run --mount=type=bind,source=.,target=/root/code fmn_alpine fasm2frames --part xc7z010clg400-1 --db-root /usr/share/xray/database/zynq7 out.fasm out.frames +podman run --mount=type=bind,source=.,target=/root/code fmn_alpine xc7frames2bit -frm_file out.frames -part_file /usr/share/xray/database/zynq7/xc7z010clg400-1/part.yaml --output_file out.bin +``` + +## Flashing the FPGA + +Finally, we can flash the bitstream on the card with `openFPGALoader`. + +Podman requires a device argument to allow openFPGALoader to access the usb interface. You can find this path with `lsusb` : + +```txt +Bus 003 Device 005: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC +``` + +Here the usb device path is `/dev/bus/usb/003/005` + +```bash +podman run --device=/dev/bus/usb/003/005 --mount=type=bind,source=.,target=/root/code fmn_alpine openFPGALoader -b zybo_z7_10 out.bin +``` diff --git a/example/adder.sv b/example/adder.sv new file mode 100644 index 0000000..72fe6dd --- /dev/null +++ b/example/adder.sv @@ -0,0 +1,14 @@ +module AC( + input clock, + io_a, + io_b, + io_c, + output io_s, + io_co +); + + wire tmp = io_a ^ io_b; + assign io_s = tmp ^ io_c; + assign io_co = io_a & io_b | tmp & io_c; +endmodule + diff --git a/example/adder.xdc b/example/adder.xdc new file mode 100644 index 0000000..5cd7b76 --- /dev/null +++ b/example/adder.xdc @@ -0,0 +1,19 @@ +# Create a clock +set_property PACKAGE_PIN L16 [get_ports clock] +set_property IOSTANDARD LVCMOS33 [get_ports clock] + +create_clock -period 8.00 [get_ports clock] + +# Buttons +set_property PACKAGE_PIN G15 [get_ports io_a] +set_property IOSTANDARD LVCMOS33 [get_ports io_a] +set_property PACKAGE_PIN P15 [get_ports io_b] +set_property IOSTANDARD LVCMOS33 [get_ports io_b] +set_property PACKAGE_PIN W13 [get_ports io_c] +set_property IOSTANDARD LVCMOS33 [get_ports io_c] + +# LEDs +set_property PACKAGE_PIN M14 [get_ports io_s] +set_property IOSTANDARD LVCMOS33 [get_ports io_s] +set_property PACKAGE_PIN M15 [get_ports io_co] +set_property IOSTANDARD LVCMOS33 [get_ports io_co] diff --git a/fmn.tar.zst b/fmn.tar.zst new file mode 100644 index 0000000..0cba4f0 Binary files /dev/null and b/fmn.tar.zst differ