Работа с параметрами сигналов для пользовательских шаблонов
Страница в процессе разработки. |
В данной статье описывается подход к получению подробной информации о сигналах с помощью пользовательских шаблонов. Рекомендуется ознакомиться со статьей по пользовательским шаблонам генерации кода прежде, чем изучать текущую. |
Генерируя код на основе пользовательских шаблонов, можно узнать полезную информацию о сигналах, такую как размер, тип данных, частота выборки и другие данные.
Далее рассмотрим ключевые структуры, поля и их применение в пользовательских шаблонах для получения информации о сигналах.
Структура signal
Структура signal
описывает сигнал в пользовательских шаблонах и предоставляет доступ ко всем необходимым параметрам через поле ty
. Эти сигналы представляются как элементы массивов ins
(входные порты) и outs
(выходные порты), либо как отдельные порты, например input(1)
или output(1)
. Доступны следующие поля структуры signal
:
-
expr :: Cstring
— выражение, связанное с сигналом. -
qual_name :: Cstring
— полное квалифицированное имя сигнала. -
pretty_name :: Cstring
— читаемое (красивое) имя сигнала. -
ieas_name :: Cstring
— имя атомарной подсистемы, наиболее близкой к выбранному блоку. -
indirect :: Cuchar
— флаг косвенной ссылки на сигнал. -
rows :: Csize_t
— количество строк в сигнале. -
cols :: Csize_t
— количество столбцов в сигнале. -
bits :: Cint
— разрядность данных сигнала. -
fractional_bits :: Cint
— количество дробных битов. -
is_unsigned :: Cuchar
— флаг, определяющий, является ли сигнал беззнаковым. -
is_floating :: Cuchar
— флаг, определяющий, является ли сигнал числом с плавающей точкой. -
is_complex :: Cuchar
— флаг, определяющий, является ли сигнал комплексным.
Поле ty
Поле ty
работает в структуре signal
и предоставляет информацию о типе данных сигнала. Поле ty
имеет следующие ключевые параметры для описания типа данных:
-
bits :: Cint
— разрядность данных. -
fractional_bits :: Cint
— количество дробных битов. -
is_unsigned :: Cuchar
— флаг, определяющий, является ли тип беззнаковым. -
is_floating :: Cuchar
— флаг, определяющий, является ли тип числом с плавающей точкой. -
is_complex :: Cuchar
— флаг, определяющий, является ли тип комплексным.
Тогда пример использования через порты, включающий signal
и ty
будет выглядеть так:
/* Получение информации о типе данных и размерах первого входного сигнала */
if $(ins[1].ty.is_floating) {
// Логика для чисел с плавающей точкой
}
if $(ins[1].rows) > 1 {
// Логика для многомерного массива
}
В примере показывается применение структур signal
и ty
для получения информации о входном сигнале, представляемом как ins[1]
. Рассмотрим основные моменты:
-
Доступ к информации о типе данных через
ty
:if $(ins[1].ty.is_floating) { // Логика для чисел с плавающей точкой }
-
Поле
ty
содержит характеристики типа данных сигнала. -
В данном случае используется свойство
is_floating
, которое возвращает флаг (true
илиfalse
), указывающий, является ли сигнал числом с плавающей точкой. -
Условие проверяет, относится ли сигнал к типу
float
. Если да (логика выполняется), то эта логика — специфичная для обработки чисел с плавающей точкой.
-
-
Доступ к размерности сигнала через
rows
:if $(ins[1].rows) > 1 { // Логика для многомерного массива }
-
Свойство
rows
возвращает количество строк в сигнале. -
Здесь проверяется, является ли сигнал многомерным массивом (количество строк больше 1). Если условие выполняется, то применяется логика для обработки многомерных сигналов.
-
В примере ins[1]
представляет входной сигнал, который является экземпляром структуры signal
. Доступ к информации о сигнале осуществляется через его свойства (rows
, cols
, ty
и другие). Например, rows
и cols
дают размеры сигнала, а поле ty
предоставляет детализированную информацию о типе данных сигнала (например, разрядность, наличие дробной части, знаковость).
Важно помнить, что массивы
|
Применение в шаблонах
В пользовательских шаблонах можно обращаться к свойствам сигналов через массивы ins
и outs
. Например, определить тип данных выходного сигнала и обработать входной:
//! BlockType = :RelationalOperator
//! TargetLang = :Chisel
/*! @Definitions
function get_dec_type(port)
if port.ty.fractional_bits == 0 && port.ty.bits == 1
out = "Bool()"
elseif port.ty.fractional_bits == 0
out = "UInt($(port.ty.bits).W)"
else
out = "FixedPoint($(port.ty.bits).W,$(port.ty.fractional_bits).BP)"
end
out
end
*/
val $(output(1)) = Wire($(get_dec_type(output(1))))
/*! @Step
function get_type(port)
if port.ty.fractional_bits == 0 && port.ty.is_unsigned == 1
out = ".asTypeOf(UInt($(port.ty.bits).W))"
else
out = ".asTypeOf(FixedPoint($(port.ty.bits).W,$(port.ty.fractional_bits).BP))"
end
out
end
*/
$(output(1)):=$(input(1)) $(param.Operator) $(input(2))$(get_type(input(1)))
В этом шаблоне для блока Relational Operator сигнал используется через порты input(1)
, input(2)
и output(1)
. Поле ty
обеспечивает доступ к информации о типе данных сигналов. Далее разберем основные части кода:
-
Определение типа выходного сигнала:
function get_dec_type(port) if port.ty.fractional_bits == 0 && port.ty.bits == 1 out = "Bool()" elseif port.ty.fractional_bits == 0 out = "UInt($(port.ty.bits).W)" else out = "FixedPoint($(port.ty.bits).W,$(port.ty.fractional_bits).BP)" end out end val $(output(1)) = Wire($(get_dec_type(output(1))))
Здесь функция
get_dec_type
определяет тип данных для выходного сигнала output(1):-
Если сигнал имеет 1 бит и не содержит дробной части
(fractional_bits == 0)
, то его тип задается как ё. -
Если сигнал целочисленный
(fractional_bits == 0)
, то его тип задается какUInt
с указанным количеством разрядов(bits)
. -
В остальных случаях предполагается использование фиксированной запятой
(FixedPoint)
с заданной разрядностью и количеством дробных битов.
-
-
Получение типа данных для входного сигнала:
function get_type(port) if port.ty.fractional_bits == 0 && port.ty.is_unsigned == 1 out = ".asTypeOf(UInt($(port.ty.bits).W))" else out = ".asTypeOf(FixedPoint($(port.ty.bits).W,$(port.ty.fractional_bits).BP))" end out end
Эта функция определяет тип преобразования для входного сигнала
input(1)
:-
Если сигнал целочисленный и беззнаковый
(is_unsigned == 1)
, то он преобразуется в тип UInt. -
В остальных случаях сигнал преобразуется в тип
FixedPoint
.
-
-
Основная логика блока:
$(output(1)):=$(input(1)) $(param.Operator) $(input(2))$(get_type(input(1)))
Здесь выполняется сравнение сигналов:
-
Оператор сравнения
($(param.Operator))
передается через параметр шаблона. -
Левым операндом выступает входной сигнал
input(1)
, а правым —input(2)
. -
Тип преобразования для операндов задается с помощью функции
get_type
.
-
Итого, в этом коде пользовательского шаблона:
-
ty
используется для получения информации о разрядности(bits)
, количестве дробных битов(fractional_bits)
, знаковости(is_unsigned)
и других характеристиках сигнала. -
Порты
input
иoutput
представляют собой экземпляры структурыsignal
, доступ к свойствам которой осуществляется через полеty
. -
Основная задача кода — корректное определение типов данных для сигналов и их преобразование в зависимости от параметров блока.