Sun Jul 19 07:07:02 UTC 2020 I: starting to build fpga-icestorm/buster/armhf on jenkins on '2020-07-19 07:06' Sun Jul 19 07:07:02 UTC 2020 I: The jenkins build log is/was available at https://jenkins.debian.net/userContent/reproducible/debian/build_service/armhf_54/933/console.log Sun Jul 19 07:07:02 UTC 2020 I: Downloading source for buster/fpga-icestorm=0~20181109git9671b76-1 --2020-07-19 07:07:03-- http://deb.debian.org/debian/pool/main/f/fpga-icestorm/fpga-icestorm_0~20181109git9671b76-1.dsc Connecting to 78.137.99.97:3128... connected. Proxy request sent, awaiting response... 200 OK Length: 2404 (2.3K) Saving to: ‘fpga-icestorm_0~20181109git9671b76-1.dsc’ 0K .. 100% 109M=0s 2020-07-19 07:07:03 (109 MB/s) - ‘fpga-icestorm_0~20181109git9671b76-1.dsc’ saved [2404/2404] Sun Jul 19 07:07:03 UTC 2020 I: fpga-icestorm_0~20181109git9671b76-1.dsc -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Format: 3.0 (quilt) Source: fpga-icestorm Binary: fpga-icestorm-chipdb, fpga-icestorm Architecture: any all Version: 0~20181109git9671b76-1 Maintainer: Debian Electronics Team Uploaders: Ruben Undheim Homepage: http://www.clifford.at/icestorm/ Standards-Version: 4.2.1 Vcs-Browser: https://salsa.debian.org/electronics-team/fpga-icestorm Vcs-Git: https://salsa.debian.org/electronics-team/fpga-icestorm.git Testsuite: autopkgtest Build-Depends: debhelper (>= 11), libftdi-dev, python3, txt2man, pkg-config Package-List: fpga-icestorm deb electronics optional arch=any fpga-icestorm-chipdb deb electronics optional arch=all Checksums-Sha1: 30c33d8a08e6a4fe050dbee8bc639bc45c6925a7 421980 fpga-icestorm_0~20181109git9671b76.orig.tar.xz cf8340ae472d114f189823e277e428ddc6a09aa3 9280 fpga-icestorm_0~20181109git9671b76-1.debian.tar.xz Checksums-Sha256: b3bf5667d873a0ec3cd6ee950caf9394bc890357e2b9a4b453df2ee9c4cf0e49 421980 fpga-icestorm_0~20181109git9671b76.orig.tar.xz 571bd712cb64ea5becfd75f9d94bcbdfda04d249bd9e743f5f6f8bcbd023dfc4 9280 fpga-icestorm_0~20181109git9671b76-1.debian.tar.xz Files: 0389037d18b5a3a506e5b5dfc6767107 421980 fpga-icestorm_0~20181109git9671b76.orig.tar.xz c03ed6f52ec9a514070617da27d210a0 9280 fpga-icestorm_0~20181109git9671b76-1.debian.tar.xz Dgit: 90ffc6a593201e4f772252727b8cafce2a7cbff9 debian archive/debian/0_20181109git9671b76-1 https://git.dgit.debian.org/fpga-icestorm -----BEGIN PGP SIGNATURE----- iQJMBAEBCgA2FiEETeTfPeKePuppVOXOGnb1/BKWi3kFAlwbanoYHHJ1YmVuLnVu ZGhlaW1AZ21haWwuY29tAAoJEBp29fwSlot5b4UQAIwNGzrh4eRBoZke8RL0+O1G 7ob/nMLs/EDomwo/zivcbKVWR9NwNBGvK5Frah/Qsw/JI6dt3uHnZGlPwLbAB6vp LVbqDpYmXBloi4xMUP54HU+RS9WB8YFfKqlT+uWhQlHqK6ygug7PfDD4+u5gvgRJ 5EInK6f51HfAJZVSl7XnK4laO40Ch48ag60/4hYHxQ9JmoxN/cmGtgFABiVm/xia KqPRcWKZCdRBplF/GPExGoYQmcxNZmQnUZbewZLQ4ICVGaVMiuVa9uqtEWoRxIUw ENI0BiDG+7peQ74UXjlbC6QpsZiBEIuxwxGjmep01K1VZc+WJ4/VtWEeTVk/9zGs rihASlwR+3TuI1vVusFhCpuA7iXSvFni4zUslOA+TMGUlU8Sh7znAykVsKSjqmUi kYfBL69UUWBXIXxYzZreL+crZnXNNNWrs4rgGOyCcIPU899lxmYg6FCYddXL2MHP wzFNRcI0FzTWVvmjJZDfPwUeOPMUQQuWcgvRJY9KmRQ4rWzZHd8NOXs1wMWYehBY a6ulvyIsgY8DqmIBLvgzWgznFjgu96GjwFQtWsyHBrS8t91fFNfFOdGZH3nrpaXi Nevn/OO1PrE/X3vrt4o3OiZ62BvSyV8u0vKh+RbDQ0lcsK0aDCIxY6rCtUq5wodf UPHwzlNAzYC8VLJckZFZ =lkAC -----END PGP SIGNATURE----- Sun Jul 19 07:07:03 UTC 2020 I: Checking whether the package is not for us Sun Jul 19 07:07:03 UTC 2020 I: Starting 1st build on remote node jtk1a-armhf-rb.debian.net. Sun Jul 19 07:07:03 UTC 2020 I: Preparing to do remote build '1' on jtk1a-armhf-rb.debian.net. Sun Jul 19 08:20:31 UTC 2020 I: Deleting $TMPDIR on jtk1a-armhf-rb.debian.net. I: pbuilder: network access will be disabled during build I: Current time: Sat Jul 18 19:07:16 -12 2020 I: pbuilder-time-stamp: 1595142436 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/buster-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~20181109git9671b76-1.dsc] I: copying [./fpga-icestorm_0~20181109git9671b76.orig.tar.xz] I: copying [./fpga-icestorm_0~20181109git9671b76-1.debian.tar.xz] I: Extracting source gpgv: unknown type of key resource 'trustedkeys.kbx' gpgv: keyblock resource '/root/.gnupg/trustedkeys.kbx': General error gpgv: Signature made Wed Dec 19 22:10:02 2018 -12 gpgv: using RSA key 4DE4DF3DE29E3EEA6954E5CE1A76F5FC12968B79 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~20181109git9671b76-1.dsc dpkg-source: info: extracting fpga-icestorm in fpga-icestorm-0~20181109git9671b76 dpkg-source: info: unpacking fpga-icestorm_0~20181109git9671b76.orig.tar.xz dpkg-source: info: unpacking fpga-icestorm_0~20181109git9671b76-1.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 I: using fakeroot in build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/22101/tmp/hooks/D02_print_environment starting I: set BUILDDIR='/build' BUILDUSERGECOS='first user,first room,first work-phone,first home-phone,first other' BUILDUSERNAME='pbuilder1' BUILD_ARCH='armhf' DEBIAN_FRONTEND='noninteractive' DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=3' DISTRIBUTION='' HOME='/root' HOST_ARCH='armhf' IFS=' ' INVOCATION_ID='daacf4630a594768b38355d3fa2f5421' LANG='C' LANGUAGE='en_US:en' LC_ALL='C' MAIL='/var/mail/root' OPTIND='1' PATH='/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' PBCURRENTCOMMANDLINEOPERATION='build' PBUILDER_OPERATION='build' PBUILDER_PKGDATADIR='/usr/share/pbuilder' PBUILDER_PKGLIBDIR='/usr/lib/pbuilder' PBUILDER_SYSCONFDIR='/etc' PPID='22101' PS1='# ' PS2='> ' PS4='+ ' PWD='/' SHELL='/bin/bash' SHLVL='2' SUDO_COMMAND='/usr/bin/timeout -k 18.1h 18h /usr/bin/ionice -c 3 /usr/bin/nice /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/pbuilderrc_L1Xd --hookdir /etc/pbuilder/first-build-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/buster-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/b1 --logfile b1/build.log fpga-icestorm_0~20181109git9671b76-1.dsc' SUDO_GID='113' SUDO_UID='107' SUDO_USER='jenkins' TERM='unknown' TZ='/usr/share/zoneinfo/Etc/GMT+12' USER='root' _='/usr/bin/systemd-run' http_proxy='http://10.0.0.15:8000/' I: uname -a Linux jtk1a 4.19.0-9-armmp-lpae #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) armv7l GNU/Linux I: ls -l /bin total 3328 -rwxr-xr-x 1 root root 767656 Apr 17 2019 bash -rwxr-xr-x 3 root root 26052 Jul 10 2019 bunzip2 -rwxr-xr-x 3 root root 26052 Jul 10 2019 bzcat lrwxrwxrwx 1 root root 6 Jul 10 2019 bzcmp -> bzdiff -rwxr-xr-x 1 root root 2227 Jul 10 2019 bzdiff lrwxrwxrwx 1 root root 6 Jul 10 2019 bzegrep -> bzgrep -rwxr-xr-x 1 root root 4877 Jun 24 2019 bzexe lrwxrwxrwx 1 root root 6 Jul 10 2019 bzfgrep -> bzgrep -rwxr-xr-x 1 root root 3641 Jul 10 2019 bzgrep -rwxr-xr-x 3 root root 26052 Jul 10 2019 bzip2 -rwxr-xr-x 1 root root 9636 Jul 10 2019 bzip2recover lrwxrwxrwx 1 root root 6 Jul 10 2019 bzless -> bzmore -rwxr-xr-x 1 root root 1297 Jul 10 2019 bzmore -rwxr-xr-x 1 root root 22432 Feb 28 2019 cat -rwxr-xr-x 1 root root 38868 Feb 28 2019 chgrp -rwxr-xr-x 1 root root 38836 Feb 28 2019 chmod -rwxr-xr-x 1 root root 42972 Feb 28 2019 chown -rwxr-xr-x 1 root root 88376 Feb 28 2019 cp -rwxr-xr-x 1 root root 75516 Jan 17 2019 dash -rwxr-xr-x 1 root root 71648 Feb 28 2019 date -rwxr-xr-x 1 root root 51212 Feb 28 2019 dd -rwxr-xr-x 1 root root 55672 Feb 28 2019 df -rwxr-xr-x 1 root root 88444 Feb 28 2019 dir -rwxr-xr-x 1 root root 54872 Jan 9 2019 dmesg lrwxrwxrwx 1 root root 8 Sep 26 2018 dnsdomainname -> hostname lrwxrwxrwx 1 root root 8 Sep 26 2018 domainname -> hostname -rwxr-xr-x 1 root root 22364 Feb 28 2019 echo -rwxr-xr-x 1 root root 28 Jan 7 2019 egrep -rwxr-xr-x 1 root root 18260 Feb 28 2019 false -rwxr-xr-x 1 root root 28 Jan 7 2019 fgrep -rwxr-xr-x 1 root root 47356 Jan 9 2019 findmnt -rwsr-xr-x 1 root root 21980 Apr 22 07:38 fusermount -rwxr-xr-x 1 root root 124508 Jan 7 2019 grep -rwxr-xr-x 2 root root 2345 Jan 5 2019 gunzip -rwxr-xr-x 1 root root 6375 Jan 5 2019 gzexe -rwxr-xr-x 1 root root 64232 Jan 5 2019 gzip -rwxr-xr-x 1 root root 13784 Sep 26 2018 hostname -rwxr-xr-x 1 root root 43044 Feb 28 2019 ln -rwxr-xr-x 1 root root 34932 Jul 26 2018 login -rwxr-xr-x 1 root root 88444 Feb 28 2019 ls -rwxr-xr-x 1 root root 67036 Jan 9 2019 lsblk -rwxr-xr-x 1 root root 47168 Feb 28 2019 mkdir -rwxr-xr-x 1 root root 43040 Feb 28 2019 mknod -rwxr-xr-x 1 root root 26552 Feb 28 2019 mktemp -rwxr-xr-x 1 root root 26024 Jan 9 2019 more -rwsr-xr-x 1 root root 34268 Jan 9 2019 mount -rwxr-xr-x 1 root root 9688 Jan 9 2019 mountpoint -rwxr-xr-x 1 root root 84284 Feb 28 2019 mv lrwxrwxrwx 1 root root 8 Sep 26 2018 nisdomainname -> hostname lrwxrwxrwx 1 root root 14 Feb 14 2019 pidof -> /sbin/killall5 -rwxr-xr-x 1 root root 22416 Feb 28 2019 pwd lrwxrwxrwx 1 root root 4 Apr 17 2019 rbash -> bash -rwxr-xr-x 1 root root 26504 Feb 28 2019 readlink -rwxr-xr-x 1 root root 42968 Feb 28 2019 rm -rwxr-xr-x 1 root root 26496 Feb 28 2019 rmdir -rwxr-xr-x 1 root root 14136 Jan 21 2019 run-parts -rwxr-xr-x 1 root root 76012 Dec 22 2018 sed lrwxrwxrwx 1 root root 4 Jul 15 20:28 sh -> dash -rwxr-xr-x 1 root root 22384 Feb 28 2019 sleep -rwxr-xr-x 1 root root 51124 Feb 28 2019 stty -rwsr-xr-x 1 root root 42472 Jan 9 2019 su -rwxr-xr-x 1 root root 22392 Feb 28 2019 sync -rwxr-xr-x 1 root root 283324 Apr 23 2019 tar -rwxr-xr-x 1 root root 9808 Jan 21 2019 tempfile -rwxr-xr-x 1 root root 63464 Feb 28 2019 touch -rwxr-xr-x 1 root root 18260 Feb 28 2019 true -rwxr-xr-x 1 root root 9636 Apr 22 07:38 ulockmgr_server -rwsr-xr-x 1 root root 21976 Jan 9 2019 umount -rwxr-xr-x 1 root root 22380 Feb 28 2019 uname -rwxr-xr-x 2 root root 2345 Jan 5 2019 uncompress -rwxr-xr-x 1 root root 88444 Feb 28 2019 vdir -rwxr-xr-x 1 root root 21980 Jan 9 2019 wdctl -rwxr-xr-x 1 root root 946 Jan 21 2019 which lrwxrwxrwx 1 root root 8 Sep 26 2018 ypdomainname -> hostname -rwxr-xr-x 1 root root 1983 Jan 5 2019 zcat -rwxr-xr-x 1 root root 1677 Jan 5 2019 zcmp -rwxr-xr-x 1 root root 5879 Jan 5 2019 zdiff -rwxr-xr-x 1 root root 29 Jan 5 2019 zegrep -rwxr-xr-x 1 root root 29 Jan 5 2019 zfgrep -rwxr-xr-x 1 root root 2080 Jan 5 2019 zforce -rwxr-xr-x 1 root root 7584 Jan 5 2019 zgrep -rwxr-xr-x 1 root root 2205 Jan 5 2019 zless -rwxr-xr-x 1 root root 1841 Jan 5 2019 zmore -rwxr-xr-x 1 root root 4552 Jan 5 2019 znew I: user script /srv/workspace/pbuilder/22101/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 (>= 11), 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 ... 18932 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 (>= 11); however: Package debhelper 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} bsdmainutils{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} libbsd0{a} libcroco3{a} libelf1{a} libexpat1{a} libfile-stripnondeterminism-perl{a} libftdi-dev{a} libftdi1{a} libglib2.0-0{a} libicu63{a} libmagic-mgc{a} libmagic1{a} libmpdec2{a} libncurses6{a} libpipeline1{a} libpython3-stdlib{a} libpython3.7-minimal{a} libpython3.7-stdlib{a} libreadline7{a} libsigsegv2{a} libssl1.1{a} libtool{a} libuchardet0{a} libusb-0.1-4{a} libusb-dev{a} libxml2{a} m4{a} man-db{a} mime-support{a} pkg-config{a} po-debconf{a} python3{a} python3-minimal{a} python3.7{a} python3.7-minimal{a} readline-common{a} sensible-utils{a} txt2man{a} The following packages are RECOMMENDED but will NOT be installed: curl libarchive-cpio-perl libglib2.0-data libgpm2 libltdl-dev libmail-sendmail-perl lynx shared-mime-info wget xdg-user-dirs 0 packages upgraded, 53 newly installed, 0 to remove and 0 not upgraded. Need to get 25.0 MB of archives. After unpacking 91.2 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian buster/main armhf libbsd0 armhf 0.9.1-2 [103 kB] Get: 2 http://deb.debian.org/debian buster/main armhf bsdmainutils armhf 11.1.2+b1 [186 kB] Get: 3 http://deb.debian.org/debian buster/main armhf libuchardet0 armhf 0.0.6-3 [62.2 kB] Get: 4 http://deb.debian.org/debian buster/main armhf groff-base armhf 1.22.4-3 [828 kB] Get: 5 http://deb.debian.org/debian buster/main armhf libpipeline1 armhf 1.5.1-2 [26.8 kB] Get: 6 http://deb.debian.org/debian buster/main armhf man-db armhf 2.8.5-2 [1240 kB] Get: 7 http://deb.debian.org/debian buster/main armhf readline-common all 7.0-5 [70.6 kB] Get: 8 http://deb.debian.org/debian buster/main armhf libreadline7 armhf 7.0-5 [131 kB] Get: 9 http://deb.debian.org/debian buster/main armhf libsigsegv2 armhf 2.12-2 [32.1 kB] Get: 10 http://deb.debian.org/debian buster/main armhf gawk armhf 1:4.2.1+dfsg-1 [622 kB] Get: 11 http://deb.debian.org/debian buster/main armhf libssl1.1 armhf 1.1.1d-0+deb10u3 [1299 kB] Get: 12 http://deb.debian.org/debian buster/main armhf libpython3.7-minimal armhf 3.7.3-2+deb10u1 [582 kB] Get: 13 http://deb.debian.org/debian buster/main armhf libexpat1 armhf 2.2.6-2+deb10u1 [78.0 kB] Get: 14 http://deb.debian.org/debian buster/main armhf python3.7-minimal armhf 3.7.3-2+deb10u1 [1465 kB] Get: 15 http://deb.debian.org/debian buster/main armhf python3-minimal armhf 3.7.3-1 [36.6 kB] Get: 16 http://deb.debian.org/debian buster/main armhf mime-support all 3.62 [37.2 kB] Get: 17 http://deb.debian.org/debian buster/main armhf libmpdec2 armhf 2.4.2-2 [69.3 kB] Get: 18 http://deb.debian.org/debian buster/main armhf libpython3.7-stdlib armhf 3.7.3-2+deb10u1 [1660 kB] Get: 19 http://deb.debian.org/debian buster/main armhf python3.7 armhf 3.7.3-2+deb10u1 [330 kB] Get: 20 http://deb.debian.org/debian buster/main armhf libpython3-stdlib armhf 3.7.3-1 [20.0 kB] Get: 21 http://deb.debian.org/debian buster/main armhf python3 armhf 3.7.3-1 [61.5 kB] Get: 22 http://deb.debian.org/debian buster/main armhf sensible-utils all 0.0.12 [15.8 kB] Get: 23 http://deb.debian.org/debian buster/main armhf libmagic-mgc armhf 1:5.35-4+deb10u1 [242 kB] Get: 24 http://deb.debian.org/debian buster/main armhf libmagic1 armhf 1:5.35-4+deb10u1 [110 kB] Get: 25 http://deb.debian.org/debian buster/main armhf file armhf 1:5.35-4+deb10u1 [65.5 kB] Get: 26 http://deb.debian.org/debian buster/main armhf gettext-base armhf 0.19.8.1-9 [118 kB] Get: 27 http://deb.debian.org/debian buster/main armhf m4 armhf 1.4.18-2 [190 kB] Get: 28 http://deb.debian.org/debian buster/main armhf autoconf all 2.69-11 [341 kB] Get: 29 http://deb.debian.org/debian buster/main armhf autotools-dev all 20180224.1 [77.0 kB] Get: 30 http://deb.debian.org/debian buster/main armhf automake all 1:1.16.1-4 [771 kB] Get: 31 http://deb.debian.org/debian buster/main armhf autopoint all 0.19.8.1-9 [434 kB] Get: 32 http://deb.debian.org/debian buster/main armhf libtool all 2.4.6-9 [547 kB] Get: 33 http://deb.debian.org/debian buster/main armhf dh-autoreconf all 19 [16.9 kB] Get: 34 http://deb.debian.org/debian buster/main armhf libarchive-zip-perl all 1.64-1 [96.8 kB] Get: 35 http://deb.debian.org/debian buster/main armhf libfile-stripnondeterminism-perl all 1.1.2-1 [19.8 kB] Get: 36 http://deb.debian.org/debian buster/main armhf dh-strip-nondeterminism all 1.1.2-1 [13.0 kB] Get: 37 http://deb.debian.org/debian buster/main armhf libelf1 armhf 0.176-1.1 [158 kB] Get: 38 http://deb.debian.org/debian buster/main armhf dwz armhf 0.12-3 [72.0 kB] Get: 39 http://deb.debian.org/debian buster/main armhf libglib2.0-0 armhf 2.58.3-2+deb10u2 [1101 kB] Get: 40 http://deb.debian.org/debian buster/main armhf libicu63 armhf 63.1-6+deb10u1 [8005 kB] Get: 41 http://deb.debian.org/debian buster/main armhf libxml2 armhf 2.9.4+dfsg1-7+b3 [595 kB] Get: 42 http://deb.debian.org/debian buster/main armhf libcroco3 armhf 0.6.12-3 [133 kB] Get: 43 http://deb.debian.org/debian buster/main armhf libncurses6 armhf 6.1+20181013-2+deb10u2 [79.8 kB] Get: 44 http://deb.debian.org/debian buster/main armhf gettext armhf 0.19.8.1-9 [1242 kB] Get: 45 http://deb.debian.org/debian buster/main armhf intltool-debian all 0.35.0+20060710.5 [26.8 kB] Get: 46 http://deb.debian.org/debian buster/main armhf po-debconf all 1.0.21 [248 kB] Get: 47 http://deb.debian.org/debian buster/main armhf debhelper all 12.1.1 [1016 kB] Get: 48 http://deb.debian.org/debian buster/main armhf libusb-0.1-4 armhf 2:0.1.12-32 [21.7 kB] Get: 49 http://deb.debian.org/debian buster/main armhf libftdi1 armhf 0.20-4 [17.0 kB] Get: 50 http://deb.debian.org/debian buster/main armhf libusb-dev armhf 2:0.1.12-32 [36.9 kB] Get: 51 http://deb.debian.org/debian buster/main armhf libftdi-dev armhf 0.20-4 [172 kB] Get: 52 http://deb.debian.org/debian buster/main armhf pkg-config armhf 0.29-6 [60.7 kB] Get: 53 http://deb.debian.org/debian buster/main armhf txt2man all 1.6.0-5 [29.7 kB] Fetched 25.0 MB in 3s (8331 kB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package libbsd0:armhf. (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 ... 18932 files and directories currently installed.) Preparing to unpack .../0-libbsd0_0.9.1-2_armhf.deb ... Unpacking libbsd0:armhf (0.9.1-2) ... Selecting previously unselected package bsdmainutils. Preparing to unpack .../1-bsdmainutils_11.1.2+b1_armhf.deb ... Unpacking bsdmainutils (11.1.2+b1) ... Selecting previously unselected package libuchardet0:armhf. Preparing to unpack .../2-libuchardet0_0.0.6-3_armhf.deb ... Unpacking libuchardet0:armhf (0.0.6-3) ... Selecting previously unselected package groff-base. Preparing to unpack .../3-groff-base_1.22.4-3_armhf.deb ... Unpacking groff-base (1.22.4-3) ... Selecting previously unselected package libpipeline1:armhf. Preparing to unpack .../4-libpipeline1_1.5.1-2_armhf.deb ... Unpacking libpipeline1:armhf (1.5.1-2) ... Selecting previously unselected package man-db. Preparing to unpack .../5-man-db_2.8.5-2_armhf.deb ... Unpacking man-db (2.8.5-2) ... Selecting previously unselected package readline-common. Preparing to unpack .../6-readline-common_7.0-5_all.deb ... Unpacking readline-common (7.0-5) ... Selecting previously unselected package libreadline7:armhf. Preparing to unpack .../7-libreadline7_7.0-5_armhf.deb ... Unpacking libreadline7:armhf (7.0-5) ... Selecting previously unselected package libsigsegv2:armhf. Preparing to unpack .../8-libsigsegv2_2.12-2_armhf.deb ... Unpacking libsigsegv2:armhf (2.12-2) ... Setting up readline-common (7.0-5) ... Setting up libreadline7:armhf (7.0-5) ... Setting up libsigsegv2:armhf (2.12-2) ... 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 ... 19599 files and directories currently installed.) Preparing to unpack .../gawk_1%3a4.2.1+dfsg-1_armhf.deb ... Unpacking gawk (1:4.2.1+dfsg-1) ... Selecting previously unselected package libssl1.1:armhf. Preparing to unpack .../libssl1.1_1.1.1d-0+deb10u3_armhf.deb ... Unpacking libssl1.1:armhf (1.1.1d-0+deb10u3) ... Selecting previously unselected package libpython3.7-minimal:armhf. Preparing to unpack .../libpython3.7-minimal_3.7.3-2+deb10u1_armhf.deb ... Unpacking libpython3.7-minimal:armhf (3.7.3-2+deb10u1) ... Selecting previously unselected package libexpat1:armhf. Preparing to unpack .../libexpat1_2.2.6-2+deb10u1_armhf.deb ... Unpacking libexpat1:armhf (2.2.6-2+deb10u1) ... Selecting previously unselected package python3.7-minimal. Preparing to unpack .../python3.7-minimal_3.7.3-2+deb10u1_armhf.deb ... Unpacking python3.7-minimal (3.7.3-2+deb10u1) ... Setting up libssl1.1:armhf (1.1.1d-0+deb10u3) ... Setting up libpython3.7-minimal:armhf (3.7.3-2+deb10u1) ... Setting up libexpat1:armhf (2.2.6-2+deb10u1) ... Setting up python3.7-minimal (3.7.3-2+deb10u1) ... 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 ... 20029 files and directories currently installed.) Preparing to unpack .../0-python3-minimal_3.7.3-1_armhf.deb ... Unpacking python3-minimal (3.7.3-1) ... Selecting previously unselected package mime-support. Preparing to unpack .../1-mime-support_3.62_all.deb ... Unpacking mime-support (3.62) ... Selecting previously unselected package libmpdec2:armhf. Preparing to unpack .../2-libmpdec2_2.4.2-2_armhf.deb ... Unpacking libmpdec2:armhf (2.4.2-2) ... Selecting previously unselected package libpython3.7-stdlib:armhf. Preparing to unpack .../3-libpython3.7-stdlib_3.7.3-2+deb10u1_armhf.deb ... Unpacking libpython3.7-stdlib:armhf (3.7.3-2+deb10u1) ... Selecting previously unselected package python3.7. Preparing to unpack .../4-python3.7_3.7.3-2+deb10u1_armhf.deb ... Unpacking python3.7 (3.7.3-2+deb10u1) ... Selecting previously unselected package libpython3-stdlib:armhf. Preparing to unpack .../5-libpython3-stdlib_3.7.3-1_armhf.deb ... Unpacking libpython3-stdlib:armhf (3.7.3-1) ... Setting up python3-minimal (3.7.3-1) ... 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 ... 20466 files and directories currently installed.) Preparing to unpack .../00-python3_3.7.3-1_armhf.deb ... Unpacking python3 (3.7.3-1) ... Selecting previously unselected package sensible-utils. Preparing to unpack .../01-sensible-utils_0.0.12_all.deb ... Unpacking sensible-utils (0.0.12) ... Selecting previously unselected package libmagic-mgc. Preparing to unpack .../02-libmagic-mgc_1%3a5.35-4+deb10u1_armhf.deb ... Unpacking libmagic-mgc (1:5.35-4+deb10u1) ... Selecting previously unselected package libmagic1:armhf. Preparing to unpack .../03-libmagic1_1%3a5.35-4+deb10u1_armhf.deb ... Unpacking libmagic1:armhf (1:5.35-4+deb10u1) ... Selecting previously unselected package file. Preparing to unpack .../04-file_1%3a5.35-4+deb10u1_armhf.deb ... Unpacking file (1:5.35-4+deb10u1) ... Selecting previously unselected package gettext-base. Preparing to unpack .../05-gettext-base_0.19.8.1-9_armhf.deb ... Unpacking gettext-base (0.19.8.1-9) ... Selecting previously unselected package m4. Preparing to unpack .../06-m4_1.4.18-2_armhf.deb ... Unpacking m4 (1.4.18-2) ... Selecting previously unselected package autoconf. Preparing to unpack .../07-autoconf_2.69-11_all.deb ... Unpacking autoconf (2.69-11) ... Selecting previously unselected package autotools-dev. Preparing to unpack .../08-autotools-dev_20180224.1_all.deb ... Unpacking autotools-dev (20180224.1) ... Selecting previously unselected package automake. Preparing to unpack .../09-automake_1%3a1.16.1-4_all.deb ... Unpacking automake (1:1.16.1-4) ... Selecting previously unselected package autopoint. Preparing to unpack .../10-autopoint_0.19.8.1-9_all.deb ... Unpacking autopoint (0.19.8.1-9) ... Selecting previously unselected package libtool. Preparing to unpack .../11-libtool_2.4.6-9_all.deb ... Unpacking libtool (2.4.6-9) ... Selecting previously unselected package dh-autoreconf. Preparing to unpack .../12-dh-autoreconf_19_all.deb ... Unpacking dh-autoreconf (19) ... Selecting previously unselected package libarchive-zip-perl. Preparing to unpack .../13-libarchive-zip-perl_1.64-1_all.deb ... Unpacking libarchive-zip-perl (1.64-1) ... Selecting previously unselected package libfile-stripnondeterminism-perl. Preparing to unpack .../14-libfile-stripnondeterminism-perl_1.1.2-1_all.deb ... Unpacking libfile-stripnondeterminism-perl (1.1.2-1) ... Selecting previously unselected package dh-strip-nondeterminism. Preparing to unpack .../15-dh-strip-nondeterminism_1.1.2-1_all.deb ... Unpacking dh-strip-nondeterminism (1.1.2-1) ... Selecting previously unselected package libelf1:armhf. Preparing to unpack .../16-libelf1_0.176-1.1_armhf.deb ... Unpacking libelf1:armhf (0.176-1.1) ... Selecting previously unselected package dwz. Preparing to unpack .../17-dwz_0.12-3_armhf.deb ... Unpacking dwz (0.12-3) ... Selecting previously unselected package libglib2.0-0:armhf. Preparing to unpack .../18-libglib2.0-0_2.58.3-2+deb10u2_armhf.deb ... Unpacking libglib2.0-0:armhf (2.58.3-2+deb10u2) ... Selecting previously unselected package libicu63:armhf. Preparing to unpack .../19-libicu63_63.1-6+deb10u1_armhf.deb ... Unpacking libicu63:armhf (63.1-6+deb10u1) ... Selecting previously unselected package libxml2:armhf. Preparing to unpack .../20-libxml2_2.9.4+dfsg1-7+b3_armhf.deb ... Unpacking libxml2:armhf (2.9.4+dfsg1-7+b3) ... Selecting previously unselected package libcroco3:armhf. Preparing to unpack .../21-libcroco3_0.6.12-3_armhf.deb ... Unpacking libcroco3:armhf (0.6.12-3) ... Selecting previously unselected package libncurses6:armhf. Preparing to unpack .../22-libncurses6_6.1+20181013-2+deb10u2_armhf.deb ... Unpacking libncurses6:armhf (6.1+20181013-2+deb10u2) ... Selecting previously unselected package gettext. Preparing to unpack .../23-gettext_0.19.8.1-9_armhf.deb ... Unpacking gettext (0.19.8.1-9) ... Selecting previously unselected package intltool-debian. Preparing to unpack .../24-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 .../25-po-debconf_1.0.21_all.deb ... Unpacking po-debconf (1.0.21) ... Selecting previously unselected package debhelper. Preparing to unpack .../26-debhelper_12.1.1_all.deb ... Unpacking debhelper (12.1.1) ... Selecting previously unselected package libusb-0.1-4:armhf. Preparing to unpack .../27-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 .../28-libftdi1_0.20-4_armhf.deb ... Unpacking libftdi1:armhf (0.20-4) ... Selecting previously unselected package libusb-dev. Preparing to unpack .../29-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 .../30-libftdi-dev_0.20-4_armhf.deb ... Unpacking libftdi-dev (0.20-4) ... Selecting previously unselected package pkg-config. Preparing to unpack .../31-pkg-config_0.29-6_armhf.deb ... Unpacking pkg-config (0.29-6) ... Selecting previously unselected package txt2man. Preparing to unpack .../32-txt2man_1.6.0-5_all.deb ... Unpacking txt2man (1.6.0-5) ... Setting up libpipeline1:armhf (1.5.1-2) ... Setting up mime-support (3.62) ... Setting up libmagic-mgc (1:5.35-4+deb10u1) ... Setting up gawk (1:4.2.1+dfsg-1) ... Setting up libarchive-zip-perl (1.64-1) ... Setting up libglib2.0-0:armhf (2.58.3-2+deb10u2) ... No schema files found: doing nothing. Setting up libmagic1:armhf (1:5.35-4+deb10u1) ... Setting up gettext-base (0.19.8.1-9) ... Setting up m4 (1.4.18-2) ... Setting up file (1:5.35-4+deb10u1) ... Setting up libicu63:armhf (63.1-6+deb10u1) ... Setting up libusb-0.1-4:armhf (2:0.1.12-32) ... Setting up autotools-dev (20180224.1) ... Setting up libncurses6:armhf (6.1+20181013-2+deb10u2) ... Setting up autopoint (0.19.8.1-9) ... Setting up pkg-config (0.29-6) ... Setting up autoconf (2.69-11) ... Setting up sensible-utils (0.0.12) ... Setting up libuchardet0:armhf (0.0.6-3) ... Setting up libmpdec2:armhf (2.4.2-2) ... Setting up libbsd0:armhf (0.9.1-2) ... Setting up libelf1:armhf (0.176-1.1) ... Setting up libxml2:armhf (2.9.4+dfsg1-7+b3) ... Setting up automake (1:1.16.1-4) ... update-alternatives: using /usr/bin/automake-1.16 to provide /usr/bin/automake (automake) in auto mode Setting up libfile-stripnondeterminism-perl (1.1.2-1) ... Setting up libpython3.7-stdlib:armhf (3.7.3-2+deb10u1) ... Setting up txt2man (1.6.0-5) ... Setting up libtool (2.4.6-9) ... Setting up libftdi1:armhf (0.20-4) ... Setting up libusb-dev (2:0.1.12-32) ... Setting up bsdmainutils (11.1.2+b1) ... update-alternatives: using /usr/bin/bsd-write to provide /usr/bin/write (write) in auto mode update-alternatives: using /usr/bin/bsd-from to provide /usr/bin/from (from) in auto mode Setting up libcroco3:armhf (0.6.12-3) ... Setting up dwz (0.12-3) ... Setting up groff-base (1.22.4-3) ... Setting up libpython3-stdlib:armhf (3.7.3-1) ... Setting up python3.7 (3.7.3-2+deb10u1) ... Setting up gettext (0.19.8.1-9) ... Setting up libftdi-dev (0.20-4) ... Setting up python3 (3.7.3-1) ... Setting up man-db (2.8.5-2) ... Not building database; man-db/auto-update is not 'true'. Setting up intltool-debian (0.35.0+20060710.5) ... Setting up po-debconf (1.0.21) ... Setting up debhelper (12.1.1) ... Setting up dh-autoreconf (19) ... Setting up dh-strip-nondeterminism (1.1.2-1) ... Processing triggers for libc-bin (2.28-10) ... 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.23-1). 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. I: Building the package I: Running cd /build/fpga-icestorm-0~20181109git9671b76/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-buildpackage -us -uc -b dpkg-buildpackage: info: source package fpga-icestorm dpkg-buildpackage: info: source version 0~20181109git9671b76-1 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~20181109git9671b76' dh_auto_clean make -j3 clean make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76' for dir in icebox icepack iceprog icemulti icepll icetime icebram; do \ make -C $dir clean || exit; \ done make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt chipdb-lm4k.txt rm -f icebox.pyc iceboxdb.pyc make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepack' rm -f icepack rm -f iceunpack rm -f icepack.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icepack' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/iceprog' rm -f iceprog rm -f iceprog.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/iceprog' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' rm -f icemulti rm -f icemulti.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' rm -f icepll rm -f icepll.exe rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' rm -f icetime icetime.exe timings.inc *.o *.d rm -rf test[0-9]* make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebram' rm -f icebram rm -f icebram.exe rm -f demo.* demo_*.* rm -f *.o *.d make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icebram' make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' rm -f debian/man/*.1 rm -f -r icebox/__pycache__ make[1]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' dh_clean debian/rules build dh build dh_update_autotools_config dh_autoreconf dh_auto_configure dh_auto_build make -j3 "INSTALL=install --strip-program=true" make[1]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76' make -C icebox all make -C icepack all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' python3 icebox_chipdb.py -3 > chipdb-384.new make -C iceprog all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepack' g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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~20181109git9671b76/iceprog' cc -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 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=] #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string vstringf(const char *fmt, va_list ap) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ char *str = NULL; ~~~~~~~~~~~~~~~~~ #ifdef _WIN32 ~~~~~~~~~~~~~ int sz = 64, rc; ~~~~~~~~~~~~~~~~ while (1) { ~~~~~~~~~~~ va_list apc; ~~~~~~~~~~~~ va_copy(apc, ap); ~~~~~~~~~~~~~~~~~ str = (char*)realloc(str, sz); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rc = vsnprintf(str, sz, fmt, apc); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(apc); ~~~~~~~~~~~~ if (rc >= 0 && rc < sz) ~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ sz *= 2; ~~~~~~~~ } ~ #else ~~~~~ if (vasprintf(&str, fmt, ap) < 0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ str = NULL; ~~~~~~~~~~~ #endif ~~~~~~ if (str != NULL) { ~~~~~~~~~~~~~~~~~~ string = str; ~~~~~~~~~~~~~ free(str); ~~~~~~~~~~ } ~ return string; ~~~~~~~~~~~~~~ } ~ string stringf(const char *fmt, ...) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ va_list ap; ~~~~~~~~~~~ va_start(ap, fmt); ~~~~~~~~~~~~~~~~~~ string = vstringf(fmt, ap); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(ap); ~~~~~~~~~~~ return string; ~~~~~~~~~~~~~~ } ~ // ================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FpgaConfig stuff ~~~~~~~~~~~~~~~~~~~ struct FpgaConfig ~~~~~~~~~~~~~~~~~ { ~ string device; ~~~~~~~~~~~~~~ string freqrange; ~~~~~~~~~~~~~~~~~ string nosleep; ~~~~~~~~~~~~~~~ string warmboot; ~~~~~~~~~~~~~~~~ // cram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int cram_width, cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> cram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int bram_width, bram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> bram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // data before preamble ~~~~~~~~~~~~~~~~~~~~~~~ vector initblop; ~~~~~~~~~~~~~~~~~~~~~~~~~ // bitstream i/o ~~~~~~~~~~~~~~~~ void read_bits(std::istream &ifs); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bits(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // icebox i/o ~~~~~~~~~~~~~ void read_ascii(std::istream &ifs, bool nosleep); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_ascii(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // netpbm i/o ~~~~~~~~~~~~~ void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query chip type metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~ int chip_width() const; ~~~~~~~~~~~~~~~~~~~~~~~ int chip_height() const; ~~~~~~~~~~~~~~~~~~~~~~~~ vector chip_cols() const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query tile metadata ~~~~~~~~~~~~~~~~~~~~~~ string tile_type(int x, int y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_width(const string &type) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // cram bit manipulation ~~~~~~~~~~~~~~~~~~~~~~~~ void cram_clear(); ~~~~~~~~~~~~~~~~~~ void cram_fill_tiles(); ~~~~~~~~~~~~~~~~~~~~~~~ void cram_checkerboard(int m = 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct CramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ string tile_type; ~~~~~~~~~~~~~~~~~ int tile_width; ~~~~~~~~~~~~~~~ int column_width; ~~~~~~~~~~~~~~~~~ bool left_right_io; ~~~~~~~~~~~~~~~~~~~ bool right_half; ~~~~~~~~~~~~~~~~ bool top_half; ~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_tx; ~~~~~~~~~~~~ int bank_ty; ~~~~~~~~~~~~ int bank_xoff; ~~~~~~~~~~~~~~ int bank_yoff; ~~~~~~~~~~~~~~ CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct BramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_off; ~~~~~~~~~~~~~ BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ static void update_crc16(uint16_t &crc, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 7; i >= 0; i--) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc = (crc << 1) ^ xor_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int byte = ifs.get(); ~~~~~~~~~~~~~~~~~~~~~ if (byte < 0) ~~~~~~~~~~~~~ error("Unexpected end of file.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return byte; ~~~~~~~~~~~~ } ~ static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ ofs << byte; ~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_bits(std::istream &ifs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // skip initial comments until preamble is found ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t preamble = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (1) ~~~~~~~~~ { ~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preamble = (preamble << 8) | byte; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0xffffffff) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("No preamble found in bitstream.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0x7EAA997E) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Found preamble at offset %d.\n", file_offset-4); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ initblop.push_back(byte); ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ // main parser loop ~~~~~~~~~~~~~~~~~~~ int current_bank = 0; ~~~~~~~~~~~~~~~~~~~~~ int current_width = 0; ~~~~~~~~~~~~~~~~~~~~~~ int current_height = 0; ~~~~~~~~~~~~~~~~~~~~~~~ int current_offset = 0; ~~~~~~~~~~~~~~~~~~~~~~~ bool wakeup = false; ~~~~~~~~~~~~~~~~~~~~ this->cram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (!wakeup) ~~~~~~~~~~~~~~~ { ~ // one command byte. the lower 4 bits of the command byte specify ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // the length of the command payload. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t command = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t payload = 0; ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (command & 0x0f); i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command, 2*(command & 0x0f), payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t end_token; ~~~~~~~~~~~~~~~~~~~ switch (command & 0xf0) ~~~~~~~~~~~~~~~~~~~~~~~ { ~ case 0x00: ~~~~~~~~~~ switch (payload) ~~~~~~~~~~~~~~~~ { ~ case 0x01: ~~~~~~~~~~ info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = std::max(this->cram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = std::max(this->cram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x03: ~~~~~~~~~~ info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = std::max(this->bram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = std::max(this->bram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x05: ~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x06: ~~~~~~~~~~ info("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~ wakeup = true; ~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ break; ~~~~~~ case 0x10: ~~~~~~~~~~ current_bank = payload; ~~~~~~~~~~~~~~~~~~~~~~~ debug("Set bank to %d.\n", current_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x20: ~~~~~~~~~~ if (crc_value != 0) ~~~~~~~~~~~~~~~~~~~ error("CRC Check FAILED.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("CRC Check OK.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x50: ~~~~~~~~~~ if (payload == 0) ~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 1) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "medium"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 2) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "high"; ~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x60: ~~~~~~~~~~ current_width = payload + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank width to %d.\n", current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x70: ~~~~~~~~~~ current_height = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank height to %d.\n", current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x80: ~~~~~~~~~~ current_offset = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank offset to %d.\n", current_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x90: ~~~~~~~~~~ switch(payload) ~~~~~~~~~~~~~~~ { ~ case 0: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 1: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 32: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 33: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown warmboot/nosleep payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ if (this->cram_width == 182 && this->cram_height == 80) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "384"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 332 && this->cram_height == 144) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "1k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 872 && this->cram_height == 272) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "8k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 336) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "5k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "u4k"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 656 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "lm4k"; ~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Failed to detect chip type.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Chip type is '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::write_bits(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto byte : this->initblop) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << byte; ~~~~~~~~~~~~ debug("Writing preamble.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0xAA); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x99); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x51); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->freqrange == "low") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "medium") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "high") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x02); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x05); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ { ~ uint8_t nosleep_flag; ~~~~~~~~~~~~~~~~~~~~~ debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x92); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->nosleep == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 0; ~~~~~~~~~~~~~~~~~ else if (this->nosleep == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 1; ~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->warmboot == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank width to %d.\n", this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank offset to 0.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_bank = 0; cram_bank < 4; cram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector cram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int height = this->cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((cram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ height = height / 2 + 8; ~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_y = 0; cram_y < height; cram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_x = 0; cram_x < this->cram_width; cram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank %d.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Writing bank %d data.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(cram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ int bram_chunk_size = 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->bram_width && this->bram_height) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Setting bank height to %d.\n", this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_bank = 0; bram_bank < 4; bram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("BRAM: Setting bank %d.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector bram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int width = this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((bram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ width = width / 2; ~~~~~~~~~~~~~~~~~~ for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_x = 0; bram_x < width; bram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank offset to %d.\n", offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Writing bank %d data.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x03); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(bram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ debug("Writing CRC value.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x22); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_hi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_lo); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x06); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Padding byte.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool got_device = false; ~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.clear(); ~~~~~~~~~~~~~~~~~~~ this->bram.clear(); ~~~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool reuse_line = true; ~~~~~~~~~~~~~~~~~~~~~~~ string line, command; ~~~~~~~~~~~~~~~~~~~~~ while (reuse_line || getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ reuse_line = false; ~~~~~~~~~~~~~~~~~~~ std::istringstream is(line); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> command; ~~~~~~~~~~~~~~ if (command.empty()) ~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ debug("Next command: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".comment") ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ this->initblop.clear(); ~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while (getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (auto ch : line) ~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(ch); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".device") ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (got_device) ~~~~~~~~~~~~~~~ error("More than one .device statement.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> this->device; ~~~~~~~~~~~~~~~~~~~ if (this->device == "384") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 182; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 80; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "1k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 332; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 144; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 64; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "8k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 872; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 272; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 128; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 336; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 160; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "u4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "lm4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 656; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ error("Unsupported chip type '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } else { ~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->bram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ got_device = true; ~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".warmboot") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ is >> this->warmboot; ~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "disabled" && ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown warmboot setting '%s'.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ // No ".nosleep" section despite sharing the same byte as .warmboot. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ".nosleep" is specified when icepack is invoked, which is too late. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // So we inject the section based on command line argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (nosleep) ~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ CramIndexConverter cic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (("." + cic.tile_type + "_tile") != command) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Got %s statement for %s tile %d %d.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (line[bit_x] == '1') { ~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".ram_data") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ BramIndexConverter bic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int value = -1; ~~~~~~~~~~~~~~~ if ('0' <= line[ch_idx] && line[ch_idx] <= '9') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - '0'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'a' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'A' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (value < 0) ~~~~~~~~~~~~~~ error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((value & (1 << i)) != 0) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[bram_bank][bram_x][bram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".extra_bit") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> cram_bank >> cram_x >> cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".sym") ~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ if (command.substr(0, 1) == ".") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown statement: %s\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unexpected data line: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ void FpgaConfig::write_ascii(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << ".comment"; ~~~~~~~~~~~~~~~~~~ bool insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto ch : this->initblop) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (ch == 0) { ~~~~~~~~~~~~~~ insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~ } else if (ch == 0xff) { ~~~~~~~~~~~~~~~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } else { ~~~~~~~~ if (insert_newline) ~~~~~~~~~~~~~~~~~~~ ofs << '\n'; ~~~~~~~~~~~~ ofs << ch; ~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ ofs << stringf("\n.device %s\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // As "nosleep" is an icepack command, we do not write out a ".nosleep" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // section. However, we parse it in read_bits() and notify the user in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // info. ~~~~~~~~ typedef std::tuple tile_bit_t; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ std::set tile_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int y = 0; y <= this->chip_height()+1; y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x <= this->chip_width()+1; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ CramIndexConverter cic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cic.tile_type == "corner" || cic.tile_type == "unsupported") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cram_x > int(this->cram[cram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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:902:6: note: in expansion of macro 'error' 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: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=] #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string vstringf(const char *fmt, va_list ap) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ char *str = NULL; ~~~~~~~~~~~~~~~~~ #ifdef _WIN32 ~~~~~~~~~~~~~ int sz = 64, rc; ~~~~~~~~~~~~~~~~ while (1) { ~~~~~~~~~~~ va_list apc; ~~~~~~~~~~~~ va_copy(apc, ap); ~~~~~~~~~~~~~~~~~ str = (char*)realloc(str, sz); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rc = vsnprintf(str, sz, fmt, apc); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(apc); ~~~~~~~~~~~~ if (rc >= 0 && rc < sz) ~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ sz *= 2; ~~~~~~~~ } ~ #else ~~~~~ if (vasprintf(&str, fmt, ap) < 0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ str = NULL; ~~~~~~~~~~~ #endif ~~~~~~ if (str != NULL) { ~~~~~~~~~~~~~~~~~~ string = str; ~~~~~~~~~~~~~ free(str); ~~~~~~~~~~ } ~ return string; ~~~~~~~~~~~~~~ } ~ string stringf(const char *fmt, ...) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ va_list ap; ~~~~~~~~~~~ va_start(ap, fmt); ~~~~~~~~~~~~~~~~~~ string = vstringf(fmt, ap); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(ap); ~~~~~~~~~~~ return string; ~~~~~~~~~~~~~~ } ~ // ================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FpgaConfig stuff ~~~~~~~~~~~~~~~~~~~ struct FpgaConfig ~~~~~~~~~~~~~~~~~ { ~ string device; ~~~~~~~~~~~~~~ string freqrange; ~~~~~~~~~~~~~~~~~ string nosleep; ~~~~~~~~~~~~~~~ string warmboot; ~~~~~~~~~~~~~~~~ // cram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int cram_width, cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> cram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int bram_width, bram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> bram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // data before preamble ~~~~~~~~~~~~~~~~~~~~~~~ vector initblop; ~~~~~~~~~~~~~~~~~~~~~~~~~ // bitstream i/o ~~~~~~~~~~~~~~~~ void read_bits(std::istream &ifs); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bits(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // icebox i/o ~~~~~~~~~~~~~ void read_ascii(std::istream &ifs, bool nosleep); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_ascii(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // netpbm i/o ~~~~~~~~~~~~~ void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query chip type metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~ int chip_width() const; ~~~~~~~~~~~~~~~~~~~~~~~ int chip_height() const; ~~~~~~~~~~~~~~~~~~~~~~~~ vector chip_cols() const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query tile metadata ~~~~~~~~~~~~~~~~~~~~~~ string tile_type(int x, int y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_width(const string &type) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // cram bit manipulation ~~~~~~~~~~~~~~~~~~~~~~~~ void cram_clear(); ~~~~~~~~~~~~~~~~~~ void cram_fill_tiles(); ~~~~~~~~~~~~~~~~~~~~~~~ void cram_checkerboard(int m = 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct CramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ string tile_type; ~~~~~~~~~~~~~~~~~ int tile_width; ~~~~~~~~~~~~~~~ int column_width; ~~~~~~~~~~~~~~~~~ bool left_right_io; ~~~~~~~~~~~~~~~~~~~ bool right_half; ~~~~~~~~~~~~~~~~ bool top_half; ~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_tx; ~~~~~~~~~~~~ int bank_ty; ~~~~~~~~~~~~ int bank_xoff; ~~~~~~~~~~~~~~ int bank_yoff; ~~~~~~~~~~~~~~ CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct BramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_off; ~~~~~~~~~~~~~ BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ static void update_crc16(uint16_t &crc, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 7; i >= 0; i--) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc = (crc << 1) ^ xor_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int byte = ifs.get(); ~~~~~~~~~~~~~~~~~~~~~ if (byte < 0) ~~~~~~~~~~~~~ error("Unexpected end of file.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return byte; ~~~~~~~~~~~~ } ~ static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ ofs << byte; ~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_bits(std::istream &ifs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // skip initial comments until preamble is found ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t preamble = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (1) ~~~~~~~~~ { ~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preamble = (preamble << 8) | byte; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0xffffffff) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("No preamble found in bitstream.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0x7EAA997E) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Found preamble at offset %d.\n", file_offset-4); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ initblop.push_back(byte); ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ // main parser loop ~~~~~~~~~~~~~~~~~~~ int current_bank = 0; ~~~~~~~~~~~~~~~~~~~~~ int current_width = 0; ~~~~~~~~~~~~~~~~~~~~~~ int current_height = 0; ~~~~~~~~~~~~~~~~~~~~~~~ int current_offset = 0; ~~~~~~~~~~~~~~~~~~~~~~~ bool wakeup = false; ~~~~~~~~~~~~~~~~~~~~ this->cram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (!wakeup) ~~~~~~~~~~~~~~~ { ~ // one command byte. the lower 4 bits of the command byte specify ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // the length of the command payload. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t command = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t payload = 0; ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (command & 0x0f); i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command, 2*(command & 0x0f), payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t end_token; ~~~~~~~~~~~~~~~~~~~ switch (command & 0xf0) ~~~~~~~~~~~~~~~~~~~~~~~ { ~ case 0x00: ~~~~~~~~~~ switch (payload) ~~~~~~~~~~~~~~~~ { ~ case 0x01: ~~~~~~~~~~ info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = std::max(this->cram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = std::max(this->cram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x03: ~~~~~~~~~~ info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = std::max(this->bram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = std::max(this->bram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x05: ~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x06: ~~~~~~~~~~ info("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~ wakeup = true; ~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ break; ~~~~~~ case 0x10: ~~~~~~~~~~ current_bank = payload; ~~~~~~~~~~~~~~~~~~~~~~~ debug("Set bank to %d.\n", current_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x20: ~~~~~~~~~~ if (crc_value != 0) ~~~~~~~~~~~~~~~~~~~ error("CRC Check FAILED.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("CRC Check OK.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x50: ~~~~~~~~~~ if (payload == 0) ~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 1) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "medium"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 2) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "high"; ~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x60: ~~~~~~~~~~ current_width = payload + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank width to %d.\n", current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x70: ~~~~~~~~~~ current_height = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank height to %d.\n", current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x80: ~~~~~~~~~~ current_offset = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank offset to %d.\n", current_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x90: ~~~~~~~~~~ switch(payload) ~~~~~~~~~~~~~~~ { ~ case 0: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 1: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 32: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 33: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown warmboot/nosleep payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ if (this->cram_width == 182 && this->cram_height == 80) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "384"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 332 && this->cram_height == 144) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "1k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 872 && this->cram_height == 272) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "8k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 336) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "5k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "u4k"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 656 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "lm4k"; ~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Failed to detect chip type.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Chip type is '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::write_bits(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto byte : this->initblop) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << byte; ~~~~~~~~~~~~ debug("Writing preamble.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0xAA); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x99); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x51); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->freqrange == "low") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "medium") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "high") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x02); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x05); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ { ~ uint8_t nosleep_flag; ~~~~~~~~~~~~~~~~~~~~~ debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x92); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->nosleep == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 0; ~~~~~~~~~~~~~~~~~ else if (this->nosleep == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 1; ~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->warmboot == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank width to %d.\n", this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank offset to 0.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_bank = 0; cram_bank < 4; cram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector cram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int height = this->cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((cram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ height = height / 2 + 8; ~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_y = 0; cram_y < height; cram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_x = 0; cram_x < this->cram_width; cram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank %d.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Writing bank %d data.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(cram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ int bram_chunk_size = 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->bram_width && this->bram_height) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Setting bank height to %d.\n", this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_bank = 0; bram_bank < 4; bram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("BRAM: Setting bank %d.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector bram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int width = this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((bram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ width = width / 2; ~~~~~~~~~~~~~~~~~~ for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_x = 0; bram_x < width; bram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank offset to %d.\n", offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Writing bank %d data.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x03); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(bram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ debug("Writing CRC value.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x22); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_hi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_lo); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x06); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Padding byte.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool got_device = false; ~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.clear(); ~~~~~~~~~~~~~~~~~~~ this->bram.clear(); ~~~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool reuse_line = true; ~~~~~~~~~~~~~~~~~~~~~~~ string line, command; ~~~~~~~~~~~~~~~~~~~~~ while (reuse_line || getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ reuse_line = false; ~~~~~~~~~~~~~~~~~~~ std::istringstream is(line); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> command; ~~~~~~~~~~~~~~ if (command.empty()) ~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ debug("Next command: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".comment") ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ this->initblop.clear(); ~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while (getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (auto ch : line) ~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(ch); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".device") ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (got_device) ~~~~~~~~~~~~~~~ error("More than one .device statement.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> this->device; ~~~~~~~~~~~~~~~~~~~ if (this->device == "384") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 182; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 80; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "1k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 332; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 144; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 64; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "8k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 872; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 272; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 128; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 336; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 160; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "u4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "lm4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 656; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ error("Unsupported chip type '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } else { ~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->bram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ got_device = true; ~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".warmboot") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ is >> this->warmboot; ~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "disabled" && ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown warmboot setting '%s'.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ // No ".nosleep" section despite sharing the same byte as .warmboot. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ".nosleep" is specified when icepack is invoked, which is too late. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // So we inject the section based on command line argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (nosleep) ~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ CramIndexConverter cic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (("." + cic.tile_type + "_tile") != command) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Got %s statement for %s tile %d %d.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (line[bit_x] == '1') { ~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".ram_data") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ BramIndexConverter bic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int value = -1; ~~~~~~~~~~~~~~~ if ('0' <= line[ch_idx] && line[ch_idx] <= '9') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - '0'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'a' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'A' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (value < 0) ~~~~~~~~~~~~~~ error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((value & (1 << i)) != 0) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[bram_bank][bram_x][bram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".extra_bit") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> cram_bank >> cram_x >> cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".sym") ~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ if (command.substr(0, 1) == ".") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown statement: %s\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unexpected data line: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ void FpgaConfig::write_ascii(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << ".comment"; ~~~~~~~~~~~~~~~~~~ bool insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto ch : this->initblop) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (ch == 0) { ~~~~~~~~~~~~~~ insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~ } else if (ch == 0xff) { ~~~~~~~~~~~~~~~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } else { ~~~~~~~~ if (insert_newline) ~~~~~~~~~~~~~~~~~~~ ofs << '\n'; ~~~~~~~~~~~~ ofs << ch; ~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ ofs << stringf("\n.device %s\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // As "nosleep" is an icepack command, we do not write out a ".nosleep" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // section. However, we parse it in read_bits() and notify the user in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // info. ~~~~~~~~ typedef std::tuple tile_bit_t; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ std::set tile_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int y = 0; y <= this->chip_height()+1; y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x <= this->chip_width()+1; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ CramIndexConverter cic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cic.tile_type == "corner" || cic.tile_type == "unsupported") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cram_x > int(this->cram[cram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ if (cram_y > int(this->cram[cram_bank][cram_x].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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:905:6: note: in expansion of macro 'error' 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: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=] #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string vstringf(const char *fmt, va_list ap) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ char *str = NULL; ~~~~~~~~~~~~~~~~~ #ifdef _WIN32 ~~~~~~~~~~~~~ int sz = 64, rc; ~~~~~~~~~~~~~~~~ while (1) { ~~~~~~~~~~~ va_list apc; ~~~~~~~~~~~~ va_copy(apc, ap); ~~~~~~~~~~~~~~~~~ str = (char*)realloc(str, sz); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rc = vsnprintf(str, sz, fmt, apc); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(apc); ~~~~~~~~~~~~ if (rc >= 0 && rc < sz) ~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ sz *= 2; ~~~~~~~~ } ~ #else ~~~~~ if (vasprintf(&str, fmt, ap) < 0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ str = NULL; ~~~~~~~~~~~ #endif ~~~~~~ if (str != NULL) { ~~~~~~~~~~~~~~~~~~ string = str; ~~~~~~~~~~~~~ free(str); ~~~~~~~~~~ } ~ return string; ~~~~~~~~~~~~~~ } ~ string stringf(const char *fmt, ...) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ va_list ap; ~~~~~~~~~~~ va_start(ap, fmt); ~~~~~~~~~~~~~~~~~~ string = vstringf(fmt, ap); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(ap); ~~~~~~~~~~~ return string; ~~~~~~~~~~~~~~ } ~ // ================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FpgaConfig stuff ~~~~~~~~~~~~~~~~~~~ struct FpgaConfig ~~~~~~~~~~~~~~~~~ { ~ string device; ~~~~~~~~~~~~~~ string freqrange; ~~~~~~~~~~~~~~~~~ string nosleep; ~~~~~~~~~~~~~~~ string warmboot; ~~~~~~~~~~~~~~~~ // cram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int cram_width, cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> cram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int bram_width, bram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> bram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // data before preamble ~~~~~~~~~~~~~~~~~~~~~~~ vector initblop; ~~~~~~~~~~~~~~~~~~~~~~~~~ // bitstream i/o ~~~~~~~~~~~~~~~~ void read_bits(std::istream &ifs); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bits(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // icebox i/o ~~~~~~~~~~~~~ void read_ascii(std::istream &ifs, bool nosleep); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_ascii(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // netpbm i/o ~~~~~~~~~~~~~ void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query chip type metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~ int chip_width() const; ~~~~~~~~~~~~~~~~~~~~~~~ int chip_height() const; ~~~~~~~~~~~~~~~~~~~~~~~~ vector chip_cols() const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query tile metadata ~~~~~~~~~~~~~~~~~~~~~~ string tile_type(int x, int y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_width(const string &type) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // cram bit manipulation ~~~~~~~~~~~~~~~~~~~~~~~~ void cram_clear(); ~~~~~~~~~~~~~~~~~~ void cram_fill_tiles(); ~~~~~~~~~~~~~~~~~~~~~~~ void cram_checkerboard(int m = 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct CramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ string tile_type; ~~~~~~~~~~~~~~~~~ int tile_width; ~~~~~~~~~~~~~~~ int column_width; ~~~~~~~~~~~~~~~~~ bool left_right_io; ~~~~~~~~~~~~~~~~~~~ bool right_half; ~~~~~~~~~~~~~~~~ bool top_half; ~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_tx; ~~~~~~~~~~~~ int bank_ty; ~~~~~~~~~~~~ int bank_xoff; ~~~~~~~~~~~~~~ int bank_yoff; ~~~~~~~~~~~~~~ CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct BramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_off; ~~~~~~~~~~~~~ BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ static void update_crc16(uint16_t &crc, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 7; i >= 0; i--) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc = (crc << 1) ^ xor_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int byte = ifs.get(); ~~~~~~~~~~~~~~~~~~~~~ if (byte < 0) ~~~~~~~~~~~~~ error("Unexpected end of file.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return byte; ~~~~~~~~~~~~ } ~ static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ ofs << byte; ~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_bits(std::istream &ifs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // skip initial comments until preamble is found ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t preamble = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (1) ~~~~~~~~~ { ~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preamble = (preamble << 8) | byte; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0xffffffff) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("No preamble found in bitstream.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0x7EAA997E) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Found preamble at offset %d.\n", file_offset-4); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ initblop.push_back(byte); ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ // main parser loop ~~~~~~~~~~~~~~~~~~~ int current_bank = 0; ~~~~~~~~~~~~~~~~~~~~~ int current_width = 0; ~~~~~~~~~~~~~~~~~~~~~~ int current_height = 0; ~~~~~~~~~~~~~~~~~~~~~~~ int current_offset = 0; ~~~~~~~~~~~~~~~~~~~~~~~ bool wakeup = false; ~~~~~~~~~~~~~~~~~~~~ this->cram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (!wakeup) ~~~~~~~~~~~~~~~ { ~ // one command byte. the lower 4 bits of the command byte specify ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // the length of the command payload. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t command = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t payload = 0; ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (command & 0x0f); i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command, 2*(command & 0x0f), payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t end_token; ~~~~~~~~~~~~~~~~~~~ switch (command & 0xf0) ~~~~~~~~~~~~~~~~~~~~~~~ { ~ case 0x00: ~~~~~~~~~~ switch (payload) ~~~~~~~~~~~~~~~~ { ~ case 0x01: ~~~~~~~~~~ info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = std::max(this->cram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = std::max(this->cram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x03: ~~~~~~~~~~ info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = std::max(this->bram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = std::max(this->bram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x05: ~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x06: ~~~~~~~~~~ info("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~ wakeup = true; ~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ break; ~~~~~~ case 0x10: ~~~~~~~~~~ current_bank = payload; ~~~~~~~~~~~~~~~~~~~~~~~ debug("Set bank to %d.\n", current_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x20: ~~~~~~~~~~ if (crc_value != 0) ~~~~~~~~~~~~~~~~~~~ error("CRC Check FAILED.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("CRC Check OK.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x50: ~~~~~~~~~~ if (payload == 0) ~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 1) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "medium"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 2) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "high"; ~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x60: ~~~~~~~~~~ current_width = payload + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank width to %d.\n", current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x70: ~~~~~~~~~~ current_height = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank height to %d.\n", current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x80: ~~~~~~~~~~ current_offset = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank offset to %d.\n", current_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x90: ~~~~~~~~~~ switch(payload) ~~~~~~~~~~~~~~~ { ~ case 0: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 1: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 32: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 33: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown warmboot/nosleep payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ if (this->cram_width == 182 && this->cram_height == 80) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "384"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 332 && this->cram_height == 144) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "1k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 872 && this->cram_height == 272) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "8k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 336) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "5k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "u4k"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 656 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "lm4k"; ~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Failed to detect chip type.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Chip type is '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::write_bits(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto byte : this->initblop) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << byte; ~~~~~~~~~~~~ debug("Writing preamble.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0xAA); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x99); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x51); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->freqrange == "low") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "medium") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "high") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x02); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x05); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ { ~ uint8_t nosleep_flag; ~~~~~~~~~~~~~~~~~~~~~ debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x92); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->nosleep == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 0; ~~~~~~~~~~~~~~~~~ else if (this->nosleep == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 1; ~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->warmboot == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank width to %d.\n", this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank offset to 0.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_bank = 0; cram_bank < 4; cram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector cram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int height = this->cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((cram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ height = height / 2 + 8; ~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_y = 0; cram_y < height; cram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_x = 0; cram_x < this->cram_width; cram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank %d.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Writing bank %d data.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(cram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ int bram_chunk_size = 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->bram_width && this->bram_height) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Setting bank height to %d.\n", this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_bank = 0; bram_bank < 4; bram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("BRAM: Setting bank %d.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector bram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int width = this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((bram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ width = width / 2; ~~~~~~~~~~~~~~~~~~ for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_x = 0; bram_x < width; bram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank offset to %d.\n", offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Writing bank %d data.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x03); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(bram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ debug("Writing CRC value.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x22); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_hi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_lo); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x06); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Padding byte.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool got_device = false; ~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.clear(); ~~~~~~~~~~~~~~~~~~~ this->bram.clear(); ~~~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool reuse_line = true; ~~~~~~~~~~~~~~~~~~~~~~~ string line, command; ~~~~~~~~~~~~~~~~~~~~~ while (reuse_line || getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ reuse_line = false; ~~~~~~~~~~~~~~~~~~~ std::istringstream is(line); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> command; ~~~~~~~~~~~~~~ if (command.empty()) ~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ debug("Next command: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".comment") ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ this->initblop.clear(); ~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while (getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (auto ch : line) ~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(ch); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".device") ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (got_device) ~~~~~~~~~~~~~~~ error("More than one .device statement.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> this->device; ~~~~~~~~~~~~~~~~~~~ if (this->device == "384") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 182; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 80; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "1k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 332; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 144; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 64; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "8k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 872; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 272; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 128; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 336; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 160; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "u4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "lm4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 656; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ error("Unsupported chip type '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } else { ~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->bram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ got_device = true; ~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".warmboot") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ is >> this->warmboot; ~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "disabled" && ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown warmboot setting '%s'.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ // No ".nosleep" section despite sharing the same byte as .warmboot. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ".nosleep" is specified when icepack is invoked, which is too late. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // So we inject the section based on command line argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (nosleep) ~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ CramIndexConverter cic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (("." + cic.tile_type + "_tile") != command) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Got %s statement for %s tile %d %d.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (line[bit_x] == '1') { ~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".ram_data") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ BramIndexConverter bic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int value = -1; ~~~~~~~~~~~~~~~ if ('0' <= line[ch_idx] && line[ch_idx] <= '9') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - '0'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'a' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'A' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (value < 0) ~~~~~~~~~~~~~~ error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((value & (1 << i)) != 0) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[bram_bank][bram_x][bram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".extra_bit") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> cram_bank >> cram_x >> cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".sym") ~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ if (command.substr(0, 1) == ".") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown statement: %s\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unexpected data line: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ void FpgaConfig::write_ascii(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << ".comment"; ~~~~~~~~~~~~~~~~~~ bool insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto ch : this->initblop) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (ch == 0) { ~~~~~~~~~~~~~~ insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~ } else if (ch == 0xff) { ~~~~~~~~~~~~~~~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } else { ~~~~~~~~ if (insert_newline) ~~~~~~~~~~~~~~~~~~~ ofs << '\n'; ~~~~~~~~~~~~ ofs << ch; ~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ ofs << stringf("\n.device %s\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // As "nosleep" is an icepack command, we do not write out a ".nosleep" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // section. However, we parse it in read_bits() and notify the user in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // info. ~~~~~~~~ typedef std::tuple tile_bit_t; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ std::set tile_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int y = 0; y <= this->chip_height()+1; y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x <= this->chip_width()+1; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ CramIndexConverter cic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cic.tile_type == "corner" || cic.tile_type == "unsupported") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cram_x > int(this->cram[cram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ if (cram_y > int(this->cram[cram_bank][cram_x].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ ofs << '\n'; ~~~~~~~~~~~~ } ~ if (cic.tile_type == "ramb") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ BramIndexConverter bic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".ram_data %d %d\n", x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int value = 0; ~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (bram_x >= int(this->bram[bram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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:924:8: note: in expansion of macro 'error' 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: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=] #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string vstringf(const char *fmt, va_list ap) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ char *str = NULL; ~~~~~~~~~~~~~~~~~ #ifdef _WIN32 ~~~~~~~~~~~~~ int sz = 64, rc; ~~~~~~~~~~~~~~~~ while (1) { ~~~~~~~~~~~ va_list apc; ~~~~~~~~~~~~ va_copy(apc, ap); ~~~~~~~~~~~~~~~~~ str = (char*)realloc(str, sz); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rc = vsnprintf(str, sz, fmt, apc); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(apc); ~~~~~~~~~~~~ if (rc >= 0 && rc < sz) ~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ sz *= 2; ~~~~~~~~ } ~ #else ~~~~~ if (vasprintf(&str, fmt, ap) < 0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ str = NULL; ~~~~~~~~~~~ #endif ~~~~~~ if (str != NULL) { ~~~~~~~~~~~~~~~~~~ string = str; ~~~~~~~~~~~~~ free(str); ~~~~~~~~~~ } ~ return string; ~~~~~~~~~~~~~~ } ~ string stringf(const char *fmt, ...) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ string string; ~~~~~~~~~~~~~~ va_list ap; ~~~~~~~~~~~ va_start(ap, fmt); ~~~~~~~~~~~~~~~~~~ string = vstringf(fmt, ap); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ va_end(ap); ~~~~~~~~~~~ return string; ~~~~~~~~~~~~~~ } ~ // ================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FpgaConfig stuff ~~~~~~~~~~~~~~~~~~~ struct FpgaConfig ~~~~~~~~~~~~~~~~~ { ~ string device; ~~~~~~~~~~~~~~ string freqrange; ~~~~~~~~~~~~~~~~~ string nosleep; ~~~~~~~~~~~~~~~ string warmboot; ~~~~~~~~~~~~~~~~ // cram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int cram_width, cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> cram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bram[BANK][X][Y] ~~~~~~~~~~~~~~~~~~~ int bram_width, bram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vector>> bram; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // data before preamble ~~~~~~~~~~~~~~~~~~~~~~~ vector initblop; ~~~~~~~~~~~~~~~~~~~~~~~~~ // bitstream i/o ~~~~~~~~~~~~~~~~ void read_bits(std::istream &ifs); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bits(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // icebox i/o ~~~~~~~~~~~~~ void read_ascii(std::istream &ifs, bool nosleep); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_ascii(std::ostream &ofs) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // netpbm i/o ~~~~~~~~~~~~~ void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query chip type metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~ int chip_width() const; ~~~~~~~~~~~~~~~~~~~~~~~ int chip_height() const; ~~~~~~~~~~~~~~~~~~~~~~~~ vector chip_cols() const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // query tile metadata ~~~~~~~~~~~~~~~~~~~~~~ string tile_type(int x, int y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_width(const string &type) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // cram bit manipulation ~~~~~~~~~~~~~~~~~~~~~~~~ void cram_clear(); ~~~~~~~~~~~~~~~~~~ void cram_fill_tiles(); ~~~~~~~~~~~~~~~~~~~~~~~ void cram_checkerboard(int m = 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct CramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ string tile_type; ~~~~~~~~~~~~~~~~~ int tile_width; ~~~~~~~~~~~~~~~ int column_width; ~~~~~~~~~~~~~~~~~ bool left_right_io; ~~~~~~~~~~~~~~~~~~~ bool right_half; ~~~~~~~~~~~~~~~~ bool top_half; ~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_tx; ~~~~~~~~~~~~ int bank_ty; ~~~~~~~~~~~~ int bank_xoff; ~~~~~~~~~~~~~~ int bank_yoff; ~~~~~~~~~~~~~~ CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ struct BramIndexConverter ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ const FpgaConfig *fpga; ~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ int bank_num; ~~~~~~~~~~~~~ int bank_off; ~~~~~~~~~~~~~ BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }; ~~ static void update_crc16(uint16_t &crc, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 7; i >= 0; i--) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc = (crc << 1) ^ xor_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int byte = ifs.get(); ~~~~~~~~~~~~~~~~~~~~~ if (byte < 0) ~~~~~~~~~~~~~ error("Unexpected end of file.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return byte; ~~~~~~~~~~~~ } ~ static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ ofs << byte; ~~~~~~~~~~~~ file_offset++; ~~~~~~~~~~~~~~ update_crc16(crc_value, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_bits(std::istream &ifs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // skip initial comments until preamble is found ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t preamble = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (1) ~~~~~~~~~ { ~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preamble = (preamble << 8) | byte; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0xffffffff) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("No preamble found in bitstream.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (preamble == 0x7EAA997E) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Found preamble at offset %d.\n", file_offset-4); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ initblop.push_back(byte); ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ initblop.pop_back(); ~~~~~~~~~~~~~~~~~~~~ // main parser loop ~~~~~~~~~~~~~~~~~~~ int current_bank = 0; ~~~~~~~~~~~~~~~~~~~~~ int current_width = 0; ~~~~~~~~~~~~~~~~~~~~~~ int current_height = 0; ~~~~~~~~~~~~~~~~~~~~~~~ int current_offset = 0; ~~~~~~~~~~~~~~~~~~~~~~~ bool wakeup = false; ~~~~~~~~~~~~~~~~~~~~ this->cram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ while (!wakeup) ~~~~~~~~~~~~~~~ { ~ // one command byte. the lower 4 bits of the command byte specify ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // the length of the command payload. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t command = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32_t payload = 0; ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (command & 0x0f); i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command, 2*(command & 0x0f), payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint16_t end_token; ~~~~~~~~~~~~~~~~~~~ switch (command & 0xf0) ~~~~~~~~~~~~~~~~~~~~~~~ { ~ case 0x00: ~~~~~~~~~~ switch (payload) ~~~~~~~~~~~~~~~~ { ~ case 0x01: ~~~~~~~~~~ info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = std::max(this->cram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = std::max(this->cram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x03: ~~~~~~~~~~ info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_bank, current_width, current_height, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ current_height*current_width, (current_height*current_width)/8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = std::max(this->bram_width, current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = std::max(this->bram_height, current_offset + current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < current_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < (current_height*current_width)/8; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = (i*8 + j) % current_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int y = (i*8 + j) / current_width + current_offset; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ end_token = read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (end_token) ~~~~~~~~~~~~~~ error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x05: ~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x06: ~~~~~~~~~~ info("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~ wakeup = true; ~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ break; ~~~~~~ case 0x10: ~~~~~~~~~~ current_bank = payload; ~~~~~~~~~~~~~~~~~~~~~~~ debug("Set bank to %d.\n", current_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x20: ~~~~~~~~~~ if (crc_value != 0) ~~~~~~~~~~~~~~~~~~~ error("CRC Check FAILED.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("CRC Check OK.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x50: ~~~~~~~~~~ if (payload == 0) ~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 1) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "medium"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (payload == 2) ~~~~~~~~~~~~~~~~~~~~~~ this->freqrange = "high"; ~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x60: ~~~~~~~~~~ current_width = payload + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank width to %d.\n", current_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x70: ~~~~~~~~~~ current_height = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank height to %d.\n", current_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x80: ~~~~~~~~~~ current_offset = payload; ~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting bank offset to %d.\n", current_offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 0x90: ~~~~~~~~~~ switch(payload) ~~~~~~~~~~~~~~~ { ~ case 0: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 1: ~~~~~~~ this->warmboot = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 32: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ case 33: ~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown warmboot/nosleep payload 0x%02x\n", payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ default: ~~~~~~~~ error("Unknown command: 0x%02x 0x%02x\n", command, payload); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ if (this->cram_width == 182 && this->cram_height == 80) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "384"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 332 && this->cram_height == 144) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "1k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 872 && this->cram_height == 272) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "8k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 336) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "5k"; ~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 692 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "u4k"; ~~~~~~~~~~~~~~~~~~~~~ else if (this->cram_width == 656 && this->cram_height == 176) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->device = "lm4k"; ~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Failed to detect chip type.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Chip type is '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::write_bits(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int file_offset = 0; ~~~~~~~~~~~~~~~~~~~~ uint16_t crc_value = 0; ~~~~~~~~~~~~~~~~~~~~~~~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing bitstream file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto byte : this->initblop) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << byte; ~~~~~~~~~~~~ debug("Writing preamble.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0xAA); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x99); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x7E); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x51); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->freqrange == "low") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "medium") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->freqrange == "high") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x02); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Resetting CRC.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x05); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ crc_value = 0xffff; ~~~~~~~~~~~~~~~~~~~ { ~ uint8_t nosleep_flag; ~~~~~~~~~~~~~~~~~~~~~ debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x92); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->nosleep == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 0; ~~~~~~~~~~~~~~~~~ else if (this->nosleep == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nosleep_flag = 1; ~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot == "disabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (this->warmboot == "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank width to %d.\n", this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank offset to 0.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_bank = 0; cram_bank < 4; cram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector cram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int height = this->cram_height; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((cram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ height = height / 2 + 8; ~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_y = 0; cram_y < height; cram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int cram_x = 0; cram_x < this->cram_width; cram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Setting bank height to %d.\n", height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("CRAM: Setting bank %d.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("CRAM: Writing bank %d data.\n", cram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(cram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ int bram_chunk_size = 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->bram_width && this->bram_height) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if(this->device != "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Setting bank height to %d.\n", this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x72); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_chunk_size); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_bank = 0; bram_bank < 4; bram_bank++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("BRAM: Setting bank %d.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x11); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ vector bram_bits; ~~~~~~~~~~~~~~~~~~~~~~~ int width = this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k" && ((bram_bank % 2) == 1)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ width = width / 2; ~~~~~~~~~~~~~~~~~~ for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bram_x = 0; bram_x < width; bram_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank offset to %d.\n", offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x82); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, offset); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("BRAM: Setting bank width to %d.\n", width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x62); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1) >> 8); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, (width-1)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ debug("BRAM: Writing bank %d data.\n", bram_bank); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x03); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < int(bram_bits.size()); i += 8) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t byte = 0; ~~~~~~~~~~~~~~~~~ for (int j = 0; j < 8; j++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, byte); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ debug("Writing CRC value.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x22); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_hi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, crc_lo); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Wakeup.\n"); ~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x01); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x06); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ debug("Padding byte.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~ write_byte(ofs, crc_value, file_offset, 0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Parsing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool got_device = false; ~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.clear(); ~~~~~~~~~~~~~~~~~~~ this->bram.clear(); ~~~~~~~~~~~~~~~~~~~ this->freqrange = "low"; ~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool reuse_line = true; ~~~~~~~~~~~~~~~~~~~~~~~ string line, command; ~~~~~~~~~~~~~~~~~~~~~ while (reuse_line || getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ reuse_line = false; ~~~~~~~~~~~~~~~~~~~ std::istringstream is(line); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> command; ~~~~~~~~~~~~~~ if (command.empty()) ~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ debug("Next command: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".comment") ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ this->initblop.clear(); ~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while (getline(ifs, line)) ~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (auto ch : line) ~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(ch); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->initblop.push_back(0x00); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->initblop.push_back(0xff); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".device") ~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (got_device) ~~~~~~~~~~~~~~~ error("More than one .device statement.\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> this->device; ~~~~~~~~~~~~~~~~~~~ if (this->device == "384") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 182; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 80; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 0; ~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 0; ~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "1k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 332; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 144; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 64; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "8k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 872; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 272; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 128; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 336; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 160; ~~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "u4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 692; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ if (this->device == "lm4k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram_width = 656; ~~~~~~~~~~~~~~~~~~~~~~~ this->cram_height = 176; ~~~~~~~~~~~~~~~~~~~~~~~~ this->bram_width = 80; ~~~~~~~~~~~~~~~~~~~~~~ this->bram_height = 2 * 128; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } else ~~~~~~ error("Unsupported chip type '%s'.\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ if(this->device == "5k") { ~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } else { ~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i].resize(this->cram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->cram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[i][x].resize(this->cram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ this->bram.resize(4); ~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i].resize(this->bram_width); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x < this->bram_width; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[i][x].resize(this->bram_height); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ got_device = true; ~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".warmboot") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ is >> this->warmboot; ~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "disabled" && ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown warmboot setting '%s'.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ // No ".nosleep" section despite sharing the same byte as .warmboot. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ".nosleep" is specified when icepack is invoked, which is too late. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // So we inject the section based on command line argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (nosleep) ~~~~~~~~~~~~ this->nosleep = "enabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ else ~~~~ this->nosleep = "disabled"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ CramIndexConverter cic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (("." + cic.tile_type + "_tile") != command) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Got %s statement for %s tile %d %d.\n", ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (line[bit_x] == '1') { ~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".ram_data") ~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int tile_x, tile_y; ~~~~~~~~~~~~~~~~~~~ is >> tile_x >> tile_y; ~~~~~~~~~~~~~~~~~~~~~~~ BramIndexConverter bic(this, tile_x, tile_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (line.substr(0, 1) == ".") { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reuse_line = true; ~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ int value = -1; ~~~~~~~~~~~~~~~ if ('0' <= line[ch_idx] && line[ch_idx] <= '9') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - '0'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'a' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ value = line[ch_idx] - 'A' + 10; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (value < 0) ~~~~~~~~~~~~~~ error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((value & (1 << i)) != 0) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->bram[bram_bank][bram_x][bram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ } ~ continue; ~~~~~~~~~ } ~ if (command == ".extra_bit") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ if (!got_device) ~~~~~~~~~~~~~~~~ error("Missing .device statement before %s.\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is >> cram_bank >> cram_x >> cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this->cram[cram_bank][cram_x][cram_y] = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ } ~ if (command == ".sym") ~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ if (command.substr(0, 1) == ".") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unknown statement: %s\n", command.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("Unexpected data line: %s\n", line.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ void FpgaConfig::write_ascii(std::ostream &ofs) const ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ debug("## %s\n", __PRETTY_FUNCTION__); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ info("Writing ascii file..\n"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << ".comment"; ~~~~~~~~~~~~~~~~~~ bool insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (auto ch : this->initblop) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (ch == 0) { ~~~~~~~~~~~~~~ insert_newline = true; ~~~~~~~~~~~~~~~~~~~~~~ } else if (ch == 0xff) { ~~~~~~~~~~~~~~~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } else { ~~~~~~~~ if (insert_newline) ~~~~~~~~~~~~~~~~~~~ ofs << '\n'; ~~~~~~~~~~~~ ofs << ch; ~~~~~~~~~~ insert_newline = false; ~~~~~~~~~~~~~~~~~~~~~~~ } ~ } ~ ofs << stringf("\n.device %s\n", this->device.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (this->warmboot != "enabled") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // As "nosleep" is an icepack command, we do not write out a ".nosleep" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // section. However, we parse it in read_bits() and notify the user in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // info. ~~~~~~~~ typedef std::tuple tile_bit_t; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ std::set tile_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int y = 0; y <= this->chip_height()+1; y++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int x = 0; x <= this->chip_width()+1; x++) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ CramIndexConverter cic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cic.tile_type == "corner" || cic.tile_type == "unsupported") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ continue; ~~~~~~~~~ ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int cram_bank, cram_x, cram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (cram_x > int(this->cram[cram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ if (cram_y > int(this->cram[cram_bank][cram_x].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~ ofs << '\n'; ~~~~~~~~~~~~ } ~ if (cic.tile_type == "ramb") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { ~ BramIndexConverter bic(this, x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ofs << stringf(".ram_data %d %d\n", x, y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_y = 0; bit_y < 16; bit_y++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int value = 0; ~~~~~~~~~~~~~~ for (int i = 0; i < 4; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int bram_bank, bram_x, bram_y; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (bram_x >= int(this->bram[bram_bank].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break; ~~~~~~ } ~ if (bram_y >= int(this->bram[bram_bank][bram_x].size())) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ icepack.cc:928:8: note: in expansion of macro 'error' error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); ^~~~~ cc -o iceprog -Wl,-z,relro -Wl,-z,now -Wl,--as-needed iceprog.o -L/usr/local/lib -lm -lftdi make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/iceprog' make -C icemulti all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 icemulti -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icemulti.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' make -C icepll all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 g++ -o icepll -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icepll.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' make -C icetime all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' python3 timings.py > timings.inc.new mv timings.inc.new timings.inc g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 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~20181109git9671b76/icepack' make -C icebram all make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebram' g++ -g -O2 -ffile-prefix-map=/build/fpga-icestorm-0~20181109git9671b76=. -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 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~20181109git9671b76/icebram' python3 icebox_chipdb.py -8 > chipdb-8k.new mv chipdb-1k.new chipdb-1k.txt python3 icebox_chipdb.py -5 > chipdb-5k.new mv chipdb-5k.new chipdb-5k.txt python3 icebox_chipdb.py -4 > chipdb-lm4k.new mv chipdb-8k.new chipdb-8k.txt mv chipdb-lm4k.new chipdb-lm4k.txt make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' In file included from /usr/include/c++/8/vector:69, from icetime.cc:35: /usr/include/c++/8/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++/8/bits/vector.tcc:413:7: note: parameter passing for argument of type 'std::vector > >::iterator' {aka '__gnu_cxx::__normal_iterator >*, std::vector > > >'} changed in GCC 7.1 vector<_Tp, _Alloc>:: ^~~~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/8/map:60, from icetime.cc:31: /usr/include/c++/8/bits/stl_tree.h: In member 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, double>; _KeyOfValue = std::_Select1st, double> >; _Compare = std::less >; _Alloc = std::allocator, double> >]': /usr/include/c++/8/bits/stl_tree.h:2411:7: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/8/bits/stl_tree.h: In member 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 >, 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++/8/bits/stl_tree.h:2411:7: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > >'} changed in GCC 7.1 In file included from /usr/include/c++/8/map:61, from icetime.cc:31: /usr/include/c++/8/bits/stl_map.h: In member function 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::__cxx11::basic_string; _Tp = 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++/8/bits/stl_map.h:499:8: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, double> > >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h: In member function 'double TimingAnalysis::calc_net_max_path_delay(const string&)': /usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type 'std::_Rb_tree, std::pair, double>, std::_Select1st, double> >, std::less >, std::allocator, double> > >::const_iterator' {aka 'std::_Rb_tree_const_iterator, double> >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, In file included from /usr/include/c++/8/map:60, from icetime.cc:31: /usr/include/c++/8/bits/stl_tree.h: In member 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++/8/bits/stl_tree.h:2411: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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >'} changed in GCC 7.1 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/8/map:61, from icetime.cc:31: /usr/include/c++/8/bits/stl_map.h: In member function 'double TimingAnalysis::report(std::__cxx11::string)': /usr/include/c++/8/bits/stl_map.h:499:8: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, In file included from /usr/include/c++/8/vector:69, from icetime.cc:35: /usr/include/c++/8/bits/vector.tcc:109:4: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator >*, std::vector > > >' changed in GCC 7.1 _M_realloc_insert(end(), std::forward<_Args>(__args)...); ^~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/8/map:61, from icetime.cc:31: /usr/include/c++/8/bits/stl_map.h: In constructor 'TimingAnalysis::TimingAnalysis(bool)': /usr/include/c++/8/bits/stl_map.h:499:8: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, /usr/include/c++/8/bits/stl_map.h:499:8: 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' {aka 'std::_Rb_tree_const_iterator, std::tuple, std::allocator >, std::__cxx11::basic_string, std::allocator > > > >'} changed in GCC 7.1 __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, g++ -o icetime -Wl,-z,relro -Wl,-z,now -Wl,--as-needed icetime.o iceutil.o -lm -lstdc++ make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' make[1]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' 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~20181109git9671b76' PREFIX=/usr dh_auto_install make -j3 install DESTDIR=/build/fpga-icestorm-0\~20181109git9671b76/debian/tmp AM_UPDATE_INFO_DIR=no "INSTALL=install --strip-program=true" make[2]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76' for dir in icebox icepack iceprog icemulti icepll icetime icebram; do \ make -C $dir install || exit; \ done make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python cp chipdb-384.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-1k.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-8k.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-5k.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp chipdb-lm4k.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ cp icebox.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox.py cp iceboxdb.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/iceboxdb.py cp icebox_chipdb.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_chipdb cp icebox_diff.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_diff cp icebox_explain.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_explain cp icebox_asc2hlc.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_asc2hlc cp icebox_hlc2asc.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_hlc2asc cp icebox_colbuf.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_colbuf cp icebox_html.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_html cp icebox_maps.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_maps cp icebox_vlog.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_vlog cp icebox_stat.py /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/python/icebox_stat make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icebox' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepack' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin cp icepack /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/icepack ln -sf icepack /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/iceunpack make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icepack' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/iceprog' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin cp iceprog /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/iceprog make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/iceprog' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin cp icemulti /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/icemulti make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icemulti' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin cp icepll /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/icepll make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icepll' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/icebox cp icetime /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/icetime cp ../icefuzz/timings_*.txt /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/share/fpga-icestorm/chipdb/ make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icetime' make[3]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76/icebram' mkdir -p /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin cp icebram /build/fpga-icestorm-0~20181109git9671b76/debian/tmp/usr/bin/icebram make[3]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76/icebram' make[2]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' make[1]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' dh_install dh_installdocs dh_installchangelogs debian/rules override_dh_installman make[1]: Entering directory '/build/fpga-icestorm-0~20181109git9671b76' cd debian/man ; CHANGELOG_DATE="20 December 2018" ./genmanpages.sh dh_installman make[1]: Leaving directory '/build/fpga-icestorm-0~20181109git9671b76' dh_perl dh_link dh_strip_nondeterminism dh_compress dh_fixperms dh_missing dh_strip dh_makeshlibs dh_shlibdeps 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 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/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/icemulti 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' in '../fpga-icestorm_0~20181109git9671b76-1_armhf.deb'. dpkg-deb: building package 'fpga-icestorm-chipdb' in '../fpga-icestorm-chipdb_0~20181109git9671b76-1_all.deb'. dpkg-deb: building package 'fpga-icestorm-dbgsym' in '../fpga-icestorm-dbgsym_0~20181109git9671b76-1_armhf.deb'. dpkg-genbuildinfo --build=binary dpkg-genchanges --build=binary >../fpga-icestorm_0~20181109git9671b76-1_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) I: copying local configuration 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/22101 and its subdirectories I: Current time: Sat Jul 18 20:19:20 -12 2020 I: pbuilder-time-stamp: 1595146760 Sun Jul 19 08:20:35 UTC 2020 I: 1st build successful. Starting 2nd build on remote node ff64a-armhf-rb.debian.net. Sun Jul 19 08:20:35 UTC 2020 I: Preparing to do remote build '2' on ff64a-armhf-rb.debian.net. Sun Jul 19 08:43:50 UTC 2020 I: Deleting $TMPDIR on ff64a-armhf-rb.debian.net. Sun Jul 19 08:43:53 UTC 2020 I: fpga-icestorm_0~20181109git9671b76-1_armhf.changes: Format: 1.8 Date: Thu, 20 Dec 2018 11:09:19 +0100 Source: fpga-icestorm Binary: fpga-icestorm fpga-icestorm-chipdb fpga-icestorm-dbgsym Architecture: all armhf Version: 0~20181109git9671b76-1 Distribution: unstable Urgency: medium Maintainer: Debian Electronics Team Changed-By: Ruben Undheim Description: fpga-icestorm - Tools to handle the bitstream format of Lattice iCE40 FPGAs fpga-icestorm-chipdb - Chip database files for fpga-icestorm Changes: fpga-icestorm (0~20181109git9671b76-1) unstable; urgency=medium . * New upstream GIT HEAD * debian/patches: Refreshed patches Checksums-Sha1: ceffeb18d5b68cb86004b75f44ba6b377ea9338e 6829396 fpga-icestorm-chipdb_0~20181109git9671b76-1_all.deb 41f0ffdbf31ed907a9ca32b5ed5e11b195c4a5cf 2787724 fpga-icestorm-dbgsym_0~20181109git9671b76-1_armhf.deb adaea08a85a8f25c5f7d59666535550982275aaa 5620 fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo ad0a205942cef546e139a226cee5ab575d96765a 354224 fpga-icestorm_0~20181109git9671b76-1_armhf.deb Checksums-Sha256: 90f6a6077291d895ebff3f92a72649f5a43bbc9681ce2b7a3d5b8d6e3e970327 6829396 fpga-icestorm-chipdb_0~20181109git9671b76-1_all.deb fc8d2f1ae2829cfb7a5b596cda9eef922005ad7e48f13724f77c9eedef09ccdb 2787724 fpga-icestorm-dbgsym_0~20181109git9671b76-1_armhf.deb 29547b871e68f7249a5eeaf751e0facc0931435818a67084fdd8907ff68d8664 5620 fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo e669885b4bb0c9b088a09a7964a632fe534e06d3f318ca074794f4bd5850db0a 354224 fpga-icestorm_0~20181109git9671b76-1_armhf.deb Files: eb0eb0008352857a53a2ad8f9e9bdccb 6829396 electronics optional fpga-icestorm-chipdb_0~20181109git9671b76-1_all.deb a8471bcca657f3854c3be5a5a79e0aff 2787724 debug optional fpga-icestorm-dbgsym_0~20181109git9671b76-1_armhf.deb a91440b4dbca19578bb422024318d281 5620 electronics optional fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo beaa97d6f27cbe3acdeffc4d87e171d2 354224 electronics optional fpga-icestorm_0~20181109git9671b76-1_armhf.deb Sun Jul 19 08:43:54 UTC 2020 I: diffoscope 152 will be used to compare the two builds: # Profiling output for: /usr/bin/diffoscope --html /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/fpga-icestorm_0~20181109git9671b76-1.diffoscope.html --text /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/fpga-icestorm_0~20181109git9671b76-1.diffoscope.txt --json /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/fpga-icestorm_0~20181109git9671b76-1.diffoscope.json --profile=- /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/b1/fpga-icestorm_0~20181109git9671b76-1_armhf.changes /srv/reproducible-results/rbuild-debian/tmp.RkABcgq4sb/b2/fpga-icestorm_0~20181109git9671b76-1_armhf.changes ## command (total time: 0.000s) 0.000s 1 call cmp (internal) ## has_same_content_as (total time: 0.000s) 0.000s 1 call abc.DotChangesFile ## main (total time: 0.364s) 0.364s 2 calls outputs 0.000s 1 call cleanup ## recognizes (total time: 0.156s) 0.156s 10 calls diffoscope.comparators.binary.FilesystemFile 0.000s 8 calls abc.DotChangesFile Sun Jul 19 08:43:56 UTC 2020 I: diffoscope 152 found no differences in the changes files, and a .buildinfo file also exists. Sun Jul 19 08:43:56 UTC 2020 I: fpga-icestorm from buster built successfully and reproducibly on armhf. Sun Jul 19 08:43:57 UTC 2020 I: Submitting .buildinfo files to external archives: Sun Jul 19 08:43:57 UTC 2020 I: Submitting 8.0K b1/fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo.asc Sun Jul 19 08:43:58 UTC 2020 I: Submitting 8.0K b2/fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo.asc Sun Jul 19 08:43:59 UTC 2020 I: Done submitting .buildinfo files to http://buildinfo.debian.net/api/submit. Sun Jul 19 08:43:59 UTC 2020 I: Done submitting .buildinfo files. Sun Jul 19 08:43:59 UTC 2020 I: Removing signed fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo.asc files: removed './b1/fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo.asc' removed './b2/fpga-icestorm_0~20181109git9671b76-1_armhf.buildinfo.asc'