How to simulate 'X' in conditional statements

Status
Not open for further replies.

weetabixharry

Full Member level 4
Joined
Oct 9, 2013
Messages
232
Helped
69
Reputation
142
Reaction score
73
Trophy points
1,318
Location
Sweden
Visit site
Activity points
3,463
When debugging VHDL designs, I often like to set my data signals to 'X' (i.e. "Unknown") whenever the driving signal is invalid. For example:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
process (clk) is
begin
    if rising_edge(clk) then
        if in_valid = '1' then
            out_data <= in_data;
        else
            out_data <= (others => 'X');
        end if;
    end if;
end process;



By doing this, it means that if an invalid data value is ever used, then a load of 'X' values will propagate thereafter (clearly visible as red lines in my Modelsim testbench simulation).

However, this does not work if I want to multiplex two data signals, based on a condition (e.g. greater than, less than, equal) that may contain 'X' values. For example, if condition_a or condition_b is assigned (others => 'X') in the following:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
process (clk) is
begin
    if rising_edge(clk) then
        if condition_a = condition_b then
            out_data <= in_data_x;
        else
            out_data <= in_data_y;
        end if;
    end if;
end process;



then out_data will not be assigned as "Unknown". Instead, Modelsim issues a warning, assumes the condition to be false and so the result is: out_data <= in_data_x... while what I wanted was out_data <= (others => 'X').

As a horrible hack, the following will do what I want:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
process (clk) is
    variable x_check : std_logic;
begin
    if rising_edge(clk) then
        x_check := condition_a(0) or not condition_a(0)
                    or condition_b(0) or not condition_b(0);
        if condition_a = condition_b then
            out_data <= in_data_x and (in_data_x'length-1 downto 0 => x_check);
        else
            out_data <= in_data_y and (in_data_x'length-1 downto 0 => x_check);
        end if;
    end if;
end process;



This works because any expression like "a or not a" will always return '1' unless the signals are unknown. Therefore if I "and" the result with my data, then an "Unknown" condition will yield an "Unknown" out_data.

However, this is a really ugly hack and I assume there must be a better way. If anyone here knows a better way (or can think of one) I would really love to know!
 

Well try this method ..
include condition_a and condition_b in process sensitive list

And by the way its really not a good idea to have 'X' as an output, works for the simulation but not when you are dumping the code on hardware
 


anything that your process needs to know about changes of inputs or signals should be in the sensitivity list
 

You are trying to write a piece of code that does two different things and are doing a lousy job at both of them. You are trying to build a protocol checker on top of the code that is also synthesized into gates. You need to split these into two seperate pieces. Create one piece soley for synthesys. If in_valid is not active then repeat the old value of out_data. Then write a completely seperate protocol checker that detects the error conditions and fires an error into the log file. This code is only used for simulations.

Never try to use x's to catch errors. They work "most" of the time but in todays world that is not good enough anymore
 

write a completely separate protocol checker that detects the error conditions and fires an error into the log file. This code is only used for simulations.
Yes, this is exactly what I want to do. Could you offer any pointers as to how this can be done? I have a fair bit of VHDL experience, but don't know of any better way of doing this.

Many thanks.
 
Last edited:

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…