User manual › Signal types — what a port carries, and why a link is refused
kind: manual#manual#ports#links#signal-types#canvas

Signal types#

Every port carries a signal type: a double, a 32-bit integer, a boolean, a string. The type decides what the port looks like, what colour the link leaving it is drawn in, and which ports that link may be dropped on. This page is what those colours and badges mean and what to do when a link will not connect.

The badge on a port#

A port's badge is a short name and a size — f64 [3x1] is a double-precision signal three rows tall and one column wide. The short names are:

BadgeWhat it is
f64a double — the ordinary signal, and the default everywhere
f32a single-precision float
boola boolean, true or false
i8 i16 i32 i64a signed integer of that many bits
u8 u16 u32 u64an unsigned integer of that many bits
stra string
busa bus — several named signals travelling together

Two badges are not followed by a size in the [rows x columns] form, because they do not have one. A string shows its length — str [12] — and a bus shows how many elements it carries, in braces: bus {4}.

Badges are hidden while a model builds cleanly. They come back on their own the moment a build fails, which is when the types and sizes on the ports are exactly what you need to read. The toolbar button that controls them says which state it is in: Port signal types stay hidden, and appear only when a model build fails. Click to always show them — clicking pins them on, and clicking again returns them to following the build.

Colours#

The colour is the family, not the individual type, so a diagram does not turn into a paint chart:

  • Doubles keep the ordinary port and wire colour the canvas has always used. A model made only of doubles looks exactly as it always did.
  • Single-precision floats are a muted grey-blue — the same family as a double, a step quieter.
  • Booleans are amber.
  • Signed integers are a deep teal; unsigned integers are the same teal a shade lighter. Signed and unsigned are neighbours on purpose: they are the same kind of thing, and the badge (i32 against u32) is what tells them apart when it matters.
  • Strings are violet, and their wire is drawn dash-dotted.
  • Buses are royal blue, and their wire is drawn as a double line — a bus is more than one signal, and the wire says so.

Two of those change the stroke as well as the colour, and that is deliberate: a dash-dotted or doubled wire is still legible when the colours are hard to tell apart, on a projector or in print.

Connection state comes first. A link with an end left dangling is drawn dashed and in the unconnected colour whatever type it is. The type's colour and stroke describe a wire that is actually connected at both ends.

A link takes its type from the port it starts at, and it may only be dropped on a port that accepts that type. Drop it somewhere that does not and the port and the wire turn red for a moment and the link is left dangling — the same place it would be if you had let go over empty canvas. Nothing is silently converted.

You find out before you let go. While you drag, the wire snaps to a port or to another link as it passes under the cursor, and it only ever snaps to one it could actually connect to. A port that will not take what you are carrying does not attract the wire at all — it turns red, and the cursor changes to the "no entry" shape for as long as you hold the pointer over it. So the drag never shows you a connection that the drop would then refuse, whichever end you are holding: the same is true dragging a link's head onto a port, dragging its tail back to a different source, and right-dragging a branch off a wire that already exists.

The check runs in all three places a connection can be made: dragging a wire by hand, the automatic connector, and the model build. So a wire that was refused on the canvas is refused the same way in a recipe, and a diagram that somehow carried a mismatched link is stopped at build time with Incorrect signal type reaching port, naming the port.

Many input ports accept more than one type — an arithmetic block will take any numeric signal. What a port accepts is part of what the block is, described in the block's own documentation.

When you genuinely want to change a signal from one type to another, that is a conversion and it is done by a block, in the open, where a reader of the diagram can see it happen.

Exporting a typed diagram#

Not every target language can carry every type, and the ones that cannot say so by name rather than generating something that quietly disagrees. A hardware description language has no variable-length string, for example: it needs a fixed bit width, and a string's size is only known while the model is running. The export target tells you which port and why before it generates anything, and code-export verification records that combination as N/A with the reason — not as a failure. See Exporting code — the ten targets, what each produces, and what verification proves.

Choosing a type#

Most blocks in the library carry doubles on every port, and you will see f64 on most badges. A handful of blocks are where a different type enters a diagram, and each of them is ordinary to use — the type is either a choice in the block's configuration or a property of the block itself:

  • Data Type Conversion (Signal Attributes) is the block to reach for when a link is refused. It takes any numeric signal and re-emits it as the type you pick under Output data type — a double, a 32-bit float, any of the integer widths, or a boolean. Converting to a narrower integer wraps rather than saturates, and the fractional part is dropped toward zero: 200 into an 8-bit signed integer reads -56, and -2.7 into any integer reads -2. Put one in the wire between a double source and a typed input, and the link on each side of it connects because each side now matches.
  • Constant (Sources) has the same Output data type choice, so a constant can be typed at its source instead of converted afterwards. A value the type cannot hold exactly is rounded the way the type rounds: 3.7 as a 32-bit float is 3.7000000476837158, which is what a single-precision target will compute with.
  • Logical Operator, Relational Operator and Bitwise Operator (Logic and Bit Operations) produce booleans and integers by their nature. A relational operator compares two numeric signals and emits a bool; a logical operator takes booleans in and emits a boolean; a bitwise operator works on unsigned 32-bit integers by default, and its Operate on data type choice selects another integer width for all three ports. Feeding a double into a boolean input is refused, and a Data Type Conversion set to bool is the way through.
  • String Constant, String Length, String Compare and String Concatenate (Strings) carry text. A string port's badge shows a length rather than a matrix size, a string link is drawn in the string colour, and the numeric result of a length or a comparison comes out as an ordinary integer or boolean that the rest of the diagram can use.
  • Bus Creator and Bus Selector (Signal Routing) bundle several typed signals into one bus link and take them apart again. Each element keeps its own type through the bus, so a 32-bit integer packed on one side comes out a 32-bit integer on the other.

Sinks such as Scope, Display and Terminator accept every numeric kind, so a typed signal can be watched without converting it first. A scope draws a boolean or an integer as steps rather than as a smoothed line, because that is what the signal is.

The type a port takes from its configuration is applied when the diagram is built, which is what happens when you run it. Until then a port whose type is chosen in a dialog still shows the badge it had.