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