In the past I've talked about my experience with TI and their support for their DSPs. Given that experience I am now looking at Analog Devices and their Blackfin line of DSPs.

Compared to the TI part this has turned out to be a breath of fresh air. The Analog folks look like they've put a lot of effort into thinking about, and talking to, their customers and how they use DSPs, and that's reflected in their newest line of DSPs.


One of the biggest differences is the number of generic digital I/Os that the Analog DSPs provide. The Blackfins typically come with 16 digital I/O lines, which is quite a bit more than you will usually find on a DSP, and these I/Os are truly general purpose, usable as inputs and outputs, aggregated as 10, 12, 14 or 16 bit input or output port suitable for interfacing to an ADC or DAC, and oh by the way, if they're configured as inputs they can each be setup to trigger interrupts.

This is incredibly important. If you are using DSP you probably want to control something based on that signal. Now there are exceptions, for example the digital processing for an MP3 player would just be from memory out to a DAC that fed the headphones, so in theory you only need a data bus interface and no DIOs. But that's theory and doesn't match up well with reality. The reality is that the MP3 Player has a user interface with buttons and knobs and something has to handle that user input. Now the traditional thinking is that you have two processors, one DSP for the signal processing, and a second less powerful processor for handling everything else. DSPs have become more powerful and there are more spare cycles. That is, the DSP has more than enough power to handle the signal processing with some to spare. Those spare cycles can be applied toward the everything else processing, unless of course you don't have the DIOs.

DIOs on the DSP are important because in a good design they may actually help displace another processor which reduces cost, energy requirements, heat, and the number of development platforms you need to maintain.

Algebraic notation

The assembler for the Blackfin uses algebraic notation as opposed to a more traditional assembler notation. For example, to set the value of a register R0 to 12 you use:

R0 = 12;

Now compare this to the more traditional assembler:

MOV A0, 12;

Which just feels like a language designed by a crack addled Yoda.

Write One To Set

This bit is absolutely brilliant. One of things you do all the time in embedded firmware is set bits. Or clear bits. Almost all of the peripherals on modern CPUs are memory mapped which means that you read and write to memory addresses to control their behavior. The problem is that a bunch of bits that control different aspects of the peripheral are all packed into the same word, and if you want to change something you read the word out into a register, flip the bits you want changed, then write the value back into the memory mapped register. That's a minimum of three operations, and you can end up spending a lot of time flipping bits in memory mapped registers.

MOV A0, B0[X+23];
AND A0, 0x0080, A0;
MOV B0[X+23], A0;

I don't know where Analog came up with this, if it's even original to them or they borrowed it from someone else, but many of the registers are W1S (write-1-to-set) or W1C (write-1-to-clear). That is, writing a value into a W1S register will set the bits where ever there is a 1 in the value written, the rest of the bits remain unchanged. Similarly for W1C, you write 1's where you want the bits cleared, the remaining bits remain unchanged. Analog combines these, so that a single register may actually have multiple memory mapped areas, a W1C register, a W1S register, and a normal register. This makes for dramatic code reduction. For example, the above code which sets bit 7 of a memory mapped register becomes a single instruction if the register is W1S:

MOV 0x0080, B0[X+23];

That's 1/3 of the code size, and also 3 times faster to execute.

Circular Buffers

Another common task in signal processing is handling buffers, and those are commonly circular buffers. The Blackfin has native support for such constructs, where you setup 2 registers to define the beginning and length of a circular buffer, and then use a third register as an index into the buffer. The CPU takes care of keeping the index register on track, you just keep on incrementing and it folds back down to the beginning of the buffer automagically. This increases the speed of your loops since you don't need to check for overflow everytime through.

These are just some of the advantages of the new Blackfin chips. I've just started exploring but it appears Analog has done a really good job listening to their customers and it shows in their products.

Oh, and that level of quality seems to extend across the company, a quick note to got a personal answer in about 12 hours, and the one documentation bug I reported got answered and closed out in a day.

single instruction if the register is W1S:

MOV 0x0080, B0[X+23];

Wouldn't this be (to be consistent w/ the "algebraic notation")?:
  B0[X+23] = 0x0080

Posted by Damon on 2004-03-31

Yes it would.

Posted by Joe on 2004-03-31