It’s a new school year!

For all you new students out there, please accept my welcome to the wonderful world of digital design. I am neither a student nor a professor, and yet I have helped many students through their projects on the Digilent forum, as well as on freenode IRC.

This post is an outgrowth of my own experience counseling beginners on Digilent’s forums. Indeed, sometimes I feel like I’m a broken record there repeating over and over the same rules for newbies.

So, before you ask for help, here are a couple rules to keep you from running into the same trouble others have gotten stuck within:

  • Build your design with only one clock.

    If the clock that comes into your chip is the wrong speed for your one clock, then use a PLL/MMCM to create the speed you want/need.

    This post discusses a variety of alternative timing approaches, done within clocked logic, that don’t require additional clocks to work.

  • Do not transition on any negative (falling) edges.

    Falling edge clocks should be considered a violation of the one clock principle, as they act like separate clocks.

  • Do not transition on the positive (rising) edge of anything other than your system clock.

    Lots of students seem to want to treat a button like a clock, for example. They then struggle to understand why their design isn’t working. Here are some better approaches that actually work with buttons.

  • Synchronize all external wire inputs by passing them through two clocked flip-flops before using them.

    This helps to avoid problems with metastability. We discussed how to synchronize inputs here when dealing with buttons.

  • Do not use an asynchronous reset within your design.

    Test for any reset within an always block on the positive edge of your system clock like everything else.

  • Simulate everything before placing it onto your hardware

    The unique thing about simulation is that a good simulator will allow you to see and examine every piece of logic on every simulated clock. A good simulator will also allow you to simulate any external peripherals, so that you don’t need your hardware to run your simulator.

    You can read about my own debugging philosophy here.

    You can also read about how to simulate hardware together with your design here.

  • Build unit tests that can “prove” your components work, via a simulator, so that when you later make changes to “improve” the component, you will know that the improvements haven’t broken anything.

  • Build simulations that will support not only unit test, but also full up integration testing

    This was also discussed in the post about my own debugging philosophy.

  • Make sure you simulate whatever means you will use for debugging your design before you transition to hardware.

    An FPGA can be a very difficult black box to get debugging information out of. Before you transition your design into an FPGA, I recommend having some means of getting debugging information back out. This means needs to be simulated and proven along with everything else.

    If you’ve read much of my blog, you’ll know that I highly recommend using a debugging bus that controls your FPGA over TCP/IP. That allows you to control your FPGA simulation, or your FPGA itself, from the same software.

    While there are proprietary solutions to this problem that do not require a debugging bus, you may struggle to integrate your FPGA interaction software with them.

  • Don’t use magic numbers

    A magic number is a number that shows up without explanation or dependency within your code.

    This one is so important, that Marcus Muller chose to echo this sentiment as well in the twitter section down below.

  • Never write the same code twice.

    Write it once, write it well, and then reuse it. Fix it, if you must fix it, just don’t rewrite it over and over again for every project. If done well, this will give you a jump start on any future projects.

Rules for software engineers

  • Hardware design is not like software design

    In software, you can use printf() or a debugger to see every variable in your algorithm. In an FPGA, you will struggle to see anything.

    Even if you could see everything in an FPGA, you wouldn’t be able to stop the FPGA to see any high speed interactions like you can stop a CPU in a debugger.

  • Simulation first.

    The only time you will be able to see everything is in simulation. Start your debugging process there. This post discusses how you can continue debugging by printf()–but only in simulation, should you wish to do so.

  • Get familiar with a logic analyzer on your first project

    While you can’t see everything in an FPGA, and especially not when you are running at speed, you can get a trace from a running FPGA showing how logic transitions over time.

    Such a trace can come from an external logic analyzer. Many of these are available for purchase. For example, I’ve used the Digital Discovery to find bugs in one of my projects. I’m hoping to blog about my experiences with it soon as well. I also have the Open Bench Logic Sniffer on my desk waiting to be tried and tested.

    We’ve also discussed using an internal scope many times on this blog. Such scopes are not hard to build, and can be very useful when trying to figure out what’s going on. I personally use a wishbone scope. We’ve discussed how to set that up here.

  • Teach your FPGA to do some of your debugging for you.

    Learn to set an LED when error conditions take place.

    Learn to trigger your “trace” generation on error conditions, so you can read back logic leading up to those “error conditions.

Just for students

I’ve seen a lot of students get burned. While some might say that this is a normal part of the learning process, don’t let it be your process. Learn from those who have gone before you. Specific lessons I would share include:

  • Success is measured by the number of failures. Plan for failure.

    Every student tends to come across some “impossible” problem in his design that he cannot figure out. He may get stuck at this point for days or even weeks. This is common. Plan on getting stuck, put some time into your schedule in case this happens, and then plan before hand on how you are going to get yourself unstuck.

  • Don’t start your project at the last minute.

    Good engineering takes time to do, and to do right. You cannot control when things will go wrong, or how long it will take to fix things when it does.

  • Plan on debugging from the beginning. Build yourself the infrastructure you need for that task first, then build your design.

    o All of my designs include both one or more wishbone scopes

    o All of my designs include a wishbone to UART debugging bus giving me access to my wishbone scopes

  • Consider this discussion on the FPGA design process, and learn what both instructors and experts often overlook when they teach you how to do the task.

Rules from Twitter

Many thanks to those who know me on twitter! They also offered the following pieces of advice for new students: (some edits applied)

My boss would tell me “Think in hardware” #parallel execution of code, not serial. sachin_bhutada

Thank you, sachin_bhutada, this may be one of the most common struggles software students have.

Use the right device for your job. Need to do 100kOps/s of multiplications? Pah, you cheapest MCU can do that. Remember: designing in HDL is hard, programming in C is easy. Marcus Muller

I think Marcus Muller meant to say that programming in C++ is easy …

One week of aimless development can easily save you two hours of writing specifications. Marcus Muller

Use build-time parameters instead of magic constants; you’ll thank me later. Marcus Muller

When working in a team, beat others with a stuck until they learn to properly use git Marcus Muller

Don’t believe hypes. Marcus Muller

If it’s complicated, make a drawing. Marcus Muller

Get a good book. The online tutorials you find are … spotty, at best. Learn the basics first. Marcus Muller

I often recommend asic-world’s online tutorials, but Marcus Muller’s advice still rings true. “Learn the basics first.” This blog cannot cover all of the basics.

Indeed, his comments hit the nail on the head so well, I’ve struggled here to figure out anything to add to them.

As for this blog and what you will find here, I’m just going to go back and underline Marcus Muller’s advice to “Learn the basics first.” Thank you, Marcus Muller!

Indeed, thank you again to all who responded!

Rules are made to be broken

Please notice how I titled this post as “Rules for new FPGA designers”. These rules are for beginners. Those who have worked with FPGAs for a longer period of time will understand that there are times and places for all of these rules to be broken.

To those who are contemplating breaking these rules, who may be at the point of moving from a beginning FPGA designer to a more intermediate one, my advice is this:

Carefully consider your steps. Do you really need to break the rule? My twitter friends and I shared these rules for a reason. Don’t break them unless you absolutely need to. Further, if you do absolutely need to break the rule, do your research first so that you know how to do so safely and reliably.

This isn’t the last word

I expect I’ll come back to this post many times to update my rules for beginners. So, if you’ve read this once, don’t be surprised if it changes again later as I add to these rules.

Have I missed anything? Feel free to let me know at the address below, and thank you for everyone who has contributed so far.

Finally good luck, have some fun, and stay out of FPGA Hell!