Mixing comb and reg part in one process

Discussion in 'VHDL' started by valentin tihomirov, Dec 31, 2003.

  1. Is it a good style to write code like the following

    process (CLK, Reset)
    variable RegNext: STD_LOGIC;
    begin
    -- comb part
    RegNext := calculate();

    -- reg part
    if Reset = '1' then
    RegNext <= '0';
    elsif CLK'event and CLK = '1' then
    REG <= RegNext;
    end if;
    end.

    ????

    I've asked this question to myself trying to define the sensetivity list and
    type (signal vs. variable) of RegNext value. This style would allow for
    combining related logic into one process rather than divide one process into
    comb and reg declaring lots ot specific signals at architecture scope.
    valentin tihomirov, Dec 31, 2003
    #1
    1. Advertising

  2. And YoC, signals are not allowed to be decalred in processes.
    valentin tihomirov, Dec 31, 2003
    #2
    1. Advertising

  3. valentin tihomirov

    David Jones Guest

    In article <bsu9a6$1e4ml$-berlin.de>,
    valentin tihomirov <> wrote:
    >Is it a good style to write code like the following
    >
    >process (CLK, Reset)
    >variable RegNext: STD_LOGIC;
    >begin
    > -- comb part
    > RegNext := calculate();
    >
    > -- reg part
    > if Reset = '1' then
    > RegNext <= '0';


    REG <= '0';

    > elsif CLK'event and CLK = '1' then
    > REG <= RegNext;
    > end if;
    >end.


    Other than the one correction above, this is OK.

    But what's wrong (in this case) with:


    process (CLK, Reset)
    begin
    -- reg part
    if Reset = '1' then
    REG <= '0';
    elsif CLK'event and CLK = '1' then
    REG <= calculate();
    end if;
    end.


    If calculate() is complex (i.e. it is a sequence of statements),
    then put it closer to where it will be used:


    process (CLK, Reset)
    variable RegNext: STD_LOGIC;
    begin
    -- reg part
    if Reset = '1' then
    REG <= '0';
    elsif CLK'event and CLK = '1' then
    RegNext := calculate();
    REG <= RegNext;();
    end if;
    end.
    David Jones, Dec 31, 2003
    #3
  4. > But what's wrong (in this case) with:
    >
    >
    > process (CLK, Reset)
    > begin
    > -- reg part
    > if Reset = '1' then
    > REG <= '0';
    > elsif CLK'event and CLK = '1' then
    > REG <= calculate();
    > end if;
    > end.


    The consern is - reuse. It often happends that there are signals in
    combinatorial part that muliple others comb signals depend on. For example,
    several registers depend on CNT = 0 comparator's out. If you enclose
    combinatorial signals behind CLK, several comparators will be generated.
    Most synthesis tools can detect this and allow reuse of resources, you say.
    But when logic becomes more comlex (for ex, one replaces that comparator
    with two comparators), the style based on reuse leads to less verbose and
    easier-to-maintain code.
    I did not adopt using of functions (a sort of reuse in a certain way), this
    is an idea though. Thanks.
    valentin tihomirov, Dec 31, 2003
    #4
  5. valentin tihomirov

    Oggie Guest

    "valentin tihomirov" <> wrote in message news:<bsu9a6$1e4ml$-berlin.de>...
    > Is it a good style to write code like the following
    >
    > process (CLK, Reset)
    > variable RegNext: STD_LOGIC;
    > begin
    > -- comb part
    > RegNext := calculate();
    >
    > -- reg part
    > if Reset = '1' then
    > RegNext <= '0';
    > elsif CLK'event and CLK = '1' then
    > REG <= RegNext;
    > end if;
    > end.
    >
    > ????
    >
    > I've asked this question to myself trying to define the sensetivity list and
    > type (signal vs. variable) of RegNext value. This style would allow for
    > combining related logic into one process rather than divide one process into
    > comb and reg declaring lots ot specific signals at architecture scope.


    Assuming you are trying to define FSM you could do that in one of the
    two ways:
    1. Using two processes (one combinational for the Next_State and one
    clocked for the Current_State).
    2. Combine the above two processes in one CLOCKED process (similar to
    your code). In this case the process should look like:

    **************************************************
    type SM_TYPE is (state_1, state_2, ....);
    signal sm_present_state : SM_TYPE;

    process (CLK, Reset)
    variable sm_next_state : SM_TYPE;
    begin
    if Reset = '1' then
    sm_present_state <= state_X; -- this is the initial state
    elsif CLK'event and CLK = '1' then
    sm_present_state <= sm_next_state;
    sm_next_state := calculate_next_state();
    end if;
    end process;
    **************************************************

    The signals involved in "calculate_next_state()" do not have to be in
    the sensitivity list because this is clocked process. Both 1 and 2
    processes FSM definitions are legal, but the two processes definition
    is considered more readable and is the preferred way.

    Cheers,
    Oggie
    Oggie, Dec 31, 2003
    #5
  6. Thanks to all, I think I have worked out a good style without next and
    clocked process. Please, appretiate my code below. As you see, it is neat;
    no _NEXT internal logic signals are shown at architecture scope. Avtive-HDL
    succesefully compiles the file but I did not ask a synthesier about it yet.


    -- signals READ and CLEANING are used in this and in a separate process
    -- signals are external nets, variables are used inside process
    -- signals are named in UPPERCASE, variables in MixedCase.
    SHIFT_REG: process (RESET, CLK, SHIFTING, AVAIL)
    variable Empty: boolean;
    variable Cnt, CntNext: Integer range 0 to WIDTH; -- amount of bits in
    shift_reg
    begin

    -- combinatorial part
    Empty := Cnt = 0;

    CntNext := Cnt;

    if not Empty and SHIFTING = '1' then
    CntNext := CntNext - 1;
    end if;

    CLEANING <= TO_STD_LOGIC(SHIFTING = '1' and CntNext = 0);

    READ <= '0';
    if (Empty or CLEANING = '1') and AVAIL = '1' then
    READ <= '1';
    CntNext := WIDTH;
    end if;

    -- clocked part
    if RESET= '1' then -- Reset
    Cnt := 0;
    elsif Rising_Edge(CLK) and ENABLE = '1' then

    if READ = '1' then
    BUF <= FOUT;
    elsif SHIFTING = '1' then
    BUF <= '1' & BUF(WIDTH-1 downto 1);
    end if;

    Cnt := CntNext;

    end if; -- clock

    end process;
    valentin tihomirov, Dec 31, 2003
    #6
  7. It is legal VHDL (saving, as others have noted, RegNext := '0' as
    it's declared a variable).
    However, it likely isn't synthesisable. If you split it into 2 parts,
    each performs a clearly defined action, & the synthesiser can see what
    you mean. Of course, RegNext is then a signal.
    Bear in mind that most synthesisers work by matching your code to a
    list of templates: when they find a match, that defines the code they
    produce. If you write "creative" VHDL, it may be syntactically OK, but
    it won't match a template, & the synthesiser will fail.
    Get a copy of the "Libraries Guide" and "XST User's Guide" from
    www.xilinx.com - they contain examples of the proper code to use to
    infer each of the Xilinx hardware primitives. Of course, these are
    specific to XST (the Xilinx tool), but the principles are general.

    "valentin tihomirov" <> wrote:

    :Is it a good style to write code like the following
    :
    :process (CLK, Reset)
    :variable RegNext: STD_LOGIC;
    :begin
    : -- comb part
    : RegNext := calculate();
    :
    : -- reg part
    : if Reset = '1' then
    : RegNext <= '0';
    : elsif CLK'event and CLK = '1' then
    : REG <= RegNext;
    : end if;
    :end.
    :
    :????
    :
    :I've asked this question to myself trying to define the sensetivity list and
    :type (signal vs. variable) of RegNext value. This style would allow for
    :combining related logic into one process rather than divide one process into
    :comb and reg declaring lots ot specific signals at architecture scope.
    :
    David R Brooks, Dec 31, 2003
    #7
  8. valentin tihomirov

    Oggie Guest

    "valentin tihomirov" <> wrote in message news:<bsv32n$1gp17$-berlin.de>...
    > Thanks to all, I think I have worked out a good style without next and
    > clocked process. Please, appretiate my code below. As you see, it is neat;
    > no _NEXT internal logic signals are shown at architecture scope. Avtive-HDL
    > succesefully compiles the file but I did not ask a synthesier about it yet.
    >
    >
    > -- signals READ and CLEANING are used in this and in a separate process
    > -- signals are external nets, variables are used inside process
    > -- signals are named in UPPERCASE, variables in MixedCase.
    > SHIFT_REG: process (RESET, CLK, SHIFTING, AVAIL)
    > variable Empty: boolean;
    > variable Cnt, CntNext: Integer range 0 to WIDTH; -- amount of bits in
    > shift_reg
    > begin
    >
    > -- combinatorial part
    > Empty := Cnt = 0;
    >
    > CntNext := Cnt;
    >
    > if not Empty and SHIFTING = '1' then
    > CntNext := CntNext - 1;
    > end if;
    >
    > CLEANING <= TO_STD_LOGIC(SHIFTING = '1' and CntNext = 0);
    >
    > READ <= '0';
    > if (Empty or CLEANING = '1') and AVAIL = '1' then
    > READ <= '1';
    > CntNext := WIDTH;
    > end if;
    >
    > -- clocked part
    > if RESET= '1' then -- Reset
    > Cnt := 0;
    > elsif Rising_Edge(CLK) and ENABLE = '1' then
    >
    > if READ = '1' then
    > BUF <= FOUT;
    > elsif SHIFTING = '1' then
    > BUF <= '1' & BUF(WIDTH-1 downto 1);
    > end if;
    >
    > Cnt := CntNext;
    >
    > end if; -- clock
    >
    > end process;



    If your intention is to synthesize hardware implementation, then the
    above code has multiple problems. The different synthesis tools will
    produce different results due to the way the code is written. The most
    important is the interpretation of multiple "IF-END IF" before
    "Rising_Edge(CLK)" and "elsif Rising_Edge(CLK) and ENABLE = '1' then".
    While it is perfectly OK for simulation, the different synthesis tools
    will have hard time to guess the intention of this code and as a
    result some will generate errors, some will generate warnings, some
    will make assumptions and try correct it. In addition to that the
    resulted hardware (if synthesized at all) will definately behave
    different from the RTL simulation.
    1. Think about the sensitivity list(if there is one) - a process only
    triggers when there is transition on at liast one signal in its
    sensitivity list. A local variable (declared inside the process) CAN
    NOT trigger a process.
    2. Given the above, all signals which are read in the combinational
    portion of the process MUST be in the sensitivity list. Keep in mind
    that all signals assigned in a process DO NOT change their value until
    after the process is terminated, Thus the signals "CLEANING" and
    "ENABLE" must be in the sensitivity list.
    3. A process which describes sequential element (FF) may also describe
    combinational logic between the input of the described FF and:
    ** the output of other FFs or LATCHEs or
    ** its own output or
    ** module inputs.
    To do that the process must have only one "[IF]-[ELSIF]-IF/ELSIF
    edge(clk)-END IF" statement. There may be multiple embedded "IF-END
    IF" statements under each clause, but the process can not have more
    then one non-embedded "IF-END IF" between the "BEGIN" and "END
    PROCESS". The first "[IF]" and "[ELSIF]" clauses (if they exist)
    define the asynchronous set/reset combinational logic (it may be
    function or only connection of the external to the process signals)
    thus the signals read in this portion MUST be in the sensitivity list.
    The "IF/ELSIF edge(clk)" (clocked portion) clause defines the
    combinational logic (it may be function or only connection of the
    external to the process signals and or local variables) which drives
    the data input of the FF or LATCH.
    4. Considering the above, it is obvious that for FSM the NEXT_STATE
    (combinational logic) could be defined under "IF/ELSIF edge(clk)"
    clause, but not in separate (non-embedded) "IF-END IF" statement.
    Since this portion is only executed upon CLOCK transition, there is no
    need for the signals read in this portion to be in the sensitivity
    list (the result of the combinational function is only used when CLOCK
    transitions). Even more, it is not recommended those signals to be in
    the sensitivity list, because it may result in unintentional
    generation of LATCHES.
    5. A process can define combinational logic only or sequencial element
    only or both - sequencial element and combinational logic. When a
    process does define sequencial element only or both - sequencial
    element and combinational logic the rules described above apply. When
    a process defines combinational logic only, then no "'EVENT" attribute
    can be used in it and every time the process is triggered all of the
    signals driven in this process MUST be assigned otherwise LATCH will
    be generated. In your code:

    > -- clocked part
    > if RESET= '1' then -- Reset
    > Cnt := 0;
    > elsif Rising_Edge(CLK) and ENABLE = '1' then


    looks like "if RESET= '1' then" is the asynchronous reset (this is not
    the clocked portion). The variable Cnt will be written when the
    process is triggered and RESET is '1' or there is Rising_Edge(CLK)
    (the portion "and ENABLE = '1'" will be discussed later for now I will
    assume it being a separate IF statement under "elsif Rising_Edge(CLK)
    then"). It all looks OK if we assume that the process will never
    trigger if there is no transition on either RESET or CLK and this is
    the only "IF-...-END IF" statement in the process. But the process
    will trigger upon SHIFTING and AVAIL, thus making it possible for Cnt
    to not be written - reason for LATCH generation, but the intention is
    for Cnt to be FF??? Furthermore "elsif Rising_Edge(CLK) and ENABLE =
    '1' then" is not welcomed by some synthesis tools - some may not even
    recognize the intention for FF generation and optimize out Cnt and all
    signals related to it (like CLK FOUT, ENABLE).

    I would suggest you review my previous post.
    Cheers,
    Oggie
    Oggie, Jan 2, 2004
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?TWlrZQ==?=

    Mixing Non-ASP.NET & ASP.NET Files in One Domain

    =?Utf-8?B?TWlrZQ==?=, Aug 10, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    289
    Cowboy \(Gregory A. Beamer\)
    Aug 10, 2007
  2. Comb Filter

    , Nov 11, 2007, in forum: VHDL
    Replies:
    3
    Views:
    641
    Mike Treseler
    Nov 11, 2007
  3. Guest

    Secure Page/Reg/Login Process Flow

    Guest, Aug 7, 2004, in forum: ASP General
    Replies:
    0
    Views:
    158
    Guest
    Aug 7, 2004
  4. Jack
    Replies:
    8
    Views:
    276
  5. Doogie

    Setting a default option for a comb box

    Doogie, Feb 25, 2007, in forum: ASP General
    Replies:
    3
    Views:
    131
    Mike Brind
    Feb 25, 2007
Loading...

Share This Page