Search code examples
processentityvhdl

How can I have two different "processes" for the same entity accessing the same outputs in VHDL?


I have an entity which looks at five pairs of switches and sets letters on a 7-segment display based on the state of those switches (H for 00, E for 01, L for 10 and, O for 11).

I have a process in the architecture of this file which has a case statement that looks at the values of the switches and writes the proper letter to the corresponding display.

Now, I also have three switches that will, depending on their states, move the letters to adjacent 7-segment displays (like a rotation). I originally had this in another process within the same architecture, but I get compilation errors because I'm using the outputs (the 7-segment displays) in two different places.

I'm completely new to VHDL so this may seem simple, but how do I separate these two functions? Do they need to be in different files? How to have them both run "concurrently"?


Solution

  • If you drive a signal from two different processes, the two drivers will "compete".

    For bit and std_ulogic types, the compiler will complain that you are not allowed to have two drivers on a signal. If you are using std_logic types, then there is a "resolution function" which decides what the resulting value is when you drive two different values onto a signal. For example, if you drive a 0 and a 1, you'll get the defined-unknown result X.

    It is possible to drive Z (high-impedance) onto a signal to allow another signal to override it, however, if you want to synthesise it you need to check what your tools will do with it as very few chips these days can actually have real high-impedance modes on their internal signals.

    A portable, tidy, synthesisable way to achieve what you want is to treat a logic 1 as less-strong than a logic-0. Then you can combine two separate signals with an AND gate:

    process1: process 
    begin
       sig1 <= '1'; -- not driving 
       -- some statemachine eventually does
         sig1 <= '0';
       -- and then 
         sig1 <= '1'; -- when it's finished
    end process;
    
    process2: process
    begin
        sig2 <= '1'; -- not driving
           --- similarly...
           sig2 <= '0'; -- at some point
    end process;
    
    actual_sig <= sig1 and sig2;
    

    If it makes more sense for your purposes for a 0 to be the 'idle' state, then use an 'or' instead to merge the signals together.