Перейти к содержанию
    

SV рандомизация. конфигурация областей памяти для DMA

хочется протестировать многоканальный DMA контроллер при работе с памятью

 

нужно задать неперекрывающиеся куски памяти (start,length) : как это законстрейнить?

 

в первом случае для постоянного числа каналов (например 3)

во втором для случайного 3<N<72

 

я для 1) завел отдельный класс для областе памяти и для 3х объектов такого класса вызываю

assert(r[0].randomize() with {start<4096;});

assert(r[1].randomize() with {start<8192; start>(r[0].start+r[0].length);});

assert(r[2].randomize() with {start<16384; start>(r[1].start+r[1].length);});

 

constraint l {length>16;}

constraint ul {length<4096;}

 

но это какая-то фигня.

 

как бы это сделать для более случайного (чтобы было не только r[0]<r[1]<r[2]) расположения областей

 

и для произвольного их числа????

 

-----------------------

 

и до кучи - почему-то не работает ! inside

//assert(r[1].randomize() with {!(start inside {[r[0].start:r[0].start+r[0].length]});});

 

// assert(r[2].randomize() with {

// !(start inside {[r[0].start:r[0].start+r[0].length]});

// !(start inside {[r[1].start:r[1].start+r[1].length]});

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как бы это сделать для более случайного (чтобы было не только r[0]<r[1]<r[2]) расположения областей

 

 

а если так

 

typedef enum {
  SMALL_DMA_NUM ,
  MED_DMA_NUM   ,
  LARGE_DMA_NUM
} dma_num_e;

typedef struct packed {
  int addr;
  int length;
} dma_header;

class dma_config;

  //
  rand dma_num_e  num;
  rand dma_header header_array [];



  constraint num_c {
    solve num before header_array;
    header_array.size() >= 1;
    (num == SMALL_DMA_NUM ) -> (header_array.size() <= 2);
    (num == MED_DMA_NUM   ) -> (header_array.size() <= 4);
    (num == LARGE_DMA_NUM ) -> (header_array.size() <= 8);
  }

  constraint dma_header_c {
    foreach (header_array[i])
      header_array[i] == 0;
  }



  function void post_randomize();
    int used_addr_array [$];
    int size;
  begin
    size = header_array.size();

    used_addr_array = '{};


    repeat (size) begin
      int addr;

      std::randomize(addr) with {
        addr >= 0;
        addr < 32'h7FFF_FFFF;  // <= is incorrect , use < (!!!!)
        !(addr inside {used_addr_array});
      };
      used_addr_array.push_back(addr);
    end

    used_addr_array.sort();

    foreach (used_addr_array[i]) begin
      int addr;
      int next_addr;
      int length;

      addr = used_addr_array[i];
      next_addr = (i == (size-1)) ? 32'h7FFF_FFFF : used_addr_array[i+1];

      std::randomize(length) with {
        length > 0;
        length <= 1024;
        length <= (next_addr - addr);
      };

      header_array[i].addr    = addr;
      header_array[i].length  = length;
    end

    header_array.shuffle();

  end
  endfunction

endclass

module test_rand;

  dma_config dma = new;

  initial begin : main
    dma.randomize();
    $display("result %p", dma.header_array);
    $stop;
  end
endmodule

 

 

# result '{'{addr:210774572, length:81}, '{addr:835849155, length:21}, '{addr:620943367, length:561}, '{addr:903674126, length:465}}

 

не сильно красиво конечно, но работает :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо, вроде бы понятно.

 

единственно - опасаюсь, что в моем случае, когда общий адрес-рэнж маленький, а каналов много солвер будет тормозить или валится...

 

btw: рандом солвер от VCS-а решает задачку с ферзями (только констрейны, без процедурного кода) вплоть до поля 7х7 (практически без паузы), а 8х8 думает какое-то время, а потом вываливается по встроенному таймауту (что-то типа 1000 сек)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

единственно - опасаюсь, что в моем случае, когда общий адрес-рэнж маленький, а каналов много солвер будет тормозить или валится...

 

тормозить то нечему, адреса тупо раздаются.

да не должен он валиться, свалиться только когда каналов больше чем 2^N где N разрядность адреса. Но мне кажеться что вряд ли вы делаете дма больше чем на 128 каналов :)

 

btw: рандом солвер от VCS-а решает задачку с ферзями (только констрейны, без процедурного кода) вплоть до поля 7х7 (практически без паузы), а 8х8 думает какое-то время, а потом вываливается по встроенному таймауту (что-то типа 1000 сек)

 

прогресс не стоит на месте :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

тормозить то нечему, адреса тупо раздаются.

да не должен он валиться, свалиться только когда каналов больше чем 2^N где N разрядность адреса. Но мне кажеться что вряд ли вы делаете дма больше чем на 128 каналов :)

 

432 канала чтения (с ограниченным сумарным bandwidth)

+ ~10каналов "обыкновенных"

+ 4 канала, которые монопольно владеют памятью

+ 1 (а может и 2) AHB

 

там память хитрая (типа как в BF по 4к блоки с одновременным доступом), тока куски по 64к и всего 4М (то есть в худшем случае 64 независимых шины)

 

предыдущий монстр с ~100 каналов (выпекли и вроде работает) был сделан без продвинутых методологий и SV

 

сейчас надеюсь, что продвинутые VM спасут :)

 

================================

 

а по поводу кода я понял так -

 

встроенный рандомизатор только выбирает количество областей

 

очень непонятный констрейн

 

constraint dma_header_c {

foreach (header_array)

header_array == 0;

}

 

если содержимое не нужно, то зачем? (кажется, что просто так получилось :), но вдруг не так)

 

post_randomize

после этого создается упорядоченный массив [$] стартовых адресов

из которого потом нарезаются фрагменты случайной длины

 

при беглом просмотре я подумал, что used_addr_array содержит уже занятые куски (start-------end) и рандомизатору нужно втиснуть туда новый кусок (я собственно так и пытался) и это было долго

 

Ваш вариант - получить случайный набор стартов, а потом к ним добавить длину, мне кажется (если я понял правильно) правильным

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

432 канала чтения (с ограниченным сумарным bandwidth)

+ ~10каналов "обыкновенных"

+ 4 канала, которые монопольно владеют памятью

+ 1 (а может и 2) AHB

 

жесть, представляю как выглядит таблица дескрипторов

 

встроенный рандомизатор только выбирает количество областей

 

это сделан knob для того, что бы можно было просто переопределить типы конфигураций + уже готовая заготовка для монитора покрытия.

хотел еще ввести knob на размерности областей памяти, но стало лень

 

очень непонятный констрейн

 

constraint dma_header_c {

foreach (header_array)

header_array == 0;

}

 

инициализация элементов динамического массива, можно было и не делать, но думаю что в этом случае будет тратиться время на заполнение массива. Более быстрый вариант убрать rand с header_array и инициализировать его в ручную в post_randomize.

 

post_randomize

после этого создается упорядоченный массив [$] стартовых адресов

из которого потом нарезаются фрагменты случайной длины

 

при беглом просмотре я подумал, что used_addr_array содержит уже занятые куски (start-------end) и рандомизатору нужно втиснуть туда новый кусок (я собственно так и пытался) и это было долго

 

Ваш вариант - получить случайный набор стартов, а потом к ним добавить длину, мне кажется (если я понял правильно) правильным

 

все так, это проще и должно быть быстрее, чем искать "дырки" в адресном пространстве и втискивать туда дма дескрипторы.

 

обратите внимание на использование для used_addr_array очереди, а не массива, только в этом случае вероятность конкретного адреса(в данном примере нулевого) != 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

единственно что плохо - работает тока с квестой, ни VCS, ни NC нифига не берут такие конструкции :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если смотреть в сторону методологий, то в VMM есть Memory Allocation Manager, который отвечает за формирование в памяти неперекрывающихся структур и их удаления после использования. Либо можно взять его исходник и переделать под себя.

 

http://vmmcentral.org/pdfs/using_memory_allocation_mger.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...