Re: Why not mix concurrent and synchronous assignments in the same process?

Discussion in 'VHDL' started by Andy, Sep 7, 2012.

  1. Andy

    Andy Guest

    You can drive combinatorial outputs from synchronous process registers if you use variables for the registers:

    process (clk, rst) is
    -- variable declarations for registers
    begin
    if rst then -- boolean rst
    state := init;
    elsif rising_edge(clk) then
    case state is
    when...
    state := ...
    end case;
    end if;
    -- combinatorial outputs
    fifo_rd <= '0'; -- default assignment to avoid latches
    case state is
    when s_idle =>
    fifo_rd <= '1';
    when others =>
    null;
    end case;
    end process;

    However, you cannot use a synchronous process to create a combinatorial output from input signals (as mentioned by rickman; the process would also have to execute when those signals changed too).

    I also echo what KJ said. Focus on the cycle-based behavior you need, and code that. Too many textbooks focus on how to code registers and combinatorial logic. If you ever use retiming or pipelining optimizations, your finelycrafted RTL that clearly shows where registers are will no longer tell youwhere the registers are anyway.

    Once you do that, then you will understand that it is not the assignment orvariable/signal that determines whether a register is inferred. Just like latches are inferred when a combinatorial process has to remember a previously assigned value, registers are inferred whenever a clocked process has to remember a previously assigned value. When you use variables in a synchronous process, you you have control over whether a register is inferred or not.

    Andy
    Andy, Sep 7, 2012
    #1
    1. Advertising

  2. Andy

    rickman Guest

    Re: Why not mix concurrent and synchronous assignments in the sameprocess?

    On 9/7/2012 9:50 AM, Andy wrote:
    > You can drive combinatorial outputs from synchronous process registers if you use variables for the registers:
    >
    > process (clk, rst) is
    > -- variable declarations for registers
    > begin
    > if rst then -- boolean rst
    > state := init;
    > elsif rising_edge(clk) then
    > case state is
    > when...
    > state := ...
    > end case;
    > end if;
    > -- combinatorial outputs
    > fifo_rd<= '0'; -- default assignment to avoid latches
    > case state is
    > when s_idle =>
    > fifo_rd<= '1';
    > when others =>
    > null;
    > end case;
    > end process;
    >
    > However, you cannot use a synchronous process to create a combinatorial output from input signals (as mentioned by rickman; the process would also have to execute when those signals changed too).
    >
    > I also echo what KJ said. Focus on the cycle-based behavior you need, and code that. Too many textbooks focus on how to code registers and combinatorial logic. If you ever use retiming or pipelining optimizations, your finely crafted RTL that clearly shows where registers are will no longer tell you where the registers are anyway.
    >
    > Once you do that, then you will understand that it is not the assignment or variable/signal that determines whether a register is inferred. Just like latches are inferred when a combinatorial process has to remember a previously assigned value, registers are inferred whenever a clocked process has to remember a previously assigned value. When you use variables in a synchronous process, you you have control over whether a register is inferred or not.
    >
    > Andy


    This is useful info to know. I'm not sure I will ever code this way.
    Partly because it can result in more verbose code if the state registers
    are needed outside of the process and partly because others who aren't
    familiar with the limitations of this technique may have difficulty
    making mods. But it is a potentially useful thing to know, if nothing
    else because it sheds some additional light on the language.

    Rick
    rickman, Sep 7, 2012
    #2
    1. Advertising

  3. Andy

    Andy Guest

    Rick,

    Yes, unfortunately, the techniques of using variables for registers and/or combinatorial logic is not widely known or taught, and even less so, the ability to create combinatorial output logic from registered variables in a synchronous process is rarely covered.

    One side thought: if a state variable (signal) is needed outside its process, I generally view that as "a bad thing". State variables should be "private", allowing changes to the state machine itself (states, transitions, etc.., but not outputs) to remain isolated from external consequences. If another process needs to know when something should be done, the state machine should create an output signal to communicate exactly that (and nothing more) to the other process.

    To mitigate the public nature of signals in two-process FSM implementations(on those rare occasions when they are a good idea), it is preferable to include both processes (combinatorial and clocked) in a block statement (with no other processes), and declare the state signal within that block. Thisallows access by the two processes that really need the state information,while hiding it from other processes within the architecture. Blocks can be thought of as a light-weight entity/architecture, with transparent accessto the enclosing scope (e.g. the architecture, generate or block that encloses the block). Though blocks are allowed to have ports/maps, if you need to use a port map on a block, then you probably need to use an entity/architecture instead.

    Andy
    Andy, Sep 10, 2012
    #3
  4. Andy

    rickman Guest

    Re: Why not mix concurrent and synchronous assignments in the sameprocess?

    On 9/10/2012 10:33 AM, Andy wrote:
    > Rick,
    >
    > Yes, unfortunately, the techniques of using variables for registers and/or combinatorial logic is not widely known or taught, and even less so, the ability to create combinatorial output logic from registered variables in a synchronous process is rarely covered.
    >
    > One side thought: if a state variable (signal) is needed outside its process, I generally view that as "a bad thing". State variables should be "private", allowing changes to the state machine itself (states, transitions, etc., but not outputs) to remain isolated from external consequences. If another process needs to know when something should be done, the state machine should create an output signal to communicate exactly that (and nothing more) to the other process.
    >
    > To mitigate the public nature of signals in two-process FSM implementations (on those rare occasions when they are a good idea), it is preferable to include both processes (combinatorial and clocked) in a block statement (with no other processes), and declare the state signal within that block. This allows access by the two processes that really need the state information, while hiding it from other processes within the architecture. Blocks can be thought of as a light-weight entity/architecture, with transparent access to the enclosing scope (e.g. the architecture, generate or block that encloses the block). Though blocks are allowed to have ports/maps, if you need to use a port map on a block, then you probably need to use an entity/architecture instead.
    >
    > Andy


    Hi Andy,

    Thanks for the suggestions. I have never structured my code quite that
    much before, but it sounds like a good habit. I typically have no
    trouble understanding my code and I expect most others could read it
    easily as well, but every once in a while I have a module that I just
    can't seem to code cleanly. I think this sort of structure would make
    it more understandable.

    This block of code was the source of an error that made it through
    simulation and was caught in bench testing, but I don't like for things
    to get that far. It's better if the customer never sees your bugs.

    Rick
    rickman, Sep 11, 2012
    #4
    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. Nicolas Matringe
    Replies:
    9
    Views:
    722
    Mike Treseler
    Jun 14, 2004
  2. Taras_96
    Replies:
    5
    Views:
    2,149
    Taras_96
    Apr 14, 2005
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,804
    Smokey Grindel
    Dec 2, 2006
  4. Rickert
    Replies:
    0
    Views:
    654
    Rickert
    Oct 6, 2011
  5. KJ
    Replies:
    4
    Views:
    676
Loading...

Share This Page