This page is about the historical development of Bluetiles. For the current state of affairs, see Bluetiles.

The most recent version of the Bluetiles protocol is Bluetiles II

In the beginning...

The basis of Bluetiles was implemented by Nathan Lasseter (NJEL) in summer 2012.

The original NJEL network protocol specified a header of the form:
  • Header Word 0: Destination address (32 bits) comprising X (16 bits) and Y (16 bits)
  • Header Word 1: Payload size (32 bits)

No format was specified for the payload. In this form, messages have a sender and a receiver. The message header identifies the physical receiver (destination address) but not the sender (source address). Other omissions include a way to specify the logical service being accessed (e.g. a port number) and the priority of the message.

Bluetiles I

Jack modified the NJEL protocol in two major ways. Firstly, he changed the packet header structure. Secondly, he changed the connections to be instances of BSV Client and Server interfaces. The result was the first Bluetiles protocol, which will now be referred to as "Bluetiles I".

When defining Bluetiles I, Jack could have taken the existing protocol as a "media access layer" and added an "IP" layer. But there are many wasted bits in the header that could be reused. The following were identified as useful (but optional) features:
  • Source port number: A sender may expect replies to messages. In this case, the sender is acting as a client, and the receiver is acting as a server. The client may contact multiple servers at the same time, a server may take some time to process a request, a server may send more than one packet in reply. A source port number allows the source to have more than one request active at a time.
  • Destination port number: A destination port identifies the service provided by the server. Including this allows a single location to provide multiple services.
  • Source address: Making this a feature of the header makes it easy to reply. Without it, the return address would have to be encoded into the payload for any request requiring a reply.
  • Command code: Sometimes it is useful to encode a bit of extra "out of band" data for a request or a reply. For instance, to send the size of a load.
Jack observed that there was no real need to scale this protocol far beyond a 16x16 NoC, because such a thing was too large for our FPGA devices. However, 640K was famously not enough for everyone, and so the fields were arranged to support a 256x256 NoC, and allow 256 ports at the source and destination, with packet payloads of up to 255 words. (Practically, the size range is from 1 (which means two header words only) to about 250 words, depending on the service being used.)

The Bluetiles I protocol has the following header structure:
  • Header Word 0 Byte 3 (most significant): Destination X
  • Header Word 0 Byte 2: Destination Y
  • Header Word 0 Byte 1: Destination Port
  • Header Word 0 Byte 0: Size of Payload plus 1 (i.e. 0 is not valid)
  • Header Word 1 Byte 3: Source X
  • Header Word 1 Byte 2: Source Y
  • Header Word 1 Byte 1: Source Port
  • Header Word 1 Byte 0: Out of band bits
Importantly, this header structure allows a packet to be routed as soon as the first header word arrives. The router may treat the second header word as part of the payload.

Moving to Bluetiles II

The Bluetiles I protocol was in use until June 2013, and during this time, the header structure became increasingly ingrained into the Blueshell codebase. Though there were standard BSV functions for creating headers, they weren't used everywhere, and in software, the same set of #defines for working with headers propagated disease-like throughout the C source code.

This would have continued to work, though it might not have been desirable, if not for the sudden requirement to add a priority field. Jack considered how the header structure could be changed. The key requirements were:
  • Route packets using only the first header word (as before)
  • Add a priority field
  • Keep compatibility with existing hardware and software
Jack thought it impossible to meet all requirements simultaneously, and decided to sacrifice compatibility, since this also offered an opportunity to centralise the definition of the header fields into exactly three places:
  • For BSV: the /Bluetiles.bsv package
  • For C: the /bt/ directory (C source and headers)
  • For Python: the /tests/TestMB.py package ("Header" class)
In the week of 10/6/13 Jack went through most of the codebase, looking for instances where deprecated #defines were used, or where headers were being generated in some other way, and replaced these with the new form. The change meant it was no longer possible to reply to a message by exchanging the first and second header words, but such is life: routers that use priorities need to see the priority as soon as possible, so it is as important as the destination address and the size.

Bluetiles II

The Bluetiles II protocol has the following header structure:
  • Header Word 0 Byte 3 (most significant): Destination X
  • Header Word 0 Byte 2: Destination Y
  • Header Word 0 Byte 1: Priority (differs from Bluetiles I)
  • Header Word 0 Byte 0: Size of Payload plus 1 (i.e. 0 is not valid)
  • Header Word 1 Byte 3: Source X
  • Header Word 1 Byte 2: Source Y
  • Header Word 1 Byte 1: Source Port
  • Header Word 1 Byte 0: Destination Port (differs from Bluetiles I)
This is defined in /bt/bt_interface.h (as a union and struct), and in /Bluetiles.bsv (as a struct), and in /tests/TestMB.py (as a class with encode/decode methods).

Standard Service Ports

The standard service ports did not change between Bluetiles I and Bluetiles II. But there is a difference in the implementation of the READ and WRITE services, described on the Bluetiles page. Specifically, for these services, the out of band bits were used to encode the read size (READ) and byte enable mask (WRITE), while payload word 0 gave the address. For Bluetiles II, there are no out of band bits in the header, so payload word 0 gives both the address and the size or mask. Payload word 0 is called a BT_RW_Header and contains both, packed into a 32-bit word.