Hardware Engineers need to Communicate

Again, I found myself staring out the window, pondering my sophomoric attempt at a blog post.  Summer had finally arrived in Oregon with temperatures in the mid-90s.  Children from the onsite daycare wandered by looking really hot.  My own kids are spending the week in a day camp at a local park, having a really good time splashing in the water fountains and playing with other kids their age.  I had better make this good to keep all of you interested.

While my first blog attempt about blinking an LED on a demo board seemed to generate some amount of interest from a few of you, I’d like to move on to the next step in explaining how to use C/C++ for hardware design.  This may be scary for some of you since engineers are notorious introverts.  We’d rather send an email than walk to the office two doors down the hall and actually talk to someone.  Okay, maybe that is just me, but I’ve got a lot of stuff to do before I can go home and hang with the wife and kids.  Who has time for all this chit-chat stuff?  Okay, I know your time is valuable, so I’m trying to make this informative and at least a little entertaining, so drop me a comment and let me know what you think.  What do you want me to ponder next?

Back to what I was meaning to say in the first place, once you can blink an LED, then you want to make sure you can communicate to the outside world.  Unless you are going to communicate via Morse code with an LED, a simple serial interface is the easiest interface to build.  Of course, much more complicated interfaces like USB, Bluetooth, PCI and AMBA are more common now, but I’m only doing this in my spare time, so give me a break.

Preparing Recommendations

The Altera NIOS II demo board I used in the last blog post had a RS-232 serial port interface to the FPGA, including level shifting buffers, so I could plug right into my laptop’s COM1 port.  I wonder how hard it would be to send “Hello World” from the board to my PC through a standard serial interface.  It’s been while since I’ve played around with this stuff, so I leaned on Wikipedia to refresh what I needed to design.  I remembered that a standard protocol back in the days of dialup modems was 115,200 BAUD with 8 data bits and 1 stop bit, but I couldn’t remember what that waveform actually was supposed to look like - Wikipedia to the rescue.

Most embedded microcontrollers and microprocessors include a standard, built-in universal asynchronous receiver/transmitter (UART), but I remembered there was always something tricky about picking the correct oscillator value for an 8051 to get the exact baud rates you wanted.  Since I’m building a custom circuit with any clock divider resolution I need, this didn’t turn out to be a problem.  Once I figured out that the baud rate was just the time interval between each bit transmission, I was well on my way.  With a 50MHz clock, I just need to build a counter approximately equal to 50e6/115200.  Using a clock divider similar to the blinking LED example in my last blog post, I just counted to 434 clocks between bit transmissions.

My aging memory banks also remembered something about a master clock needing to be 16x the transmission rate.  It has to do with the asynchronous part of receiving a serial communication stream, so I’ll worry about that later if my loyal readers want to see me receive input as well as dish it out.  The transmission protocol is pretty simple.  A start bit signals the start of a transmission, followed by 8-bits of data and terminated with a stop bit.  The start bit is active low or a logic 0, while the stop bit is a logic 1.  To test whether I was on the right track, I just toggled the TXD signal every 434 clock cycles and watched what came across the HyperTerminal screen in Windows.  I received a whole bunch of “U” characters.  Looking up the ASCII code in Wikipedia, I confirmed that was what I was expecting.  The first logic 0 was the start bit, then a pattern “10101010″, followed by a logic 1 as the stop bit.  I might be able to pull this off.

At this point, I had little more than a blinking LED transmitting over the serial port.  Thinking back to the previous blog post title, I decided the message should be “Hello World” back to the PC.  To send an arbitrary character, I needed to send a start bit, followed by the 8-bit binary value for ASCII character, and then a stop bit.  My constant send buffer is basically the characters in “Hello World” followed by a new line and carriage return to make the HyperTerminal display look pretty.  In VHDL or Verilog, I’d have to create a look up table to convert characters to ASCII, but in C it is as simple as the following:

unsigned const char send_buffer[BUF_LEN]={’H', ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘, ‘W’, ‘o’, ‘r’, ‘l’, ‘d’, ‘\n’, ‘\r’};

To send the bits from each character, I had to mask off the least significant bit and then shift after sending each bit until all eight were sent.  Again, in C, this is pretty easy:

*txd=(byte & 0×01);
byte = byte >> 1;

Running the debugger in MSVC++ seemed to be giving me what I wanted (figure 1), so I took the code through Catapult C Synthesis.  I was a little worried that I had the timing correct, so I used Catapult’s SCVerify flow to run the RTL using the same C test bench I used in MSVC++.  I received confirmation that the RTL and C matched, plus a quick look at Questa’s waveform convinced me I was ready to try the real thing (figure 2).

Figure 1: Printf debug

Figure 1: Printf debug

Figure 2: Questa waveform

Figure 2: Questa waveform

I just needed to run through Precision RTL Synthesis and Quartus II to get the bitstream for the Altera Stratix II device on the board. What do you know, it actually worked (figure 3).

Figure 3: Proof in HyperTerminal

Figure 3: Proof in HyperTerminal

Just to prove it, I took another video (http://www.youtube.com/watch?v=9K8X__I2O2A).  If you want to check out the full C code for this circuit and the test bench, go to the public ESL Communities discussion forum thread.

For more stuff on Catapult C Synthesis, go to our product page to grab the datasheet  or view more videos.

If you made it this far, take a few seconds to drop me a comment.

Thanks,
Dan

About Dan Gardner

imageDan Gardner is a technical marketing engineer at Mentor Graphics on the high-level synthesis team. He is an experienced RTL hardware design engineer with both ASIC and FPGA experience. Visit Dan Gardner's Blog

More Posts by Dan Gardner

More Blog Posts

Preparing Recommendations

Comments (↓ Add Your Own)

1 Comment on this Post

[...] continue on the topic from my previous blog posts; I wanted to spend some more time on my experiment with serial communication.  Getting the [...]

Add Your Comment

Please complete the following information to comment or sign in.

(Your email will not be published)