Creating Custom Hardware Pt.1
So if anyone has been paying attention to my twitter and other social media accounts you may have seen the neat little recurrent spiking neural network I created
This is a network of 16,384k neurons arranged in a 128x128 grid. Each neuron has connections between itself and it's 8 immediate neighbors, as well as an “axon” which receives signals from a selection of neurons within a specific radius around the axons 2D position.
Each of these connections is weighted, and during run-time if the neuron detects that the target neurons of any of these connections is also firing then the weighting factor will increase, otherwise it slowly decays each update.
Signals are modeled as a rising and falling output that follows the SIN function from 0 to (PI/2*3) which isn't psychically accurate and can be swapped out with outer activation functions easily but I haven't done that yet. The rate at which the neuron sweeps through this 0-(PI/2*3) range is also modified, with the sweep rate increasing when the neuron fires and decreasing otherwise.
Each neurons output is then mapped to a single pixel in the image above, leading to a very impressive visualization! All in all, this is less than 175 lines of code counting white-space and comments in the file. It's worthy of a post of it's own, and I'll be writing one after this series.
I've created a lot of different neural networks but none of them were as realistic and certainly none of them showed the interesting activity seen with this model. One thing I really like is the different wave like frequencies seen in the average activation level of the network. So I started to wonder, what would happen to this network if I could feed it some real world information?
Assumptions
This is not a beginners guide by any means, but that doesn't mean a beginner couldn't follow along. Our main assumption is that you've at least programmed a microcontroller such as an Arduino, PIC, etc. If you haven't we highly recommend it before starting this article, Arduinos are very cheap and readily available, with tons of project ideas and a great community behind it.
It's also assumed you know how to read schematics, and are familiar enough with them to at least draw them at a novice level.
Designing Hardware 101 – The Specifications
The first step to designing good hardware is to come up with an idea of exactly what your project needs to be successful. These specifications guide the design process and component selection, and help us to avoid a lot of wasted time pursuing dead ends (keep reading for an example within this project).
This project needs to:
Run a artificial neural network (ANN) with 128x160 neurons, 20,480 neurons total
Display the output of this network on a LCD screen at a minimum of 30 frames per second
Receive inputs such as audio and orientation from the environment
Be capable of running for a limited duration detached from its power source
These simple specifications will help keep our project on track.
Component Selection
Now that we have a set of specifications lets proceed to choose the kind of hardware we want to build our project from. Since so many things are dependent on it, choosing a processor is a good first step, and will help avoid any revisions to include a different chip because of something we didn't think about. We'll be ordering all our components through Digikey because they are awesome, trustworthy and have great customer support. I've used them for years and can't recommend them enough.
I've only programmed Microchip PIC16/PIC18 microprocessors. And while I'd love to use them, they can't run as fast as I'd like (capped at 64MHz) and even if I got a PIC32 and ran it at 100MHz. I'm still limited by the fact that the instruction clock is internally divided by four...that means our instructions are only running at 25MHz. There are lots of alternatives out there that are much faster, for example AVRs instruction clock is the same as the input. ARM Cortex processors are 1.25x the clock which means for every 4 clock cycles you get 5 instructions! Lets go with that! But...out of the 3,000 different ones on Digikey which one would be the best fit? Well, let's specify exactly what we want:
100MHz or faster
Enough I/O pins to handle a TFT display and any peripherals we might require.
TFT display buses are USUALLY 16-bits wide with 3 to 4 control lines. This comes out to 20 pins at least. I like to double that, so anything with 40+ I/O pins will work.
Analog to Digital Converter, we plan on feeding audio into the network so we'll need a way to convert that to a digital value for input into the network.
These specifications reduce our choices from 3,000 to ~124 or so. From that point it's mostly the price point that drives my selection. The one I chose is the NXP MK02FN128VLH10, a Cortex M4 processor. It has 46 I/O lines, and ADC, and can run at 100MHz! Perfect!
The next thing we need to think about is memory, the processor alone doesn't have enough memory to handle running an ANN. This is easy to calculate by looking at the data structure of an individual neuron:
unsigned int ID unsigned char x unsigned char y unsigned char status unsigned int weights * N unsigned int targets * N unsigned int signal_t unsigned int signal_start unsigned int input unsigned int output unsigned int threshold
N is the maximum number of neurons an individual neuron can be connected to. For N=50, each neuron takes up 217 bytes of memory, for 20,480 neurons (128x160) that's 4,444,160 bytes or 4.24 MB. Looks like we're going to need some memory, because most microcontrollers do not come with that much onboard ram. Our specifications for memory are:
64Mb of memory
MB = Megabytes, Mb = Megabits. Divide Megabits by 8 to get Megabytes, and divide to convert the other direction. For a 4.24MB dataset we need 33.92Mb of space to store it. Memory is cheap, so we'll go with 64Mb
8-bit wide parallel interface. Having 2 16-bit bus devices would eat up 32/40 I/O lines, and we'd like to preserve some for other uses. 8-bit should work fine.
WARNING! DEAD END AHEAD! DRAM, it has a high write cycle reliability, when I first designed this project I chose flash memory which lets you write and erase only about 100,000 times before things start failing. That means if our project ran at 60FPS our memory would wear out in less than 3 hours. If I had thought about the write cycles beforehand I could have avoided wasting the time on the flash memory altogether.
These restrictions made it easy to narrow our selections down to less than 200 or so on Digikey. The cheapest price point was the Cypress Semiconductor S27KL0641DABHI020 at $3. It's a BGA component however, and so you'll need a hot-air rework station to place it if you're using it.
The rest of the components is simply selecting input sensors, the battery, and the display. For the display I already was aware of the DT018ATFT 1.8” 128x160 display and had decided I would use that. It has a 16-bit wide bus, full color display and a backlight. Everything we could want. For inputs I'm using a MEMS Microphone (INMP510ACEZ-R7), an Accelerometer/Gyroscope combo (LSM6DS3TR), a Magnetometer (MAG3110FCR), and a NTC Thermistor. For the battery we're using the popular 102535 800MAh Lipo battery along with the MCP73831T02ACL/OT single cell lipo charger. The last thing we need is a 3.3v Linear voltage regulator, really any will do for this application but I recommend one with a current capacity of 400mA (or more) like the MIC5504-3.3YM5-TR
With this we have a Bill-of-Materials for our design, the major components are:
MK02FN128VLH10
S27KL0641DABHI020
DT018ATFT
INMP510ACEZ-R7
LSM6DS3TR
MAG3110FCR
MCP73831T02ACL/OT
MIC5504-3.3YM5-TR
The rest of the components are minor ones such as flat panel connectors, a Micro-B USB, and resistors and capacitors and not listed here. If you’re interested in the complete component listing you can get the Bill-of-Materials by clicking the following link:
BrainBox Bill-Of-Materials
MCUExpresso Configuration Tools
Before we get into creating a schematic and circuit board, we should take some time to check out the pin configuration tool created by NXP for our MK02FN128VLH processor. This processor has a lot of pins that can function as standard GPIO, but only some of these are available for things such as the crystal oscillator, I2C, and analog functions. These can be found on page 48 of the datasheet for our processor:
NXP makes it very easy to set these pins up with their Pin Configuration Tool
This tool will even generate the code to setup all the pins properly! How cool is that?
And I've made it even easier to follow along with this guide by making the configuration use for this project available for you to download here
BrainBox MCUXpresso Config
Use this when creating your schematic symbols in your preferred software to help save some time.
Schematics and Board Drafting
Once all of the packages and symbols are defined in our electronics drafting software, we can begin the process of laying out a schematic for everything. I like to use a modular process where everything is isolated and connected by their pin function, for example:
Here you can see that the pins in the bottom half our routed to the pins on the object in the top half. I can move these objects and all of their associated pins and passive components independantly of the object they connect to, which allows me to organize the schematic like this.
This makes it really easy to double check everything before sending the board out for production. Does U5 have the right caps? Are all the pins connected like they are supposed to be? All verifiable visually.
When setting up each device I always have the datasheet for that device up for me to look at the application example within the datasheet, take U2, the magnetometer,
and compare it to our schematic:
you can see that I basically just copied the application example from the schematic. And honestly that's what 99% of hardware designers do! There might be the occasional deviation, in mine I omit the .1uF capacitor because I have several near this IC that will provide that function just fine. Simply repeat this process for our 8 major components, and in the end you'll have a schematic that looks similar to this:
Routing the board is easy if you have software that allows backward annotations, this ensures that the software checks constantly for the board and schematic to remain true to one another. At this point you can route and place components wherever you want as long as you connect everything, and this is left as an exercise for the reader because if you can create the schematic this part is easy. Lets take a look at how my final design looks, and discuss some points that will make your routing easier:
Looking at my routings it's easy to see that the first thing I did was place the display so it is centered on the PCB board. I then placed major components like the processor U4, the JTAG header at the bottom, and the memory IC above it. I then routed all the data signals between the processor, display, and DRAM memory, because we want to keep these traces very short to reduce noise. I don't do this with the I2C bus however, why? Well this bus operates at a MUCH slower speed, 400kHz-1MHz compared to the parallel bus, 10MHz+, this means I don't need to worry about keeping these lines as short.
After that is done, I group components with their ICs and route them in their own little space. This is in the same deal as when we did this with the schematics, it keeps everything modular and easy to identify, and makes troubleshooting a lot easier if I need to examine a part of the board that might misbehave. Those are moved into suitable positions on the board, and then their data signals are routed.
The very final thing I do is route the power and ground lines. This is because we really don't have to worry about HOW these get routed, and you can daisy chain the routing between chips to make it easier. Additionally, most ICs have multiple data lines but only 2 lines for power and ground. After all is said in done, you should have a nice and compact circuit board, that is ready to be sent off to a production facility to be fabricated and later assembled by you!
This is the point we are at so far and the end of part 1 of this article. Check back in a couple weeks when I should have received my circuit boards and can begin the last two parts of this series. Thank you for reading!










