将 SystemVerilog 结构转换为 C/C++ 结构

问题描述 投票:0回答:1

在我的环境中的某个地方,有一个大文件,其中包含(以及其他内容)许多 64 位的系统 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
};

我不知道该怎么做,所以非常感谢任何帮助(任何语言/shell 脚本等)。

谢谢!

c struct system-verilog text-manipulation
1个回答
1
投票

正如许多评论所暗示的那样,C 位字段的使用可能有点冒险。没有定义的内存中表示,因此这是一个使用编译器进行实验的问题,并且可能还需要一堆#pragmas来获得可行的组合。

存在三个选项。

  1. 编写代码

您可以编写代码来显式操作数据以隔离每个字段的位,并创建一个仅包含整数/布尔值(无位字段)的结构来包含解析的数据。一个简单的函数来隔离并返回任何给定的位/位序列作为 int64 将使这变得容易得多。

  1. 使用 ASN.1

这是一种具有多种有线格式的序列化技术。令人感兴趣的是 uPER——未对齐的打包编码规则。您可以相对轻松地编写一个 ASN.1 模式,与 uPER 一起使用,能够生成和解析您的数据。例如,在 uPER 中,BOOLEAN 变成单个位。 INTEGER (0..15) 变为 4 位。如果您有 ASN.1 PDU,例如

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 编译器可能可以胜任这项工作,我可以推荐 这个网页来了解概述,这个游乐场来尝试一下,以及 Dubuisson 的书可以在这里免费获得。您还可以将 ASN.1 架构转换为 XML 架构 (XSD),这为您提供了更多选项来传递数据,并且您和接收者都使用相同的架构。

  1. 使用CSN.1

ASN.1 是“抽象语法符号 #1”,而 CSN.1 是“具体语法符号 #1”。

ASN.1 的目的是定义需要交换哪些信息,而无需关心信息如何在网络上表示(因此二进制和文本网络格式的激增)。 CSN.1 的重点是定义需要交换哪些信息,并完全明确如何在网络上表示这些信息。

因此,使用 CSN.1,人们可以定义任何任意比特流,并让编译器自动构建可以解释和写入比特流的代码。然而,用于此目的的工具要少得多,而且经常会出错。如果您对这种方法感兴趣,您可能正在考虑其中一种商业工具(例如 Objective Systems inc,我认为其 ASN.1 编译器现在也可以处理 CSN.1)。

建议:我会使用 ASN.1 方法。令人高兴的是,一旦您开始工作,您的 C 代码就可以轻松地以各种不同的格式(包括 XML)重新发出数据。如果有未来的系统来接收数据,这可能会让生活变得更容易一些。

Objective Systems 的 ASN.1 编译器现在也支持 JER(JSON 编码规则),因此它可以非常轻松地向 Web 发送数据,而接收者不必了解有关 ASN.1 的任何信息。

如果您不想尝试 ASN.1 uPER,我会编写一些代码来显式地手动设置您自己的位。这是无聊的样板代码,但相当简单和确定。这比依赖 C 编译器总是按照您想要的方式布局位字段要好得多。

© www.soinside.com 2019 - 2024. All rights reserved.