Here are some quick FPGA pointers
- Be very clear on what sort of reset, asynchronous/synchronous you want. An asynchronous reset in clocked logic can result in your whole design becoming one big metastable input
- Often a reset is not required. Most FPGAs upon start up can have their initial contents specified for signals (i.e. signal bla : std_logic:='1';). Doing this removes one signal form almost every LUT in your design, removes the net with the biggest fanout and removes other reset timing problems. Don't feel as though you NEED to have a system reset pin. This can be done through the FPGA programming interface if really required (A well designed system and FPGA should not really need a reset).
- Understand metastability (That is where a changing asynchronous input is sampled and its result can stay in an undetermined state). The undetermined state is an obvious problem, however the instance where due to logic structure the 'same' signal actually resolves differently in two different places in the design on the same clock edge can cause all manner of problems. This is easy to accidentally do as in:
if rising_edge(clk) then if b='1' then a <= a+1; end if; end if;
If b is asynchronous, then a may take on some random value if b changes close to a clock edge.
- Specify timing constraints: Especially on clocks and any timing critical IO. If you don't your system may not meet timing and you'll not realise and spend a long time tracking down odd behaviour.
- If you don't care what a signal is, then say so. The implementation tools can take advantage of this and specify what would result in the fastest or the smallest implementation. i.e.
if b='1' then a <= X"01"; elseif c='1' then a <= X"10"; else a <= "XXXXXXXX"; end if; end if;
- Count to a predefined number, initialize to a arbitrary one. Often this means counting down to zero. This results in a smaller fan in on the comparison and thus lower propagation delay, and higher speed.
- Clock as slow as you can. This makes your life easier and reduces power consumption.
- Pipeline. Pipelining improves thruput. Its harder to think about, and does have complications, but can make higher clock speeds easier.
- Plan your pinout BEFORE committing to a layout. Too often the FPGA firmware developer is badgered into picking a pinout so the hardware can be built. RESIST! There is nothing more annoying than trying to make a design work with pins, clocks in the wrong place on the package so the propagation delay is increased. Pay particular care with VREF, VRN and VRP pins. Realizing you've missed these can ruin your day. Ideally generate a design with a proposed pinout to check for any problems.
- Where you can allow the PCB layout guys to swap pins. It is equally annoying for the PCB layout engineer to fan out a mess of an FPGA pinout which when all is said and done is arbitrary. You'll have better tracking, better decoupling, better signal integrity.
- Reduce the number of signals contributing to any other signal. This reduces fan in, fan out. Thus reducing propagation delay and power consumption.