FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > VHDL

VHDL comp.lang.vhdl newsgroup / Usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 03-11-2005, 03:10 PM
Seb
Guest
 
Posts: n/a
Default Procedures and array element assigment from different processes.

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
  #2 (permalink)  
Old 03-14-2005, 07:09 AM
Neo
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

I think there is a race condition imposed by your two clocked processes
calling the same procedure.

Reply With Quote
  #3 (permalink)  
Old 03-14-2005, 06:13 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #4 (permalink)  
Old 03-15-2005, 09:55 AM
Seb
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #5 (permalink)  
Old 03-15-2005, 03:25 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #6 (permalink)  
Old 03-15-2005, 04:24 PM
Seb
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #7 (permalink)  
Old 03-15-2005, 11:36 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #8 (permalink)  
Old 03-16-2005, 10:53 AM
Seb
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.


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
  #9 (permalink)  
Old 03-16-2005, 05:05 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #10 (permalink)  
Old 03-17-2005, 09:43 AM
Alan Fitch
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

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
  #11 (permalink)  
Old 03-17-2005, 09:52 AM
Seb
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

Thanks for these ansewers, very interesting.

So I guess the same is true for records (i.e each concurrent statement
that executes has a separate driver for the longest static prefix of
each signal that is target of a signal assignment statement within the
concurrent statement..) So all the different fields of a record should
be assigned in a single process. If so, that make the use of records far
less attractive.

Seb.
Reply With Quote
  #12 (permalink)  
Old 03-17-2005, 10:16 AM
Seb
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

Thanks very much for your answer Alan, it is very clear now, and it also
answers my question about records! (i.e. it's fine with records)

Alan Fitch wrote:
> I've lost track of the original post :-( but you might also want


I was surprised by the fact that in the following code, the 3 vectors
did not behave the same.

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
  #13 (permalink)  
Old 03-17-2005, 04:08 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Procedures and array element assigment from different processes.

Alan Fitch wrote:

> 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.


Yes. I gave the reference, but your example of the
"non-static" 1 to 1 loop really clarified the
words for me.

>> 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.


I stand corrected.
In the future, I will avoid the word "anything" almost always

Seb's original question concerned avoiding multiple
drivers while concatenating vector segments. My
point was that using a single process might
make his job easier.

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


Thanks Alan for the illuminating post and kind words.
Thanks to Seb for the interesting problem.

-- Mike Treseler
Reply With Quote
Reply

Bookmarks


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 On


Similar Threads
Thread Thread Starter Forum Replies Last Post
array element assignment problem thomasc Verilog 8 05-27-2005 05:39 PM
Force sequential assigment AL FPGA 4 05-03-2005 09:31 PM
Re: Force sequential assigment AL FPGA 0 05-02-2005 08:45 PM
Procedures, variables and their scope. Michel Bieleveld VHDL 5 10-29-2004 03:18 PM
using procedures Michel Bieleveld VHDL 17 08-14-2004 02:45 PM


All times are GMT +1. The time now is 12:20 PM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved