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

Rep:[f-cpu] Coding for Synthesis



Nice resume but...

-----Message d'origine-----
De: Michael Riepe <michael@stud.uni-hannover.de>
A: F-CPU Mailing List <f-cpu@seul.org>
Date: 10/07/02
Objet: [f-cpu] Coding for Synthesis

[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;

    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.

- 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.

>>>ok ! But i always read that synopsys prefer synchronous reset but in
every design i see asynchronous reset was compulsory ! 

- 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>.

>>>Gloups ! i don't like that at all : a new asynch signal (that's
introduice slew rate problem). I think that such signal must be under
the rising_edge of the process.
nicO

- 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

-- 
 Michael "Tired" Riepe <Michael.Riepe@stud.uni-hannover.de>
 "All I wanna do is have a little fun before I die"
*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu       in the body. http://f-cpu.seul.org/

 
______________________________________________________________________________
ifrance.com, l'email gratuit le plus complet de l'Internet !
vos emails depuis un navigateur, en POP3, sur Minitel, sur le WAP...
http://www.ifrance.com/_reloc/email.emailif


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