Hardware programming guidelines
- Synchronous design
- synchronization of external signals (at very high frequencies use two register)
- never cross a clock domain without a register/FIFO
- always use output registers on statemachines (be aware of the potential latency) code examples of the two accepted formats go in here: Jan
- take care not to use inferred latches, most likely you don't want that.
- there is no design without constraints
- clock (register to register)
- register to IO-pad
- IO-pad to register
- use the registers in the IO pads if possible
- pinout file has to correspond with place and route report
- use an automatically generated version number in the code, which should be readable for example by the slow-control channel of the TRB-Net. Code is already available from Marek.
Recommendations for a common VHDL code style
Everyone agrees that it is of some advantage if we agree on some coding style to ease the maintenance
and also reduce the number of errors when we have to merge code of different people.
Naming issues
- The underscore "_" separates different parts of port and signal names
- Signal names should be verbose: don't save characters
- Use a scheme that clearly marks signals as belonging to the same part of logic, for instance timing_counter, timing_counter_reset, timing_counter_stop
- Names of processes and instances should have a distinct namespace such as THE_* or PROC_*
- Processname has to be different then signal names
- Processnames are unique
Lower / Upper Case
- capital letters for ports, like DATA0, CLK and so on
- capital letters for constants, instance names and process names
- lower case letters for signals and entities
- Maybe one exception - if a signal is correlated with a port, I (Ingo) like copy-n-paste. Example: tmp_DATA0
Signals and Ports
- Use only postive logic for signals in entities.
- If in the top-level there are low-active ports, then append a "_N" to the name and introduce a signal with positive logic and use this in the entity
- All Ports have a _IN respectively _OUT postfix to show their direction. Exceptions: CLK, RESET, CLK_EN, STAT, CTRL as well as top level ports with a verbose name like TX_DATA.
- Signals leaving an entity should always be registered. Don't forward combinatorial information to the next entity!
- Defined signals are to be used (unused signals generates generates warnings)
Prefixes for Signals
- Depending on how they are generated, signals should have one of the following prefixes
- buf_ : A signal to make the output of an entity readible.
- reg_ : Output of a Flipflop
- next_: Combinatorial signal that is fed into a fliflop
- comb_: Combinatorial signal that is not registered
- last_: A signal that is delayed by one clock cycle by a flipflop
- comments should tell why something is done and not what and how (this tells the code).
Code review
- After finishing the development of an entity, please remove all unused signals, code lines introduced during debugging...
- Keep debugging signals that might be useful later when debugging the whole system!
Resets
- Use synchronous resets only, never asynchronous! This may not be true for Lattice, but only Xilinx devices.
- Lattice ECP2M series: if you want to use the GSR network, be sure that
- your reset set there is really asynchronous
- no logic is included in the signal (i.e. use an external pin for the GSR net)
- you force the mapper to use the GSR with your signal (LPF: USE_GSR NET "netname";)
- the mapper really followed your command
- this issue is still under investigation! -- MichaelBoehmer - 19 Feb 2009
- Watch out for clock domains! (example: TRBnet regIO "general reset" signal is driven by 100MHz clock, but is used in frontend handling logic with 40MHz clock like in the RICH ADCM, so a short pulse on "general reset" may be missed on the slow flipflops, or even worse, lead to metastability).
- All registers (including state machines) should have a reset
- Exceptions: Data registers like shift registers that are only read when another flag signal is set and can remain invalid until they are written
Processes
- All synchronous processes use "RESET", "CLK" (if system clock is used) and "CLK_EN" as inputs
- use rising_edge(xx) and falling_edge(xx)
- A process should look like this:
library IEEE;
use ieee.std_logic_1164.all
-- purpose: simple counter, multipurpose
COUNTER1: process (CLK) -- no CLK_EN, RESET for synchronous reset
begin
if rising_edge(CLK) then
if RESET = '1' then
counter <= (others => '0');
elsif CLK_EN = '1' then
counter <= counter + 1;
end if;
end if;
end process;
Entities
- Entities should by default have a port with some status information of the entitiy which can be used for debugging, name: STAT_DEBUG
Making code "readable"
- One blank line between processes, components ...
- Three lines between logical sections
- Signal, types, constants, port names etc. grouped in logical parts (one line space beetween them)
- Here you can find a VHDL code example:
- trigger_distributor.vhd: entity trigger distributor
Synchronizing - asynchronous signals and clock domains
- Whenever using an asynchronous signal, sourced either from FPGA logic or from the outside world, use a synchronizer. Don't use such signal directly in synchronous logic!
- Whenever crossing a clock domain, use a synchronizer. Either a state or pulse synchronizer will do, but don't leave it out, even if the two clock domains are sourced from the same PLL with known relationship in phase.
- There is a special entity in the cvs, basics/signal_sync.vhd, that generates a row of flipflops
- Just a historical note, this is a problem as old as computers are (read chapter 5): bigram.pdf
cvs organization
The cvs modules should be organized in order to prevent copying the source code around.
General idea: everything what is of common interest have to go into a dedicated module (like trbnet).
Projects will have different modules
Module + Path |
Description |
trbnet |
Application independent base package |
trbnet/xilinx |
Xilinx dependent stuff, like fifos |
trbnet/lattice |
lattice dependent stuff, like fifos |
trbnet/basics |
Basic design blocks like simple roms |
trbnet/special |
Special purpose entities like top level entities |
Implementation Help from Xilinx
*
TimingConstraintsGuide6i_7i_8i.pdf: Very useful information about constraints.
- 24 Aug 2006
- bigram.pdf: some technical stuff from 1990, chapter 5 has some remarks