Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Procedures and array element assigment from different processes.

Reply
Thread Tools

Procedures and array element assigment from different processes.

 
 
Seb
Guest
Posts: n/a
 
      03-11-2005
Dear all,

I am surprised by the behaviour of the following code where I try to
assign (different) elements of an array from different processes. When
doing so with a procedure, it does not work as expected. Can somebody
explain me why?

Thanks a lot.

Seb.

=====
library ieee;
use ieee.std_logic_1164.all;

entity vector_splicing is
end vector_splicing;

architecture one of vector_splicing is

signal ok, still_ok, not_ok : std_logic_vector(1 downto 0);
signal clk : std_logic := '1';

procedure assign(signal d: inout std_logic_vector; i: in integer;
v: in std_logic) is
begin
d(i) <= v;
end assign;

begin

clk <= not clk after 5 ns;

process( clk )
begin
if rising_edge( clk ) then
ok(0) <= '0';
assign(still_ok, 0, '0');
assign(still_ok, 1, '1');
assign(not_ok, 0, '0');
end if;
end process;

process( clk )
begin
if rising_edge( clk ) then
ok(1) <= '1';
assign(not_ok, 1, '1');
end if;
end process;

end one;
 
Reply With Quote
 
 
 
 
Neo
Guest
Posts: n/a
 
      03-14-2005
I think there is a race condition imposed by your two clocked processes
calling the same procedure.

 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      03-14-2005
Seb wrote:

> I am surprised by the behaviour of the following code where I try to
> assign (different) elements of an array from different processes. When
> doing so with a procedure, it does not work as expected. Can somebody
> explain me why?


Your processes are both writing to the same signals.
This "shorts" the outputs together.
Consider a single process.
I don't know what you expected, but to
splice vectors consider
big_vec <= this_vec & this_bit & another_vec;

-- Mike Treseler
 
Reply With Quote
 
Seb
Guest
Posts: n/a
 
      03-15-2005
Hi Mike,

Mike Treseler wrote:
> Your processes are both writing to the same signals.

Yes, but to differents elements of the array!

> I don't know what you expected,

I expeced the signals "ok", "still_ok" and "not_ok" to give the same
results. They all try to achieve the same thing: assign a value to an
element of a vector.
In the first case, the 2 elements of the vector "ok" are assigned from
two different processes, it works, hence the sig name.
In the second case, the 2 elements of the vector "still_ok" are assigned
in the same process, but with the use of a procedure, it works.
But oddly enough, in the third case, "not_ok" does not work. This time
the 2 elements are also assign by the procedure, but from different
processes. I was expecting it to just work fine as well and I do not
know the reasons why it does not. Is it intrinsic to VHDL or an effect
to the Modelsim simulator I use?

Obviously, this example seems artificial, but it is just an abstraction
and simplification of a real case, where indeed some elements of a large
vector are assigned through procedures in different processes generated
by generate statements.

Seb.
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      03-15-2005
Mike Treseler wrote:
>> Your processes are both writing to the same signals.


Seb wrote:
> Yes, but to differents elements of the array!


That's still a problem. If you drive one bit,
the process has a driver on the whole object.
http://www.eda.org/comp.lang.vhdl/FAQ1.html#drivers

> In the first case, the 2 elements of the vector "ok" are assigned from
> two different processes, it works, hence the sig name.


That's fine.

> In the second case, the 2 elements of the vector "still_ok" are assigned
> in the same process, but with the use of a procedure, it works.


Same thing using a procedure.

> But oddly enough, in the third case, "not_ok" does not work. This time
> the 2 elements are also assign by the procedure, but from different
> processes. I was expecting it to just work fine as well and I do not
> know the reasons why it does not.


Two non-'Z' drivers on the same signal.

> Is it intrinsic to VHDL or an effect
> to the Modelsim simulator I use?


That's how vhdl works.
But it's not really a problem.
You can do a lot with one processs.
http://home.comcast.net/~mike_treseler/uart.vhd
for example.

-- Mike Treseler
 
Reply With Quote
 
Seb
Guest
Posts: n/a
 
      03-15-2005
Thanks for your response Mike,

Mike Treseler wrote:
> That's still a problem. If you drive one bit,
> the process has a driver on the whole object.
> http://www.eda.org/comp.lang.vhdl/FAQ1.html#drivers

Ok, fair enough.


>> In the first case, the 2 elements of the vector "ok" are assigned from
>> two different processes, it works, hence the sig name.

>
>
> That's fine.

According to your statement above, that should be a problem!!! The
vector is assigned from two different processes, so it should not be ok
then.

>
>> In the second case, the 2 elements of the vector "still_ok" are
>> assigned in the same process, but with the use of a procedure, it works.

>
>
> Same thing using a procedure.

No, not same thing, this time it is from a single process, so it should
and it is fine.

>
>> But oddly enough, in the third case, "not_ok" does not work. This time
>> the 2 elements are also assign by the procedure, but from different
>> processes. I was expecting it to just work fine as well and I do not
>> know the reasons why it does not.

>
>
> Two non-'Z' drivers on the same signal.

Ok, but then why does the first case (signal "ok") works fine? It should
not, it is driven from 2 processes as well!?


Seb.
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      03-15-2005
Seb wrote:
> Ok, but then why does the first case (signal "ok") works fine? It should
> not, it is driven from 2 processes as well!?


If you move your architecture-scoped procedure into
the scope of each process, modelsim will catch
the driver problem:

** Error: vector_splicing.vhd(43):
No feasible entries for subprogram 'assign'.

Passing drive signals from multiple processes
to an architecture-scoped procedure is a risky business.
It is up to the designer not to pass signals
owned by another process.
If you break this rule, you get run-time 'U's
instead of an error message.

-- Mike Treseler
 
Reply With Quote
 
Seb
Guest
Posts: n/a
 
      03-16-2005

Mike Treseler wrote:
> If you move your architecture-scoped procedure into
> the scope of each process, modelsim will catch
> the driver problem:


Ok, fair enoug, but not let's go back to the simple case:

process( clk )
begin
if rising_edge( clk ) then
ok(0) <= '0';
end if;
end process;

process( clk )
begin
if rising_edge( clk ) then
ok(1) <= '1';
end if;
end process;

Surely that should not work either. signal "ok" has two drivers, I
should get 'U'. Why does it work? Is that due to the simulator
implementation? (It even works when ok is decalred as std_ulogic_vector)

Unfortunately, I often drive a vector (but different elements of it)
from different processes generated by generate statements:
gen: generate for i in 0 to NB
process(clk)
begin
....
sig(i) <=

So I really should move away from that, no?

Often it is easy to replace the generate by a for loop inside the
process, but when it also uses variables, it is not that easy.

Thanks for your responses Mike.

Seb.
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      03-16-2005
Seb wrote:

> Ok, fair enoug, but not let's go back to the simple case:
> process( clk )
> begin
> if rising_edge( clk ) then
> ok(0) <= '0';
> end if;
> end process;
> process( clk )
> begin
> if rising_edge( clk ) then
> ok(1) <= '1';
> end if;
> end process;
>
> Surely that should not work either. signal "ok" has two drivers, I
> should get 'U'. Why does it work?


Because the drivers all agree to resolve
to '1' or '0' in this example.
A smart tool will notice this and treat the
case as a single combined process.
I expect that some tools are not as smart.

combined: process( clk )
begin
if rising_edge( clk ) then
ok(0) <= '0';
ok(1) <= '1';
end if;
end process combined;

Try View, Dataflow in modelsim to see this.

> It even works when ok is decalred as std_ulogic_vector


This is because the case is treated
as a virtual single process by Modelsim.

> Unfortunately, I often drive a vector (but different elements of it)
> from different processes generated by generate statements:
> gen: generate for i in 0 to NB
> process(clk)
> begin
> ....
> sig(i) <=
>
> So I really should move away from that, no?


You might consider it for future designs.
Anything that can done by generating processes
can also be done procedurally in a single process.

> Often it is easy to replace the generate by a for loop inside the
> process, but when it also uses variables, it is not that easy.


Also consider array types instead of loops.

> Thanks for your responses Mike.


You are welcome.

-- Mike Treseler
 
Reply With Quote
 
Alan Fitch
Guest
Posts: n/a
 
      03-17-2005
Mike Treseler wrote:
> Seb wrote:
>
>> Ok, fair enoug, but not let's go back to the simple case:
>> process( clk )
>> begin
>> if rising_edge( clk ) then
>> ok(0) <= '0';
>> end if;
>> end process;
>> process( clk )
>> begin
>> if rising_edge( clk ) then
>> ok(1) <= '1';
>> end if;
>> end process;
>>
>> Surely that should not work either. signal "ok" has two drivers, I
>> should get 'U'. Why does it work?

>


I've lost track of the original post but you might also want to look
up the Longest Static Prefix section of the VHDL FAQ, e.g.

http://www.eda.org/comp.lang.vhdl/FAQ1.html#drivers

which I think is the same reference someone else gave above.

In the example above, only one driver is created from each element
of the vector because the index of the signal elements is static, so
the tool creates one driver in the first process on ok(0), and one
driver in the second process on ok(1).

If, however, you had something like

process(clk)
begin
if rising_edge(clk) then
ok(0) <= '0';
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
for i in 1 to 1 loop
ok(i) <= '1';
end loop;
end if;
end process;

then the second process would also create a driver on ok(0), because
for loops are considered non-static by VHDL. Hence the longest static
prefix is "ok", and the second process creates drivers on all elements
of "ok".

<snip>
>> Unfortunately, I often drive a vector (but different elements of it)
>> from different processes generated by generate statements:
>> gen: generate for i in 0 to NB
>> process(clk)
>> begin
>> ....
>> sig(i) <=
>>
>> So I really should move away from that, no?

>
>


Using generate is fine, because then you only create drivers on the
specific elements you drive within the generate. The example I gave
above would work without multiple drivers if you wrote

process(clk)
begin
if rising_edge(clk) then
ok(0) <= '0';
end if;
end process;


g1: for i in 1 to 1 generate
process(clk)
begin
if rising_edge(clk) then
ok(i) <= '1';
end if;
end process;
end generate g1;

because then the generate contents are statically elaborated, so
only one driver is created on ok(1).

So I would say that sometimes you have to use generate to avoid
creating multiple drivers on elements of a signal.

> You might consider it for future designs.
> Anything that can done by generating processes
> can also be done procedurally in a single process.
>


I would disagree with this Mike. You can't create multiple drivers
on a signal using a single process, a signal process pair only
creates one driver. For instance

g2: for i in 0 to 7 generate
process(inp, EN)
begin
if EN = '1' then
o <= inp(i);
else
o <= 'Z';
end if;
end process;
end generate g2;

cannot be done in a single procedural process because you could only
create one single driver on "o" using one process.

Of course everyone avoids internal tristates, so in practise what you
say is pretty well always true!

regards
Alan
--
Alan Fitch
Doulos Ltd
http://www.doulos.com
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Assigment operator and container of base type Adrian C++ 10 12-05-2006 12:12 AM
Iterators and Assigment Godspeed Ruby 3 03-01-2006 12:21 PM
Catching errors in attribute names at assigment Thomas Philips Python 4 06-22-2004 08:24 AM
Vonage and PSTN assigment Brian Young VOIP 1 05-11-2004 05:22 AM
trouble with assigment operators,s tl container and a reference Dean Mitchell C++ 4 08-27-2003 06:16 AM



Advertisments