I thought that a bare signal assignment will be updated concurrently if any signal on the right hand side changes. In other words, it's equivalent to a process that is sensitive to all signals involved in the assignment.
That's correct.
Why doesn't test_char_c get updated in the first instance?
It does.
A Minimal, Complete, and Verifiable example with a monitor process that will report all value updates on test_char_c
:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity my_entity is
end entity;
architecture my_arc of my_entity is
signal test_char : std_logic_vector(7 downto 0);
signal test_char_c : character;
signal test_char_i : natural; -- integer;
begin
test_char <= "01001010";
test_char_i <= to_integer(unsigned(test_char));
test_char_c <= character'val(test_char_i);
process (test_char_c)
begin
report "test_char_c = " & character'image(test_char_c);
end process;
end architecture my_arc;
Note the change to the declaration of test_char_i
to overcome the default initial value (INTEGER'LOW) causing a bound check failure as reported by Martin Thompson.
This was analyzed, elaborated and simulated using a -1993 compliant VHDL tool:
ghdl -r my_entity
../../src/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
my_entity.vhdl:19:9:@0ms:(report note): test_char_c = nul
my_entity.vhdl:19:9:@0ms:(report note): test_char_c = 'J'
The assertion warning from package numeric_std is caused by the test_char
default intial value of "UUUUUUUU".
The first reported test_char_c
value is the NUL you reported and occurs because the initial value of test_char_i
is 0 (mapping to NUL).
The second is in response to the concurrent simple signal assignment to test_char
resulting in an update of test_char_i
in turn resulting in an update of test_char_c
(and resuming the monitor process). It reflects the assigned bit string to test_char
with a value x"4A" (corresponding to the character 'J').
If instead of the shown monitor process you were to have an assertion statement of the form:
assert test_char_c /= NUL
report "test_char_c = " & character'image(test_char_c);
You'd find that only the first report statement is displayed because an assertion statement condition is evaluated and when found false asserts.
Likewise if the "/=" in the condition were changed to "=" only the second report statement would be displayed (showing 'J').
Without providing a MCVe your problem can't be duplicated (or blamed on the then nascent ISIM).