How to write synthesizable RTL
- RTL is a description of a sequential design that possesses data between registers, possibly applying some logic to the data on the way.
- RTL is the synthesizable subset of an HDL (Verilog, VHDL, System Verilog).
- But not everything can be implemented in the hardware (i.e. with logic gates). Therefore, only a subset of the HDL is considered "Synthesizable".
- Never put logic on "reset" or the "clock".
- Never mix reset types.
- Never create clock domain crossings.
- Do not infer latches
- Every "if" has an "Else".
- Full case settlement
- LHS for every signal for each condition
- Assignment (always blocks)
- In Combinational (always @ *) use blocking (=) assignment
- In Sequential (always @ posedge) use non-blocking (<=) assignment
- Always separate the sequential and combinational logic
- Never assign a signal (LHS) from more than one always blocks
1. No logic on reset (or clock):-
- The reset and clock signals are not just any signal and they needed to be handled with the core.
- clock signals should be only used to clock registers.
- reset signals should be only used to reset registers.
- Logic glitches are a [characteristic, not a design error.
- A glitch on the clock causes an unwanted data sampling.
- A glitch on the reset causes fops to reset accidentally.
Therefore, do not put the logic on reset and clock signals.
Ex: 1. assign something == a&&reset; ......(wrong)
2. always@*
case (state) .....(wrong)
1'b1011 : if (b || reset)
next_state=idle;
Note: Let's assume you have an input that you want to sample at the beginning of a process. The wrong way to do it would be a something like this-
input in;
reg in_sampled;
always @ (posedge clk or negedge rst)
if (!rst) in_sampled <= in;
else...........
But remember we need to map a synchronous block to a flip-flop. A flip-flop can be reset/set to '0' or '1' and "in" is a non-constant signal. Therefore, the synthesizer would need to decide to create a set or reset signal during reset, depending on the value of "n". This is logic on reset.
- Alternate way is by making an "initialize" state and a "start"state.
Ex: always@*
case state:
INIT: begin
next_in = in;
next_STATE = start;
......
always @ (posedge clk or negedge rst)
if(!rst)
state <= INIT;
in_sample <= 0;
else
state <= next_state;
in_sampled <= next_in;
2. No clock domain crossings:-
- Some (or most) designs have more than one clock.
- These clocks may have a different source.
- They may run at different frequencies.
- If we cannot know the phase between them- they are "asynchronous".
- If you cannot have a path between asynchronous clocks, this is known as a "Clock Domain Crossing".
- The only way to "remember" a value, is with a register (i.e. flip-flop or latch).
- If we accidentally ask to remember a value, a latch with inferred.
- This is due to not assigning LHS for all conditions.
- A missing case option (and no default)
- A combinational 'if' but without an 'else'.
- An if/else/case without assignment to all LHS signals.
- For all of the above, we have to keep the value for the non-defined condition.
- A similar problem is a missing signal in the sensitivity list.
- Essentially don't change the output when this signal changes.
- The Synthesizer may ignore this, but the simulator will adhere to it!
- Just use always@* and this will not happen!
- To ensure no latch interference, just assign default values for all combinational assignments:
- At the beginning of an always@* block assign all LHS to a default value.
- Overwrite the default value, as necessary within following if/else/case conditions.
- "Sequential logic" is defined within simple "always@ posedge" blocks that map directly to std cells from the library.
- Everything else (i.e., combinational logic) is defined using "assign" and "always@*" blocks.
- In other words, there is a clear separation between sequential and combinational logic.
- Never assign a signal from two always blocks (or "assign's" )
- This results in two logic blocks driving the same net.
- CMOS cannot tolerate multi-driven nets
- Each register have its own always@ posedge block.
- Signals can appear in the LHS of only one always@8 block.
- Signals can appear in the RHS all over the phases.
- A combination signal cannot be assigned (LHS) by itself.
- In other words, it cannot appears on both LHS and RHS in the same logic path even upstream several stages.
Comments
Post a Comment