2016-12-19 3 views
0

Я хочу создать и определить локальный массив в SystemVerilog. Размер массива должен быть настраиваемым, а значение каждой ячейки массива localparam рассчитывается на основе его местоположения. По существу этот код:Systemverilog localparam array с настраиваемым размером

localparam [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = '{ 
    7*PAGE_SIZE, 
    6*PAGE_SIZE, 
    5*PAGE_SIZE, 
    4*PAGE_SIZE, 
    3*PAGE_SIZE, 
    2*PAGE_SIZE, 
    1*PAGE_SIZE, 
    0 
}; 

, но где первый «7» заменяется параметром, и где инициализация параметров распространяется на общий случай. Поэтому мне нужен способ для цикла от 0 до (N-1) и установить ADDR_OFFSET (loop) = loop * PAGE_SIZE.

«Очевидная» опция в SystemVerilog будет сгенерирована, но я прочитал, что размещение определения параметра внутри блока генерации генерирует новый локальный параметр относительно иерархической области внутри генерирующего блока (source).

Любые предложения?

Для справочной информации: мне нужно рассчитать фактический адрес на основе базового адреса и числа. Расчет прост: real_address = base_address + number * PAGE_SIZE

Однако я не хочу иметь «*» в своем коде, так как я боюсь, что синтаксический инструмент будет генерировать множитель, чтобы он попытался для упрощения, поскольку PAGE_SIZE является постоянным значением. Я предполагаю, что это может привести к большей логике, чем если я попытаюсь выполнить все вычисления при создании массива localparam, так как это наверняка не даст никакого множителя в логике.

Так с приведенным выше определением localparam, я выполнить требуемый расчет адрес, как это:

function [ADDR_BITS-1:0] addr_calc; 
    input [ADDR_BITS-1:0] base_addr; 
    input [NBITS-1:0] num; 

    addr_calc = base_addr + ADDR_OFFSET[num]; 
    endfunction 

Я думаю, что, возможно, я нашел решение. Разве я не выполнил бы то же самое, не определяя массив localparam, а скорее выполнив вычисление адреса внутри цикла? Так как systemverilog видит переменную цикла как «постоянную» (когда речь идет о генерации логики), которая, похоже, делает то же самое? Как это (внутри функции, которую я написал выше):

ответ

3

Вы можете установить локальный параметр с возвращаемым значением функции.

localparam bit [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = ADDR_CALC(); 
    function bit [7:0] [ADDR_BITS-1:0] ADDR_CALC(); 
     for(int ii=0;ii<$size(ADDR_CALC,1); ii++) 
    ADDR_CALC[ii] = ii * PAGE_SIZE; 
    endfunction 
+0

Блестящий, спасибо! – ArneA