Есть ли способ узнать, объявлен ли член случайным или нет в классе в SV
// Current Class
class x;
rand int a;
int b; // b is nonrandom as of now
function new();
endfunction
function abc;
// if a != ref.a, where ref is reference object of class x, declared somewhere else
a.rand_mode(0);
endfunciton
// Future Possible Class
class x;
rand int a;
rand int b; // b is also a random variable now
function new();
endfunction
function abc;
// if a != ref.a, where ref is reference object of class x, declared somewhere else
a.rand_mode(0);
// if b != ref.b, where ref is reference object of class x, declared somewhere else
b.rand_mode(0);
endfunciton
Таким образом, в функции abc, в зависимости от того, совпадает или не совпадает значение элемента rand со значением этого члена в ссылочном классе, эти объявленные члены класса x должны быть активными или неактивными соответственно.
Цель - мне нужно проверить, совпадает ли переменная rand со значением ссылочного класса, тогда только она должна быть рандомизирована, в противном случае - нет.
Я хочу обобщить метод abc для всех возможных будущих вариантов (поэтому мне не нужно изменять его, как это сделано в приведенном выше примере), и, как я не знаю, когда член класса может стать членом rand или nonrand, Есть ли какой-нибудь встроенный метод, чтобы узнать, объявлен ли член класса как rand или нет в этом классе?
2 ответа
Вы можете немного изменить свой взгляд на проблему. Вместо того, чтобы пытаться отключить рандомизацию для полей, которые объявлены rand
почему бы не сказать, что когда их рандомизируют, они должны сохранять свою ценность?
Согласно этому хорошему посту, в SV 2012 появилась новая конструкция, const'(...)
это будет работать в этом случае. К сожалению, я не думаю, что многие поставщики поддерживают это. Ваш randomize()
вызов будет выглядеть так:
if (!rand_obj.randomize() with {
const'(a) != ref_obj.a -> a == const'(a);
})
$fatal(0, "rand error");
Давайте разберем этот код. const(a)
будет образец значения a
до выполнения любого рода рандомизации. Если значение a
до того, как рандомизация не равна эталонному значению, у нас есть вторая часть ограничения, которая говорит a
должен сохранить свою ценность. Я пробовал этот код на двух симуляторах, но он не был поддержан ни одним (хотя это должен быть законный синтаксис SV 2012). Может быть, вам повезло иметь поставщика, который его поддерживает.
Вы можете написать такие ограничения даже для переменных состояния, так как они все еще будут сохраняться.
Если вы не можете получить const
синтаксис для работы в вашем симуляторе, затем в том же посте показано, как вы могли бы обойти проблему. Вы можете сохранить значения до рандомизации внутри объекта и использовать их в ограничении:
class some_class;
rand bit [2:0] a;
bit [2:0] b;
bit [2:0] pre_rand_a;
bit [2:0] pre_rand_b;
function void pre_randomize();
pre_rand_a = a;
pre_rand_b = b;
endfunction
endclass
Если вы хотите рандомизировать, вы добавите следующие ограничения:
if (!rand_obj.randomize() with {
pre_rand_a != ref_obj.a -> a == pre_rand_a;
pre_rand_b != ref_obj.b -> b == pre_rand_b;
})
$fatal(0, "rand error");
Вы можете найти полный пример на EDAPlayground.
Вы упоминаете, что ваша функция, которая выполняет рандомизацию, определяется вне объекта. Из-за этого pre_rand_*
поля не могут быть локальными / защищенными, что не очень приятно. Вам следует подумать о том, чтобы сделать функцию членом класса и передать ей ссылочный объект, чтобы можно было обеспечить правильную инкапсуляцию.
Это невозможно, поскольку SystemVerilog не предоставляет никаких возможностей отражения. Вы могли бы, вероятно, понять это, используя VPI, но я не уверен, насколько завершена реализация VPI для классов.
Исходя из того, что вы хотите сделать, я бы сказал, что в любом случае не имеет смысла реализовывать такой запрос только для того, чтобы в будущем проверить ваш код на случай, если однажды поля станут rand
, Так же, как вы добавляете rand
Модификатор к полю, вы также можете добавить его в список полей, для которых рандомизация должна быть отключена. Оба местоположения кода находятся в одном файле, поэтому их трудно пропустить.
Вернется один определенный симулятор -1
при опросе переменной состояния rand_mode()
, но это нестандартно. LRM прямо заявляет, что вызывать ошибку компиляции rand_mode()
на неслучайных полях.