yes 5 4 марта, 2009 Опубликовано 4 марта, 2009 · Жалоба хочется протестировать многоканальный 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]}); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 4 марта, 2009 Опубликовано 4 марта, 2009 · Жалоба как бы это сделать для более случайного (чтобы было не только 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}} не сильно красиво конечно, но работает :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 5 4 марта, 2009 Опубликовано 4 марта, 2009 · Жалоба спасибо, вроде бы понятно. единственно - опасаюсь, что в моем случае, когда общий адрес-рэнж маленький, а каналов много солвер будет тормозить или валится... btw: рандом солвер от VCS-а решает задачку с ферзями (только констрейны, без процедурного кода) вплоть до поля 7х7 (практически без паузы), а 8х8 думает какое-то время, а потом вываливается по встроенному таймауту (что-то типа 1000 сек) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 4 марта, 2009 Опубликовано 4 марта, 2009 · Жалоба единственно - опасаюсь, что в моем случае, когда общий адрес-рэнж маленький, а каналов много солвер будет тормозить или валится... тормозить то нечему, адреса тупо раздаются. да не должен он валиться, свалиться только когда каналов больше чем 2^N где N разрядность адреса. Но мне кажеться что вряд ли вы делаете дма больше чем на 128 каналов :) btw: рандом солвер от VCS-а решает задачку с ферзями (только констрейны, без процедурного кода) вплоть до поля 7х7 (практически без паузы), а 8х8 думает какое-то время, а потом вываливается по встроенному таймауту (что-то типа 1000 сек) прогресс не стоит на месте :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 5 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба тормозить то нечему, адреса тупо раздаются. да не должен он валиться, свалиться только когда каналов больше чем 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) и рандомизатору нужно втиснуть туда новый кусок (я собственно так и пытался) и это было долго Ваш вариант - получить случайный набор стартов, а потом к ним добавить длину, мне кажется (если я понял правильно) правильным Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 6 марта, 2009 Опубликовано 6 марта, 2009 · Жалоба 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 5 6 марта, 2009 Опубликовано 6 марта, 2009 · Жалоба единственно что плохо - работает тока с квестой, ни VCS, ни NC нифига не берут такие конструкции :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Escorial 0 9 марта, 2009 Опубликовано 9 марта, 2009 · Жалоба Если смотреть в сторону методологий, то в VMM есть Memory Allocation Manager, который отвечает за формирование в памяти неперекрывающихся структур и их удаления после использования. Либо можно взять его исходник и переделать под себя. http://vmmcentral.org/pdfs/using_memory_allocation_mger.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться