Преобразование структур SystemVerilog в структуры C/C++

Где-то в моей среде есть большой файл, который содержит (помимо прочего) множество 64-битных структур System Verilog, например.:

typedef struct packed {  
  logic [63:63]  my_field_1;  
  logic [62:60]  my field_2;  
  ...  
  logic [0:0]  my field_n;
} my_struct_1_t;

Мне нужен способ преобразовать это в структуры C/CPP с битовыми полями. например

struct my_struct_1_t {  
  uint64_t my_field_n:1;//This is the LSB
  ...  
  uint64_t my_field_2:3;  
  uint64_t my_field_1:1;//This is the MSB
};

Я понятия не имею, как это сделать, поэтому буду признателен за любую помощь (на любом языке/скрипте оболочки и т. д.).

Спасибо!

Verilog, в отличие от C, вероятно, имеет четко определенные битовые поля, поэтому здесь не обязательно существует перевод 1 к 1. C не нуждается в поддержке битовых полей uint64_t, а в случае, если это так, все равно не совсем точно определено, является ли uint64_t my_field_n:1; битом 63 или битом 0.

Lundin 15.04.2024 11:18

@Lundin - что ты имеешь в виду, говоря, что в C нет четко определенного битового поля? Я работал с ним много лет... И, судя по моему опыту, порядок также четко определен (LSB вверху. MSB внизу). Кроме того, uint64_t существует, если вы добавите #include <inttypes.h>

Benny80 15.04.2024 11:24

Это похоже на то, что компилятор verilog должен уметь генерировать, хотя и с метрической тонной макросов...

Botje 15.04.2024 11:26

Раздел о битовых полях в стандарте C просто слишком расплывчат и содержит слишком много аспектов, определяемых реализацией, чтобы быть полезным; компиляторы могут просто реализовывать битовые поля более или менее по своему усмотрению, и это делает их непереносимыми и непредсказуемыми. См. например это. Кроме того, стандарт C охватывает только типы bool, signed int и unsigned int, но uint64_t вряд ли является одним из них.

Lundin 15.04.2024 11:32

@Botje - интересное направление... Хотя я больше склоняюсь к манипулированию текстом (просматриваю исходный файл, манипулирую содержимым и печатаю его в файл .h), но также рассмотрю вашу идею. Есть еще подсказки о том, по каким ключевым словам искать в документации компилятора?

Benny80 15.04.2024 11:35

Без понятия. Я был потребителем таких сгенерированных заголовочных файлов, но не участвовал в их производстве.

Botje 15.04.2024 11:38

Спасибо @Botje — попробую спросить у компиляторов из моей компании.

Benny80 15.04.2024 11:48

Обратите внимание, что это не должно быть отмечено тегами C и C++ одновременно, поскольку это разные языки. C++, по крайней мере, попытался спасти сломанный стандарт с введением std::bitset. Судя по всему, C намерен навсегда остаться сломанным.

Lundin 15.04.2024 11:49

@Lundin - насчет битового поля - очень интересно, я понятия не имел... Спасибо, что сообщили мне. Но давайте предположим, что я всегда использую один и тот же компилятор (gcc/g++), поэтому меня не беспокоит переносимость. Из прошлого опыта я знаю, что gcc дает детерминированные результаты относительно местоположения битового поля.

Benny80 15.04.2024 11:49

@Benny80 Benny80 Если вы сможете найти документацию gcc об «ABI» для конкретной цели и сослаться на нее, вполне возможно создать что-то, что будет работать в этих конкретных условиях. Однако написание кода с использованием битовых масок и битовых сдвигов сделало бы его переносимым, но тогда вам, возможно, придется удалить структуру.

Lundin 15.04.2024 11:51

Существует также вопрос, как эти «логические» переменные должны быть представлены аппаратному обеспечению. Можете ли вы написать отдельные биты? Байты? Слова? Четверные слова? Лучше всего придерживаться непрозрачного char[] blob с атомарной операцией чтения/записи.

Botje 15.04.2024 11:54

@Botje - HW может получить доступ к отдельным битам.

Benny80 15.04.2024 12:01

@Лундин - я начинаю думать, что ты прав, а битовые маски и сдвиги более надежны. Но я оставляю вопрос открытым, поскольку, если кто-нибудь предложит хороший способ выполнить преобразование, о котором я просил, - оно подойдет для моих нужд.

Benny80 15.04.2024 12:02

А как обновить my_field_2, состоящий из трех битов? LSB в MSB? MSB в LSB? С середины? Есть ли регистр-защелка, который вам нужно запустить для отправки обновления?

Botje 15.04.2024 12:02

@Botje Аппаратное обеспечение выполняет чтение-изменение-запись. И моей программе на C/C++ просто нужен доступ к этой структуре, чтобы иметь возможность анализировать некоторые необработанные данные (я получаю полные 64-битные данные, и мне нужно знать, какое поле и в каком месте находится).

Benny80 15.04.2024 12:05

Вы пытаетесь перевести код SystemVerilog на C/C++ или пытаетесь взаимодействовать с исполняемым кодом SystemVerilog в моделировании?

dave_59 15.04.2024 16:51

@ dave_59 - просто переведите структуры с одного языка на другой. Никакого взаимодействия с симуляцией.

Benny80 15.04.2024 19:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
17
136
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как следует из многих комментариев, использование битовых полей C может быть немного рискованным. Определенного представления в памяти не существует, поэтому приходится экспериментировать с компиляторами и, возможно, с кучей #pragmas, чтобы получить работоспособную комбинацию.

Существуют три варианта.

  1. Написать код

Вы можете написать код для явного манипулирования данными, чтобы изолировать биты каждого поля, и создать структуру, в которой просто есть int/bools (без битовых полей), чтобы содержать проанализированные данные. Простая функция для изоляции и возврата любой заданной последовательности бит/бит в виде int64 сделала бы это намного проще.

  1. Используйте АСН.1

Это технология сериализации, которая имеет несколько форматов проводов. Интерес представляют uPER — правила невыровненного упакованного кодирования. Вы можете относительно легко написать схему ASN.1, которая, используя uPER, сможет генерировать и анализировать ваши данные. Например, в uPER логическое значение превращается в один бит. ЦЕЛОЕ ЧИСЛО (0..15) становится 4-битным. Если у вас был PDU ASN.1, например

MyStruct ::= SET OF
{
   my_field_1 [0] BOOLEAN,          -- 1 bit
   my_field_2 [1] INTEGER (0..7),   -- 3 bits as an integer
   etc
}

компилятор ASN.1 будет генерировать код C/C++, который анализирует/записывает его в проводном формате uPER, и это будет соответствовать вашей структуре данных. Это немного похоже на вариант 1, за исключением того, что компилятор ASN.1 пишет код, а мы используем спецификацию формата uPER для «приведения в соответствие» с вашими данными.

Этот компилятор ASN.1 , вероятно, справится со своей задачей, и я могу порекомендовать эту веб-страницу для обзора, эту игровую площадку , чтобы попробовать что-то, и книгу Дюбюиссона, доступную здесь бесплатно. Вы также можете преобразовать схему ASN.1 в схему XML (XSD), что дает вам больше возможностей для передачи данных, когда вы и получатель работаете с одной и той же схемой.

  1. Используйте ДНС.1

В то время как ASN.1 — это «абстрактная синтаксическая нотация №1», CSN.1 — это «конкретная синтаксическая нотация №1».

Целью ASN.1 является определение того, какой информацией необходимо обмениваться, не заботясь о том, как она представлена ​​в сети (отсюда и распространение для нее двоичных и текстовых форматов передачи данных). Целью CSN.1 является определение того, какой информацией необходимо обмениваться, и абсолютно четкое представление о том, как она должна быть представлена ​​в сети.

Таким образом, с помощью CSN.1 можно определить любой произвольный битовый поток, и компилятор автоматически создаст код, который сможет интерпретировать и записывать ваш битовый поток. Однако инструментов для этого гораздо меньше, и что-то часто идет не так. Если вас интересует этот подход, вы, вероятно, смотрите на один из коммерческих инструментов (например, Objective Systems inc, чей компилятор ASN.1 теперь, я думаю, также обрабатывает CSN.1).

Рекомендация: я бы использовал подход ASN.1. Приятно то, что как только вы это заработаете, ваш код C сможет легко повторно создавать данные в различных форматах, включая XML. Это могло бы немного облегчить жизнь, если появятся более совершенные системы для получения данных.

Компилятор ASN.1 от Objective Systems теперь также поддерживает JER (правила кодирования JSON), поэтому он может довольно легко отправлять данные через Интернет, причем получателю не обязательно знать что-либо об ASN.1 как таковом.

Если вам не хочется экспериментировать с ASN.1 uPER, я бы написал код, который бы самостоятельно обрабатывал биты. Это скучный шаблонный код, но он достаточно прост и надежен. Это было бы намного лучше, чем полагаться на компилятор C, который всегда будет располагать битовые поля так, как вы хотите.

Другие вопросы по теме