Showing posts with label SDCC. Show all posts
Showing posts with label SDCC. Show all posts

Sunday, December 28, 2014

Microcontroller Showdown, Revisited

Back in March I finished the microcontroller comparison of a few chips I was considering using. The 8051 based chips all fared poorly in BCD calculations, which is the main thing they would be used for in another calculator project. Some other 8051 fans pointed out that tests like mine test the compiler more than the chip and the SDCC compiler does a lot less optimizing than GCC. So, I decided to recode the BCD Add routine from the test in assembly. At the beginning I didn't consider this because I thought I would only ever write C for the 8051, but after writing assembly for the 6502, I was excited to try it for the 8051 too.

For this test I used the MCU 8051 IDE simulator. It is really impressive! Being able to see all the RAM and registers helped a lot. It is similar in some ways to what I hoped to accomplish with my 6502 Virtual Trainer. When I translated the original BCD Add function from C, I left out the parts used for subtraction, since they weren't used in the test. Also, some of the values that don't change inside loops are calculated once before the loop and stored for use later. This makes sense because a good C compiler would do this for you. All values are stored in the internal DATA, although this would be far too small for real calculations. The simulator can also work with SDCC, so I was able to simulate the function in C after commenting out the parts for subtraction.

The assembly took a simulated 440us to execute. The C version took between 1365 and 1732us depending on memory model and whether the BCD data was stored in DATA or XDATA. Curiously, storing it in XDATA was always faster. The medium memory model was faster than the large memory model. It seems then that hand-coding the routine in assembly is 3-4 times faster. To be fair, the routines for other architectures might also show a speed up if they were rewritten. Compared to the original numbers of the test, a 3x speedup would make the DS89C450 faster than the MSP430 for this routine. The difference might actually be a little bigger since this test used an upgraded version of SDCC that might optimize better. With that in mind, an 8051-based calculator with external bus (coded in assembly) would outperform an MSP430 with SPI SRAM. That is a bit of a surprise after the results of the first test.

The LPC1114 could also be sped up a little. In the original test the chip was configured to run at 50MHz. Because the flash runs at a maximum 20MHz, 3 wait states are required when executing from flash. However, 3 wait states is a little wasteful since 2.5 would be enough. Running the chip at 40MHz would only require 2 wait states, and would let the flash run at full speed. I'm not sure this would give a whole 16% speedup but I imagine it would offer a little bit of a boost.

Sunday, February 2, 2014

Microcontroller Showdown, Part 3

The next chip I compared was the DS89C450 from Maxim. This is a single-cycle 8051 with clock speeds up to 33MHz. The other single-cycle 8051 I wanted to test is the AT89LP6440 but I wasn't able to program it with an FTDI cable. It expects an SPI interface based on a parallel port and I do not know how to get it working with the FTDI cable.

At first I had a lot of trouble getting the DS89C450 running with the flashing software supplied by Maxim. It just would not connect no matter what crystal or capacitor combination I tried. After a little digging I found out that the baud rate depends on the crystal and that 4800 is the max for 12 and 20MHz crystals. Unfortunately, the flashing software only supports 1200 and 9600 or higher bauds. At 1200 baud I was finally able to connect successfully but the chip returned an error when I tried to load firmware. After more digging it seems the problem is caused by using an FTDI cable instead of a real serial port. I can't really hold this against the manufacturer, though, since the chip and software are over 10 years old at this point. Next I tried connecting over Hyperterminal at 4800 baud and this worked great. The interface for communicating with the chip is actually kind of slick. It gives you a prompt you can type commands into and responds back to your input. Loading firmware at 4800 baud, however, was a real pain. If I decide to seriously use this chip, I will definitely track down a crystal that lets me connect at 57600 baud.

The results of the tests are after the break. I ran them with a 20MHz crystal and scaled the results for what they would probably be with a 33MHz crystal. For compiling I used SDCC. This compiler is new to me but it seems pretty simple to use. In place of -O3 I used --opt-code-speed and for -Os I used --opt-code-size. There wasn't really a difference in the results though. As you can see, it adds 8 bit numbers even faster than the LPC1114, 16 bit numbers about as fast as the MSP430, and 32 bit numbers almost twice as fast. It is also much faster at multiplying than the MSP430, which was a surprise to me. Out of curiosity I looked at the 8051 instruction set and was quite surprised to learn that it has 4-cycle multiplication of 8 bit values. The rest of the instruction set and architecture seems very straightforward and I imagine it would be fun to write assembly code for this chip. Division and shifting are pretty slow. GPIO, however, is very fast. Each pin is mapped to its own byte in memory. This seems like a simple feature and I wish more chips had it. With this the chip can bit bang almost as fast as the LPC1114 can with masks. The real test of the chip, though, is BCD calculations and in this it was pretty disappointing, running 2-3 times slower than the MSP430. For these tests all the data was stored in the on-chip external RAM (xdata). This is slower to access but it was necessary to store it here since the internal RAM holds less than 100 bytes. I also tried storing it in the idata section available in 8052 compatible chips like this but that was even slower. It looks like I won't be using this chip for any calculator designs but I will keep it in case I do a project that needs an external memory interface or memory mapped peripherals.