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

SystemVerilog cгенерировать произвольное количество reg

Хочу написать максимально параметризорованный синтезируемый модуль. 

Вход модуля это вектор произвольной длины:

input wire [DATA_WIDTH-1:0] data[VECT_WIDTH];

Необходимо производить операции с парами входных wire, например логическое &. Пары "нулевой с первым", "второй с третьим" и тд.

Результат также представляют собой вектор, с ним проделываем ту же операцию. Так продолжается пока вектор не выродится в одно число.

Spoiler

image.png.5e77f71cf8bff7549eb56662738af6dd.png

 

Результат каждой логической операции записывается в регистр. Я хочу создать "reg S" зависящий от входной длины вектора, дальше в циклах записать что надо в этот регистр уже будет не сложно. Я общем виде S может любой. S[][][][][]...

Написал следующий код:

//генерируем массив регистров
genvar gen_result;
generate
    begin
        for ( gen_result = 1; gen_result < VECT_WIDTH/2; gen_result++ )    
            begin:gen_result_var                
                reg [DATA_WIDTH-1:0] result[(VECT_WIDTH/2)]; //для примера просто (VECT_WIDTH/2), вообще надо при каждом проходе делить еще на 2
            end              
    end        
endgenerate

//записываем один пробный регистр
always @( posedge clk )
    gen_summ_var[0].result[0] <= 1;

В ModelSim все выглядит как надо. Но Quartus ругается. Во всей видимости мои хотелки не синтезируемы.

Подскажите, как лучше решить такую задачу?

Вдохновение черпал отсюда: https://www.hdlworks.com/hdl_corner/verilog_ref/items/Genvar.htm 

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


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

6 hours ago, Kapsik said:

Написал следующий код:


//генерируем массив регистров
genvar gen_result;
...
        for ( gen_result = 1; gen_result < VECT_WIDTH/2; gen_result++ )    
...
    end        
endgenerate

//записываем один пробный регистр
always @( posedge clk )
    gen_summ_var[0].result[0] <= 1;

В ModelSim все выглядит как надо. Но Quartus ругается. Во всей видимости мои хотелки не синтезируемы.

Сразу в глаза бросилось, что у вас блок называется gen_result_var, а записывать пробный регистр вы пытаетесь в gen_summ_var. Может быть, я не  правильно понял, но выглядит ошибкой.

А вообще, можно посчитать, сколько вам нужно регистров S и создать массив типа: reg [DATA_WIDTH-1:0] result [N], где N - полное количество требуемых регистров S на вашей схеме. После этого будет 100% правильный массив, удобный для отладки (легко смотреть каждый адрес). И потом уже извращаться в циклах с адресацией в этом массиве. Отдать под первый слой первые N/2 элементов массива, под второй слой N/2+N/4 и т.д.

 

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


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

9 hours ago, Kapsik said:

reg [DATA_WIDTH-1:0] result[(VECT_WIDTH/2)];

Вы просто объявляете переменную result в блоке generate. Этого делать не обязательно. Можно сразу инициализировать переменную нужной длинны на основе параметра. А вот собственно в generate нужно делать присваивание (или я не так понял вашу задумку)

Второе - ваш шифратор (в общем понимании) будет работать только при условии кратности VECT_WIDTH=2^N. В противном случае вы будете терять один элемент в операциях, когда строка не делится на 2 нацело.

Третье - не уверен как обстоят дела в Verilog, но для SV лучше не использовать смешинные типы массивов (packed и unpacked). Не то чтобы нельзя, просто не запутывайте себя, при условии что от этого можно избавится (например при описании BRAM - нельзя).

В общем виде должно получаться что-то такое:

reg [DATA_WIDTH-1:0] data_1_stage [VECT_WIDTH/2];
genvar i;
generate begin
	for (i = 0; i < VECT_WIDTH/2; i++) begin: first_stage_generation
		data_1_stage[i] = data[i*2] ^ data[i*2+1];
	end
endgenerate

 

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


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

4 hours ago, nice_vladi said:

Сразу в глаза бросилось, что у вас блок называется gen_result_var, а записывать пробный регистр вы пытаетесь в gen_summ_var. Может быть, я не  правильно понял, но выглядит ошибкой.

Опечатался когда переносил код на форум =( ошибка будет и при совпадении имен.

 

4 hours ago, nice_vladi said:

А вообще, можно посчитать, сколько вам нужно регистров S и создать массив типа: reg [DATA_WIDTH-1:0] result [N], где N - полное количество требуемых регистров S на вашей схеме.

Тоже об этом думал, но никак не мог сообразить как мне хитрые вычисления засунуть в range регистра. Ведь это получается как минимум цикл с делением и аккумулятором, в параметр таки вычисления уже не засунуть. 

А сейчас вернулся к этой идее, написал функцию расчета общего количества необходимых регистра и вызываю ее при декларировании параметра, такой способ работает.

Но у него есть и минусы. 

Сейчас я хочу делать логическую операцию которая не влияет на разрядность числа. Но если строить такой конвейер с умножением или сложением, разрядность каждого следующего "слоя" растет. Если использовать метод объявления длинного вектора под все вычисления все их надо делать одной, максимальной разрядности. При способе с использованием generate у меня получилось создавать векторы разной длины с разными разрядностями, но к сожалению только в симуляторе...

 

То есть если говорить в самом широком смысле, то идея была нагенерить вот таких регистров у которых варьируется как длина так и разрядность. 

image.png.b03d094bc3d63e8aea333c967a2cb330.png

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


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

36 minutes ago, Kapsik said:

...

 

Если использовать метод объявления длинного вектора под все вычисления все их надо делать одной, максимальной разрядности

...

Все равно компилятор ненужные разрядности посокращает. Так что, думаю, можно смело объявлять максимальные.

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


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

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

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

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

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

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

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

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

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

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