VHDL signal sources problem

T

Topi

Guest
Hi,

I don't understand why the following code won't elaborate.

The compiler thinks that v(7 downto 4) is driven by both processes.
But process "a" definitely doesn't touch it.

Tested with GHDL and Active HDL.

Ideas appreciated ...

- Topi

*****************
library ieee;
use ieee.std_logic_1164.all;

entity process_for_tester is
end;

architecture test of process_for_tester is
signal v: std_ulogic_vector(7 downto 0);
signal i: integer;
begin
a: process(i)
variable n: integer;
begin
for n in 0 to 3 loop
if i mod 2 = 0 then
v(n) <= '1';
else
v(n) <= '0';
end if;
end loop;
end process;

b: process
begin
v(7 downto 4) <= "0101";
wait;
end process;

process
begin
i <= 0;
wait for 1 us;
loop
i <= i + 1;
wait for 1 us;
end loop;
end process;
end;
 
Hi,

On Tue, 2011-06-21 at 05:23 -0700, Topi wrote:
Hi,

I don't understand why the following code won't elaborate.

The compiler thinks that v(7 downto 4) is driven by both processes.
But process "a" definitely doesn't touch it.
It does touch v ...

a: process(i)
variable n: integer;
begin
for n in 0 to 3 loop
if i mod 2 = 0 then
v(n) <= '1';
^^^^^^^^^^ here
else
v(n) <= '0';
^^^^^^^^^^ here
end if;
end loop;
end process;
ben
 
On Tue, 21 Jun 2011 16:10:53 +0200, Benjamin Krill wrote:

On Tue, 2011-06-21 at 05:23 -0700, Topi wrote:
Hi,

I don't understand why the following code won't elaborate.

The compiler thinks that v(7 downto 4) is driven by both processes.
But process "a" definitely doesn't touch it.

It does touch v ...

a: process(i)
variable n: integer;
begin
for n in 0 to 3 loop
if i mod 2 = 0 then
v(n) <= '1';
^^^^^^^^^^ here
else
v(n) <= '0';
^^^^^^^^^^ here
end if;
end loop;
end process;
Ben is completely correct, but the reason is
not at all obvious.

It's clear that "n" is statically restricted to be
only 0 to 3. However, this isn't enough. The 'for'
loop is dynamically elaborated, even though its loop
range is in fact static. So the assignment target
v(n) has simply "v" as its longest static prefix.

Consequently, the process drives all eight bits of v.
Since bits (7 downto 4) are never updated, they are
permanently driven with 'U'. Because v's type is
std_ulogic_vector, the multiple drivers are illegal.

If v were a std_logic_vector, the multiple drivers
would be resolved and you would see an unchanging
'U' value on v(7 downto 4).

The solution is to construct two signals and
mux them together. You could use a for-loop to
do that:

signal p,q,v: std_ulogic_vector(7 downto 0);
choose_bits: process(...)
begin
for i in v'range loop
if i>BOUNDARY then
v(i) <= p(i);
else
v(i) <= q(i);
end if;
end loop;
end process;

Or something like that. BOUNDARY is a generic
or constant indicating where in the vector you
should switch over from p to q.

By the way, your declaration of n as an integer
is redundant and inappropriate. The "loop counter"
in a for-loop is implicitly declared, and exists
only in the scope of the loop.
 
On 6/21/2011 8:25 AM, Jonathan Bromley wrote:
By the way, your declaration of n as an integer
is redundant and inappropriate. The "loop counter"
in a for-loop is implicitly declared, and exists
only in the scope of the loop.
Huh. I've been using them for years, happily declaring them as
variables, and never knew that. You learn something new every day.

--
Rob Gaddi, Highland Technology
Email address is currently out of order
 
On Jun 21, 6:25 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
It's clear that "n" is statically restricted to be
only 0 to 3.  However, this isn't enough.  The 'for'
loop is dynamically elaborated, even though its loop
range is in fact static.  So the assignment target
v(n) has simply "v" as its longest static prefix.
Thanks, got it.

I managed to change it to for-generate and if-generate structure:
http://vhdlmodels.blogspot.com/2011/06/registers-getting-even-better.html

- Topi
 
Something like this should work:
a: process(i)
variable t : std_ulogic_vector(3 downto 0);
begin
for n in 0 to 3 loop
if i mod 2 = 0 then
t(n) := '1';
else
t(n) := '0';
end if;
end loop;
v(3 downto 0) <= t;
end process;

-- And, your "b" process can be boiled down to just
v(7 downto 4) <= "0101";


Charles Bailey
 

Welcome to EDABoard.com

Sponsor

Back
Top