Как написать ограничение для класса транзакций, в котором мне нужно только 50% пакетов для рандомизации? - PullRequest
1 голос
/ 09 апреля 2019

Мне нужно написать класс транзакции так, чтобы у каждого пакета было случайное поле SA [7: 0], поле DA [7: 0] и поле DATA. Длина данных случайна от 1 до 64 байтов. Содержимое поля DATA может быть случайным (или) некоторым другим фиксированным шаблоном. 50% пакетов имеют случайные данные во всех байтах данных. 25% пакетов должны иметь 8'h55 во всех байтах данных. 25% пакетов имеют 8'hAA во всех байтах данных

  class my_transaction extends uvm_sequence_item;
  'uvm_object_utils(my_transaction);

  function new(string name="my_transaction")
  super.new(name);
  endfunction

  rand bit[7:0] SA;
  rand bit[7:0] DA;
  rand bit[7:0] data[];

  constraint my_c { data.size() inside [1:64] };
  ????how to write constraint for dynamic array data[] here ??

  endclass

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

Я работал над подходом, подобным подходу Мэтью, но я предпочитаю не использовать post_randomize для рандомизации, если его легко избежать

module top;
  class A;
    rand bit[7:0] data[];      
    typedef enum {RAND, h55, hAA} knob_t;
    rand knob_t knobs[];

    constraint size_c { data.size() inside {[1:64]}; data.size == knobs.size; }

    constraint dist_c { 
      foreach(knobs[i]) knobs[i] dist {RAND := 50, h55 := 25, hAA := 25}; }
    constraint data_element_c {
      foreach (data[i]) {
        knobs[i] == h55 -> data[i] == 8'h55;
        knobs[i] == hAA -> data[i] == 8'hAA;
      } }
  endclass

  A a = new;

  initial
      repeat (10)
        begin
          assert(a.randomize);
          $display("%p", a);
        end

 endmodule
0 голосов
/ 09 апреля 2019

Ваш друг - две вещи:

i) ручка управления . Ручка управления - это переменная, которая рандомизируется для управления процессом рандомизации. Итак, давайте рандомизируем переменную, чтобы решить, хотим ли мы, чтобы массив data был случайным, 55 или AA.

typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
rand control_knob_t control_knob;

constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }

ii) post_randomize метод. Это SystemVerilog, а не UVM. post_randomize вызывается после того, как произошла рандомизация класса, и позволяет вам что-то делать, когда произошла рандомизация. В этом случае мы позволим стандартной рандомизации рандомизировать длину массива data, а затем введем значения data в методе post_randomize.

function void post_randomize;
  case (control_knob)
    RANDOM:    foreach (data[i]) 
                 data[i] = $urandom_range(0,255);
    FIVE_FIVE: foreach (data[i]) 
                 data[i] = 8'h55;
    A_A:       foreach (data[i]) 
                 data[i] = 8'haa;
  endcase
endfunction

[MCVE]:

module M;

  class C;

    rand bit[7:0] data[];

    typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
    rand control_knob_t control_knob;

    constraint my_c { data.size() inside {[1:4]}; }

    constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }

    function void post_randomize;
      case (control_knob)
        RANDOM:    foreach (data[i]) 
                     data[i] = $urandom_range(0,255);
        FIVE_FIVE: foreach (data[i]) 
                     data[i] = 8'h55;
        A_A:       foreach (data[i]) 
                     data[i] = 8'haa;
      endcase
    endfunction

  endclass

  C c;

  initial
    begin
      c = new;
      repeat (100)
        begin
          c.randomize;
          $display("c = %p", c);
        end
    end

 endmodule

https://www.edaplayground.com/x/2cPk

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...