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!