It is typically performed on the synthesisable Register Transfer Level (RTL) subset of the HDL, be it VHDL or Verilog/SystemVerilog, though it can also be partially applied at the gate level too.
Why lint? Because simulation and synthesis can take a long time, particularly for large gate-count devices, it is worth going into both with the cleanest code possible; thus minimising the risk of having to trace problems back to HDL. Or to put it another way, linting is about securing design quality assurance early on in the design flow.
Linting performs a static analysis of the code, checking it against recognized design rules and best-practice guidelines. It also helps identify problems such as unreachable statements, suboptimal synthesis, simulation versus synthesis mismatches, clock/reset connectivity issues, unsynchronized Clock Domain Crossings (CDCs) as well as looking for obstacles against testability, all of which help reduce the number of synthesis and implementation re-runs.
There are a number of RTL linting tools available on the market. They tend to be integrated with whichever design entry tool is being used. In some cases, and subject to the capabilities of the design entry tool, bugs discovered during linting can be shown in the design environment, in the code editor and/or on a schematic representation of the design’s netlist.