whitequark [Thu, 11 Jun 2020 16:12:52 +0000 (16:12 +0000)]
_yosys: translate Yosys warnings to Python warnings.
This isn't used yet (the only Yosys warning we can get is useless),
but will be handy for CXXRTL.
whitequark [Thu, 11 Jun 2020 15:36:43 +0000 (15:36 +0000)]
nmigen.cli: fix file type autodetection code.
whitequark [Thu, 11 Jun 2020 15:17:49 +0000 (15:17 +0000)]
back.verilog: remove unused imports. NFC.
Adam Greig [Sat, 6 Jun 2020 11:43:25 +0000 (12:43 +0100)]
hdl.xfrm: preserve allow_reset_less when transforming ResetSignal.
Fixes #400.
Shawn Anastasio [Fri, 5 Jun 2020 03:19:46 +0000 (22:19 -0500)]
hdl.rec: preserve shapes when constructing a layout.
Preserve the original user-provided shape, while still checking
its validity. This allows Enum decoders to work when specifying
record fields with Enums.
Fixes #393.
whitequark [Fri, 29 May 2020 17:45:09 +0000 (17:45 +0000)]
setup: exclude tests.
The inclusion of tests in the package was completely unintentional
and a result of my lack of knowledge of setuptools. If you are using
nmigen.test.utils, please copy the parts you need to your own code
because the nmigen.test code can and will change without notice.
whitequark [Fri, 29 May 2020 17:45:09 +0000 (17:45 +0000)]
vendor.lattice_ice40: reword confusing comment. NFC.
Robin Ole Heinemann [Sun, 24 May 2020 15:54:17 +0000 (17:54 +0200)]
hdl.ast: fix typo
whitequark [Fri, 22 May 2020 16:50:45 +0000 (16:50 +0000)]
back.verilog: fall back to nmigen_yosys package.
The nmigen-yosys PyPI package provides a custom, minimal build of
Yosys that uses (at the moment) wasmtime-py to deliver a single
WASM binary that can run on many platforms, and eliminates the need
to build Yosys from source.
Not only does this lower barrier to entry for new nMigen developers,
but also decouples nMigen from Yosys' yearly release cycle, which
lets us use new features and drop workarounds for Yosys bugs earlier.
The source for the nmigen-yosys package is provided at:
https://github.com/nmigen/nmigen-yosys
The package is built from upstream source and released automatically
with no manual steps.
Fixes #371.
whitequark [Thu, 21 May 2020 10:41:23 +0000 (10:41 +0000)]
Update .gitignore.
whitequark [Thu, 21 May 2020 09:49:42 +0000 (09:49 +0000)]
vendor.intel: don't use `write_verilog -decimal`.
See commit
702e41ba for details.
whitequark [Thu, 21 May 2020 09:48:42 +0000 (09:48 +0000)]
vendor.intel: double-quote Tcl values rather than brace-quoting.
For unknown reasons, Quartus treats {foo} and "foo" in completely
different ways, which is not true for normal Tcl code; specifically,
it preserves the braces if they are used. Because of this, since
commit
6cee2804, the vendor.intel package was completely broken.
whitequark [Thu, 21 May 2020 08:57:30 +0000 (08:57 +0000)]
vendor.xilinx_{7series,ultrascale}: don't use `write_verilog -decimal`.
In commit
892cff05, `-decimal` was used when writing Verilog for
Vivado targets because it treats (* keep=32'd1 *) and (* keep=1 *)
differently in violation of Verilog LRM. However, it is possible
to avoid that workaround by using (* keep="TRUE" *). Do that,
and remove `-decimal` to avoid special-casing 32-bit constants.
Refs #373.
whitequark [Wed, 20 May 2020 05:35:47 +0000 (05:35 +0000)]
build.plat: skip clock constraints on unused signals.
It's not very nice to add more internal mutable state to Platform
related classes, but our whole approach for Platform is inherently
stateful, and other solutions (like changing every individual vendor
platform to check for unused signals) are even worse.
Fixes #374.
whitequark [Wed, 20 May 2020 04:58:03 +0000 (04:58 +0000)]
vendor.xilinx_{7series,ultrascale}: add (*keep*) on constrained clocks.
If the clock signal is not a top-level port and has aliases, it can
be optimized out, and then the constraint will no longer apply.
To prevent this, make sure the constrained signal is preferred over
any aliases by using the `keep` attribute.
Vivado does not parse attributes like (* keep = 32'd1 *) as valid
even though, AFAICT, they are equivalent to (* keep = 1 *) or simply
(* keep *) per IEEE 1364. To work around this, use the solution we
currently use for Quartus, which is `write_verilog -decimal`.
Fixes #373.
whitequark [Wed, 20 May 2020 03:18:33 +0000 (03:18 +0000)]
hdl.ast: add const-shift operations.
Also, clean up the rotate code a bit.
Fixes #378.
whitequark [Tue, 19 May 2020 23:43:25 +0000 (23:43 +0000)]
hdl.ast: clarify docs for Value.rotate_{left,right}.
"Rotate modulo 2**len(self)" is redundant because that's just how
rotates work.
whitequark [Tue, 19 May 2020 23:40:49 +0000 (23:40 +0000)]
hdl.dsl: check for unique domain name.
Fixes #385.
whitequark [Tue, 19 May 2020 23:33:14 +0000 (23:33 +0000)]
back.rtlil: handle signed and large Instance parameters correctly.
Fixes #388.
whitequark [Mon, 4 May 2020 05:51:08 +0000 (05:51 +0000)]
tracer: fix get_var_name() to work on toplevel attributes.
E.g. this now works:
>>> class dummy: pass
>>> self = dummy()
>>> self.foo = Signal()
>>> self.foo.name
'foo'
Gwenhael Goavec-Merou [Fri, 8 May 2020 04:42:21 +0000 (06:42 +0200)]
vendor.lattice_machxo2: generate binary bitstreams.
whitequark [Sat, 2 May 2020 10:41:18 +0000 (10:41 +0000)]
plat, vendor: systematically escape net and file names in Tcl.
Before this commit, there was only occasional quoting of some names
used in any Tcl files. (I'm not sure what I was thinking.)
After this commit, any substs that may include Tcl special characters
are escaped. This does not include build names (which are explicitly
restricted to ASCII to avoid this problem), or attribute names (which
are chosen from a predefined set). Ideally we'd use a more principled
approach but Jinja2 does not support custom escaping mechanisms.
Note that Vivado restricts clock names to a more restrictive set that
forbids using Tcl special characters even when escaped.
Fixes #375.
whitequark [Tue, 28 Apr 2020 02:16:12 +0000 (02:16 +0000)]
back.rtlil: fix incorrect escaping of signed parameters.
Also, improve escaping code in general.
whitequark [Mon, 27 Apr 2020 18:06:12 +0000 (18:06 +0000)]
hdl.ast: use SignalSet, not ValueSet, for _[lr]hs_signals().
The implementation of these functions likely predates support for
{Clock,Reset}Signal() in SignalKey.
whitequark [Mon, 27 Apr 2020 02:06:10 +0000 (02:06 +0000)]
lib.cdc: add missing documentation for AsyncFFSynchronizer. NFC.
awygle [Fri, 24 Apr 2020 22:27:04 +0000 (15:27 -0700)]
lib.fifo: add r_rst output for AsyncFIFO{,Buffered}.
Fixes #181.
awygle [Fri, 24 Apr 2020 21:15:00 +0000 (14:15 -0700)]
hdl.ir: typecheck `convert(ports=)` more carefully.
The `ports` argument to the `convert` functions is a frequent hotspot of
beginner issues. Check to make sure it is either a list or a tuple, and
give an appropriately helpful error message if not.
Fixes #362.
whitequark [Fri, 24 Apr 2020 21:09:58 +0000 (21:09 +0000)]
README: link directly to Yosys build instructions.
Teguh Hofstee [Thu, 23 Apr 2020 21:46:10 +0000 (14:46 -0700)]
back.verilog: add workaround for evaluation Verific behavior.
The evaluation version of Verific prints its license information to stdout,
and since it is against the EULA to change that in any way, this behavior
is not possible to fix in Yosys. Add a workaround in nMigen instead.
Teguh Hofstee [Wed, 22 Apr 2020 12:23:14 +0000 (05:23 -0700)]
back.verilog: make Yosys version check compatible with Verific.
Kate Temkin [Mon, 20 Apr 2020 22:25:50 +0000 (16:25 -0600)]
vendor: use nextpnr -12k for -12F devices; remove theoretical devices
nextpnr now supports -12k; which replaces the use of -25k and --idcode
together to build bitstreams compatible with -12F devices. Use this.
This also removes the LFEUM-12K and its 5G counterpart; as per Dave Shah
they're currently only theoretical FPGAs.
anuejn [Thu, 16 Apr 2020 16:46:55 +0000 (18:46 +0200)]
hdl.rec: make Record inherit from UserValue.
Closes #354.
whitequark [Wed, 15 Apr 2020 14:42:46 +0000 (14:42 +0000)]
back.rtlil: translate enum decoders to Yosys enum attributes.
Fixes #254.
whitequark [Tue, 14 Apr 2020 06:17:16 +0000 (06:17 +0000)]
buil.plat: enable strict undefined behavior in Jinja2.
By default, if an operation produces an undefined value (a Jinja2
concept that corresponds to Python's KeyError, AttributeError, etc)
then this value may be printed in a template, which is a nop. This
behavior can hide bugs.
This commit changes the Jinja2 behavior to raise an error instead of
producing an undefined value in all cases. (We produce undefined
values deliberately in a few places. Those are unaffected; it is OK
to use several kinds of undefined values in one Jinja2 environment.)
Fixes #337.
whitequark [Mon, 13 Apr 2020 17:04:13 +0000 (17:04 +0000)]
back.rtlil: don't emit connections to zero width ports.
Fixes #335.
whitequark [Mon, 13 Apr 2020 16:38:36 +0000 (16:38 +0000)]
back.rtlil: refuse to create extremely large wires.
Such wires are likely to trigger pathological behavior in Yosys and,
if applicable, other toolchains that consume Verilog converted from
RTLIL.
Fixes #341.
whitequark [Mon, 13 Apr 2020 15:56:39 +0000 (15:56 +0000)]
back.rtlil: fix expansion of Part() for partial dummy writes.
Before this commit, selecting a part that was fully out of bounds of
a value was correctly implemented as a write to a dummy wire, but
selecting a part that was only partially out of bounds resulted in
a crash.
Fixes #351.
whitequark [Mon, 13 Apr 2020 14:43:43 +0000 (14:43 +0000)]
back.rtlil: fix legalization of Part() with stride.
Also known as word_select().
whitequark [Mon, 13 Apr 2020 13:03:31 +0000 (13:03 +0000)]
Clarify a few comments. NFC.
Dan Ravensloft [Mon, 13 Apr 2020 13:40:39 +0000 (14:40 +0100)]
hdl.ast: add Value.{rotate_left,rotate_right}.
whitequark [Mon, 13 Apr 2020 11:04:25 +0000 (11:04 +0000)]
Travis: require tests to pass on pypy3.
Fixes #147.
whitequark [Mon, 13 Apr 2020 09:40:00 +0000 (09:40 +0000)]
Travis: upgrade to bionic.
whitequark [Sun, 12 Apr 2020 04:56:15 +0000 (04:56 +0000)]
build.run: fix BuildProducts.extract to work with subdirectories.
Fixes #353.
whitequark [Sun, 12 Apr 2020 04:47:40 +0000 (04:47 +0000)]
hdl.rec: improve repr() for Layout.
Fixes #326.
whitequark [Sun, 12 Apr 2020 03:59:56 +0000 (03:59 +0000)]
hdl.ast: improve repr() for Shape.
The default __repr__() from typing.NamedTuple does not include
the module name, so the replacement (which uses the preferred syntax
for specifying these shapes) doesn't either.
whitequark [Sun, 12 Apr 2020 03:28:29 +0000 (03:28 +0000)]
build.plat: don't check for toolchain presence if do_build=False.
Stuart Olsen [Tue, 7 Apr 2020 11:17:14 +0000 (04:17 -0700)]
back.pysim: Clear pending updates after they are effected
Stuart Olsen [Tue, 7 Apr 2020 05:22:45 +0000 (22:22 -0700)]
back.pysim: Eliminate duplicate dict lookup in VCD update
Stuart Olsen [Tue, 7 Apr 2020 05:22:09 +0000 (22:22 -0700)]
back.pysim: Reuse clock simulation commands
whitequark [Sun, 5 Apr 2020 02:00:06 +0000 (02:00 +0000)]
hdl.mem: fix source location of ReadPort.en.
whitequark [Fri, 3 Apr 2020 05:20:42 +0000 (05:20 +0000)]
back.pysim: fix emission of undriven traces to VCD files.
This has been originally implemented in commit
d3775eed (which fixed
`write_vcd(traces=)` to do something at all), but had a flaw where
undriven traces would not be correctly placed in hierarchy. This
used to produce incorrect results on pyvcd 0.1, but started causing
assertion failures on pyvcd 0.2.
Fixes #345.
whitequark [Thu, 2 Apr 2020 11:17:41 +0000 (11:17 +0000)]
setup: bump pyvcd to ~=0.2.
We don't use any of the deprecated functionality, and the added
requirement of Python 3.6+ matches ours.
Having a requirement for pyvcd ~=0.1.4 was actually the cause of
the error I tried to fix in commit
6e1145e2. It had nothing to do
with Jinja2 (though it is definitely still good to have the tighter
requirement on Jinja2); the cause of the error was that pip would
install Jinja2, schedule installing markupsafe, install pyvcd 0.2.0
and then choke on the pyvcd 0.1.4 requirement, which would prevent
it from installing markupsafe &c. Why it does that is beyond me.
Jacob Lifshay [Thu, 2 Apr 2020 02:38:14 +0000 (19:38 -0700)]
Add support for using non-compat Elaboratable instances with compat.fhdl.verilog.convert and compat.run_simulation
Fixes #344
whitequark [Thu, 2 Apr 2020 01:35:39 +0000 (01:35 +0000)]
setup: tighten version constraint on Jinja2.
I remember thinking that not constraining it properly might bite us
someday, but assumed that Jinja2 will always stay version 2. Now it
looks like Jinja2 3.0.0a1 got released, pip picks it by default, and
it's currently broken (something about markupsafe missing).
Do what needed to be done in the first place.
whitequark [Sun, 22 Mar 2020 20:50:07 +0000 (20:50 +0000)]
hdl.ast: implement abs() on values.
WRansohoff [Fri, 20 Mar 2020 08:10:48 +0000 (04:10 -0400)]
vendor.lattice_ice40: add support for SB_[LH]FOSC as default_clk.
These oscillators are only available on iCE40 UltraPlus devices.
Nicolas Robin [Sun, 15 Mar 2020 09:33:22 +0000 (10:33 +0100)]
vendor: fix typo `async_ff_sync`
Stuart Olsen [Sun, 15 Mar 2020 05:22:03 +0000 (22:22 -0700)]
back.pysim: implement modulus operator.
awygle [Sat, 14 Mar 2020 23:26:07 +0000 (16:26 -0700)]
Correctly handle resets in AsyncFIFO.
This commit improves handling of resets in AsyncFIFO in two ways:
* First, resets no longer violate Gray counter CDC invariants.
* Second, write domain reset now empties the entire FIFO.
whitequark [Thu, 12 Mar 2020 20:28:41 +0000 (20:28 +0000)]
vendor: fix a few issues in commit
2f8669ca.
awygle [Sun, 8 Mar 2020 21:37:40 +0000 (14:37 -0700)]
lib.cdc: extract AsyncFFSynchronizer.
In some cases, it is necessary to synchronize a reset-like signal but
a new clock domain is not desirable. To address these cases, extract
the implementation of ResetSynchronizer into AsyncFFSynchronizer,
and replace ResetSynchronizer with a thin wrapper around it.
whitequark [Wed, 19 Feb 2020 01:28:14 +0000 (01:28 +0000)]
hdl.ast: fix off-by-1 in Initial.__init__().
whitequark [Wed, 19 Feb 2020 01:21:00 +0000 (01:21 +0000)]
back.pysim: fix RHS codegen for Cat() and Repl(..., 0).
Fixes #325.
whitequark [Wed, 19 Feb 2020 00:56:24 +0000 (00:56 +0000)]
back.pysim: optionally allow introspecting generated code.
awygle [Sun, 16 Feb 2020 07:01:44 +0000 (23:01 -0800)]
nmigen.compat.genlib.cdc: add PulseSynchronizer.
awygle [Sun, 16 Feb 2020 06:51:53 +0000 (22:51 -0800)]
nmigen.lib.cdc: port PulseSynchronizer.
Co-authored-by: Luke Wren <wren6991@gmail.com>
whitequark [Fri, 14 Feb 2020 06:34:28 +0000 (06:34 +0000)]
Travis: prune dependencies.
bitarray is not required since commit
7df70059.
whitequark [Fri, 14 Feb 2020 06:33:08 +0000 (06:33 +0000)]
Travis: test on Python 3.8.
whitequark [Wed, 12 Feb 2020 14:42:24 +0000 (14:42 +0000)]
cli: update use of deprecated code.
whitequark [Wed, 12 Feb 2020 14:42:06 +0000 (14:42 +0000)]
back.pysim: accept write_vcd(vcd_file=None).
Because write_vcd() is a context manager, this is useful if the VCD
file should be sometimes not written, since it avoids awkward
conditionals with duplicated code. It's not very elegant though.
Fixes #319.
whitequark [Sun, 9 Feb 2020 17:03:06 +0000 (17:03 +0000)]
setup: update project URLs.
whitequark [Sun, 9 Feb 2020 14:15:51 +0000 (14:15 +0000)]
doc: remove outdated files and references to them.
whitequark [Sat, 8 Feb 2020 11:00:08 +0000 (11:00 +0000)]
README: link to IRC channel.
whitequark [Sat, 8 Feb 2020 10:54:01 +0000 (10:54 +0000)]
README: consolidate requirements in the Installation section.
whitequark [Fri, 7 Feb 2020 00:07:19 +0000 (00:07 +0000)]
test_build_res: fix after commit
3e2ecdf2.
whitequark [Thu, 6 Feb 2020 23:37:15 +0000 (23:37 +0000)]
build.res,vendor: place clock constraint on port, not net, if possible.
For most toolchains, these are functionally identical, although ports
tend to work a bit better, being the common case. For Vivado, though,
it is necessary to place them on the port because its timing analyzer
considers input buffer delay.
Fixes #301.
whitequark [Thu, 6 Feb 2020 19:38:21 +0000 (19:38 +0000)]
xilinx_{7series,ultrascale}: run `report_methodology`.
This can expose important timing issues, such as #301.
whitequark [Thu, 6 Feb 2020 18:27:55 +0000 (18:27 +0000)]
hdl.ast: add Value.{as_signed,as_unsigned}.
Before this commit, there was no way to do so besides creating and
assigning an intermediate signal, which could not be extracted into
a helper function due to Module statefulness.
Fixes #292.
whitequark [Thu, 6 Feb 2020 18:10:15 +0000 (18:10 +0000)]
test_lib_fifo: define all referenced FSM states.
Broken in commit
a1c58633.
whitequark [Thu, 6 Feb 2020 17:47:46 +0000 (17:47 +0000)]
hdl.dsl: make referencing undefined FSM states an error.
Before this commit, doing something like:
with m.FSM():
with m.State("FOO"):
m.next = "bAR"
with m.State("BAR"):
m.next = "FOO"
would silently create an empty state `bAR` and get stuck in it until
the module is reset. This was done intentionally (in Migen, this code
would in fact miscompile), but in retrospect was clearly a bad idea;
it turns typos into bugs, while in the rare case that branching to
a completely empty state is desired, it is trivial to define one.
Fixes #315.
whitequark [Thu, 6 Feb 2020 17:33:41 +0000 (17:33 +0000)]
hdl.ir: type check ports.
Fixes #290.
whitequark [Thu, 6 Feb 2020 17:19:47 +0000 (17:19 +0000)]
back.pysim: emit toplevel inputs in VCD files as well.
Before this commit, only signals driven from fragments (in practice,
everything except toplevel inputs) would get written to a VCD file.
Not having toplevel inputs in the dump made debugging ~impossible.
After this commit, all signals the fragment refers to get written to
a VCD file. (More specifically, all signals the compiler assigns
an index to, i.e. signals the generated code reads or writes.)
Fixes #280.
whitequark [Thu, 6 Feb 2020 17:07:48 +0000 (17:07 +0000)]
back.pysim: make `write_vcd(traces=)` actually use those traces.
Reported in #280.
whitequark [Thu, 6 Feb 2020 16:13:59 +0000 (16:13 +0000)]
hdl.dsl: reject name mismatch in `m.domains.<name> +=`.
This would violate invariants later in the elaboration process.
Fixes #282.
whitequark [Thu, 6 Feb 2020 15:19:16 +0000 (15:19 +0000)]
hdl.dsl: type check when adding to m.domains.
whitequark [Thu, 6 Feb 2020 14:48:48 +0000 (14:48 +0000)]
hdl.mem: add synthesis attribute support.
Fixes #291.
whitequark [Thu, 6 Feb 2020 13:47:13 +0000 (13:47 +0000)]
hdl.mem: document Memory.
whitequark [Tue, 4 Feb 2020 07:54:54 +0000 (07:54 +0000)]
hdl.{ast,dsl}: allow whitespace in bit patterns.
Fixes #316.
whitequark [Sat, 1 Feb 2020 23:15:18 +0000 (23:15 +0000)]
hdl.ast: update documentation for Signal.
Fixes #288.
whitequark [Sat, 1 Feb 2020 23:04:25 +0000 (23:04 +0000)]
hdl.ast: prohibit shifts by signed value.
These are not desirable in a HDL, and currently elaborate to broken
RTLIL (after YosysHQ/yosys#1551); prohibit them completely, like
we already do for division and modulo.
Fixes #302.
whitequark [Sat, 1 Feb 2020 03:24:26 +0000 (03:24 +0000)]
build.plat: align pipeline with Fragment.prepare().
Since commit
7257c20a, platform code calls create_missing_domains()
before _propagate_domains_up() (as a part of prepare() call). Since
commit
a7be3b48, without a platform, create_missing_domains() is
calle after _propagate_domains_up(); because of that, it adds
the missing domain to the fragment. When platform code then calls
prepare() again, this causes an assertion failure.
The true intent behind the platform code being written this way is
that it *overrides* a part of prepare()'s mechanism. Because it was
not changed when prepare() was modified in
7257c20a, the override,
which happened to work by coincidence, stopped working. This is
now fixed by inlining the relevant parts of Fragment.prepare() into
Platform.prepare().
This is not a great solution, but given the amount of breakage this
causes (no platform-using code works), it is acceptable for now.
Fixes #307.
whitequark [Sat, 1 Feb 2020 02:15:45 +0000 (02:15 +0000)]
hdl.dsl: don't allow inheriting from Module.
`Module` is an object with a lot of complex and sometimes fragile
behavior that overrides Python attribute accessors and so on.
To prevent user designs from breaking when it is changed, it is not
supposed to be inherited from (unlike in Migen), but rather returned
from the elaborate() method. This commit makes sure it will not be
inherited from by accident (most likely by users familiar with
Migen).
Fixes #286.
whitequark [Sat, 1 Feb 2020 01:55:23 +0000 (01:55 +0000)]
hdl.ast: warn on unused property statements (Assert, Assume, etc).
A property statement that is created but not added to a module is
virtually always a serious bug, since it can make formal verification
pass when it should not. Therefore, add a warning to it, similar to
UnusedElaboratable.
Doing this to all statements is possible, but many temporary ones are
created internally by nMigen, and the extensive changes required to
remove false positives are likely not worth the true positives.
We can revisit this in the future.
Fixes #303.
whitequark [Sat, 1 Feb 2020 01:35:05 +0000 (01:35 +0000)]
_unused: extract must-use logic from hdl.ir.
whitequark [Fri, 31 Jan 2020 23:14:16 +0000 (23:14 +0000)]
hdl.dsl: add missing case width check for Enum values.
Fixes #305.
whitequark [Fri, 31 Jan 2020 21:10:59 +0000 (21:10 +0000)]
README: clarify relationship to Migen.
whitequark [Fri, 31 Jan 2020 06:37:45 +0000 (06:37 +0000)]
hdl.dsl: make `if m.{If,Elif,Else}(...)` a syntax error.
A common typo, and hard to notice when it's silently ignored.
Fixes #284.
whitequark [Fri, 31 Jan 2020 03:38:58 +0000 (03:38 +0000)]
back.rtlil: don't emit wires for empty signals.
Fixes #312.
Mike Walters [Fri, 17 Jan 2020 16:10:33 +0000 (16:10 +0000)]
vendor.lattice_ecp5: support internal oscillator (OSCG).
Jaro Habiger [Sun, 26 Jan 2020 17:35:41 +0000 (18:35 +0100)]
build.dsl: allow strings to be used as connector numbers.
Fixes #311.