Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to execute two or more processes sequentially ?

Status
Not open for further replies.

Dijskstra

Newbie level 5
Joined
Jun 28, 2014
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
93
As a VHDL beginner, I'm stranded in the language idiosyncrasies.

One of the basic things I've learning are as follows:

1) All statments runs in parallel.
2) Inside processes all statements runs sequentially, even though we have imediate assigments and deferred assigments (this is one of the biggest sources of confusion).
3) Several processes runs in parallel among them.


As more I study as more I have questions (and misconceptions).

Let's suppose I have two (or more) processes:


Code:
process1: process(clk)
begin
.
.
.
end process;



process2: process(clk)
begin
.
.
.
end process;


I want to run the two processe sequentially and, because of that, I think I need some kind of "main" process
that "calls" each "subprocess" (sorry but I am strongly software biased).

Something like the pseudocode below:

Code:
Main_Process : process(clk)
begin
    process1;
    process2;
end process;
However I can't accomplish valid results !

Can someone write a little code that does what I want ?


Thank you

Anders
 

No we cant. Thats not how VHDL works.
Given you have "clk" in your sensitivity list, I assume you're trying to describe a synchronous circuit. Remeber, VHDL stands for VHSIC Hardware Description Language. Not a programming language.

So, you are trying to describe hardware. I suggest you stop writing VHDL, and get out a pencil and a peice of paper. Draw the circuit you are trying to create. Then come back to VHDL using the standard templates for the elements you just drew. Without knowing the hardware, you cannot write the description of it.

- - - Updated - - -

Just so you understand, a process is not a function like in C. It is executed all the time, in a loop, until it halts (hits a wait statement) in the case where there is no sensitivity list, or evaluated once when it is triggered by a 'event (ie. a change) from any signal in the sensitivity list.

Functions do exist in VHDL, but they execute in zero time, and are really just a wait to tidy up repeated sections of code.
 

...I suggest you stop writing VHDL, and get out a pencil and a peice of paper. Draw the circuit you are trying to create. Then come back to VHDL using the standard templates for the elements you just drew. Without knowing the hardware, you cannot write the description of it.

- - - Updated - - -

...



Thank you for the quick response. Let me be more specific.

My circuit is very basic. I have two 4-bit counters (the simplism is for educational porposes only)


Code:
entity two_counters is
    port (
              clk : in std_logic;
              Led0, Led1, Led2, Led3,                 -- Counter1
              Led4, Led5, Led6, Led7 : out std_logic  -- Counter2
    );
end two_counters;

architecture behavioral of two_counters is
    signal cnt1 : std_logic_vector(3 downto 0);
    signal cnt2 : std_logic_vector(3 downto 0);

begin

    counter1: process(clk)
    begin
        if raising_edge(clk) then
            cnt1 <= cnt1 + 1;
        end if;
    end process;


    counter2: process(clk)
    begin
        if raising_edge(clk) then
            cnt2 <= cnt2 + 1;
        end if;
    end process;

    -- display counter1
    Led0 <= cnt1(0);
    Led1 <= cnt1(1);
    Led2 <= cnt1(2);
    Led3 <= cnt1(3);

    -- display counter2
    Led4 <= cnt2(0);
    Led5 <= cnt2(1);
    Led6 <= cnt2(2);
    Led7 <= cnt2(3);

end behavioral;



What I want is:

Counter1 counts from '0000' to '1111' and then stops, starting Counter2
Counter2 counts from '0000' to '1111' and then both counters are stopped.


How can I do that ?

Sorry for the question. I know this is a very basic question but I'm at the very beginning of VHDL.


Thank you

Anders
 

Ok. Lets get some basic VHDL pedantry out of the way.
From the code you posted, you must be using non-standard libraries, because you cannot do arithmatic with std_logic_vector in standard VHDL (well, you can from 2008, but tht isnt very well supported). I guess you have included std_logic_unsigned library - this is not part of the VHDL standard, neither is std_logic_arith. As you're a beginner, I suggest you start using the ieee.numeric_std library. It defines unsigned and signed types that should be used for arithmatic, and representing numbers. With the non-standard libraries you cannot do signed and unsigned in the same file. with numeric_std you can (std_logic_arith needs to be avoid as it conflicts with numeric_std).

Anyway, on to your problem.

You need to think about your problem. For a start, in your current code, your first counter will not stop (lets put asside the fact is has no reset or initial value, so in a simulation all you will get at the moment is "UUUU"). When it gets to "1111", it will wrap around to "0000" again. You need an if to stop it counting, put a clause in there to only count to a certain value, something like this:

Code:
if cnt1 < 15 then
  cnt1 <= cnt1 + 1;
end if;

Now, you know you can read signals in another process, so you could do a similar thing in the 2nd process. Ill let you have a go and work out what you need to do.
 

Code:
[COLOR=#FF0000]use ieee.numeric_std.all;[/COLOR]
architecture behavioral of two_counters is
    signal cnt1 : [COLOR=#FF0000]unsigned[/COLOR](3 downto 0);
    signal cnt2 : [COLOR=#FF0000]unsigned[/COLOR](3 downto 0);

begin

    counter1: process(clk)
    begin
        if raising_edge(clk) then
            [COLOR=#FF0000]if (Reset = '1')[/COLOR] then -- Assuming that you want to initialize them to a known value
               cnt1 <= (others => '0');
               cnt2 <= (others => '0');
            else
                if (cnt1 = 15) then
                   if (cnt2 /= 15) then
                      cnt2 <= cnt2 + 1;
                   end if;
                else
                   cnt1 <= cnt1 + 1;
                end if;
        end if;
    end process;

    -- display counter1
    Led0 <= cnt1(0);
    Led1 <= cnt1(1);
    Led2 <= cnt1(2);
    Led3 <= cnt1(3);

    -- display counter2
    Led4 <= cnt2(0);
    Led5 <= cnt2(1);
    Led6 <= cnt2(2);
    Led7 <= cnt2(3);

end behavioral;

Code has not been compiled or simulated...but should be pretty close if it's not 100%

Kevin Jennings
 


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
process (clk) begin
  if rising_edge(clk) then
    -- increment till cnt1 is 15 then stop
    if (cnt1 < 15) then
      cnt1 <= cnt1 + 1;
    end if;
  end if;
end process;
 
process (clk) begin
  if rising_edge(clk) then
    -- increment till cnt2 is 15 only if cnt1 is done counting to 15
    if (cnt1 = 15 and cnt2 < 15) then
        cnt2 <= cnt2 + 1;
    end if;
  end if;
end process;



This is assuming the signals which are declared as integers are initialized with 0 to start.

Regards

- - - Updated - - -

Darn K-J beat me to it. ;-)

- - - Updated - - -

K-J, You have two processes that both assign cnt2, that isn't going to work...you'll get problems with multiple drivers.
Code:
    counter1: process(clk)
    begin
        if raising_edge(clk) then
            if (Reset = '1') then -- Assuming that you want to initialize them to a known value
               cnt1 <= (others => '0');
               cnt2 <= (others => '0');
            else
                if (cnt1 = 15) then
                   if (cnt2 /= 15) then
                      [COLOR="#FF0000"]cnt2 <= cnt2 + 1;[/COLOR]
                   end if;
                else
                   cnt1 <= cnt1 + 1;
                end if;
        end if;
    end process;


    counter2: process(clk)
    begin
        if raising_edge(clk) then
            [COLOR="#FF0000"]cnt2 <= cnt2 + 1;[/COLOR]
        end if;
    end process;

- - - Updated - - -

Sorry Tricky, looks like K-J and I just messed up your lesson plan.
 

K-J, You have two processes that both assign cnt2, that isn't going to work...you'll get problems with multiple drivers.

I just forgot to delete the second process before posting. It has been corrected now, everything in one process.
 

Guys answered question very clear and i must highlight this
"So, you are trying to describe hardware. I suggest you stop writing VHDL, and get out a pencil and a piece of paper. Draw the circuit you are trying to create. Then come back to VHDL using the standard templates for the elements you just drew. Without knowing the hardware, you cannot write the description of it."
Yes it is fundamental rule for beginner especially for those that have experiences with software.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top