关于数字硬件建模SystemVerilog联合体

描述

数字硬件建模SystemVerilog-联合体(union)

  硬件

联合体(union)

联合体是一个可以有多个数据类型表示的单个存储元素,联合体的声明类似结构体,但推断出的硬件非常不同。结构体是几个变量的集合。union是单个变量,可以在不同的时间使用不同的数据类型。union可以存储的变量类型列在大括号({})之间,每个变量类型都有一个名称:

硬件

在本例中,变量是data。data变量有两种可能的数据类型:名为s的有符号整数类型,或名为u的无符号整数值。

在RTL建模中,联合体的一个典型应用是,一个值可以表示为几种不同的类型,但在任何特定的时钟周期中只能表示为一种类型。例如,数据总线有时可能使用用户网络接口(UNI,User NetworkInterface)电信协议发送数据包,而在其他时间,同一数据总线可能使用网络到网络接口(NNI,Network to Network Interface)电信协议发送数据包。SystemVerilog联合体可以代表同一总线的这种双重用途。联合体的另一个用途是表示共享硬件资源,例如可以在不同时间存储不同类型数据的硬件寄存器。

自定义和匿名联合体

同结构体一样, 联合体可以使用 typedef 来定义, 按这种方式定义的是自定义联合体。如果没有使用 typedef,就是匿名联合体.

硬件

匿名联合体和自定义联合体都是可综合的,但自定义联合体在RTL建模方面有优势。自定义联合体可以是:

用于声明多个变量,如上例中的数据输入和数据输出。

用作模块端口类型。

在一个包中定义,然后在多个模块中使用。

分配和读取联合体变量

引用联合体的数据类型时,使用联合体的名称,后跟表示数据类型的名称,并用句点(.)分隔(同结构体一样)。

硬件

在本例中,变量数据有两种可能的数据类型,每个表示中都存储了-5。data.s数据类型将打印为-5,一个有符号整数值。data.u数据类型将打印为4294967291,一个无符号整数值。

非压缩联合体和标记的联合体

最佳做法准则4-4

在RTL建模中仅使用压缩联合体。

 

SystemVerilog有三种类型的联合体:非压缩联合体、压缩联合体和标签联合体,大多数综合编译器只支持压缩联合体。

大多数综合编译器不支持非压缩和标签联合体。这些联合体类型可以代表任何数据类型的存储,包括不可综合的数据类型。非压缩的联合体体和标签联合体体可用于建模测试台和高级抽象模型,但不应用于RTL建模。

通过在union关键字后添加关键字Packed来定义压缩联合体:

硬件

压缩联合体是可综合的。压缩联合体对联合体可以表示的数据类型有很多限制。这些限制与硬件行为密切相关。在压缩联合体中,它只能表示向量类型,并且联合体可以存储的每个数据类型的向量宽度必须相同。这确保了无论存储值的数据类型如何,压缩联合体都将以相同的位数表示其存储。

压缩联合体允许使用一种格式写入数据,并使用另一种格式读回数据。设计模型不需要进行任何特殊处理来跟踪数据的存储方式,这是因为压缩联合体中的数据总是使用相同的位数存储。下面的示例定义了一个压缩联合体,其中一个值可以用两种方式表示:数据包(使用压缩结构体)或连续字节数组,

硬件

图4-3说明了dreg的两种数据类型是如何表示的。

图4-3:具有相同存储的两种表示形式的压缩联合体 硬件

因为联合体是压缩的,所以无论使用哪种联合体表示,信息都将使用相同的位对齐来存储。这意味着可以使用bytes格式(可能来自字节的串行输入流)加载一个值,然后使用data_packet格式读取相同的值,

通过端口将压缩联合体传递给任务和函数

自定义联合体(使用typedef定义的联合体)可以用作模块端口和任务/函数参数的数据类型。非压缩的联合体要求将相同的联合体类型用于端口的外部连接,或用于传递给任务或函数参数的外部信号。压缩联合体只能表示压缩数据类型,这允许任何向量类型用于外部连接或外部值。

示例4-6显示了一个包含结构体和联合体定义的包。示例4-7在一个简单算术逻辑单元(ALU)模型中使用了这个包,ALU可以对有符号或无符号的值进行操作,但不能同时对两者进行操作,一个标志用于指示操作数据是有符号的还是无符号的。ALU操作码、两个操作数和一个有符号标志作为单个指令字传递到ALU中,用结构体表示。ALU输出是单个值,可以表示有符号或无符号值,建模为这两种类型的并集。这允许相同的输出端口用于不同的数据类型:

示例4-6:包含结构体和联合体定义的包

//
// Package with union and structure definitions
//
//`begin_keywords "1800-2012" // use SystemVerilog-2012 keywords
`define _4bit        // use 4-bit data for testing synthesis
//`define _32bit     // use 32-bit data word size
//`define _64bit     // use 64-bit data word size
package definitions_pkg;
 `ifdef _4bit
   typedef logic        [ 3:0] uword_t;
   typedef logic signed [ 3:0] sword_t;
 `elsif _64bit
   typedef logic        [63:0] uword_t;
   typedef logic signed [63:0] sword_t;
 `else  // default is 32-bit vectors 
   typedef logic        [31:0] uword_t;
   typedef logic signed [31:0] sword_t;
 `endif 
 
 typedef enum logic [2:0] {ADD, SUB, MULT, DIV} op_t;
 typedef enum logic {UNSIGNED, SIGNED} operand_type_t;

 // Packed union represents a variable that can store 
 // different types
 typedef union packed {
   uword_t u_data;
   sword_t s_data;
 } data_t;
 
 // Packed structure represents a collection of variables 
 // that can referenced and passed through ports as a group
 typedef struct packed {
   op_t            opcode;
   operand_type_t  op_type;
   data_t          op_a;
   data_t          op_b;
 } instruction_t;
endpackage: definitions_pkg
//`end_keywords 
示例4-7:带结构体和联合体端口的算术逻辑单元(ALU)
//
// Module with structure input port and union output port
//
//`begin_keywords "1800-2012" // use SystemVerilog-2012 keywords
module alu 
import definitions_pkg::*;   // wildcard import the package
(input  logic         clk, rstN,
input  instruction_t iw,         // input is a structure
output data_t        alu_out     // output is a union
);
 timeunit 1ns; timeprecision 1ns;

 always_ff @(posedge clk or negedge rstN) // async reset
   if (!rstN)                             // active-low
     alu_out <= '0;
   else begin: alu_operations 
     if (iw.op_type == SIGNED) begin: signed_ops 
       case (iw.opcode)
         ADD : alu_out.s_data <= iw.op_a.s_data
                                 + iw.op_b.s_data;
         SUB : alu_out.s_data <= iw.op_a.s_data
                                 - iw.op_b.s_data;
         MULT: alu_out.s_data <= iw.op_a.s_data
                                 * iw.op_b.s_data;
         DIV : alu_out.s_data <= iw.op_a.s_data
                                 / iw.op_b.s_data;
       endcase 
     end: signed_ops 
     else begin: unsigned_ops 
       case (iw.opcode)
         ADD : alu_out.u_data <= iw.op_a.u_data
                                 + iw.op_b.u_data;
         SUB : alu_out.u_data <= iw.op_a.u_data
                                 - iw.op_b.u_data;
         MULT: alu_out.u_data <= iw.op_a.u_data
                                 * iw.op_b.u_data;
         DIV : alu_out.u_data <= iw.op_a.u_data
                                 / iw.op_b.u_data;
       endcase 
     end: unsigned_ops 
   end: alu_operations 
endmodule: alu
`end_keywords 

 

图4-4显示了综合该示例的结果。说明了在RTL模型中使用结构体和联合体的两个重要特征:

结构体和联合体可以简洁地仿真大量功能。用更少的代码行仿真更多功能的能力是在原始Verilog中添加结构体和联合体等功能的原因之一,

当与本节所述的RTL编码准则一起使用时,联合体可以表示多路复用功能,允许多个资源(本例中的有符号和无符号加法器、减法器、乘法器和除法器)共享相同的硬件寄存器。图4-4中的圆圈代表通用算法 操作,梯形符号代表多路复用器:

图4-4:示例4-7的综合结果:具有结构体和联合体端口的ALU 硬件

硬件

SystemVerilog-结构体(一)

硬件

SystemVerilog-结构体(二)

原文标题:SystemVerilog-联合体(union)

文章出处:【微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。  

      审核编辑:彭静

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分