Best practice, design and code

From Robin

Revision as of 12:11, 12 June 2023 by Sigmuha (Talk | contribs)
Jump to: navigation, search


The rules noted here are guidelines that will help creating designs that are easy to verify, read and maintain

RTL code

Sequential logic

Separate registers from combinational logic

  • By separating registers from combinational logic you will reduce the risk of creating more registers than you planned to do. By keeping combinational logic in processes that are solely combinational, you will get the full benefit of warnings from the toolchain if you accidentally create latches or registers within the code.

Register reset should be stated where the registers are assigned

  • Reset is for clearing registers to have them in a predictable state. Although synchronous reset can be stated as combinational logic, the use of reset is setting registers, not interfering with the combinational code function. This may seem as a slight contradiction to the bullet above, but for the sake of modifiability and general readability, it makes sense to keep reset.

Sequential logic example:

REGISTERS: process(clk) is 
  begin 
    if rising_edge(clk) then 
      if reset then 
        r_signal <= '0';
        r_vector <= (others => '0');
      else
        r_signal <= next_signal;
        r_vector <= next_vector;
      end if;
    end if;
  end process;
  
COMBINATIONAL_LOGIC:
next_signal <= valid_a and valid_b;
next_vector <= std_logic_vector("0" & unsigned(a) + "0" & unsigned(b));

Conditional Statements

In VHDL there are many ways of describing the wanted conditional behaviour of your design. To help with deciding which syntax is best in terms of correctness, compactness and readability, look at this overview:

Conditional statement overview in VHDL
Statement Targets Conditions Process
if Multiple Multiple Required
case Multiple Single Requires
when ... else Single Multiple Optional
with ... select Single Single Optional
  • When in doubt...
    • Try 'with...select'. This will force you to make visible choices.
  • Only use 'if'...
    • When you need to prioritize conditions...
    • and have multiple targets
      • Typically used for clocked processes.
  • It is fine to use 'when...select' or 'when...else' inside if and case
    • Do you need if inside if?
    • Case inside case?
    • Readability suffers when nesting several levels of if or case.

Latching

Often times the issue with using the incorrect conditional statement for the task is the inferring of latches in the design. To understand why this is a problem, we must understand what a latch is, and how this can create a misbehaving and unpredictable design.

A latch is a digital component used to store values, but differs from a flip-flop in when it is able to be read to. A latch is "open" during the positive duty cycle of the clock, while a flip-flop is edge-triggered. This means that is a value changes during the positive duty cycle (maybe to prepare for the next clock cycle) a latch will read this changed value, making an incorrect design.

if

case

when...else

when...select

FSM

  • Keep register assignment separate from combinational logic (as with/see sequential logic)
  • Keep calculation of next state separate from state output

While this is stating the same criteria (state tree) twice, it makes reading the state machine behavior easier. In contrast, having next_state logic mixed with state output, debugging one will include debugging the other. It does not take much logic before the smokescreen effect is notable when reading code.

FSM Example:

This example will base itself on this diagram:

File:Best_practices_fsm_diagram.png

Personal tools
Front page