Close

SDB (Self Describing Bus)

A project log for Nysa: FPGA Development Environment

Hardware and software to simplify FPGA development and interaction.

daveDave 05/31/2015 at 15:061 Comment

I started working on Nysa over three years ago. At the time I was working with a software guy who seemed to be allergic to FPGAs, he said that all of his experiences with them has been tedious, frustrating and required long conversations with the guy writing the FPGA code.

The problem was this: When you want to talk to an FPGA using some controller the controller and FPGA need to be designed in concert. If the designer adds GPIOs to the FPGA the controller needs to know about the GPIOs including their location and characteristics. How to solve this?

One method would be to document all the behaviors of the FPGA design and then use this document to design the software. This is obviously prone to errors, any late night changes to the FPGA code (HDL) and missed documentation would result in a communication break down. Another approach is to use something like USB Descriptors. If you are curious and you have a Linux box you can look at all the USB devices attached to your computer using:

cospan@yogurt:~$ lsusb
Bus 001 Device 003: ID 0483:91d1 STMicroelectronics 
Bus 001 Device 002: ID 8087:8000 Intel Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 004: ID 0bda:5720 Realtek Semiconductor Corp. 
Bus 002 Device 003: ID 04f3:0296 Elan Microelectronics Corp. 
Bus 002 Device 002: ID 8087:07dc Intel Corp. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Then for more details into some device you can type (looking at the first device):

cospan@yogurt:~$ lsusb -d 0483:91d1 -v

Bus 001 Device 003: ID 0483:91d1 STMicroelectronics 
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0483 STMicroelectronics
  idProduct          0x91d1 
  bcdDevice            0.28
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength    3177
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

Although it looks odd this gives all the information to the host computer to either use a built in driver like a mouse/keyboard controller or enough information to tell the user that it needs a custom driver, and who is the vendor that should provide that driver (STMicroelectronics in this case).

This is awesome and it would be great if it was easy to design an FPGA image that generated a descriptor such as this. I tried that a couple of years ago. It worked... ish, well it worked but it was lacking a lot of functionality. I called it the DRT or the Device ROM Table. The idea was the user specified a configuration file that would be used to program the FPGA and the script that generated the FPGA image would also generate this DRT at a known location within the FPGA. The controller would then read the DRT and know enough information to talk to the device. Essentially the FPGA itself was all the documentation required for the software developer.

The DRT worked out great for about a year and a half, it was limited in that it gave only the bare essentials of what was needed. I would add more features hesitantly knowing that I might one day paint myself into a corner. I had considered using the USB descriptor table but the amount of information within USB is very large, and to waste so much space within the FPGA on documentation seemed crazy.

In January I stumbled upon this site from CERN: Self Describing Bus. Apparently I wasn't the only one trying to solve this and these people did it, and did it very well. The SDB is great! It allows me to describe all the essential information I need while still being very compact. To give you a reference of what it looks like Here is a screenshot of the SDB Viewer from the nysa-gui reading and parsing the SDB within an Artems image:

On the left is the Raw ROM data read from the FPGA and on the right is the data parsed. It is only showing the name, address and size but there is more information within each element. For example the GPIO element called gpio1 contains the location of the GPIO device, the size of the module, a 'vendor' and 'product' id and even some class identifiers. I didn't want to use this view so I created another view:

Here is the same information shown visually:

I hope the Self Describing Bus becomes a standard in the future this way any controller can talk to any FPGA.

As for me the Self Describing Bus has enabled me to implement software to control different components on both Dionysus and Artemis. It is a lot more fun only writing high level drivers to control different aspects of the FPGA.

For reference how simple it is to talk to something like GPIOs in an interactive Python shell where I get a reference to a GPIO controller from the SDB in the form of a URN (Universal Resource Name) and turn the LED at address 0 on and off

cospan@loki ~ $ python
Python 2.7.8 (default, Oct 20 2014, 15:05:19) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from nysa.host.platform_scanner import get_platforms_with_device
>>> from nysa.host.driver.gpio import GPIO
>>> from nysa.common import status
>>> print "Get a reference to a status to print out messages"
Get a reference to a status to print out messages
>>> s = status.Status()
>>> s.set_level("warning")
>>> platform = get_platforms_with_device(GPIO, s)[0]
>>> print "Using platform: %s" % platform.get_board_name()
Using platform: Artemis
>>> urn = platform.find_device(GPIO)[0]
>>> print "A URN or Universal Resource Name is a unique name for the GPIO"
A URN or Universal Resource Name is a unique name for the GPIO
>>> print "URN: %s" % urn
URN: /top/peripheral/gpio1
>>> gpio = GPIO(platform, urn)
>>> gpio.set_port_direction(0xFFFFFFFF)
>>> gpio.set_bit_value(0, 1)
>>> gpio.get_bit_value(0)
True
>>> gpio.set_bit_value(0, 0)
>>> gpio.get_bit_value(0)
False


Discussions

Xark wrote 06/01/2015 at 04:36 point

Neat.  SDB does seem like a good idea (especially if standardized).  Thanks for the post.

  Are you sure? yes | no