Unknown fault: signals not assigning

T

Trit

function in question (most visible case):

library IEEE;
use IEEE.std_logic_1164.all;
use Ieee.numeric_std.all;
entity dec_addr5 is
port( mem_in_use : in std_logic;
addr_in : in std_logic_vector (4 downto 0);
addr_out : out std_logic_vector (4 downto 0));
end entity dec_addr5;

architecture decriment of dec_addr5 is
signal tempout : std_logic_vector( 4 downto 0 );
begin
decr : process( mem_in_use, addr_in )
begin
--force to 0 if mem in use for the memory OR on inputs
if( mem_in_use = '1') then
tempout <= "00000";
--wordcount of 32 is 00000, but memory is 0-31 - handle
reverse wraparound
elsif( addr_in = "00000" ) then
tempout <= "11111";
else
tempout <= std_logic_vector(unsigned(addr_in) - 1);
end if;
end process decr;
addr_out <= tempout;
end architecture decriment;

Now my simulations show that tempout is taking the values it is
supposed to (I pulse mem_in_use on startup to initialise it), the
counter that is an input to it is initialised too (sitting at
"00000"), however, addr_out is not assigning and modelsim maintains it
is "UUUUU". The assignment is clearly outside the process and so not
subject to it's visibility constraints

I'm not particularly experienced at VHDL but I don't see much wrong
with that code (and it has in fact worked several times elsewhere in
similar forms). I have also checked the file is properly saved,
compiled and then restarted the simulator to be sure. Any help would
be appreciated
 
K

KJ

Trit said:
Now my simulations show that tempout is taking the values it is
supposed to (I pulse mem_in_use on startup to initialise it), the
counter that is an input to it is initialised too (sitting at
"00000"), however, addr_out is not assigning and modelsim maintains it
is "UUUUU". The assignment is clearly outside the process and so not
subject to it's visibility constraints

I'm not particularly experienced at VHDL but I don't see much wrong
with that code (and it has in fact worked several times elsewhere in
similar forms). I have also checked the file is properly saved,
compiled and then restarted the simulator to be sure. Any help would
be appreciated

1. If you're testing this entity in isolation, then you're mistaken,
addr_out is doing exactly what you've set it up to do (see testbench and
script below)

2. If what you're testing includes other things besides what you've shown
here, then you have some other entity attached to addr_out and that other
entity is driving "UUUUU" on to addr_out thus overriding what entity
'dec_addr5' is trying to output ('U' wins out over every other std_logic
value).

Kevin Jennings

---------- Testbench
library IEEE;
use IEEE.std_logic_1164.all;
use Ieee.numeric_std.all;
entity tb_dec_addr5 is
end entity tb_dec_addr5;
architecture RTL of tb_dec_addr5 is
signal mem_in_use: std_logic;
signal addr_in: std_logic_vector (4 downto 0);
signal addr_out: std_logic_vector (4 downto 0);
begin
process
begin
mem_in_use <= '0', '1' after 1 ns, '0' after 2 ns;
addr_in <= "00000";
wait for 1.5 ns;
assert addr_out = "00000"
report "OOPS! addr_out /= '00000'"
severity ERROR;
wait for 2 ns;
assert addr_out = "11111"
report "OOPS! addr_out /= '00000'"
severity ERROR;
report "Simulation complete";
wait;
end process;

DUT : entity work.dec_addr5 port map(
mem_in_use => mem_in_use,
addr_in => addr_in,
addr_out => addr_out);
end RTL;
------------ Sim script and results
vsim work.tb_dec_addr5; log -r /*; run -a
# vsim work.tb_dec_addr5
# Loading std.standard
# Loading ieee.std_logic_1164(body)
# Loading ieee.numeric_std(body)
# Loading work.tb_dec_addr5(rtl)
# Loading work.dec_addr5(decriment)
# ** Note: Simulation complete
# Time: 3500 ps Iteration: 0 Instance: /tb_dec_addr5

Note: The two assertions that check for the proper value of addr_out did
not fire, because addr_out in fact did have the correct value. You can also
add the various signals to the wave window and see for yourself
 
T

Trit

1. If you're testing this entity in isolation, then you're mistaken,
addr_out is doing exactly what you've set it up to do (see testbench and
script below)

2. If what you're testing includes other things besides what you've shown
here, then you have some other entity attached to addr_out and that other
entity is driving "UUUUU" on to addr_out thus overriding what entity
'dec_addr5' is trying to output ('U' wins out over every other std_logic
value).

Kevin Jennings

---------- Testbench
library IEEE;
use IEEE.std_logic_1164.all;
use Ieee.numeric_std.all;
entity tb_dec_addr5 is
end entity tb_dec_addr5;
architecture RTL of tb_dec_addr5 is
    signal mem_in_use:  std_logic;
    signal addr_in:     std_logic_vector (4 downto 0);
    signal addr_out:    std_logic_vector (4 downto 0);
begin
    process
    begin
        mem_in_use  <= '0', '1' after 1 ns, '0' after 2 ns;
        addr_in     <= "00000";
        wait for 1.5 ns;
        assert addr_out = "00000"
            report  "OOPS!  addr_out /= '00000'"
            severity ERROR;
        wait for 2 ns;
        assert addr_out = "11111"
            report  "OOPS!  addr_out /= '00000'"
            severity ERROR;
        report "Simulation complete";
        wait;
    end process;

    DUT : entity work.dec_addr5 port map(
        mem_in_use  => mem_in_use,
        addr_in     => addr_in,
        addr_out    => addr_out);
end RTL;
------------ Sim script and results
vsim work.tb_dec_addr5; log -r /*; run -a
# vsim work.tb_dec_addr5
# Loading std.standard
# Loading ieee.std_logic_1164(body)
# Loading ieee.numeric_std(body)
# Loading work.tb_dec_addr5(rtl)
# Loading work.dec_addr5(decriment)
# ** Note: Simulation complete
#    Time: 3500 ps  Iteration: 0  Instance: /tb_dec_addr5

Note:  The two assertions that check for the proper value of addr_out did
not fire, because addr_out in fact did have the correct value.  You can also
add the various signals to the wave window and see for yourself

well there is nothing else on the lines asseting U that I can see.
Equally to the point, the point where I see the U start (and cascade
up) is at the output of the decrimenter itself. It's a straight
connection up the parent modules: one componant outout straight to 1
entity output, and up to the testbench. I've checked it is the right
spelling and it is connected at each stage, so I'm a little stumped
 
K

KJ

well there is nothing else on the lines asseting U that I can see.

Well, since I produced a testbench that exercises the code you posted, this
implies that the problem is not in the code that you posted...which means
the problem is elsewhere.

If you're using Modelsim, then type the following command at the prompt
drivers addr_out(0)

That will produce a list of drivers for one of the addr_out bits and also
tell you what each driver is trying to drive the signal to. You'll end up
with one of the following situations:

1. There are no drivers (Solution, hook it up)
2. There is more than one driver (Solution, disconnect the unintended
driver(s))
3. There is only one driver and it is coming out of entity 'dec_addr5' which
is where it should be coming from. In that case, since I've already shown
that the code that you posted for 'dec_addr5' is correct this implies that
one of the inputs to 'dec_addr5' is unknown when it shouldn't be.
Equally to the point, the point where I see the U start (and cascade
up) is at the output of the decrimenter itself. It's a straight
connection up the parent modules: one componant outout straight to 1
entity output, and up to the testbench. I've checked it is the right
spelling and it is connected at each stage, so I'm a little stumped

If it turns out that #2 is the problem, then you should consider using
std_ulogic and std_ulogic_vector rather than std_logic and std_logic_vector.
The ulogic types will cause the compiler to immediately flag when you have
more than one driver and tell you who the offenders are. It's much easier
to have the compiler find a design error than to sit and debug to find it.

If #3 is the problem, then the problem probably has to do with how you're
generating 'mem_in_use' or 'addr_in'. You're not using a synchronous design
process, it could be that 'mem_in_use' is being generated one simulation
delta cycle early and causing it to sample addr_in before it should. To see
this, put a breakpoint in at the start of your process and single step
through.

The drivers command is a very useful debug tool. Single stepping through
code is also. Good luck.

KJ
 
T

Trit

Well, since I produced a testbench that exercises the code you posted, this
implies that the problem is not in the code that you posted...which means
the problem is elsewhere.

If you're using Modelsim, then type the following command at the prompt
drivers addr_out(0)

That will produce a list of drivers for one of the addr_out bits and also
tell you what each driver is trying to drive the signal to.  You'll end up
with one of the following situations:

1. There are no drivers (Solution, hook it up)
2. There is more than one driver (Solution, disconnect the unintended
driver(s))
3. There is only one driver and it is coming out of entity 'dec_addr5' which
is where it should be coming from.  In that case, since I've already shown
that the code that you posted for 'dec_addr5' is correct this implies that
one of the inputs to 'dec_addr5' is unknown when it shouldn't be.


If it turns out that #2 is the problem, then you should consider using
std_ulogic and std_ulogic_vector rather than std_logic and std_logic_vector.
The ulogic types will cause the compiler to immediately flag when you have
more than one driver and tell you who the offenders are.  It's much easier
to have the compiler find a design error than to sit and debug to find it..

If #3 is the problem, then the problem probably has to do with how you're
generating 'mem_in_use' or 'addr_in'.  You're not using a synchronous design
process, it could be that 'mem_in_use' is being generated one simulation
delta cycle early and causing it to sample addr_in before it should.  To see
this, put a breakpoint in at the start of your process and single step
through.

The drivers command is a very useful debug tool.  Single stepping through
code is also.  Good luck.

KJ



Classic mistake, Had the addr_out connected to a temporary signal in
the test bench so i could use it to generate some data, but rather
than have the module drive the temp signal, I linked it to the output
which was driven by an unassigned temp signal.

Cheers for the help, the drivers command is one I hadn't known before
(and wont forget in future). I think this advice will be helpful in
future (typos are a pest are they not?)

-Trit

10 PRINT Idle
20 GOTO 10
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top