whitequark [Fri, 6 Nov 2020 01:31:14 +0000 (01:31 +0000)]
vendor.lattice_{ice40,ecp5}: clean up $verilog_initial_trigger wires.
These only matter in simulation and after conversion to Verilog.
During synthesis they cause Yosys to produce warnings:
Warning: Wire $verilog_initial_trigger has an unprocessed 'init' attribute.
awygle [Fri, 6 Nov 2020 01:10:39 +0000 (17:10 -0800)]
hdl.rec: migrate Record from UserValue to ValueCastable.
Closes #528.
awygle [Fri, 6 Nov 2020 00:20:54 +0000 (16:20 -0800)]
hdl.ast: implement ValueCastable.
Closes RFC issue #355.
whitequark [Thu, 5 Nov 2020 07:36:13 +0000 (07:36 +0000)]
vendor.quicklogic: part→package
Norbert Braun [Mon, 2 Nov 2020 21:00:17 +0000 (22:00 +0100)]
vendor.xilinx_7series: byte swap generated bitstream
The Zynq driver in the FPGA Manager framework on Linux expects bitstreams that
are byte swapped with respect to what the Vivado command
`write_bitstream -bin_file` produces. Thus, use the `write_cfgmem` command with
appropriate options to generate the bitstream (.bin file).
Fixes #519.
Jaro Habiger [Tue, 18 Aug 2020 11:11:30 +0000 (13:11 +0200)]
lib.fifo: fix {r,w}_level in AsyncFIFOBuffered
Jaro Habiger [Tue, 3 Nov 2020 09:10:07 +0000 (10:10 +0100)]
lib.fifo: fix level on fifo full
David Lattimore [Mon, 2 Nov 2020 06:19:47 +0000 (17:19 +1100)]
vendor.lattice_ice40: zero-pad CLKHF_DIV in SB_HFOSC instance.
Fixes #520.
Jan Kowalewski [Wed, 21 Oct 2020 12:24:41 +0000 (14:24 +0200)]
vendor.quicklogic: utilize internal SoC clock in EOS-S3
Signed-off-by: Jan Kowalewski <jkowalewski@antmicro.com>
Jan Kowalewski [Tue, 20 Oct 2020 10:46:58 +0000 (12:46 +0200)]
vendor.quicklogic: fix toolchain nomenclature
Signed-off-by: Jan Kowalewski <jkowalewski@antmicro.com>
Robin Ole Heinemann [Tue, 27 Oct 2020 23:41:01 +0000 (00:41 +0100)]
lib.fifo.AsyncFFSynchronizer: check input and output signal width
Ben Newhouse [Tue, 27 Oct 2020 01:16:25 +0000 (01:16 +0000)]
setup: link to latest docs if VCS information is not available.
whitequark [Mon, 26 Oct 2020 19:50:21 +0000 (19:50 +0000)]
build.dsl: clean up inversion logic.
* Add invert= argument to DiffPairs() constructor, like in Pins().
* Make PinsN() and DiffPairsN() pass invert= to the corresponding
construtor instead of mutating.
whitequark [Sun, 25 Oct 2020 01:59:46 +0000 (01:59 +0000)]
back.{verilog,rtlil}: adjust $verilog_initial_trigger insertion.
To track upstream changes.
whitequark [Sun, 25 Oct 2020 00:13:39 +0000 (00:13 +0000)]
CI: disable codecov project status.
Every PR should be covered by tests, and codecov patch statuses are
extremely useful. However, codecov project statuses mostly create
noise because project-wide coverage in nMigen is currently primarily
informational.
anuejn [Sat, 24 Oct 2020 14:58:23 +0000 (16:58 +0200)]
lib.fifo.AsyncFIFO: fix incorrect latency of r_level.
Co-authored-by: Andrew Wygle <awygle@gmail.com>
anuejn [Thu, 22 Oct 2020 21:38:44 +0000 (23:38 +0200)]
tests: make spec directory name unique per test method.
whitequark [Thu, 22 Oct 2020 16:08:38 +0000 (16:08 +0000)]
sim._pyrtl: sign extend RHS of assignment.
Fixes #502.
whitequark [Thu, 22 Oct 2020 13:23:06 +0000 (13:23 +0000)]
hdl.dsl: error on Elif immediately nested in an If.
I.e. on this code, which is currently not only wrongly accepted but
also results in completely unexpected RTL:
with m.If(...):
with m.Elif(...):
...
Fixes #500.
Jan Kowalewski [Mon, 19 Oct 2020 10:09:50 +0000 (12:09 +0200)]
vendor.quicklogic: fix syntax
Signed-off-by: Jan Kowalewski <jkowalewski@antmicro.com>
Xiretza [Mon, 19 Oct 2020 17:23:43 +0000 (19:23 +0200)]
setup.py: Exclude "tests" package
67b957d moved the tests from nmigen/test/ to tests/, and removed the
exclude= parameter from find_packages() in setup.py. However, even if
the new location is not inside the module tree, it is still found by
find_packages(), resulting in a stray "tests" module on the system.
Xiretza [Fri, 16 Oct 2020 16:36:56 +0000 (18:36 +0200)]
hdl.ir: Update error message for Instance arguments
48d4ee4 added the option to specify attributes using Instance arguments,
but the error message wasn't updated accordingly.
whitequark [Thu, 15 Oct 2020 18:10:39 +0000 (18:10 +0000)]
README: Quicklogic EOS S3 is now supported.
whitequark [Thu, 15 Oct 2020 18:09:04 +0000 (18:09 +0000)]
CI: fix code coverage collection.
This has been broken since commit
d71e19e2 (2020-07-22).
Jan Kowalewski [Thu, 15 Oct 2020 18:02:25 +0000 (20:02 +0200)]
vendor.quicklogic: new platform.
Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
Signed-off-by: Jan Kowalewski <jkowalewski@antmicro.com>
Co-authored-by: Kamil Rakoczy <krakoczy@antmicro.com>
whitequark [Thu, 15 Oct 2020 17:02:50 +0000 (17:02 +0000)]
tests: keep comments up to date. NFC.
whitequark [Thu, 15 Oct 2020 08:54:48 +0000 (08:54 +0000)]
build.plat: avoid type confusion in _check_feature.
Before this commit, `_check_feature(valid_xdrs=0)` would mean that
XDR buffers are not supported. Only `_check_feature(valid_xdrs=())`
was intended to be an indicator of that.
Jean-François Nguyen [Tue, 15 Sep 2020 00:20:35 +0000 (02:20 +0200)]
hdl.mem: document ReadPort and WritePort.
Fixes #496.
William D. Jones [Sat, 29 Aug 2020 19:34:57 +0000 (15:34 -0400)]
vendor.lattice_{ecp5,machxo_2_3l}: explain how to set up NMIGEN_ENV_Diamond on Windows.
whitequark [Thu, 27 Aug 2020 13:39:42 +0000 (13:39 +0000)]
setup: synchronize builtin-yosys dependency.
whitequark [Thu, 27 Aug 2020 13:03:15 +0000 (13:03 +0000)]
back.verilog: use `proc -nomux` if it is available.
Yosys offers no stability guarantees for individual `proc_*` passes,
though so far it worked out fine. This commit changes the Verilog
backend to use `proc -nomux` instead, which is guaranteed to have
backwards-compatible behavior.
Fixes #479.
whitequark [Thu, 27 Aug 2020 10:17:02 +0000 (10:17 +0000)]
sim: split into base, core, and engines.
Before this commit, each simulation engine (which is only pysim at
the moment, but also cxxsim soon) was a subclass of SimulatorCore,
and every simulation engine module would essentially duplicate
the complete structure of a simulator, with code partially shared.
This was a really bad idea: it was inconvenient to use, with
downstream code having to branch between e.g. PySettle and CxxSettle;
it had no well-defined external interface; it had multiple virtually
identical entry points; and it had no separation between simulation
algorithms and glue code.
This commit completely rearranges simulation code.
1. sim._base defines internal simulation interfaces. The clarity of
these internal interfaces is important because simulation
engines mix and match components to provide a consistent API
regardless of the chosen engine.
2. sim.core defines the external simulation interface: the commands
and the simulator facade. The facade provides a single entry
point and, when possible, validates or lowers user input.
It also imports built-in simulation engines by their symbolic
name, avoiding eager imports of pyvcd or ctypes.
3. sim.xxxsim (currently, only sim.pysim) defines the simulator
implementation: time and state management, process scheduling,
and waveform dumping.
The new simulator structure has none of the downsides of the old one.
See #324.
whitequark [Thu, 27 Aug 2020 08:33:48 +0000 (08:33 +0000)]
sim.pysim: in write_vcd(), close files if an exception is raised.
This also avoids leaving the waveform writer list in an inconsistent
state after an exception.
whitequark [Thu, 27 Aug 2020 07:54:27 +0000 (07:54 +0000)]
sim._pyclock: new type of process.
The overhead of coroutine processes is fairly high. A clock driver
implemented through a coroutine process is mostly overhead. This was
partially addressed in commit
2398b792 by microoptimizing yielding.
This commit eliminates the coroutine process overhead completely by
introducing dedicated clock processes. It also simplifies the logic
to a simple toggle.
This change improves runtime by about 12% on Minerva SRAM SoC.
whitequark [Thu, 27 Aug 2020 07:11:14 +0000 (07:11 +0000)]
sim._pycoro: make src_loc() more robust.
* Guard for finished coroutines.
* Guard for coroutines yielding from iterators and not generators.
whitequark [Thu, 27 Aug 2020 06:53:14 +0000 (06:53 +0000)]
_toolchain.cxx: work around PyPy missing LDCXXSHARED sysconfig variable.
whitequark [Thu, 27 Aug 2020 06:24:18 +0000 (06:24 +0000)]
_toolchain.cxx: new toolchain.
whitequark [Thu, 27 Aug 2020 01:14:05 +0000 (01:14 +0000)]
hdl.ast: clarify exception message for out of bounds indexing.
Fixes #488.
whitequark [Thu, 27 Aug 2020 00:46:50 +0000 (00:46 +0000)]
nmigen.test.utils: restore FHDLTestCase to gracefully deprecate it.
Fixes #484.
whitequark [Thu, 27 Aug 2020 00:33:31 +0000 (00:33 +0000)]
tests: move out of the main package.
Compared to tests in the repository root, tests in the package have
many downsides:
* Unless explicitly excluded in find_packages(), tests and their
support code effectively become a part of public API.
This, unfortunately, happened with FHDLTestCase, which was never
intended for downstream use.
* Even if explicitly excluded from the setuptools package, using
an editable install, or setting PYTHONPATH still allows accessing
the tests.
* Having a sub-package that is present in the source tree but not
exported (or, worse, exported only sometimes) is confusing.
* The name `nmigen.test` cannot be used for anything else, such as
testing utilities that *are* intended for downstream use.
William D. Jones [Wed, 26 Aug 2020 22:49:49 +0000 (18:49 -0400)]
build.run: implement SSH remote builds using Paramiko.
whitequark [Wed, 26 Aug 2020 22:45:19 +0000 (22:45 +0000)]
back.rtlil: do not squash empty modules.
In commit
9faa1d37, the RTLIL backend was changed to ignore modules
without ports completely, since Yosys would recognize empty modules
as black boxes without explicit `write_verilog -noblackbox` and break
the design. That change had many flaws:
* It removed instances without ports, which are used in e.g. SoC
FPGAs to instantiate a dummy CPU.
* It removed fragments without ports, which can appear in e.g. SoC
FPGAs in case the fabric is not connected to any I/O ports.
* Finally, it was just conceptually unjustified.
This commit changes the logic to actually check for empty fragments,
and instead of removing them, it adds a dummy wire inside. It would
be possible to use the Yosys-specific (*noblackbox*) attribute.
However, it would be necessary to strip it for most targets right
away, and also the wire doubles as documentation.
Fixes #441.
whitequark [Wed, 26 Aug 2020 09:01:57 +0000 (09:01 +0000)]
back.verilog: omit Verilog initial trigger only if Yosys adds it.
Verilog has an edge case where an `always @*` process, which is used
to describe a combinatorial function procedurally, may not execute
at time zero because none of the signals in its implicit sensitivity
list change, i.e. when the process doesn't read any signals. This
causes the wires driven by the process to stay undefined.
The workaround to this problem (assuming SystemVerilog `always_comb`
is not available) is to introduce a dummy signal that changes only
at time zero and is optimized out during synthesis. nMigen has had
its own workaround, `$verilog_initial_trigger`, for a while. However,
`proc_prune`, while increasing readability, pulls references to this
signal out of the process. Because of this, a similar workaround was
implemented in Yosys' `write_verilog` itself.
This commit ensures we use our workaround on versions of Yosys
without the updated `write_verilog`, and Yosys' workaround on later
versions.
Fixes #418.
whitequark [Wed, 26 Aug 2020 10:18:02 +0000 (10:18 +0000)]
vendor.xilinx_{7series,ultrascale}: set BUFG* SIM_DEVICE as appropriate.
Fixes #438 (again).
whitequark [Wed, 26 Aug 2020 14:57:31 +0000 (14:57 +0000)]
vendor.xilinx_7series: unbreak.
This commit fixes a series of typos introduced in commit
4e208b0a.
whitequark [Wed, 26 Aug 2020 13:26:38 +0000 (13:26 +0000)]
sim._pyrtl: optimize uses of reflexive operators.
When a literal is used on the left-hand side of a numeric operator,
Python is able to constant-fold some expressions:
>>> dis.dis(lambda x: 0 + 0 + x)
1 0 LOAD_CONST 1 (0)
2 LOAD_FAST 0 (x)
4 BINARY_ADD
6 RETURN_VALUE
If a literal is used on the right-hand side such that the left-hand
side is variable, this doesn't happen:
>>> dis.dis(lambda x: x + 0 + 0)
1 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (0)
4 BINARY_ADD
6 LOAD_CONST 1 (0)
8 BINARY_ADD
10 RETURN_VALUE
PyRTL generates fairly redundant code due to the pervasive masking,
and because of that, transforming expressions into the former form,
where possible, improves runtime by about 10% on Minerva SRAM SoC.
whitequark [Wed, 26 Aug 2020 09:16:46 +0000 (09:16 +0000)]
back.cxxrtl: actualize Yosys version requirement.
whitequark [Wed, 26 Aug 2020 06:58:22 +0000 (06:58 +0000)]
hdl.ast: avoid unnecessary sign padding in ArrayProxy.
Before this commit, ArrayProxy would add sign padding (an extra bit)
a homogeneous array of signed values, or an array where all unsigned
values are smaller than the largest signed one. After this commit,
ArrayProxy would only add padding in arrays with mixed signedness
where all signed values are smaller or equal in size to the largest
unsigned value.
Fixes #476.
Co-authored-by: Pepijn de Vos <pepijndevos@gmail.com>
whitequark [Wed, 26 Aug 2020 04:15:26 +0000 (04:15 +0000)]
sim._pyrtl: fix miscompilation of -(Const(0b11, 2).as_signed()).
Fixes #473.
whitequark [Wed, 26 Aug 2020 03:19:13 +0000 (03:19 +0000)]
lib.cdc: in AsyncFFSynchronizer(), rename domain= to o_domain=.
This is for consistency with other synchronizers.
Fixes #467.
Robin Ole Heinemann [Tue, 4 Aug 2020 15:30:18 +0000 (17:30 +0200)]
vendor.lattice_machxo_2_3l: add SRAM svf generation
Mariusz Glebocki [Sun, 2 Aug 2020 16:48:26 +0000 (18:48 +0200)]
vendor: Add initial support for Symbiflow for Xilinx 7-series
Mariusz Glebocki [Mon, 24 Aug 2020 11:03:59 +0000 (13:03 +0200)]
vendor.xilinx_7series: add `_part` property getter
Xiretza [Sat, 22 Aug 2020 13:46:58 +0000 (15:46 +0200)]
cli: Improve help texts
545e49c2 added the option to export as CXXRTL, but the help texts for
the CLI options don't reflect this yet.
whitequark [Sat, 15 Aug 2020 13:00:50 +0000 (13:00 +0000)]
docs/lang: use less confusing placeholder variable names.
Fixes #474.
awygle [Sat, 15 Aug 2020 08:40:56 +0000 (01:40 -0700)]
lib.fifo: add `r_level` and `w_level` to all FIFOs
whitequark [Thu, 13 Aug 2020 03:10:17 +0000 (03:10 +0000)]
Add Linguist tags to .gitattributes.
This should make it possible to navigate to nmigen/vendor/*.py using
GitHub's file finder.
Robin Ole Heinemann [Mon, 10 Aug 2020 15:23:29 +0000 (17:23 +0200)]
vendor.lattice_{ecp5,machxo_2_3l}: specify impl-dir correctly
whitequark [Fri, 31 Jul 2020 13:17:39 +0000 (13:17 +0000)]
build,vendor: never carry around parts of differential signals.
When a port component is skipped, it should appear neither in the RTL
nor in the constraint file. However, passing around components of
differential ports explicitly makes that harder.
Fixes #456.
Supersedes #457.
Co-authored-by: Jean THOMAS <git0@pub.jeanthomas.me>
whitequark [Fri, 31 Jul 2020 14:45:38 +0000 (14:45 +0000)]
vendor.xilinx_{7series,ultrascale}: use BUFGCTRL rather than BUFGCE.
Fixes #438 (again).
Adam Greig [Thu, 30 Jul 2020 07:05:18 +0000 (08:05 +0100)]
hdl.mem: cast reset value for transparent read ports to integer.
Jean THOMAS [Tue, 28 Jul 2020 21:02:01 +0000 (23:02 +0200)]
nmigen.lib.scheduler: add RoundRobin.
Jacob Graves [Tue, 28 Jul 2020 19:35:25 +0000 (13:35 -0600)]
tests: fix remove unnecessary workaround for some unittest assertions.
whitequark [Wed, 22 Jul 2020 02:13:10 +0000 (02:13 +0000)]
vendor.xilinx_{7series,ultrascale}: add SIM_DEVICE parameter.
The parameter defaults to "ULTRASCALE", even when synthesizing for
7-series devices. This could lead to a simulation/synthesis mismatch,
and causes a warning.
Fixes #438.
Jean THOMAS [Thu, 23 Jul 2020 12:24:31 +0000 (14:24 +0200)]
vendor.lattice_ecp5: add missing differential IO types.
whitequark [Wed, 22 Jul 2020 14:43:44 +0000 (14:43 +0000)]
back.rtlil: lower maximum accepted wire size.
In practice wires of just 100000 bits sometimes have unacceptable
performance with Yosys, so stick to Verilog's minimum limit of 65536
bits.
whitequark [Wed, 22 Jul 2020 14:32:45 +0000 (14:32 +0000)]
sim._pycoro: avoid spurious wakeups.
This bug was introduced in commit
e435a217.
whitequark [Wed, 22 Jul 2020 08:11:59 +0000 (08:11 +0000)]
CI: replace Travis with GitHub Actions.
Fixes #445.
whitequark [Tue, 21 Jul 2020 02:53:29 +0000 (02:53 +0000)]
compat.fhdl.bitcontainer: fix value_bits_sign().
This function was broken in commit
659b0e81; some downstream code
expects bits_sign to be e.g. indexable.
whitequark [Thu, 16 Jul 2020 08:00:10 +0000 (08:00 +0000)]
CI: use WASM yosys instead of building our own.
Fixes #434.
whitequark [Wed, 15 Jul 2020 04:09:58 +0000 (04:09 +0000)]
back.rtlil: fix guard for division by zero.
Oops... that should be checking the divisor, not the dividend. This
was discovered by running the test suite on cxxsim.
Filipe Laíns [Mon, 13 Jul 2020 23:42:02 +0000 (00:42 +0100)]
docs: add install instructions for arch
Signed-off-by: Filipe Laíns <lains@archlinux.org>
whitequark [Tue, 14 Jul 2020 00:25:11 +0000 (00:25 +0000)]
CI: run on pull requests as well, not just pushes.
whitequark [Mon, 13 Jul 2020 23:16:27 +0000 (23:16 +0000)]
lib.cdc: fix typo.
Co-authored-by: @ECP5-PCIe
Jacob Lifshay [Mon, 13 Jul 2020 02:10:01 +0000 (19:10 -0700)]
sim.pysim: write the next, not curr signal value to the VCD file
This is a temporary fix for #429.
whitequark [Sat, 11 Jul 2020 12:25:31 +0000 (12:25 +0000)]
sim.pysim: use VCD aliases to reduce space and time overhead.
On Minerva SoC, this reduces VCD file size by about 35%, and reduces
runtime overhead of writing VCDs by 10% or less.
whitequark [Wed, 8 Jul 2020 17:30:06 +0000 (17:30 +0000)]
sim: simplify. NFC.
whitequark [Wed, 8 Jul 2020 12:49:38 +0000 (12:49 +0000)]
back.pysim→sim.pysim; split into more manageable parts.
This is necessary to add cxxrtl as an alternate simulation engine.
whitequark [Wed, 8 Jul 2020 09:08:00 +0000 (09:08 +0000)]
vendor.xilinx_{7series,ultrascale}: remove `grade` property.
This was added in commit
bfd4538d based on a misunderstanding of how
Xilinx part numbers work.
* non-ultrascale 7-series parts don't have temperature grades;
* ultrascale parts have temperature grade as a part of speed grade.
whitequark [Wed, 8 Jul 2020 08:29:20 +0000 (08:29 +0000)]
back.pysim: only extract signal names if VCD is requested.
This commit also fixes an issue introduced in
2606ee33 that regressed
simulator startup time and bloated VCD files. (It's actually about
10% faster now than *before* the regression was introduced.)
whitequark [Wed, 8 Jul 2020 07:12:00 +0000 (07:12 +0000)]
back.pysim: reset timeline as well.
This is a bug that was introduced in
94faf497b.
whitequark [Wed, 8 Jul 2020 06:29:34 +0000 (06:29 +0000)]
back.pysim: simplify. NFC.
whitequark [Wed, 8 Jul 2020 06:04:50 +0000 (06:04 +0000)]
back.pysim: extract timeline handling to class _Timeline. NFC.
whitequark [Wed, 8 Jul 2020 05:42:33 +0000 (05:42 +0000)]
back.pysim: extract simulator commands to sim._cmds. NFC.
whitequark [Wed, 8 Jul 2020 03:55:09 +0000 (03:55 +0000)]
back.pysim: simplify. NFC.
awygle [Tue, 7 Jul 2020 05:17:03 +0000 (22:17 -0700)]
hdl.ast: don't inherit Shape from NamedTuple.
Fixes #421.
whitequark [Tue, 7 Jul 2020 04:29:13 +0000 (04:29 +0000)]
back.pysim: simplify.
Compiled process names were never particularly useful (comments in
the source would make more sense for debugging), and coroutine
process names were actually source locations.
whitequark [Tue, 7 Jul 2020 04:19:05 +0000 (04:19 +0000)]
back.pysim: simplify. NFC.
whitequark [Tue, 7 Jul 2020 04:09:10 +0000 (04:09 +0000)]
back.pysim: simplify. NFC.
whitequark [Tue, 7 Jul 2020 04:06:06 +0000 (04:06 +0000)]
back.pysim: synchronize waveform writing with cxxrtl.
whitequark [Tue, 7 Jul 2020 02:35:04 +0000 (02:35 +0000)]
back.pysim: synchronize terms with cxxrtl. NFC.
whitequark [Tue, 7 Jul 2020 02:14:06 +0000 (02:14 +0000)]
back.pysim: simplify. NFC.
whitequark [Tue, 7 Jul 2020 01:59:25 +0000 (01:59 +0000)]
back.pysim: simplify. NFC.
whitequark [Mon, 6 Jul 2020 16:01:49 +0000 (16:01 +0000)]
Remove everything deprecated in nmigen 0.2.
Alan Green [Wed, 1 Jul 2020 21:29:30 +0000 (17:29 -0400)]
Update license and copyright info
Remove non-license explanatory text from LICENSE.txt.
Create CONTRIBUTING file with instructions and notes for contributors.
This change relates to issue #412
Konrad Beckmann [Mon, 6 Jul 2020 14:04:24 +0000 (16:04 +0200)]
vendor.lattice_ecp5: Add support for io with xdr=7
This adds support for IOs with xdr=7 using the
IODDR71B and ODDR71B primitives.
Konrad Beckmann [Mon, 6 Jul 2020 14:01:19 +0000 (16:01 +0200)]
vendor.lattice_ecp5: Add support for io with xdr=4
This adds support for IOs with xdr=4 using the
IDDRX2F and ODDRX2F primitives.
whitequark [Sun, 5 Jul 2020 23:51:14 +0000 (23:51 +0000)]
docs: use working sphinxcontrib-platformpicker.
whitequark [Sun, 5 Jul 2020 23:39:47 +0000 (23:39 +0000)]
docs: use sphinxcontrib-platformpicker.
Fixes #416.
whitequark [Sat, 4 Jul 2020 02:09:35 +0000 (02:09 +0000)]
docs: link to community tutorials until we have an official one.