2
votes

If I have the following VHDL-200X architecture:

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 : integer;
begin
    test_char   <= "01001010";
    test_char_i <= to_integer(unsigned(test_char));
    test_char_c <= character'val(test_char_i);
end architecture my_arc;

...and simulate it (in Xilinx iSim 14.1), test_char_c does not change from its initial value of NUL even though test_char_i takes the value 74. If, however, I replace the last line in the architecture with:

    process(test_char_i)
    begin
        test_char_c <= character'val(test_char_i);
    end process;

...then test_char_c takes on the value J as I'd expect.

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.

Why doesn't test_char_c get updated in the first instance?

Edit: Changing test_char_i to a natural doesn't change the result.

2
Your thought is correct, it's a bug/non-conformance of iSim. – wap26
@wap26: I'm not so sure, as Isim is being asked to do something it can't. It might simply need an error message... – Martin Thompson
@MartinThompson: It doesn't seem to matter, I've opened a webcase with Xilinx to see what they think. – detly

2 Answers

2
votes

At initialisation time, test_char_i has the value integer'low, which doesn't map to a character - Modelsim 10.0 reports:

# ** Fatal: (vsim-3390) Result ?(-2147483648) of attribute 'VAL is out of range NUL (0) to 'ΓΏ' (255).
#    Time: 0 ns  Iteration: 0  Process: /my_entity/line__15 File: attr.vhd
# Fatal error in Architecture my_arc at attr.vhd line 15
# 

If I make test_char_i a natural, so that it initialises to 0, things work as you expect (in Modelsim at least, haven't tried iSim)

0
votes

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