I: pbuilder: network access will be disabled during build I: Current time: Fri Aug 13 06:48:28 +14 2021 I: pbuilder-time-stamp: 1628786908 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/bullseye-reproducible-base.tgz] I: copying local configuration I: mounting /proc filesystem I: mounting /sys filesystem I: creating /{dev,run}/shm I: mounting /dev/pts filesystem I: redirecting /dev/ptmx to /dev/pts/ptmx I: policy-rc.d already exists I: Copying source file I: copying [fpga-icestorm_0~20190913git0ec00d8-2.dsc] I: copying [./fpga-icestorm_0~20190913git0ec00d8.orig.tar.xz] I: copying [./fpga-icestorm_0~20190913git0ec00d8-2.debian.tar.xz] I: Extracting source gpgv: unknown type of key resource 'trustedkeys.kbx' gpgv: keyblock resource '/tmp/dpkg-verify-sig.1VI7GzD1/trustedkeys.kbx': General error gpgv: Signature made Tue Oct 13 22:16:43 2020 +14 gpgv: using RSA key 3474C4096729ED0C51807D3CE69822C7E02958CD gpgv: issuer "ruben.undheim@gmail.com" gpgv: Can't check signature: No public key dpkg-source: warning: failed to verify signature on ./fpga-icestorm_0~20190913git0ec00d8-2.dsc dpkg-source: info: extracting fpga-icestorm in fpga-icestorm-0~20190913git0ec00d8 dpkg-source: info: unpacking fpga-icestorm_0~20190913git0ec00d8.orig.tar.xz dpkg-source: info: unpacking fpga-icestorm_0~20190913git0ec00d8-2.debian.tar.xz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying 0001-Install-the-python-programs-and-the-iceboxdb-module-.patch dpkg-source: info: applying 0002-Fix-MD-and-O0-passed-as-CFLAGS-and-CXXFLAGS.patch dpkg-source: info: applying 0003-Install-timing-data-also-in-fpga-icestorm-chipdb.patch dpkg-source: info: applying 0004-Remove-hard-coded-path-in-icebox_vlog.py.patch dpkg-source: info: applying 0005-Fix-GCC-10-build-with-missing-include.patch I: using fakeroot in build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/11574/tmp/hooks/D01_modify_environment starting debug: Running on virt32b. I: Changing host+domainname to test build reproducibility I: Adding a custom variable just for the fun of it... I: Changing /bin/sh to bash Removing 'diversion of /bin/sh to /bin/sh.distrib by dash' Adding 'diversion of /bin/sh to /bin/sh.distrib by bash' Removing 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash' Adding 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by bash' I: Setting pbuilder2's login shell to /bin/bash I: Setting pbuilder2's GECOS to second user,second room,second work-phone,second home-phone,second other I: user script /srv/workspace/pbuilder/11574/tmp/hooks/D01_modify_environment finished I: user script /srv/workspace/pbuilder/11574/tmp/hooks/D02_print_environment starting I: set BASH=/bin/sh BASHOPTS=checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=([0]="12" [1]="0") BASH_SOURCE=([0]="/tmp/hooks/D02_print_environment" [1]="/tmp/hooks/D02_print_environment") BASH_VERSINFO=([0]="5" [1]="1" [2]="4" [3]="1" [4]="release" [5]="arm-unknown-linux-gnueabihf") BASH_VERSION='5.1.4(1)-release' BUILDDIR=/build BUILDUSERGECOS='second user,second room,second work-phone,second home-phone,second other' BUILDUSERNAME=pbuilder2 BUILD_ARCH=armhf DEBIAN_FRONTEND=noninteractive DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all,-fixfilepath parallel=4' DIRSTACK=() DISTRIBUTION= EUID=0 FUNCNAME=([0]="Echo" [1]="main") GROUPS=() HOME=/root HOSTNAME=i-capture-the-hostname HOSTTYPE=arm HOST_ARCH=armhf IFS=' ' INVOCATION_ID=4ed9a59b6c58458894d3b49896915375 LANG=C LANGUAGE=it_CH:it LC_ALL=C MACHTYPE=arm-unknown-linux-gnueabihf MAIL=/var/mail/root OPTERR=1 OPTIND=1 OSTYPE=linux-gnueabihf PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path PBCURRENTCOMMANDLINEOPERATION=build PBUILDER_OPERATION=build PBUILDER_PKGDATADIR=/usr/share/pbuilder PBUILDER_PKGLIBDIR=/usr/lib/pbuilder PBUILDER_SYSCONFDIR=/etc PIPESTATUS=([0]="0") POSIXLY_CORRECT=y PPID=11574 PS4='+ ' PWD=/ SHELL=/bin/bash SHELLOPTS=braceexpand:errexit:hashall:interactive-comments:posix SHLVL=3 SUDO_COMMAND='/usr/bin/timeout -k 24.1h 24h /usr/bin/ionice -c 3 /usr/bin/nice -n 11 /usr/bin/unshare --uts -- /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/tmp.sE7kD1Y43L/pbuilderrc_plsX --hookdir /etc/pbuilder/rebuild-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/bullseye-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/tmp.sE7kD1Y43L/b2 --logfile b2/build.log --extrapackages usrmerge fpga-icestorm_0~20190913git0ec00d8-2.dsc' SUDO_GID=112 SUDO_UID=106 SUDO_USER=jenkins TERM=unknown TZ=/usr/share/zoneinfo/Etc/GMT-14 UID=0 USER=root _='I: set' http_proxy=http://10.0.0.15:8000/ I: uname -a Linux i-capture-the-hostname 5.10.0-8-armmp-lpae #1 SMP Debian 5.10.46-4 (2021-08-03) armv7l GNU/Linux I: ls -l /bin total 3580 -rwxr-xr-x 1 root root 816764 Aug 5 10:25 bash -rwxr-xr-x 3 root root 26052 Jul 21 2020 bunzip2 -rwxr-xr-x 3 root root 26052 Jul 21 2020 bzcat lrwxrwxrwx 1 root root 6 Jul 21 2020 bzcmp -> bzdiff -rwxr-xr-x 1 root root 2225 Jul 21 2020 bzdiff lrwxrwxrwx 1 root root 6 Jul 21 2020 bzegrep -> bzgrep -rwxr-xr-x 1 root root 4877 Sep 5 2019 bzexe lrwxrwxrwx 1 root root 6 Jul 21 2020 bzfgrep -> bzgrep -rwxr-xr-x 1 root root 3775 Jul 21 2020 bzgrep -rwxr-xr-x 3 root root 26052 Jul 21 2020 bzip2 -rwxr-xr-x 1 root root 9636 Jul 21 2020 bzip2recover lrwxrwxrwx 1 root root 6 Jul 21 2020 bzless -> bzmore -rwxr-xr-x 1 root root 1297 Jul 21 2020 bzmore -rwxr-xr-x 1 root root 26668 Sep 23 2020 cat -rwxr-xr-x 1 root root 43104 Sep 23 2020 chgrp -rwxr-xr-x 1 root root 38984 Sep 23 2020 chmod -rwxr-xr-x 1 root root 43112 Sep 23 2020 chown -rwxr-xr-x 1 root root 92616 Sep 23 2020 cp -rwxr-xr-x 1 root root 75524 Dec 11 2020 dash -rwxr-xr-x 1 root root 75880 Sep 23 2020 date -rwxr-xr-x 1 root root 55436 Sep 23 2020 dd -rwxr-xr-x 1 root root 59912 Sep 23 2020 df -rwxr-xr-x 1 root root 96764 Sep 23 2020 dir -rwxr-xr-x 1 root root 55012 Jul 29 09:09 dmesg lrwxrwxrwx 1 root root 8 Nov 8 2019 dnsdomainname -> hostname lrwxrwxrwx 1 root root 8 Nov 8 2019 domainname -> hostname -rwxr-xr-x 1 root root 22508 Sep 23 2020 echo -rwxr-xr-x 1 root root 28 Nov 10 2020 egrep -rwxr-xr-x 1 root root 22496 Sep 23 2020 false -rwxr-xr-x 1 root root 28 Nov 10 2020 fgrep -rwxr-xr-x 1 root root 47492 Jul 29 09:09 findmnt -rwsr-xr-x 1 root root 26076 Feb 27 06:12 fusermount -rwxr-xr-x 1 root root 124508 Nov 10 2020 grep -rwxr-xr-x 2 root root 2346 Mar 3 13:30 gunzip -rwxr-xr-x 1 root root 6376 Mar 3 13:30 gzexe -rwxr-xr-x 1 root root 64212 Mar 3 13:30 gzip -rwxr-xr-x 1 root root 13784 Nov 8 2019 hostname -rwxr-xr-x 1 root root 43180 Sep 23 2020 ln -rwxr-xr-x 1 root root 35068 Feb 8 2020 login -rwxr-xr-x 1 root root 96764 Sep 23 2020 ls -rwxr-xr-x 1 root root 99940 Jul 29 09:09 lsblk -rwxr-xr-x 1 root root 51408 Sep 23 2020 mkdir -rwxr-xr-x 1 root root 43184 Sep 23 2020 mknod -rwxr-xr-x 1 root root 30780 Sep 23 2020 mktemp -rwxr-xr-x 1 root root 34408 Jul 29 09:09 more -rwsr-xr-x 1 root root 34400 Jul 29 09:09 mount -rwxr-xr-x 1 root root 9824 Jul 29 09:09 mountpoint -rwxr-xr-x 1 root root 88524 Sep 23 2020 mv lrwxrwxrwx 1 root root 8 Nov 8 2019 nisdomainname -> hostname lrwxrwxrwx 1 root root 14 Apr 19 05:38 pidof -> /sbin/killall5 -rwxr-xr-x 1 root root 26652 Sep 23 2020 pwd lrwxrwxrwx 1 root root 4 Aug 5 10:25 rbash -> bash -rwxr-xr-x 1 root root 30740 Sep 23 2020 readlink -rwxr-xr-x 1 root root 43104 Sep 23 2020 rm -rwxr-xr-x 1 root root 30732 Sep 23 2020 rmdir -rwxr-xr-x 1 root root 14144 Sep 28 2020 run-parts -rwxr-xr-x 1 root root 76012 Dec 23 2018 sed lrwxrwxrwx 1 root root 4 Aug 13 06:48 sh -> bash lrwxrwxrwx 1 root root 4 Aug 11 23:26 sh.distrib -> dash -rwxr-xr-x 1 root root 22532 Sep 23 2020 sleep -rwxr-xr-x 1 root root 55360 Sep 23 2020 stty -rwsr-xr-x 1 root root 46704 Jul 29 09:09 su -rwxr-xr-x 1 root root 22532 Sep 23 2020 sync -rwxr-xr-x 1 root root 340872 Feb 17 23:55 tar -rwxr-xr-x 1 root root 9808 Sep 28 2020 tempfile -rwxr-xr-x 1 root root 67696 Sep 23 2020 touch -rwxr-xr-x 1 root root 22496 Sep 23 2020 true -rwxr-xr-x 1 root root 9636 Feb 27 06:12 ulockmgr_server -rwsr-xr-x 1 root root 22108 Jul 29 09:09 umount -rwxr-xr-x 1 root root 22520 Sep 23 2020 uname -rwxr-xr-x 2 root root 2346 Mar 3 13:30 uncompress -rwxr-xr-x 1 root root 96764 Sep 23 2020 vdir -rwxr-xr-x 1 root root 38512 Jul 29 09:09 wdctl lrwxrwxrwx 1 root root 8 Nov 8 2019 ypdomainname -> hostname -rwxr-xr-x 1 root root 1984 Mar 3 13:30 zcat -rwxr-xr-x 1 root root 1678 Mar 3 13:30 zcmp -rwxr-xr-x 1 root root 5880 Mar 3 13:30 zdiff -rwxr-xr-x 1 root root 29 Mar 3 13:30 zegrep -rwxr-xr-x 1 root root 29 Mar 3 13:30 zfgrep -rwxr-xr-x 1 root root 2081 Mar 3 13:30 zforce -rwxr-xr-x 1 root root 7585 Mar 3 13:30 zgrep -rwxr-xr-x 1 root root 2206 Mar 3 13:30 zless -rwxr-xr-x 1 root root 1842 Mar 3 13:30 zmore -rwxr-xr-x 1 root root 4553 Mar 3 13:30 znew I: user script /srv/workspace/pbuilder/11574/tmp/hooks/D02_print_environment finished -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy Version: 0.invalid.0 Architecture: armhf Maintainer: Debian Pbuilder Team Description: Dummy package to satisfy dependencies with aptitude - created by pbuilder This package was created automatically by pbuilder to satisfy the build-dependencies of the package being currently built. Depends: debhelper-compat (= 12), libftdi-dev, python3, txt2man, pkg-config dpkg-deb: building package 'pbuilder-satisfydepends-dummy' in '/tmp/satisfydepends-aptitude/pbuilder-satisfydepends-dummy.deb'. Selecting previously unselected package pbuilder-satisfydepends-dummy. (Reading database ... 19398 files and directories currently installed.) Preparing to unpack .../pbuilder-satisfydepends-dummy.deb ... Unpacking pbuilder-satisfydepends-dummy (0.invalid.0) ... dpkg: pbuilder-satisfydepends-dummy: dependency problems, but configuring anyway as you requested: pbuilder-satisfydepends-dummy depends on debhelper-compat (= 12); however: Package debhelper-compat is not installed. pbuilder-satisfydepends-dummy depends on libftdi-dev; however: Package libftdi-dev is not installed. pbuilder-satisfydepends-dummy depends on python3; however: Package python3 is not installed. pbuilder-satisfydepends-dummy depends on txt2man; however: Package txt2man is not installed. pbuilder-satisfydepends-dummy depends on pkg-config; however: Package pkg-config is not installed. Setting up pbuilder-satisfydepends-dummy (0.invalid.0) ... Reading package lists... Building dependency tree... Reading state information... Initializing package states... Writing extended state information... Building tag database... pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) The following NEW packages will be installed: autoconf{a} automake{a} autopoint{a} autotools-dev{a} bsdextrautils{a} debhelper{a} dh-autoreconf{a} dh-strip-nondeterminism{a} dwz{a} file{a} gawk{a} gettext{a} gettext-base{a} groff-base{a} intltool-debian{a} libarchive-zip-perl{a} libdebhelper-perl{a} libelf1{a} libexpat1{a} libfile-stripnondeterminism-perl{a} libftdi-dev{a} libftdi1{a} libglib2.0-0{a} libicu67{a} libmagic-mgc{a} libmagic1{a} libmpdec3{a} libpipeline1{a} libpython3-stdlib{a} libpython3.9-minimal{a} libpython3.9-stdlib{a} libreadline8{a} libsigsegv2{a} libsub-override-perl{a} libtool{a} libuchardet0{a} libusb-0.1-4{a} libusb-dev{a} libxml2{a} m4{a} man-db{a} media-types{a} pkg-config{a} po-debconf{a} python3{a} python3-minimal{a} python3.9{a} python3.9-minimal{a} readline-common{a} sensible-utils{a} txt2man{a} The following packages are RECOMMENDED but will NOT be installed: ca-certificates curl libarchive-cpio-perl libglib2.0-data libltdl-dev libmail-sendmail-perl lynx shared-mime-info wget xdg-user-dirs 0 packages upgraded, 51 newly installed, 0 to remove and 0 not upgraded. Need to get 24.8 MB of archives. After unpacking 88.5 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian bullseye/main armhf bsdextrautils armhf 2.36.1-8 [138 kB] Get: 2 http://deb.debian.org/debian bullseye/main armhf libuchardet0 armhf 0.0.7-1 [65.0 kB] Get: 3 http://deb.debian.org/debian bullseye/main armhf groff-base armhf 1.22.4-6 [847 kB] Get: 4 http://deb.debian.org/debian bullseye/main armhf libpipeline1 armhf 1.5.3-1 [30.1 kB] Get: 5 http://deb.debian.org/debian bullseye/main armhf man-db armhf 2.9.4-2 [1319 kB] Get: 6 http://deb.debian.org/debian bullseye/main armhf readline-common all 8.1-1 [73.7 kB] Get: 7 http://deb.debian.org/debian bullseye/main armhf libreadline8 armhf 8.1-1 [147 kB] Get: 8 http://deb.debian.org/debian bullseye/main armhf libsigsegv2 armhf 2.13-1 [34.0 kB] Get: 9 http://deb.debian.org/debian bullseye/main armhf gawk armhf 1:5.1.0-1 [568 kB] Get: 10 http://deb.debian.org/debian bullseye/main armhf libpython3.9-minimal armhf 3.9.2-1 [790 kB] Get: 11 http://deb.debian.org/debian bullseye/main armhf libexpat1 armhf 2.2.10-2 [76.3 kB] Get: 12 http://deb.debian.org/debian bullseye/main armhf python3.9-minimal armhf 3.9.2-1 [1630 kB] Get: 13 http://deb.debian.org/debian bullseye/main armhf python3-minimal armhf 3.9.2-3 [38.2 kB] Get: 14 http://deb.debian.org/debian bullseye/main armhf media-types all 4.0.0 [30.3 kB] Get: 15 http://deb.debian.org/debian bullseye/main armhf libmpdec3 armhf 2.5.1-1 [74.9 kB] Get: 16 http://deb.debian.org/debian bullseye/main armhf libpython3.9-stdlib armhf 3.9.2-1 [1608 kB] Get: 17 http://deb.debian.org/debian bullseye/main armhf python3.9 armhf 3.9.2-1 [466 kB] Get: 18 http://deb.debian.org/debian bullseye/main armhf libpython3-stdlib armhf 3.9.2-3 [21.4 kB] Get: 19 http://deb.debian.org/debian bullseye/main armhf python3 armhf 3.9.2-3 [37.9 kB] Get: 20 http://deb.debian.org/debian bullseye/main armhf sensible-utils all 0.0.14 [14.8 kB] Get: 21 http://deb.debian.org/debian bullseye/main armhf libmagic-mgc armhf 1:5.39-3 [273 kB] Get: 22 http://deb.debian.org/debian bullseye/main armhf libmagic1 armhf 1:5.39-3 [117 kB] Get: 23 http://deb.debian.org/debian bullseye/main armhf file armhf 1:5.39-3 [68.1 kB] Get: 24 http://deb.debian.org/debian bullseye/main armhf gettext-base armhf 0.21-4 [171 kB] Get: 25 http://deb.debian.org/debian bullseye/main armhf m4 armhf 1.4.18-5 [192 kB] Get: 26 http://deb.debian.org/debian bullseye/main armhf autoconf all 2.69-14 [313 kB] Get: 27 http://deb.debian.org/debian bullseye/main armhf autotools-dev all 20180224.1+nmu1 [77.1 kB] Get: 28 http://deb.debian.org/debian bullseye/main armhf automake all 1:1.16.3-2 [814 kB] Get: 29 http://deb.debian.org/debian bullseye/main armhf autopoint all 0.21-4 [510 kB] Get: 30 http://deb.debian.org/debian bullseye/main armhf libdebhelper-perl all 13.3.4 [189 kB] Get: 31 http://deb.debian.org/debian bullseye/main armhf libtool all 2.4.6-15 [513 kB] Get: 32 http://deb.debian.org/debian bullseye/main armhf dh-autoreconf all 20 [17.1 kB] Get: 33 http://deb.debian.org/debian bullseye/main armhf libarchive-zip-perl all 1.68-1 [104 kB] Get: 34 http://deb.debian.org/debian bullseye/main armhf libsub-override-perl all 0.09-2 [10.2 kB] Get: 35 http://deb.debian.org/debian bullseye/main armhf libfile-stripnondeterminism-perl all 1.12.0-1 [26.3 kB] Get: 36 http://deb.debian.org/debian bullseye/main armhf dh-strip-nondeterminism all 1.12.0-1 [15.4 kB] Get: 37 http://deb.debian.org/debian bullseye/main armhf libelf1 armhf 0.183-1 [161 kB] Get: 38 http://deb.debian.org/debian bullseye/main armhf dwz armhf 0.13+20210201-1 [179 kB] Get: 39 http://deb.debian.org/debian bullseye/main armhf libicu67 armhf 67.1-7 [8319 kB] Get: 40 http://deb.debian.org/debian bullseye/main armhf libxml2 armhf 2.9.10+dfsg-6.7 [602 kB] Get: 41 http://deb.debian.org/debian bullseye/main armhf gettext armhf 0.21-4 [1243 kB] Get: 42 http://deb.debian.org/debian bullseye/main armhf intltool-debian all 0.35.0+20060710.5 [26.8 kB] Get: 43 http://deb.debian.org/debian bullseye/main armhf po-debconf all 1.0.21+nmu1 [248 kB] Get: 44 http://deb.debian.org/debian bullseye/main armhf debhelper all 13.3.4 [1049 kB] Get: 45 http://deb.debian.org/debian bullseye/main armhf libusb-0.1-4 armhf 2:0.1.12-32 [21.7 kB] Get: 46 http://deb.debian.org/debian bullseye/main armhf libftdi1 armhf 0.20-4+b1 [17.4 kB] Get: 47 http://deb.debian.org/debian bullseye/main armhf libusb-dev armhf 2:0.1.12-32 [36.9 kB] Get: 48 http://deb.debian.org/debian bullseye/main armhf libftdi-dev armhf 0.20-4+b1 [183 kB] Get: 49 http://deb.debian.org/debian bullseye/main armhf libglib2.0-0 armhf 2.66.8-1 [1206 kB] Get: 50 http://deb.debian.org/debian bullseye/main armhf pkg-config armhf 0.29.2-1 [62.4 kB] Get: 51 http://deb.debian.org/debian bullseye/main armhf txt2man all 1.7.1-1 [37.7 kB] Fetched 24.8 MB in 2s (11.1 MB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package bsdextrautils. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 19398 files and directories currently installed.) Preparing to unpack .../0-bsdextrautils_2.36.1-8_armhf.deb ... Unpacking bsdextrautils (2.36.1-8) ... Selecting previously unselected package libuchardet0:armhf. Preparing to unpack .../1-libuchardet0_0.0.7-1_armhf.deb ... Unpacking libuchardet0:armhf (0.0.7-1) ... Selecting previously unselected package groff-base. Preparing to unpack .../2-groff-base_1.22.4-6_armhf.deb ... Unpacking groff-base (1.22.4-6) ... Selecting previously unselected package libpipeline1:armhf. Preparing to unpack .../3-libpipeline1_1.5.3-1_armhf.deb ... Unpacking libpipeline1:armhf (1.5.3-1) ... Selecting previously unselected package man-db. Preparing to unpack .../4-man-db_2.9.4-2_armhf.deb ... Unpacking man-db (2.9.4-2) ... Selecting previously unselected package readline-common. Preparing to unpack .../5-readline-common_8.1-1_all.deb ... Unpacking readline-common (8.1-1) ... Selecting previously unselected package libreadline8:armhf. Preparing to unpack .../6-libreadline8_8.1-1_armhf.deb ... Unpacking libreadline8:armhf (8.1-1) ... Selecting previously unselected package libsigsegv2:armhf. Preparing to unpack .../7-libsigsegv2_2.13-1_armhf.deb ... Unpacking libsigsegv2:armhf (2.13-1) ... Setting up readline-common (8.1-1) ... Setting up libreadline8:armhf (8.1-1) ... Setting up libsigsegv2:armhf (2.13-1) ... Selecting previously unselected package gawk. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20004 files and directories currently installed.) Preparing to unpack .../gawk_1%3a5.1.0-1_armhf.deb ... Unpacking gawk (1:5.1.0-1) ... Selecting previously unselected package libpython3.9-minimal:armhf. Preparing to unpack .../libpython3.9-minimal_3.9.2-1_armhf.deb ... Unpacking libpython3.9-minimal:armhf (3.9.2-1) ... Selecting previously unselected package libexpat1:armhf. Preparing to unpack .../libexpat1_2.2.10-2_armhf.deb ... Unpacking libexpat1:armhf (2.2.10-2) ... Selecting previously unselected package python3.9-minimal. Preparing to unpack .../python3.9-minimal_3.9.2-1_armhf.deb ... Unpacking python3.9-minimal (3.9.2-1) ... Setting up libpython3.9-minimal:armhf (3.9.2-1) ... Setting up libexpat1:armhf (2.2.10-2) ... Setting up python3.9-minimal (3.9.2-1) ... Selecting previously unselected package python3-minimal. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20473 files and directories currently installed.) Preparing to unpack .../0-python3-minimal_3.9.2-3_armhf.deb ... Unpacking python3-minimal (3.9.2-3) ... Selecting previously unselected package media-types. Preparing to unpack .../1-media-types_4.0.0_all.deb ... Unpacking media-types (4.0.0) ... Selecting previously unselected package libmpdec3:armhf. Preparing to unpack .../2-libmpdec3_2.5.1-1_armhf.deb ... Unpacking libmpdec3:armhf (2.5.1-1) ... Selecting previously unselected package libpython3.9-stdlib:armhf. Preparing to unpack .../3-libpython3.9-stdlib_3.9.2-1_armhf.deb ... Unpacking libpython3.9-stdlib:armhf (3.9.2-1) ... Selecting previously unselected package python3.9. Preparing to unpack .../4-python3.9_3.9.2-1_armhf.deb ... Unpacking python3.9 (3.9.2-1) ... Selecting previously unselected package libpython3-stdlib:armhf. Preparing to unpack .../5-libpython3-stdlib_3.9.2-3_armhf.deb ... Unpacking libpython3-stdlib:armhf (3.9.2-3) ... Setting up python3-minimal (3.9.2-3) ... Selecting previously unselected package python3. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20870 files and directories currently installed.) Preparing to unpack .../00-python3_3.9.2-3_armhf.deb ... Unpacking python3 (3.9.2-3) ... Selecting previously unselected package sensible-utils. Preparing to unpack .../01-sensible-utils_0.0.14_all.deb ... Unpacking sensible-utils (0.0.14) ... Selecting previously unselected package libmagic-mgc. Preparing to unpack .../02-libmagic-mgc_1%3a5.39-3_armhf.deb ... Unpacking libmagic-mgc (1:5.39-3) ... Selecting previously unselected package libmagic1:armhf. Preparing to unpack .../03-libmagic1_1%3a5.39-3_armhf.deb ... Unpacking libmagic1:armhf (1:5.39-3) ... Selecting previously unselected package file. Preparing to unpack .../04-file_1%3a5.39-3_armhf.deb ... Unpacking file (1:5.39-3) ... Selecting previously unselected package gettext-base. Preparing to unpack .../05-gettext-base_0.21-4_armhf.deb ... Unpacking gettext-base (0.21-4) ... Selecting previously unselected package m4. Preparing to unpack .../06-m4_1.4.18-5_armhf.deb ... Unpacking m4 (1.4.18-5) ... Selecting previously unselected package autoconf. Preparing to unpack .../07-autoconf_2.69-14_all.deb ... Unpacking autoconf (2.69-14) ... Selecting previously unselected package autotools-dev. Preparing to unpack .../08-autotools-dev_20180224.1+nmu1_all.deb ... Unpacking autotools-dev (20180224.1+nmu1) ... Selecting previously unselected package automake. Preparing to unpack .../09-automake_1%3a1.16.3-2_all.deb ... Unpacking automake (1:1.16.3-2) ... Selecting previously unselected package autopoint. Preparing to unpack .../10-autopoint_0.21-4_all.deb ... Unpacking autopoint (0.21-4) ... Selecting previously unselected package libdebhelper-perl. Preparing to unpack .../11-libdebhelper-perl_13.3.4_all.deb ... Unpacking libdebhelper-perl (13.3.4) ... Selecting previously unselected package libtool. Preparing to unpack .../12-libtool_2.4.6-15_all.deb ... Unpacking libtool (2.4.6-15) ... Selecting previously unselected package dh-autoreconf. Preparing to unpack .../13-dh-autoreconf_20_all.deb ... Unpacking dh-autoreconf (20) ... Selecting previously unselected package libarchive-zip-perl. Preparing to unpack .../14-libarchive-zip-perl_1.68-1_all.deb ... Unpacking libarchive-zip-perl (1.68-1) ... Selecting previously unselected package libsub-override-perl. Preparing to unpack .../15-libsub-override-perl_0.09-2_all.deb ... Unpacking libsub-override-perl (0.09-2) ... Selecting previously unselected package libfile-stripnondeterminism-perl. Preparing to unpack .../16-libfile-stripnondeterminism-perl_1.12.0-1_all.deb ... Unpacking libfile-stripnondeterminism-perl (1.12.0-1) ... Selecting previously unselected package dh-strip-nondeterminism. Preparing to unpack .../17-dh-strip-nondeterminism_1.12.0-1_all.deb ... Unpacking dh-strip-nondeterminism (1.12.0-1) ... Selecting previously unselected package libelf1:armhf. Preparing to unpack .../18-libelf1_0.183-1_armhf.deb ... Unpacking libelf1:armhf (0.183-1) ... Selecting previously unselected package dwz. Preparing to unpack .../19-dwz_0.13+20210201-1_armhf.deb ... Unpacking dwz (0.13+20210201-1) ... Selecting previously unselected package libicu67:armhf. Preparing to unpack .../20-libicu67_67.1-7_armhf.deb ... Unpacking libicu67:armhf (67.1-7) ... Selecting previously unselected package libxml2:armhf. Preparing to unpack .../21-libxml2_2.9.10+dfsg-6.7_armhf.deb ... Unpacking libxml2:armhf (2.9.10+dfsg-6.7) ... Selecting previously unselected package gettext. Preparing to unpack .../22-gettext_0.21-4_armhf.deb ... Unpacking gettext (0.21-4) ... Selecting previously unselected package intltool-debian. Preparing to unpack .../23-intltool-debian_0.35.0+20060710.5_all.deb ... Unpacking intltool-debian (0.35.0+20060710.5) ... Selecting previously unselected package po-debconf. Preparing to unpack .../24-po-debconf_1.0.21+nmu1_all.deb ... Unpacking po-debconf (1.0.21+nmu1) ... Selecting previously unselected package debhelper. Preparing to unpack .../25-debhelper_13.3.4_all.deb ... Unpacking debhelper (13.3.4) ... Selecting previously unselected package libusb-0.1-4:armhf. Preparing to unpack .../26-libusb-0.1-4_2%3a0.1.12-32_armhf.deb ... Unpacking libusb-0.1-4:armhf (2:0.1.12-32) ... Selecting previously unselected package libftdi1:armhf. Preparing to unpack .../27-libftdi1_0.20-4+b1_armhf.deb ... Unpacking libftdi1:armhf (0.20-4+b1) ... Selecting previously unselected package libusb-dev. Preparing to unpack .../28-libusb-dev_2%3a0.1.12-32_armhf.deb ... Unpacking libusb-dev (2:0.1.12-32) ... Selecting previously unselected package libftdi-dev. Preparing to unpack .../29-libftdi-dev_0.20-4+b1_armhf.deb ... Unpacking libftdi-dev (0.20-4+b1) ... Selecting previously unselected package libglib2.0-0:armhf. Preparing to unpack .../30-libglib2.0-0_2.66.8-1_armhf.deb ... Unpacking libglib2.0-0:armhf (2.66.8-1) ... Selecting previously unselected package pkg-config. Preparing to unpack .../31-pkg-config_0.29.2-1_armhf.deb ... Unpacking pkg-config (0.29.2-1) ... Selecting previously unselected package txt2man. Preparing to unpack .../32-txt2man_1.7.1-1_all.deb ... Unpacking txt2man (1.7.1-1) ... Setting up media-types (4.0.0) ... Setting up libpipeline1:armhf (1.5.3-1) ... Setting up bsdextrautils (2.36.1-8) ... update-alternatives: using /usr/bin/write.ul to provide /usr/bin/write (write) in auto mode Setting up libicu67:armhf (67.1-7) ... Setting up libmagic-mgc (1:5.39-3) ... Setting up gawk (1:5.1.0-1) ... Setting up libarchive-zip-perl (1.68-1) ... Setting up libglib2.0-0:armhf (2.66.8-1) ... No schema files found: doing nothing. Setting up libdebhelper-perl (13.3.4) ... Setting up libmagic1:armhf (1:5.39-3) ... Setting up gettext-base (0.21-4) ... Setting up m4 (1.4.18-5) ... Setting up file (1:5.39-3) ... Setting up libusb-0.1-4:armhf (2:0.1.12-32) ... Setting up autotools-dev (20180224.1+nmu1) ... Setting up autopoint (0.21-4) ... Setting up pkg-config (0.29.2-1) ... Setting up autoconf (2.69-14) ... Setting up sensible-utils (0.0.14) ... Setting up libuchardet0:armhf (0.0.7-1) ... Setting up libmpdec3:armhf (2.5.1-1) ... Setting up libsub-override-perl (0.09-2) ... Setting up libelf1:armhf (0.183-1) ... Setting up libxml2:armhf (2.9.10+dfsg-6.7) ... Setting up libpython3.9-stdlib:armhf (3.9.2-1) ... Setting up libpython3-stdlib:armhf (3.9.2-3) ... Setting up automake (1:1.16.3-2) ... update-alternatives: using /usr/bin/automake-1.16 to provide /usr/bin/automake (automake) in auto mode Setting up libfile-stripnondeterminism-perl (1.12.0-1) ... Setting up gettext (0.21-4) ... Setting up txt2man (1.7.1-1) ... Setting up libtool (2.4.6-15) ... Setting up libftdi1:armhf (0.20-4+b1) ... Setting up libusb-dev (2:0.1.12-32) ... Setting up intltool-debian (0.35.0+20060710.5) ... Setting up dh-autoreconf (20) ... Setting up dh-strip-nondeterminism (1.12.0-1) ... Setting up dwz (0.13+20210201-1) ... Setting up groff-base (1.22.4-6) ... Setting up python3.9 (3.9.2-1) ... Setting up libftdi-dev (0.20-4+b1) ... Setting up po-debconf (1.0.21+nmu1) ... Setting up python3 (3.9.2-3) ... Setting up man-db (2.9.4-2) ... Not building database; man-db/auto-update is not 'true'. Setting up debhelper (13.3.4) ... Processing triggers for libc-bin (2.31-13) ... Reading package lists... Building dependency tree... Reading state information... Reading extended state information... Initializing package states... Writing extended state information... Building tag database... -> Finished parsing the build-deps Reading package lists... Building dependency tree... Reading state information... fakeroot is already the newest version (1.25.3-1.1). The following additional packages will be installed: libfile-find-rule-perl libnumber-compare-perl libtext-glob-perl The following NEW packages will be installed: libfile-find-rule-perl libnumber-compare-perl libtext-glob-perl usrmerge 0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded. Need to get 59.5 kB of archives. After this operation, 157 kB of additional disk space will be used. Get:1 http://deb.debian.org/debian bullseye/main armhf libnumber-compare-perl all 0.03-1.1 [6956 B] Get:2 http://deb.debian.org/debian bullseye/main armhf libtext-glob-perl all 0.11-1 [8888 B] Get:3 http://deb.debian.org/debian bullseye/main armhf libfile-find-rule-perl all 0.34-1 [30.6 kB] Get:4 http://deb.debian.org/debian bullseye/main armhf usrmerge all 25 [13.0 kB] debconf: delaying package configuration, since apt-utils is not installed Fetched 59.5 kB in 0s (867 kB/s) Selecting previously unselected package libnumber-compare-perl. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 22440 files and directories currently installed.) Preparing to unpack .../libnumber-compare-perl_0.03-1.1_all.deb ... Unpacking libnumber-compare-perl (0.03-1.1) ... Selecting previously unselected package libtext-glob-perl. Preparing to unpack .../libtext-glob-perl_0.11-1_all.deb ... Unpacking libtext-glob-perl (0.11-1) ... Selecting previously unselected package libfile-find-rule-perl. Preparing to unpack .../libfile-find-rule-perl_0.34-1_all.deb ... Unpacking libfile-find-rule-perl (0.34-1) ... Selecting previously unselected package usrmerge. Preparing to unpack .../archives/usrmerge_25_all.deb ... Unpacking usrmerge (25) ... Setting up libtext-glob-perl (0.11-1) ... Setting up libnumber-compare-perl (0.03-1.1) ... Setting up libfile-find-rule-perl (0.34-1) ... Setting up usrmerge (25) ... The system has been successfully converted. Processing triggers for man-db (2.9.4-2) ... Not building database; man-db/auto-update is not 'true'. I: Building the package hostname: Name or service not known I: Running cd /build/fpga-icestorm-0~20190913git0ec00d8/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-genchanges -S > ../fpga-icestorm_0~20190913git0ec00d8-2_source.changes dpkg-buildpackage: info: source package fpga-icestorm dpkg-buildpackage: info: source version 0~20190913git0ec00d8-2 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Ruben Undheim dpkg-source --before-build . dpkg-buildpackage: info: host architecture armhf fakeroot debian/rules clean dh clean debian/rules override_dh_auto_clean make[1]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' dh_auto_clean make -j4 clean make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' for dir in icebox icepack icemulti icepll icebram icetime iceprog; do \ make -C $dir clean || exit; \ done make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt chipdb-lm4k.txt chipdb-u4k.txt rm -f icebox.pyc iceboxdb.pyc make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' rm -f icepack rm -f iceunpack rm -f icepack.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' rm -f icemulti rm -f icemulti.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' rm -f icepll rm -f icepll.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' rm -f icebram rm -f icebram.exe rm -f demo.* demo_*.* rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' rm -f icetime icetime.exe *.o *.d timings-*.cc rm -rf test[0-9]* make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' rm -f iceprog rm -f iceprog.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' rm -f debian/man/*.1 rm -f -r icebox/__pycache__ make[1]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' dh_clean debian/rules build dh build dh_update_autotools_config dh_autoreconf dh_auto_configure dh_auto_build make -j4 "INSTALL=install --strip-program=true" make[1]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' make -C icebox all make -C icepack all make -C icemulti all make -C icepll all make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o icepack.o icepack.cc make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' python3 icebox_chipdb.py -3 > chipdb-384.new make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o icepll.o icepll.cc make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o icemulti.o icemulti.cc g++ -o icepll -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icepll.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' make -C icebram all make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o icebram.o icebram.cc icepack.cc: In member function 'void FpgaConfig::write_ascii(std::ostream&) const': icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'std::vector >::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | bool skip_bram_initialization; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 | | 117 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 118 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | | 120 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 121 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 123 | | 124 | // icebox i/o | ~~~~~~~~~~~~~ 125 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | | 128 | // netpbm i/o | ~~~~~~~~~~~~~ 129 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 131 | | 132 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 134 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 135 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | | 137 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 138 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140 | | 141 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 142 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 143 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 144 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | }; | ~~ 146 | | 147 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 148 | { | ~ 149 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 150 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 151 | | 152 | string tile_type; | ~~~~~~~~~~~~~~~~~ 153 | int tile_width; | ~~~~~~~~~~~~~~~ 154 | int column_width; | ~~~~~~~~~~~~~~~~~ 155 | | 156 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 157 | bool right_half; | ~~~~~~~~~~~~~~~~ 158 | bool top_half; | ~~~~~~~~~~~~~~ 159 | | 160 | int bank_num; | ~~~~~~~~~~~~~ 161 | int bank_tx; | ~~~~~~~~~~~~ 162 | int bank_ty; | ~~~~~~~~~~~~ 163 | int bank_xoff; | ~~~~~~~~~~~~~~ 164 | int bank_yoff; | ~~~~~~~~~~~~~~ 165 | | 166 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 168 | }; | ~~ 169 | | 170 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 171 | { | ~ 172 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 173 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 174 | | 175 | int bank_num; | ~~~~~~~~~~~~~ 176 | int bank_off; | ~~~~~~~~~~~~~ 177 | | 178 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 180 | }; | ~~ 181 | | 182 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 | { | ~ 184 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 | } | ~ 189 | } | ~ 190 | | 191 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 192 | { | ~ 193 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 194 | | 195 | if (byte < 0) | ~~~~~~~~~~~~~ 196 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 197 | | 198 | file_offset++; | ~~~~~~~~~~~~~~ 199 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 200 | | 201 | return byte; | ~~~~~~~~~~~~ 202 | } | ~ 203 | | 204 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 205 | { | ~ 206 | ofs << byte; | ~~~~~~~~~~~~ 207 | file_offset++; | ~~~~~~~~~~~~~~ 208 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 | } | ~ 210 | | 211 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 | { | ~ 213 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 214 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 215 | | 216 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 | | 219 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 | | 221 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 222 | | 223 | while (1) | ~~~~~~~~~ 224 | { | ~ 225 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 231 | break; | ~~~~~~ 232 | } | ~ 233 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 234 | } | ~ 235 | | 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 239 | | 240 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 241 | | 242 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 243 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 246 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 247 | | 248 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 249 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 250 | | 251 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 252 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 253 | | 254 | while (!wakeup) | ~~~~~~~~~~~~~~~ 255 | { | ~ 256 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258 | | 259 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 260 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 261 | | 262 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 264 | | 265 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 267 | | 268 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 269 | | 270 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 271 | { | ~ 272 | case 0x00: | ~~~~~~~~~~ 273 | switch (payload) | ~~~~~~~~~~~~~~~~ 274 | { | ~ 275 | case 0x01: | ~~~~~~~~~~ 276 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 | | 280 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 | | 283 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 284 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 287 | | 288 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 | } | ~ 295 | } | ~ 296 | | 297 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299 | if (end_token) | ~~~~~~~~~~~~~~ 300 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 301 | break; | ~~~~~~ 302 | | 303 | case 0x03: | ~~~~~~~~~~ 304 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 | | 308 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 310 | | 311 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 312 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 315 | | 316 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 | } | ~ 323 | } | ~ 324 | | 325 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 327 | if (end_token) | ~~~~~~~~~~~~~~ 328 | error("Expected 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 329 | break; | ~~~~~~ 330 | | 331 | case 0x05: | ~~~~~~~~~~ 332 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 333 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 334 | break; | ~~~~~~ 335 | | 336 | case 0x06: | ~~~~~~~~~~ 337 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 338 | wakeup = true; | ~~~~~~~~~~~~~~ 339 | break; | ~~~~~~ 340 | | 341 | default: | ~~~~~~~~ 342 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 343 | } | ~ 344 | break; | ~~~~~~ 345 | | 346 | case 0x10: | ~~~~~~~~~~ 347 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 348 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 349 | break; | ~~~~~~ 350 | | 351 | case 0x20: | ~~~~~~~~~~ 352 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 353 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 354 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 355 | break; | ~~~~~~ 356 | | 357 | case 0x50: | ~~~~~~~~~~ 358 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 359 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 360 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 361 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 362 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 363 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 364 | else | ~~~~ 365 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 367 | break; | ~~~~~~ 368 | | 369 | case 0x60: | ~~~~~~~~~~ 370 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 372 | break; | ~~~~~~ 373 | | 374 | case 0x70: | ~~~~~~~~~~ 375 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 377 | break; | ~~~~~~ 378 | | 379 | case 0x80: | ~~~~~~~~~~ 380 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 382 | break; | ~~~~~~ 383 | | 384 | case 0x90: | ~~~~~~~~~~ 385 | switch(payload) | ~~~~~~~~~~~~~~~ 386 | { | ~ 387 | case 0: | ~~~~~~~ 388 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 390 | break; | ~~~~~~ 391 | case 1: | ~~~~~~~ 392 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 394 | break; | ~~~~~~ 395 | case 32: | ~~~~~~~~ 396 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 398 | break; | ~~~~~~ 399 | case 33: | ~~~~~~~~ 400 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 402 | break; | ~~~~~~ 403 | default: | ~~~~~~~~ 404 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 405 | } | ~ 406 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 407 | break; | ~~~~~~ 408 | | 409 | default: | ~~~~~~~~ 410 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 411 | } | ~ 412 | } | ~ 413 | | 414 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 415 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 416 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 417 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 418 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 419 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 420 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 421 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 422 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 423 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 424 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 425 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 426 | else | ~~~~ 427 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 428 | | 429 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 430 | } | ~ 431 | | 432 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 433 | { | ~ 434 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 435 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 436 | | 437 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 439 | | 440 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 441 | ofs << byte; | ~~~~~~~~~~~~ 442 | | 443 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 448 | | 449 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 457 | else | ~~~~ 458 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 459 | | 460 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 463 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 464 | | 465 | { | ~ 466 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 467 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 470 | | 471 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 472 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 473 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 474 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 475 | else | ~~~~ 476 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 477 | | 478 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 482 | else | ~~~~ 483 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 484 | } | ~ 485 | | 486 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 495 | } | ~ 496 | | 497 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 501 | | 502 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | { | ~ 504 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 505 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 507 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 511 | | 512 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 517 | } | ~ 518 | | 519 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 522 | | 523 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 527 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 528 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 531 | } | ~ 532 | | 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 535 | } | ~ 536 | | 537 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 538 | | 539 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 540 | { | ~ 541 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 546 | } | ~ 547 | | 548 | | 549 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 553 | | 554 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 555 | { | ~ 556 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 559 | | 560 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 561 | { | ~ 562 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 563 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 565 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 566 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 569 | | 570 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 574 | | 575 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 580 | } | ~ 581 | | 582 | | 583 | if (!this->skip_bram_initialization) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 587 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 589 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 591 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 592 | } | ~ 593 | | 594 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 595 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 596 | } | ~ 597 | } | ~ 598 | } | ~ 599 | } | ~ 600 | | 601 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 604 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | | 607 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 608 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | | 611 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 612 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | } | ~ 614 | | 615 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | { | ~ 617 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 618 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 619 | | 620 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 622 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 623 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 624 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 627 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 628 | | 629 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 630 | { | ~ 631 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 632 | | 633 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 634 | is >> command; | ~~~~~~~~~~~~~~ 635 | | 636 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 637 | continue; | ~~~~~~~~~ 638 | | 639 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 | | 641 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | { | ~ 643 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 644 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 646 | | 647 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 648 | { | ~ 649 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 650 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 651 | break; | ~~~~~~ 652 | } | ~ 653 | | 654 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 655 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 656 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | } | ~ 658 | | 659 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 660 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 661 | continue; | ~~~~~~~~~ 662 | } | ~ 663 | | 664 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | { | ~ 666 | if (got_device) | ~~~~~~~~~~~~~~~ 667 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 668 | | 669 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 670 | | 671 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 672 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 673 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 674 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 675 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 676 | } else | ~~~~~~ 677 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 678 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 679 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 680 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 681 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 | } else | ~~~~~~ 683 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 685 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 686 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 688 | } else | ~~~~~~ 689 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 691 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 692 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 694 | } else | ~~~~~~ 695 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 696 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 697 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 698 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 699 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 700 | } else | ~~~~~~ 701 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 702 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 703 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 704 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 705 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 706 | } else | ~~~~~~ 707 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | | 709 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 710 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 713 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 714 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 715 | } | ~ 716 | | 717 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 718 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 721 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 722 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | } | ~ 724 | } else { | ~~~~~~~~ 725 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 727 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 728 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 729 | } | ~ 730 | | 731 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 732 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 734 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 735 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 736 | } | ~ 737 | } | ~ 738 | | 739 | | 740 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 741 | continue; | ~~~~~~~~~ 742 | } | ~ 743 | | 744 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 745 | { | ~ 746 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 747 | | 748 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 749 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 750 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 751 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 752 | | 753 | continue; | ~~~~~~~~~ 754 | } | ~ 755 | | 756 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 757 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 759 | if (nosleep) | ~~~~~~~~~~~~ 760 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 761 | else | ~~~~ 762 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 763 | | 764 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | { | ~ 766 | if (!got_device) | ~~~~~~~~~~~~~~~~ 767 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 770 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 771 | | 772 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | | 774 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 775 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 777 | | 778 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 779 | { | ~ 780 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 781 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 782 | break; | ~~~~~~ 783 | } | ~ 784 | | 785 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 789 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 790 | } | ~ 791 | } | ~ 792 | | 793 | continue; | ~~~~~~~~~ 794 | } | ~ 795 | | 796 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | { | ~ 798 | if (!got_device) | ~~~~~~~~~~~~~~~~ 799 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 802 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 803 | | 804 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 805 | | 806 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 807 | { | ~ 808 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 809 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 810 | break; | ~~~~~~ 811 | } | ~ 812 | | 813 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | { | ~ 815 | int value = -1; | ~~~~~~~~~~~~~~~ 816 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 820 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 822 | if (value < 0) | ~~~~~~~~~~~~~~ 823 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | | 825 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 828 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 829 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 830 | } | ~ 831 | } | ~ 832 | } | ~ 833 | | 834 | continue; | ~~~~~~~~~ 835 | } | ~ 836 | | 837 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | { | ~ 839 | if (!got_device) | ~~~~~~~~~~~~~~~~ 840 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | | 842 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 843 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 844 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 845 | | 846 | continue; | ~~~~~~~~~ 847 | } | ~ 848 | | 849 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 850 | continue; | ~~~~~~~~~ 851 | | 852 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 853 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 854 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 855 | } | ~ 856 | } | ~ 857 | | 858 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | { | ~ 860 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 861 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | | 863 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 864 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 865 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 866 | if (ch == 0) { | ~~~~~~~~~~~~~~ 867 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 868 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 869 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 870 | } else { | ~~~~~~~~ 871 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 872 | ofs << '\n'; | ~~~~~~~~~~~~ 873 | ofs << ch; | ~~~~~~~~~~ 874 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 875 | } | ~ 876 | } | ~ 877 | | 878 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 879 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | | 882 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 883 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | // info. | ~~~~~~~~ 885 | | 886 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | | 889 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 891 | { | ~ 892 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 893 | | 894 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | continue; | ~~~~~~~~~ 896 | | 897 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | | 899 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 904 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector >::size_type {aka unsigned int} icepack.cc:905:6: note: in expansion of macro 'error' 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ^~~~~ icepack.cc:905:60: note: format string is defined here 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 7 has type 'std::vector::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | bool skip_bram_initialization; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 | | 117 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 118 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | | 120 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 121 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 123 | | 124 | // icebox i/o | ~~~~~~~~~~~~~ 125 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | | 128 | // netpbm i/o | ~~~~~~~~~~~~~ 129 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 131 | | 132 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 134 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 135 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | | 137 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 138 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140 | | 141 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 142 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 143 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 144 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | }; | ~~ 146 | | 147 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 148 | { | ~ 149 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 150 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 151 | | 152 | string tile_type; | ~~~~~~~~~~~~~~~~~ 153 | int tile_width; | ~~~~~~~~~~~~~~~ 154 | int column_width; | ~~~~~~~~~~~~~~~~~ 155 | | 156 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 157 | bool right_half; | ~~~~~~~~~~~~~~~~ 158 | bool top_half; | ~~~~~~~~~~~~~~ 159 | | 160 | int bank_num; | ~~~~~~~~~~~~~ 161 | int bank_tx; | ~~~~~~~~~~~~ 162 | int bank_ty; | ~~~~~~~~~~~~ 163 | int bank_xoff; | ~~~~~~~~~~~~~~ 164 | int bank_yoff; | ~~~~~~~~~~~~~~ 165 | | 166 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 168 | }; | ~~ 169 | | 170 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 171 | { | ~ 172 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 173 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 174 | | 175 | int bank_num; | ~~~~~~~~~~~~~ 176 | int bank_off; | ~~~~~~~~~~~~~ 177 | | 178 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 180 | }; | ~~ 181 | | 182 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 | { | ~ 184 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 | } | ~ 189 | } | ~ 190 | | 191 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 192 | { | ~ 193 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 194 | | 195 | if (byte < 0) | ~~~~~~~~~~~~~ 196 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 197 | | 198 | file_offset++; | ~~~~~~~~~~~~~~ 199 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 200 | | 201 | return byte; | ~~~~~~~~~~~~ 202 | } | ~ 203 | | 204 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 205 | { | ~ 206 | ofs << byte; | ~~~~~~~~~~~~ 207 | file_offset++; | ~~~~~~~~~~~~~~ 208 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 | } | ~ 210 | | 211 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 | { | ~ 213 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 214 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 215 | | 216 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 | | 219 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 | | 221 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 222 | | 223 | while (1) | ~~~~~~~~~ 224 | { | ~ 225 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 231 | break; | ~~~~~~ 232 | } | ~ 233 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 234 | } | ~ 235 | | 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 239 | | 240 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 241 | | 242 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 243 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 246 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 247 | | 248 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 249 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 250 | | 251 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 252 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 253 | | 254 | while (!wakeup) | ~~~~~~~~~~~~~~~ 255 | { | ~ 256 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258 | | 259 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 260 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 261 | | 262 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 264 | | 265 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 267 | | 268 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 269 | | 270 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 271 | { | ~ 272 | case 0x00: | ~~~~~~~~~~ 273 | switch (payload) | ~~~~~~~~~~~~~~~~ 274 | { | ~ 275 | case 0x01: | ~~~~~~~~~~ 276 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 | | 280 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 | | 283 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 284 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 287 | | 288 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 | } | ~ 295 | } | ~ 296 | | 297 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299 | if (end_token) | ~~~~~~~~~~~~~~ 300 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 301 | break; | ~~~~~~ 302 | | 303 | case 0x03: | ~~~~~~~~~~ 304 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 | | 308 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 310 | | 311 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 312 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 315 | | 316 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 | } | ~ 323 | } | ~ 324 | | 325 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 327 | if (end_token) | ~~~~~~~~~~~~~~ 328 | error("Expected 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 329 | break; | ~~~~~~ 330 | | 331 | case 0x05: | ~~~~~~~~~~ 332 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 333 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 334 | break; | ~~~~~~ 335 | | 336 | case 0x06: | ~~~~~~~~~~ 337 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 338 | wakeup = true; | ~~~~~~~~~~~~~~ 339 | break; | ~~~~~~ 340 | | 341 | default: | ~~~~~~~~ 342 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 343 | } | ~ 344 | break; | ~~~~~~ 345 | | 346 | case 0x10: | ~~~~~~~~~~ 347 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 348 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 349 | break; | ~~~~~~ 350 | | 351 | case 0x20: | ~~~~~~~~~~ 352 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 353 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 354 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 355 | break; | ~~~~~~ 356 | | 357 | case 0x50: | ~~~~~~~~~~ 358 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 359 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 360 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 361 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 362 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 363 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 364 | else | ~~~~ 365 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 367 | break; | ~~~~~~ 368 | | 369 | case 0x60: | ~~~~~~~~~~ 370 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 372 | break; | ~~~~~~ 373 | | 374 | case 0x70: | ~~~~~~~~~~ 375 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 377 | break; | ~~~~~~ 378 | | 379 | case 0x80: | ~~~~~~~~~~ 380 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 382 | break; | ~~~~~~ 383 | | 384 | case 0x90: | ~~~~~~~~~~ 385 | switch(payload) | ~~~~~~~~~~~~~~~ 386 | { | ~ 387 | case 0: | ~~~~~~~ 388 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 390 | break; | ~~~~~~ 391 | case 1: | ~~~~~~~ 392 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 394 | break; | ~~~~~~ 395 | case 32: | ~~~~~~~~ 396 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 398 | break; | ~~~~~~ 399 | case 33: | ~~~~~~~~ 400 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 402 | break; | ~~~~~~ 403 | default: | ~~~~~~~~ 404 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 405 | } | ~ 406 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 407 | break; | ~~~~~~ 408 | | 409 | default: | ~~~~~~~~ 410 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 411 | } | ~ 412 | } | ~ 413 | | 414 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 415 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 416 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 417 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 418 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 419 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 420 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 421 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 422 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 423 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 424 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 425 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 426 | else | ~~~~ 427 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 428 | | 429 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 430 | } | ~ 431 | | 432 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 433 | { | ~ 434 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 435 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 436 | | 437 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 439 | | 440 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 441 | ofs << byte; | ~~~~~~~~~~~~ 442 | | 443 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 448 | | 449 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 457 | else | ~~~~ 458 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 459 | | 460 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 463 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 464 | | 465 | { | ~ 466 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 467 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 470 | | 471 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 472 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 473 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 474 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 475 | else | ~~~~ 476 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 477 | | 478 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 482 | else | ~~~~ 483 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 484 | } | ~ 485 | | 486 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 495 | } | ~ 496 | | 497 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 501 | | 502 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | { | ~ 504 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 505 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 507 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 511 | | 512 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 517 | } | ~ 518 | | 519 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 522 | | 523 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 527 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 528 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 531 | } | ~ 532 | | 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 535 | } | ~ 536 | | 537 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 538 | | 539 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 540 | { | ~ 541 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 546 | } | ~ 547 | | 548 | | 549 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 553 | | 554 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 555 | { | ~ 556 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 559 | | 560 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 561 | { | ~ 562 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 563 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 565 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 566 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 569 | | 570 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 574 | | 575 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 580 | } | ~ 581 | | 582 | | 583 | if (!this->skip_bram_initialization) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 587 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 589 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 591 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 592 | } | ~ 593 | | 594 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 595 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 596 | } | ~ 597 | } | ~ 598 | } | ~ 599 | } | ~ 600 | | 601 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 604 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | | 607 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 608 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | | 611 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 612 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | } | ~ 614 | | 615 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | { | ~ 617 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 618 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 619 | | 620 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 622 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 623 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 624 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 627 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 628 | | 629 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 630 | { | ~ 631 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 632 | | 633 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 634 | is >> command; | ~~~~~~~~~~~~~~ 635 | | 636 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 637 | continue; | ~~~~~~~~~ 638 | | 639 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 | | 641 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | { | ~ 643 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 644 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 646 | | 647 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 648 | { | ~ 649 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 650 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 651 | break; | ~~~~~~ 652 | } | ~ 653 | | 654 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 655 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 656 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | } | ~ 658 | | 659 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 660 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 661 | continue; | ~~~~~~~~~ 662 | } | ~ 663 | | 664 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | { | ~ 666 | if (got_device) | ~~~~~~~~~~~~~~~ 667 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 668 | | 669 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 670 | | 671 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 672 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 673 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 674 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 675 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 676 | } else | ~~~~~~ 677 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 678 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 679 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 680 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 681 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 | } else | ~~~~~~ 683 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 685 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 686 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 688 | } else | ~~~~~~ 689 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 691 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 692 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 694 | } else | ~~~~~~ 695 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 696 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 697 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 698 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 699 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 700 | } else | ~~~~~~ 701 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 702 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 703 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 704 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 705 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 706 | } else | ~~~~~~ 707 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | | 709 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 710 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 713 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 714 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 715 | } | ~ 716 | | 717 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 718 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 721 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 722 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | } | ~ 724 | } else { | ~~~~~~~~ 725 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 727 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 728 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 729 | } | ~ 730 | | 731 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 732 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 734 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 735 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 736 | } | ~ 737 | } | ~ 738 | | 739 | | 740 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 741 | continue; | ~~~~~~~~~ 742 | } | ~ 743 | | 744 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 745 | { | ~ 746 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 747 | | 748 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 749 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 750 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 751 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 752 | | 753 | continue; | ~~~~~~~~~ 754 | } | ~ 755 | | 756 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 757 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 759 | if (nosleep) | ~~~~~~~~~~~~ 760 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 761 | else | ~~~~ 762 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 763 | | 764 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | { | ~ 766 | if (!got_device) | ~~~~~~~~~~~~~~~~ 767 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 770 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 771 | | 772 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | | 774 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 775 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 777 | | 778 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 779 | { | ~ 780 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 781 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 782 | break; | ~~~~~~ 783 | } | ~ 784 | | 785 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 789 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 790 | } | ~ 791 | } | ~ 792 | | 793 | continue; | ~~~~~~~~~ 794 | } | ~ 795 | | 796 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | { | ~ 798 | if (!got_device) | ~~~~~~~~~~~~~~~~ 799 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 802 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 803 | | 804 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 805 | | 806 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 807 | { | ~ 808 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 809 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 810 | break; | ~~~~~~ 811 | } | ~ 812 | | 813 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | { | ~ 815 | int value = -1; | ~~~~~~~~~~~~~~~ 816 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 820 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 822 | if (value < 0) | ~~~~~~~~~~~~~~ 823 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | | 825 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 828 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 829 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 830 | } | ~ 831 | } | ~ 832 | } | ~ 833 | | 834 | continue; | ~~~~~~~~~ 835 | } | ~ 836 | | 837 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | { | ~ 839 | if (!got_device) | ~~~~~~~~~~~~~~~~ 840 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | | 842 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 843 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 844 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 845 | | 846 | continue; | ~~~~~~~~~ 847 | } | ~ 848 | | 849 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 850 | continue; | ~~~~~~~~~ 851 | | 852 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 853 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 854 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 855 | } | ~ 856 | } | ~ 857 | | 858 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | { | ~ 860 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 861 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | | 863 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 864 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 865 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 866 | if (ch == 0) { | ~~~~~~~~~~~~~~ 867 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 868 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 869 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 870 | } else { | ~~~~~~~~ 871 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 872 | ofs << '\n'; | ~~~~~~~~~~~~ 873 | ofs << ch; | ~~~~~~~~~~ 874 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 875 | } | ~ 876 | } | ~ 877 | | 878 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 879 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | | 882 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 883 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | // info. | ~~~~~~~~ 885 | | 886 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | | 889 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 891 | { | ~ 892 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 893 | | 894 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | continue; | ~~~~~~~~~ 896 | | 897 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | | 899 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 904 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 | } | ~ 907 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector::size_type {aka unsigned int} icepack.cc:908:6: note: in expansion of macro 'error' 908 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ^~~~~ icepack.cc:908:63: note: format string is defined here 908 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'std::vector >::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | bool skip_bram_initialization; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 | | 117 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 118 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | | 120 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 121 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 123 | | 124 | // icebox i/o | ~~~~~~~~~~~~~ 125 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | | 128 | // netpbm i/o | ~~~~~~~~~~~~~ 129 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 131 | | 132 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 134 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 135 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | | 137 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 138 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140 | | 141 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 142 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 143 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 144 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | }; | ~~ 146 | | 147 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 148 | { | ~ 149 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 150 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 151 | | 152 | string tile_type; | ~~~~~~~~~~~~~~~~~ 153 | int tile_width; | ~~~~~~~~~~~~~~~ 154 | int column_width; | ~~~~~~~~~~~~~~~~~ 155 | | 156 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 157 | bool right_half; | ~~~~~~~~~~~~~~~~ 158 | bool top_half; | ~~~~~~~~~~~~~~ 159 | | 160 | int bank_num; | ~~~~~~~~~~~~~ 161 | int bank_tx; | ~~~~~~~~~~~~ 162 | int bank_ty; | ~~~~~~~~~~~~ 163 | int bank_xoff; | ~~~~~~~~~~~~~~ 164 | int bank_yoff; | ~~~~~~~~~~~~~~ 165 | | 166 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 168 | }; | ~~ 169 | | 170 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 171 | { | ~ 172 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 173 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 174 | | 175 | int bank_num; | ~~~~~~~~~~~~~ 176 | int bank_off; | ~~~~~~~~~~~~~ 177 | | 178 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 180 | }; | ~~ 181 | | 182 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 | { | ~ 184 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 | } | ~ 189 | } | ~ 190 | | 191 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 192 | { | ~ 193 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 194 | | 195 | if (byte < 0) | ~~~~~~~~~~~~~ 196 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 197 | | 198 | file_offset++; | ~~~~~~~~~~~~~~ 199 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 200 | | 201 | return byte; | ~~~~~~~~~~~~ 202 | } | ~ 203 | | 204 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 205 | { | ~ 206 | ofs << byte; | ~~~~~~~~~~~~ 207 | file_offset++; | ~~~~~~~~~~~~~~ 208 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 | } | ~ 210 | | 211 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 | { | ~ 213 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 214 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 215 | | 216 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 | | 219 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 | | 221 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 222 | | 223 | while (1) | ~~~~~~~~~ 224 | { | ~ 225 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 231 | break; | ~~~~~~ 232 | } | ~ 233 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 234 | } | ~ 235 | | 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 239 | | 240 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 241 | | 242 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 243 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 246 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 247 | | 248 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 249 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 250 | | 251 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 252 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 253 | | 254 | while (!wakeup) | ~~~~~~~~~~~~~~~ 255 | { | ~ 256 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258 | | 259 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 260 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 261 | | 262 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 264 | | 265 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 267 | | 268 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 269 | | 270 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 271 | { | ~ 272 | case 0x00: | ~~~~~~~~~~ 273 | switch (payload) | ~~~~~~~~~~~~~~~~ 274 | { | ~ 275 | case 0x01: | ~~~~~~~~~~ 276 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 | | 280 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 | | 283 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 284 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 287 | | 288 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 | } | ~ 295 | } | ~ 296 | | 297 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299 | if (end_token) | ~~~~~~~~~~~~~~ 300 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 301 | break; | ~~~~~~ 302 | | 303 | case 0x03: | ~~~~~~~~~~ 304 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 | | 308 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 310 | | 311 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 312 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 315 | | 316 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 | } | ~ 323 | } | ~ 324 | | 325 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 327 | if (end_token) | ~~~~~~~~~~~~~~ 328 | error("Expected 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 329 | break; | ~~~~~~ 330 | | 331 | case 0x05: | ~~~~~~~~~~ 332 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 333 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 334 | break; | ~~~~~~ 335 | | 336 | case 0x06: | ~~~~~~~~~~ 337 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 338 | wakeup = true; | ~~~~~~~~~~~~~~ 339 | break; | ~~~~~~ 340 | | 341 | default: | ~~~~~~~~ 342 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 343 | } | ~ 344 | break; | ~~~~~~ 345 | | 346 | case 0x10: | ~~~~~~~~~~ 347 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 348 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 349 | break; | ~~~~~~ 350 | | 351 | case 0x20: | ~~~~~~~~~~ 352 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 353 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 354 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 355 | break; | ~~~~~~ 356 | | 357 | case 0x50: | ~~~~~~~~~~ 358 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 359 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 360 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 361 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 362 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 363 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 364 | else | ~~~~ 365 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 367 | break; | ~~~~~~ 368 | | 369 | case 0x60: | ~~~~~~~~~~ 370 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 372 | break; | ~~~~~~ 373 | | 374 | case 0x70: | ~~~~~~~~~~ 375 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 377 | break; | ~~~~~~ 378 | | 379 | case 0x80: | ~~~~~~~~~~ 380 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 382 | break; | ~~~~~~ 383 | | 384 | case 0x90: | ~~~~~~~~~~ 385 | switch(payload) | ~~~~~~~~~~~~~~~ 386 | { | ~ 387 | case 0: | ~~~~~~~ 388 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 390 | break; | ~~~~~~ 391 | case 1: | ~~~~~~~ 392 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 394 | break; | ~~~~~~ 395 | case 32: | ~~~~~~~~ 396 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 398 | break; | ~~~~~~ 399 | case 33: | ~~~~~~~~ 400 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 402 | break; | ~~~~~~ 403 | default: | ~~~~~~~~ 404 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 405 | } | ~ 406 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 407 | break; | ~~~~~~ 408 | | 409 | default: | ~~~~~~~~ 410 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 411 | } | ~ 412 | } | ~ 413 | | 414 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 415 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 416 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 417 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 418 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 419 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 420 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 421 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 422 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 423 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 424 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 425 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 426 | else | ~~~~ 427 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 428 | | 429 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 430 | } | ~ 431 | | 432 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 433 | { | ~ 434 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 435 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 436 | | 437 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 439 | | 440 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 441 | ofs << byte; | ~~~~~~~~~~~~ 442 | | 443 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 448 | | 449 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 457 | else | ~~~~ 458 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 459 | | 460 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 463 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 464 | | 465 | { | ~ 466 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 467 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 470 | | 471 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 472 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 473 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 474 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 475 | else | ~~~~ 476 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 477 | | 478 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 482 | else | ~~~~ 483 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 484 | } | ~ 485 | | 486 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 495 | } | ~ 496 | | 497 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 501 | | 502 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | { | ~ 504 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 505 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 507 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 511 | | 512 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 517 | } | ~ 518 | | 519 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 522 | | 523 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 527 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 528 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 531 | } | ~ 532 | | 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 535 | } | ~ 536 | | 537 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 538 | | 539 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 540 | { | ~ 541 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 546 | } | ~ 547 | | 548 | | 549 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 553 | | 554 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 555 | { | ~ 556 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 559 | | 560 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 561 | { | ~ 562 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 563 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 565 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 566 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 569 | | 570 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 574 | | 575 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 580 | } | ~ 581 | | 582 | | 583 | if (!this->skip_bram_initialization) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 587 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 589 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 591 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 592 | } | ~ 593 | | 594 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 595 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 596 | } | ~ 597 | } | ~ 598 | } | ~ 599 | } | ~ 600 | | 601 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 604 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | | 607 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 608 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | | 611 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 612 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | } | ~ 614 | | 615 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | { | ~ 617 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 618 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 619 | | 620 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 622 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 623 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 624 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 627 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 628 | | 629 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 630 | { | ~ 631 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 632 | | 633 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 634 | is >> command; | ~~~~~~~~~~~~~~ 635 | | 636 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 637 | continue; | ~~~~~~~~~ 638 | | 639 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 | | 641 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | { | ~ 643 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 644 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 646 | | 647 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 648 | { | ~ 649 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 650 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 651 | break; | ~~~~~~ 652 | } | ~ 653 | | 654 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 655 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 656 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | } | ~ 658 | | 659 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 660 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 661 | continue; | ~~~~~~~~~ 662 | } | ~ 663 | | 664 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | { | ~ 666 | if (got_device) | ~~~~~~~~~~~~~~~ 667 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 668 | | 669 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 670 | | 671 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 672 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 673 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 674 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 675 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 676 | } else | ~~~~~~ 677 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 678 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 679 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 680 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 681 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 | } else | ~~~~~~ 683 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 685 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 686 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 688 | } else | ~~~~~~ 689 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 691 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 692 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 694 | } else | ~~~~~~ 695 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 696 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 697 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 698 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 699 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 700 | } else | ~~~~~~ 701 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 702 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 703 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 704 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 705 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 706 | } else | ~~~~~~ 707 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | | 709 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 710 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 713 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 714 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 715 | } | ~ 716 | | 717 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 718 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 721 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 722 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | } | ~ 724 | } else { | ~~~~~~~~ 725 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 727 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 728 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 729 | } | ~ 730 | | 731 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 732 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 734 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 735 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 736 | } | ~ 737 | } | ~ 738 | | 739 | | 740 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 741 | continue; | ~~~~~~~~~ 742 | } | ~ 743 | | 744 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 745 | { | ~ 746 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 747 | | 748 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 749 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 750 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 751 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 752 | | 753 | continue; | ~~~~~~~~~ 754 | } | ~ 755 | | 756 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 757 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 759 | if (nosleep) | ~~~~~~~~~~~~ 760 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 761 | else | ~~~~ 762 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 763 | | 764 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | { | ~ 766 | if (!got_device) | ~~~~~~~~~~~~~~~~ 767 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 770 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 771 | | 772 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | | 774 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 775 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 777 | | 778 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 779 | { | ~ 780 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 781 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 782 | break; | ~~~~~~ 783 | } | ~ 784 | | 785 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 789 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 790 | } | ~ 791 | } | ~ 792 | | 793 | continue; | ~~~~~~~~~ 794 | } | ~ 795 | | 796 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | { | ~ 798 | if (!got_device) | ~~~~~~~~~~~~~~~~ 799 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 802 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 803 | | 804 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 805 | | 806 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 807 | { | ~ 808 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 809 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 810 | break; | ~~~~~~ 811 | } | ~ 812 | | 813 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | { | ~ 815 | int value = -1; | ~~~~~~~~~~~~~~~ 816 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 820 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 822 | if (value < 0) | ~~~~~~~~~~~~~~ 823 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | | 825 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 828 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 829 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 830 | } | ~ 831 | } | ~ 832 | } | ~ 833 | | 834 | continue; | ~~~~~~~~~ 835 | } | ~ 836 | | 837 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | { | ~ 839 | if (!got_device) | ~~~~~~~~~~~~~~~~ 840 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | | 842 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 843 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 844 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 845 | | 846 | continue; | ~~~~~~~~~ 847 | } | ~ 848 | | 849 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 850 | continue; | ~~~~~~~~~ 851 | | 852 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 853 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 854 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 855 | } | ~ 856 | } | ~ 857 | | 858 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | { | ~ 860 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 861 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | | 863 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 864 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 865 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 866 | if (ch == 0) { | ~~~~~~~~~~~~~~ 867 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 868 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 869 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 870 | } else { | ~~~~~~~~ 871 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 872 | ofs << '\n'; | ~~~~~~~~~~~~ 873 | ofs << ch; | ~~~~~~~~~~ 874 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 875 | } | ~ 876 | } | ~ 877 | | 878 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 879 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | | 882 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 883 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | // info. | ~~~~~~~~ 885 | | 886 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | | 889 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 891 | { | ~ 892 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 893 | | 894 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | continue; | ~~~~~~~~~ 896 | | 897 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | | 899 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 904 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 | } | ~ 907 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 909 | } | ~ 910 | ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 911 | } | ~ 912 | ofs << '\n'; | ~~~~~~~~~~~~ 913 | } | ~ 914 | | 915 | if (cic.tile_type == "ramb" && !this->bram.empty()) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 916 | { | ~ 917 | BramIndexConverter bic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 918 | ofs << stringf(".ram_data %d %d\n", x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 919 | | 920 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 921 | for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 922 | int value = 0; | ~~~~~~~~~~~~~~ 923 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 924 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 925 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 926 | if (bram_x >= int(this->bram[bram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 927 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector >::size_type {aka unsigned int} icepack.cc:927:8: note: in expansion of macro 'error' 927 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ^~~~~ icepack.cc:927:62: note: format string is defined here 927 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'std::vector::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | bool skip_bram_initialization; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 | | 117 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 118 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | | 120 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 121 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 123 | | 124 | // icebox i/o | ~~~~~~~~~~~~~ 125 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | | 128 | // netpbm i/o | ~~~~~~~~~~~~~ 129 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 131 | | 132 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 134 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 135 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | | 137 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 138 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140 | | 141 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 142 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 143 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 144 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | }; | ~~ 146 | | 147 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 148 | { | ~ 149 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 150 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 151 | | 152 | string tile_type; | ~~~~~~~~~~~~~~~~~ 153 | int tile_width; | ~~~~~~~~~~~~~~~ 154 | int column_width; | ~~~~~~~~~~~~~~~~~ 155 | | 156 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 157 | bool right_half; | ~~~~~~~~~~~~~~~~ 158 | bool top_half; | ~~~~~~~~~~~~~~ 159 | | 160 | int bank_num; | ~~~~~~~~~~~~~ 161 | int bank_tx; | ~~~~~~~~~~~~ 162 | int bank_ty; | ~~~~~~~~~~~~ 163 | int bank_xoff; | ~~~~~~~~~~~~~~ 164 | int bank_yoff; | ~~~~~~~~~~~~~~ 165 | | 166 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 168 | }; | ~~ 169 | | 170 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 171 | { | ~ 172 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 173 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 174 | | 175 | int bank_num; | ~~~~~~~~~~~~~ 176 | int bank_off; | ~~~~~~~~~~~~~ 177 | | 178 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 180 | }; | ~~ 181 | | 182 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 | { | ~ 184 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 | } | ~ 189 | } | ~ 190 | | 191 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 192 | { | ~ 193 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 194 | | 195 | if (byte < 0) | ~~~~~~~~~~~~~ 196 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 197 | | 198 | file_offset++; | ~~~~~~~~~~~~~~ 199 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 200 | | 201 | return byte; | ~~~~~~~~~~~~ 202 | } | ~ 203 | | 204 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 205 | { | ~ 206 | ofs << byte; | ~~~~~~~~~~~~ 207 | file_offset++; | ~~~~~~~~~~~~~~ 208 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 | } | ~ 210 | | 211 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 | { | ~ 213 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 214 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 215 | | 216 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 | | 219 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 | | 221 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 222 | | 223 | while (1) | ~~~~~~~~~ 224 | { | ~ 225 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 231 | break; | ~~~~~~ 232 | } | ~ 233 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 234 | } | ~ 235 | | 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 239 | | 240 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 241 | | 242 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 243 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 246 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 247 | | 248 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 249 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 250 | | 251 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 252 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 253 | | 254 | while (!wakeup) | ~~~~~~~~~~~~~~~ 255 | { | ~ 256 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258 | | 259 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 260 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 261 | | 262 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 264 | | 265 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 267 | | 268 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 269 | | 270 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 271 | { | ~ 272 | case 0x00: | ~~~~~~~~~~ 273 | switch (payload) | ~~~~~~~~~~~~~~~~ 274 | { | ~ 275 | case 0x01: | ~~~~~~~~~~ 276 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 | | 280 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 | | 283 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 284 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 287 | | 288 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 | } | ~ 295 | } | ~ 296 | | 297 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299 | if (end_token) | ~~~~~~~~~~~~~~ 300 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 301 | break; | ~~~~~~ 302 | | 303 | case 0x03: | ~~~~~~~~~~ 304 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 | | 308 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 310 | | 311 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 312 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 315 | | 316 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 | } | ~ 323 | } | ~ 324 | | 325 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 327 | if (end_token) | ~~~~~~~~~~~~~~ 328 | error("Expected 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 329 | break; | ~~~~~~ 330 | | 331 | case 0x05: | ~~~~~~~~~~ 332 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 333 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 334 | break; | ~~~~~~ 335 | | 336 | case 0x06: | ~~~~~~~~~~ 337 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 338 | wakeup = true; | ~~~~~~~~~~~~~~ 339 | break; | ~~~~~~ 340 | | 341 | default: | ~~~~~~~~ 342 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 343 | } | ~ 344 | break; | ~~~~~~ 345 | | 346 | case 0x10: | ~~~~~~~~~~ 347 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 348 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 349 | break; | ~~~~~~ 350 | | 351 | case 0x20: | ~~~~~~~~~~ 352 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 353 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 354 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 355 | break; | ~~~~~~ 356 | | 357 | case 0x50: | ~~~~~~~~~~ 358 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 359 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 360 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 361 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 362 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 363 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 364 | else | ~~~~ 365 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 367 | break; | ~~~~~~ 368 | | 369 | case 0x60: | ~~~~~~~~~~ 370 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 372 | break; | ~~~~~~ 373 | | 374 | case 0x70: | ~~~~~~~~~~ 375 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 377 | break; | ~~~~~~ 378 | | 379 | case 0x80: | ~~~~~~~~~~ 380 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 382 | break; | ~~~~~~ 383 | | 384 | case 0x90: | ~~~~~~~~~~ 385 | switch(payload) | ~~~~~~~~~~~~~~~ 386 | { | ~ 387 | case 0: | ~~~~~~~ 388 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 390 | break; | ~~~~~~ 391 | case 1: | ~~~~~~~ 392 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 394 | break; | ~~~~~~ 395 | case 32: | ~~~~~~~~ 396 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 398 | break; | ~~~~~~ 399 | case 33: | ~~~~~~~~ 400 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 402 | break; | ~~~~~~ 403 | default: | ~~~~~~~~ 404 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 405 | } | ~ 406 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 407 | break; | ~~~~~~ 408 | | 409 | default: | ~~~~~~~~ 410 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 411 | } | ~ 412 | } | ~ 413 | | 414 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 415 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 416 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 417 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 418 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 419 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 420 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 421 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 422 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 423 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 424 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 425 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 426 | else | ~~~~ 427 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 428 | | 429 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 430 | } | ~ 431 | | 432 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 433 | { | ~ 434 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 435 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 436 | | 437 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 439 | | 440 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 441 | ofs << byte; | ~~~~~~~~~~~~ 442 | | 443 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 448 | | 449 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 457 | else | ~~~~ 458 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 459 | | 460 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 463 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 464 | | 465 | { | ~ 466 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 467 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 470 | | 471 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 472 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 473 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 474 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 475 | else | ~~~~ 476 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 477 | | 478 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 482 | else | ~~~~ 483 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 484 | } | ~ 485 | | 486 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 495 | } | ~ 496 | | 497 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 501 | | 502 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | { | ~ 504 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 505 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 507 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 511 | | 512 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 517 | } | ~ 518 | | 519 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 522 | | 523 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 527 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 528 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 531 | } | ~ 532 | | 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 535 | } | ~ 536 | | 537 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 538 | | 539 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 540 | { | ~ 541 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 546 | } | ~ 547 | | 548 | | 549 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 553 | | 554 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 555 | { | ~ 556 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 559 | | 560 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 561 | { | ~ 562 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 563 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 565 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 566 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 569 | | 570 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 574 | | 575 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 580 | } | ~ 581 | | 582 | | 583 | if (!this->skip_bram_initialization) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 587 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 589 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 591 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 592 | } | ~ 593 | | 594 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 595 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 596 | } | ~ 597 | } | ~ 598 | } | ~ 599 | } | ~ 600 | | 601 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 604 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | | 607 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 608 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | | 611 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 612 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | } | ~ 614 | | 615 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | { | ~ 617 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 618 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 619 | | 620 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 622 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 623 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 624 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 627 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 628 | | 629 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 630 | { | ~ 631 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 632 | | 633 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 634 | is >> command; | ~~~~~~~~~~~~~~ 635 | | 636 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 637 | continue; | ~~~~~~~~~ 638 | | 639 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 | | 641 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | { | ~ 643 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 644 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 646 | | 647 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 648 | { | ~ 649 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 650 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 651 | break; | ~~~~~~ 652 | } | ~ 653 | | 654 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 655 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 656 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | } | ~ 658 | | 659 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 660 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 661 | continue; | ~~~~~~~~~ 662 | } | ~ 663 | | 664 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | { | ~ 666 | if (got_device) | ~~~~~~~~~~~~~~~ 667 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 668 | | 669 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 670 | | 671 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 672 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 673 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 674 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 675 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 676 | } else | ~~~~~~ 677 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 678 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 679 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 680 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 681 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 | } else | ~~~~~~ 683 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 685 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 686 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 688 | } else | ~~~~~~ 689 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 691 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 692 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 694 | } else | ~~~~~~ 695 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 696 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 697 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 698 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 699 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 700 | } else | ~~~~~~ 701 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 702 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 703 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 704 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 705 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 706 | } else | ~~~~~~ 707 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | | 709 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 710 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 713 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 714 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 715 | } | ~ 716 | | 717 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 718 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 721 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 722 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | } | ~ 724 | } else { | ~~~~~~~~ 725 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 727 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 728 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 729 | } | ~ 730 | | 731 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 732 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 734 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 735 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 736 | } | ~ 737 | } | ~ 738 | | 739 | | 740 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 741 | continue; | ~~~~~~~~~ 742 | } | ~ 743 | | 744 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 745 | { | ~ 746 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 747 | | 748 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 749 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 750 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 751 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 752 | | 753 | continue; | ~~~~~~~~~ 754 | } | ~ 755 | | 756 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 757 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 759 | if (nosleep) | ~~~~~~~~~~~~ 760 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 761 | else | ~~~~ 762 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 763 | | 764 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | { | ~ 766 | if (!got_device) | ~~~~~~~~~~~~~~~~ 767 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 770 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 771 | | 772 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | | 774 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 775 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 777 | | 778 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 779 | { | ~ 780 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 781 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 782 | break; | ~~~~~~ 783 | } | ~ 784 | | 785 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 789 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 790 | } | ~ 791 | } | ~ 792 | | 793 | continue; | ~~~~~~~~~ 794 | } | ~ 795 | | 796 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | { | ~ 798 | if (!got_device) | ~~~~~~~~~~~~~~~~ 799 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 802 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 803 | | 804 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 805 | | 806 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 807 | { | ~ 808 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 809 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 810 | break; | ~~~~~~ 811 | } | ~ 812 | | 813 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | { | ~ 815 | int value = -1; | ~~~~~~~~~~~~~~~ 816 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 820 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 822 | if (value < 0) | ~~~~~~~~~~~~~~ 823 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | | 825 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 828 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 829 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 830 | } | ~ 831 | } | ~ 832 | } | ~ 833 | | 834 | continue; | ~~~~~~~~~ 835 | } | ~ 836 | | 837 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | { | ~ 839 | if (!got_device) | ~~~~~~~~~~~~~~~~ 840 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | | 842 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 843 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 844 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 845 | | 846 | continue; | ~~~~~~~~~ 847 | } | ~ 848 | | 849 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 850 | continue; | ~~~~~~~~~ 851 | | 852 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 853 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 854 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 855 | } | ~ 856 | } | ~ 857 | | 858 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | { | ~ 860 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 861 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | | 863 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 864 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 865 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 866 | if (ch == 0) { | ~~~~~~~~~~~~~~ 867 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 868 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 869 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 870 | } else { | ~~~~~~~~ 871 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 872 | ofs << '\n'; | ~~~~~~~~~~~~ 873 | ofs << ch; | ~~~~~~~~~~ 874 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 875 | } | ~ 876 | } | ~ 877 | | 878 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 879 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | | 882 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 883 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | // info. | ~~~~~~~~ 885 | | 886 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | | 889 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 891 | { | ~ 892 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 893 | | 894 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | continue; | ~~~~~~~~~ 896 | | 897 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | | 899 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 904 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 | } | ~ 907 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 909 | } | ~ 910 | ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 911 | } | ~ 912 | ofs << '\n'; | ~~~~~~~~~~~~ 913 | } | ~ 914 | | 915 | if (cic.tile_type == "ramb" && !this->bram.empty()) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 916 | { | ~ 917 | BramIndexConverter bic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 918 | ofs << stringf(".ram_data %d %d\n", x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 919 | | 920 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 921 | for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 922 | int value = 0; | ~~~~~~~~~~~~~~ 923 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 924 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 925 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 926 | if (bram_x >= int(this->bram[bram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 927 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 928 | break; | ~~~~~~ 929 | } | ~ 930 | if (bram_y >= int(this->bram[bram_bank][bram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 931 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector::size_type {aka unsigned int} icepack.cc:931:8: note: in expansion of macro 'error' 931 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ^~~~~ icepack.cc:931:56: note: format string is defined here 931 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ~~^ | | | long unsigned int | %u g++ -o icemulti -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icemulti.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' make -C icetime all make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o icetime.o icetime.cc mv chipdb-384.new chipdb-384.txt python3 icebox_chipdb.py > chipdb-1k.new g++ -o icebram -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icebram.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' make -C iceprog all make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' cc -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c99 -I/usr/local/include -O2 -Wall -std=c99 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o iceprog.o iceprog.c cc -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c99 -I/usr/local/include -O2 -Wall -std=c99 -I/usr/local/include -Wdate-time -D_FORTIFY_SOURCE=2 -c -o mpsse.o mpsse.c cc -o iceprog -Wl,-z,relro -Wl,-z,now -Wl,--as-needed iceprog.o mpsse.o -L/usr/local/lib -lm -lftdi make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' python3 icebox_chipdb.py -8 > chipdb-8k.new g++ -o icepack -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icepack.o -lm -lstdc++ ln -sf icepack iceunpack make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o iceutil.o iceutil.cc python3 timings.py lp384 > timings-lp384.cc python3 timings.py lp1k > timings-lp1k.cc python3 timings.py lp8k > timings-lp8k.cc python3 timings.py hx1k > timings-hx1k.cc python3 timings.py hx8k > timings-hx8k.cc python3 timings.py up5k > timings-up5k.cc g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-lp384.o timings-lp384.cc g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-lp1k.o timings-lp1k.cc g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-lp8k.o timings-lp8k.cc g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-hx1k.o timings-hx1k.cc g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-hx8k.o timings-hx8k.cc In file included from /usr/include/c++/10/vector:72, from icetime.cc:35: /usr/include/c++/10/bits/vector.tcc: In member function 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::pair, std::allocator > >}; _Tp = std::pair >; _Alloc = std::allocator > >]': /usr/include/c++/10/bits/vector.tcc:426:7: note: parameter passing for argument of type 'std::vector > >::iterator' changed in GCC 7.1 426 | vector<_Tp, _Alloc>:: | ^~~~~~~~~~~~~~~~~~~ /usr/include/c++/10/bits/vector.tcc:426:7: note: parameter passing for argument of type 'std::vector > >::iterator' changed in GCC 7.1 g++ -g -O2 -fdebug-prefix-map=/build/fpga-icestorm-0~20190913git0ec00d8=. -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -std=c++11 -I/usr/local/include -O2 -Wall -std=c++11 -I/usr/local/include -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -Wdate-time -D_FORTIFY_SOURCE=2 -c -o timings-up5k.o timings-up5k.cc mv chipdb-1k.new chipdb-1k.txt python3 icebox_chipdb.py -5 > chipdb-5k.new In file included from /usr/include/c++/10/map:60, from icetime.cc:31: /usr/include/c++/10/bits/stl_tree.h: In member function 'std::pair std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const key_type&) [with _Key = std::__cxx11::basic_string; _Val = std::pair, double>; _KeyOfValue = std::_Select1st, double> >; _Compare = std::less >; _Alloc = std::allocator, double> >]': /usr/include/c++/10/bits/stl_tree.h:2193:5: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' changed in GCC 7.1 2193 | _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/10/bits/stl_tree.h: In member function 'std::pair std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const key_type&) [with _Key = std::__cxx11::basic_string; _Val = std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> >; _KeyOfValue = std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > >; _Compare = std::less >; _Alloc = std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > >]': /usr/include/c++/10/bits/stl_tree.h:2193:5: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > > >::const_iterator' changed in GCC 7.1 /usr/include/c++/10/bits/stl_tree.h: In member function 'std::pair std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const key_type&) [with _Key = std::__cxx11::basic_string; _Val = std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >; _KeyOfValue = std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >; _Compare = std::less >; _Alloc = std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >]': /usr/include/c++/10/bits/stl_tree.h:2193:5: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 /usr/include/c++/10/bits/stl_tree.h: In function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple, std::allocator >&>, std::tuple<>}; _Key = std::__cxx11::basic_string; _Val = std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >; _KeyOfValue = std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >; _Compare = std::less >; _Alloc = std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >]': /usr/include/c++/10/bits/stl_tree.h:2458:7: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 2458 | _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/10/bits/stl_tree.h:2458:7: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 In file included from /usr/include/c++/10/map:61, from icetime.cc:31: /usr/include/c++/10/bits/stl_map.h: In member function 'double TimingAnalysis::report(std::string)': /usr/include/c++/10/bits/stl_map.h:501:37: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 501 | __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | std::tuple(__k), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | std::tuple<>()); | ~~~~~~~~~~~~~~~ In file included from /usr/include/c++/10/vector:72, from icetime.cc:35: /usr/include/c++/10/bits/vector.tcc:121:21: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator >*, std::vector > > >' changed in GCC 7.1 121 | _M_realloc_insert(end(), std::forward<_Args>(__args)...); | ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/10/map:61, from icetime.cc:31: /usr/include/c++/10/bits/stl_map.h: In constructor 'TimingAnalysis::TimingAnalysis(bool)': /usr/include/c++/10/bits/stl_map.h:501:37: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 501 | __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | std::tuple(__k), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | std::tuple<>()); | ~~~~~~~~~~~~~~~ /usr/include/c++/10/bits/stl_map.h:501:37: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 501 | __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | std::tuple(__k), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | std::tuple<>()); | ~~~~~~~~~~~~~~~ /usr/include/c++/10/bits/stl_map.h:501:37: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > >, std::_Select1st, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >, std::less >, std::allocator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > > >::const_iterator' changed in GCC 7.1 501 | __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | std::tuple(__k), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 503 | std::tuple<>()); | ~~~~~~~~~~~~~~~ python3 icebox_chipdb.py -4 > chipdb-lm4k.new mv chipdb-5k.new chipdb-5k.txt python3 icebox_chipdb.py -u > chipdb-u4k.new mv chipdb-lm4k.new chipdb-lm4k.txt mv chipdb-8k.new chipdb-8k.txt mv chipdb-u4k.new chipdb-u4k.txt make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' g++ -o icetime -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icetime.o iceutil.o timings-lp384.o timings-lp1k.o timings-lp8k.o timings-hx1k.o timings-hx8k.o timings-up5k.o -lm -lstdc++ rm timings-lp8k.cc timings-hx1k.cc timings-up5k.cc timings-lp384.cc timings-lp1k.cc timings-hx8k.cc make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' make[1]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' dh_auto_test create-stamp debian/debhelper-build-stamp fakeroot debian/rules binary dh binary dh_testroot dh_prep debian/rules override_dh_auto_install make[1]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' PREFIX=/usr dh_auto_install make -j4 install DESTDIR=/build/fpga-icestorm-0\~20190913git0ec00d8/debian/tmp AM_UPDATE_INFO_DIR=no "INSTALL=install --strip-program=true" make[2]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' for dir in icebox icepack icemulti icepll icebram icetime iceprog; do \ make -C $dir install || exit; \ done make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python cp chipdb-384.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-1k.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-8k.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-5k.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-u4k.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-lm4k.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp icebox.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox.py cp iceboxdb.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/iceboxdb.py cp icebox_chipdb.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_chipdb cp icebox_diff.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_diff cp icebox_explain.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_explain cp icebox_asc2hlc.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_asc2hlc cp icebox_hlc2asc.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_hlc2asc cp icebox_colbuf.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_colbuf cp icebox_html.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_html cp icebox_maps.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_maps cp icebox_vlog.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_vlog cp icebox_stat.py /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/python/icebox_stat make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebox' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin cp icepack /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/icepack ln -sf icepack /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/iceunpack make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepack' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin cp icemulti /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/icemulti make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icemulti' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin cp icepll /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/icepll make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icepll' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin cp icebram /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/icebram make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icebram' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/icebox cp icetime /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/icetime cp ../icefuzz/timings_*.txt /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/share/fpga-icestorm/chipdb/ make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/icetime' make[3]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' mkdir -p /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin cp iceprog /build/fpga-icestorm-0~20190913git0ec00d8/debian/tmp/usr/bin/iceprog make[3]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8/iceprog' make[2]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' make[1]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' dh_install dh_installdocs dh_installchangelogs debian/rules override_dh_installman make[1]: Entering directory '/build/fpga-icestorm-0~20190913git0ec00d8' cd debian/man ; CHANGELOG_DATE="13 October 2020" ./genmanpages.sh dh_installman make[1]: Leaving directory '/build/fpga-icestorm-0~20190913git0ec00d8' dh_perl dh_link dh_strip_nondeterminism dh_compress dh_fixperms dh_missing dh_dwz dh_strip dh_makeshlibs dh_shlibdeps dpkg-shlibdeps: warning: debian/fpga-icestorm/usr/bin/icebram contains an unresolvable reference to symbol __aeabi_atexit@CXXABI_ARM_1.3.3: it's probably a plugin dpkg-shlibdeps: warning: debian/fpga-icestorm/usr/bin/icemulti contains an unresolvable reference to symbol __aeabi_atexit@CXXABI_ARM_1.3.3: it's probably a plugin dpkg-shlibdeps: warning: debian/fpga-icestorm/usr/bin/icepack contains an unresolvable reference to symbol __aeabi_atexit@CXXABI_ARM_1.3.3: it's probably a plugin dpkg-shlibdeps: warning: debian/fpga-icestorm/usr/bin/icetime contains an unresolvable reference to symbol __aeabi_atexit@CXXABI_ARM_1.3.3: it's probably a plugin dh_installdeb dh_gencontrol dh_md5sums dh_builddeb dpkg-deb: building package 'fpga-icestorm-chipdb' in '../fpga-icestorm-chipdb_0~20190913git0ec00d8-2_all.deb'. dpkg-deb: building package 'fpga-icestorm-dbgsym' in '../fpga-icestorm-dbgsym_0~20190913git0ec00d8-2_armhf.deb'. dpkg-deb: building package 'fpga-icestorm' in '../fpga-icestorm_0~20190913git0ec00d8-2_armhf.deb'. dpkg-genbuildinfo --build=binary dpkg-genchanges --build=binary >../fpga-icestorm_0~20190913git0ec00d8-2_armhf.changes dpkg-genchanges: info: binary-only upload (no source code included) dpkg-source --after-build . dpkg-buildpackage: info: binary-only upload (no source included) dpkg-genchanges: info: not including original source code in upload I: copying local configuration I: user script /srv/workspace/pbuilder/11574/tmp/hooks/B01_cleanup starting I: user script /srv/workspace/pbuilder/11574/tmp/hooks/B01_cleanup finished I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem I: unmounting dev/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env I: removing directory /srv/workspace/pbuilder/11574 and its subdirectories I: Current time: Fri Aug 13 07:02:45 +14 2021 I: pbuilder-time-stamp: 1628787765