Приведение строк к перечислениям

Есть ли способ передать строку для перечисления в системе Verilog?

typedef enum {ABC1,ABC2,ABC3} abc;

program Test ;
    abc x1;
    string teststring;   
    initial
    begin
        teststring="ABC2";
        x1=abc'(teststring); // Static cast doesn't work
        $display("[%s][%0d]",teststring,x1);
    end
endprogram

person Jean    schedule 17.07.2013    source источник


Ответы (1)


Кастинг осуществляется по значению, а не по имени. Учитывая, что вы используете тип данных enum по умолчанию (int) и не присваиваете значения никакому идентификатору, тогда ABC1, ABC2 и ABC3 имеют значения 0, 1 и 2 соответственно (все типа int).

Забросить жало в этот enum примерно так же, как бросить его в int. int'("ABC2") == 32'h41424332 и не соответствует ни одному из идентификаторов перечисления.

Варианты получения желаемой функциональности:

  1. Создайте функцию, которая проходит по списку и сравнивает имена:

    function abc a2e(input string s);
        a2e = a2e.first;
        repeat(a2e.num) begin
            if(a2e.name == s) return a2e;
            else a2e = a2e.next;
        end
        assert(0) else $error("Identifier '%s' not in enum abc",s);
    endfunction
    

    Подробнее о методах перечисления: IEEE Std 1800-2012, раздел 6.19.5.

  2. Поиск в ассоциативном массиве: (см. IEEE Std 1800-2012, разделы 7.8 и 7.9)

    abc lookup[string];
    ...
    x1 = abc.first;
    repeat(x1.num) begin
        lookup[x1.name] = x1;
        x1 = x1.next;
    end
    ...
    teststring="ABC2";
    /* Without protection: Non-match creates new entry for with the value
       of abc.first (or '{default:???} if specified) and returns the value */
    x1 = lookup[teststring];
    
    // With protection
    if ( lookup.exists( teststring ))
        x1= lookup[teststring];
    else
        assert(0) else $error("Identifier '%s' not in enum abc",teststring );
    
  3. Если идентификаторы перечисления имеют длину от 1 до 4 символов, значение не имеет значения, сделайте имя значением. typedef enum {ABC1="ABC1",ABC2="ABC2",ABC3="ABC3"} abc;

    • Долго писать? Попробуйте эквивалент:

      typedef enum {ABC[1:3]="ABC1"} abc;
      
    • Нужно больше 4 символов? Назначьте тип данных.

      typedef enum bit[5*8-1:0] {ABC[10:19]="ABC10", ABC[20:29]="ABC20"} abc;
      
    • Дополнительные сведения о диапазонах перечисляемых типов: IEEE Std 1800-2012, раздел 6.19. 2


Примечание. Все вышеперечисленные функции существуют после стандарта IEEE Std 1800-2005. Для чтения необходимо приобрести эту версию LRM. Версия 2012 года свободна от IEEE, отсюда и ссылки на эту версию.

person Greg    schedule 17.07.2013