VHDL signal sources problem

T

Topi

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;
 
B

Benjamin Krill

Hi,

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
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
The Xilinx ISE software had no problems with this code :)

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Process_for_tester is
end Process_for_tester;

architecture test of process_for_tester is
   signal v: std_logic_vector(7 downto 0) := "WWWW0000";
   signal i: integer := 0;
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 for 3 us;
   end process;

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

end test;
 
J

Jonathan Bromley

It does touch v ...

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

logic_guy

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top