[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [f-cpu] Coding for Synthesis





Michael Riepe wrote:

>[Yann, you may copy&paste this to the VHDL HOWTO if you wish]
>
>VHDL is a very powerful language, but synthesis tools support only a
>rather limited subset of it. Many constructions that work fine during
>simulation won't be accepted by synthesizers at all.  Since some of you
>are going to rewrite their units (and expressed their wishes to do it
>only *once* ;), I'll give you some more hints.
>
>- processes, wait statements and sensitivity lists:
>
>    DO NOT use `wait' statements; always write processes with an
>    explicit sensitivity list. Make sure that every signal that
>    is used (= read) inside the process is also mentioned in its
>    sensitivity list.
>
>- clocked circuits:
>
>    In order to instantiate flipflops (or pipeline registers),
>    use the following idiom:
>
>        process (...)
>            ...
>        begin
>            expression1 := ...;
>            expression2 := ...;
>            expression3 := ...;
>            ...
>            if rising_edge(clock_signal) then
>                signal1 <= expression1;
>                signal2 <= expression2;
>                signal3 <= expression3;
>                ...
>            end if;
>        end process;
>
if rising_edge... is well but the syntax

if (clock_signal'event and clock_signal='1') then ...

is better (see synopsys recommendation coding style)

and for falling_edge

if (clock_signal'event and clock_signal='0') then ...

>
>    Note that there must be AT MOST ONE `if rising_edge(clock_signal)'
>    inside a particular process, the conditional expression MUST NOT
>    have other elements, and the `if' statement MUST NOT have `elsif'
>    or `else' clauses. The `if rising_edge(clock_signal)' may be nested
>    inside another `if' statement (or may be an `elsif' clause itself),
>    but you should limit this use to the cases listed below.  Also note
>    that use of rising_edge() - or the signal'event attribute - is NOT
>    supported inside functions or procedures!
>
>    BTW: It is considered good style to write one process per
>    pipeline stage (unless the pipeline is `forked'), and put the
>    `if rising_edge(clock_signal)' clause at the very end of the
>    process, as shown.
>
BTW (2) : It is considered good style to write one process to drive only 
one signal.

>
>- clock enable and reset:
>
>    If you need a clock enable signal and asynchronous reset, you
>    can write:
>
>        if to_X01(async_reset) = '1' then
>            some_signal <= '0';
>        elsif rising_edge(clock_signal) then
>            if to_X01(clock_enable) = '1' then
>                some_signal <= some_expression;
>            end if;
>        end if;
>
>    Synchronous reset is also possible:
>
>        if rising_edge(clock_signal) then
>            if to_X01(sync_reset) = '1' then
>                some_signal <= '0';
>            elsif to_X01(clock_enable) = '1' then
>                some_signal <= some_expression;
>            end if;
>        end if;
>
>    But I used asynchronous reset everywhere.
>
>- pipeline enable:
>
>    If your unit has more than two pipeline stages, you probably want
>    to chain the enable signal. That is, the enable signal `travels'
>    through the pipeline together with the data `wavefront' (I used
>    that trick in the IMU in order to save power). To do so, provide an
>    `enable out' signal in each stage:
>
>        if to_X01(async_reset) = '1' then
>            some_signal <= '0';
>            enable_out <= '0';
>        elsif rising_edge(clock_signal) then
>            if to_X01(enable_in) = '1' then
>                some_signal <= some_expression;
>            end if;
>            enable_out <= enable_in;
>        end if;
>
>    Then, connect `enable_out' of stage <n> to `enable_in' of stage <n+1>.
>
>- multibit:
>
>    Avoid fiddling with individual bits if a vector will do. It is
>    a good idea to put more complex operations inside a procedure
>    or function, and then apply that to its argument vectors (if
>    there is a single result vector, please use a function).
>
>    Some operations are already defined. E.g. `reduce_and' calculates
>
>        A(A'low) and A(A'low+1) and ... and A(A'high)
>
>    for an arbitrary std_ulogic_vector A; analogously, `reduce_or'
>    and `reduce_xor' perform the `or' and `xor' operations. These
>    functions (among others) can be found in package Bit_Manipulation
>    in the common/ subdirectory, and are documented in common/doc/.
>
>
>- while loops:
>
>    The sequential `while ... loop' statement is not supported by
>    Synopsys (and probably other synthesizers).  If you need something
>    like that, use
>
>        for i in 0 to MAX_LOOPS loop
>            exit when condition;
>            ...
>        end loop;
>
>    or similar, and make sure MAX_LOOPS is big enough (integer'high is
>    a possible choice).
>
>- assertions:
>
>    If you use assertions or report statements (which is a good
>    idea for simulation but won't work during synthesis), surround
>    them with
>
>        -- pragma synthesis_off
>        assert blah ... ;
>        -- pragma synthesis_on
>
@+
Just an Illusion

-- 
______________________________
"The matrix is my world, I am a shadow.
Shadow in world, shadow in life. Don't try to keep me,
I am a Corpo's Killer.
Don't follow me or die..."
		The KingWalker - 1996



*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu       in the body. http://f-cpu.seul.org/