typedef enum {HEARTS, DIAMONDS, CLUBS, SPADES} Suit;
typedef enum {TWO = 2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE} Value;
typedef struct{
randc Suit card_type;
rand Value card_value;
}card;
class Deck;
rand card cards_drawn[2:0];
// Constraint to ensure that the cards are in increasing order
constraint cards_order_and_suit {
foreach (cards_drawn[i]) {
if (i > 0) {
cards_drawn[i].card_value > cards_drawn[i-1].card_value;
}
}
}
endclass
module test;
initial repeat(5) begin
automatic Deck deck = new();
assert(deck.randomize()) else $display("Failed to draw three cards");
foreach (deck.cards_drawn[i]) begin
$display("Card %0d: Suit = %s, Value = %s", i, deck.cards_drawn[i].card_type.name(), deck.cards_drawn[i].card_value.name());
end
end
endmodule
Я хочу уникальные масти для трех вытянутых карт. Я пробовал использовать randc
для переменной костюма типа enum
, но, похоже, это не работает. Я не получаю никаких ошибок моделирования с тремя симуляторами.
Код работает нормально, если я указываю отдельное ограничение уникальности масти карты, но я хотел выяснить, можем ли мы сделать что-то подобное, упомянув randc
внутри структуры для переменной типа enum
.
randc
работает только при последующих вызовах randomize
, а не в пределах одного вызова randomize
. Например, при первом вызове randomize
, randc
не влияет на массив объектов card
. Он случайным образом выберет Suit
для каждого элемента массива без ограничений. В наборе могут оказаться 2 и более карты одной масти. При втором вызове randomize
он запомнит случайные значения из первого вызова. Подробное обсуждение см. в стандарте IEEE Std 1800-2023, раздел 18.4 «Случайные переменные».
Просто объявите card_type
как rand
. Один из простых способов получить уникальные костюмы — использовать ключевое слово unique
внутри блока constraint
. Да, вам нужно повторить один и тот же код 3 раза, но это всего лишь 3 строки кода:
typedef struct{
rand Suit card_type;
rand Value card_value;
} card;
class Deck;
rand card cards_drawn [3];
// Constraint to ensure that the cards are in increasing order
constraint cards_order_and_suit {
foreach (cards_drawn[i]) {
if (i > 0) {
cards_drawn[i].card_value > cards_drawn[i-1].card_value;
}
}
unique {
cards_drawn[0].card_type,
cards_drawn[1].card_type,
cards_drawn[2].card_type
};
}
endclass
См. стандарт IEEE 1800-2023, раздел 18.5.4 Ограничения уникальности.
@Chomusuke: ответ обновлен
Вы также можете опубликовать рабочую версию своего кода в Code Review, если вы заинтересованы в получении отзывов по любому его аспекту, в том числе о том, как делать что-то по-другому.