分类: FPGA预览模式: 普通 | 列表

SystemVerilog学习笔记(7) ------ 结构体(2)

        SystemVerilog 中的结构体分为压缩和非压缩结构体.

SystemVerilog代码
  1. typedef struct packed {  
  2.     bit [7:0]   main_ver;  
  3.     bit [15:0]  sub_ver;  
  4. }version;  

        计算机在处理一般的结构体时, 对于结构体中的成员处理的方式仍是按一般的数据类型对待的. 如在处理 byte 类型的数据时, 计算机可能按照 32 bit 处理, 因为对于一般的 32 位操作系统来说,处理 32 位数据比 8 位数据可能要简单, 因此, 8 bit 的数据所占的内存空间可能不是 8 bit, 而是 32 bit. 这种情况实际在 C 语言中也有的. C 中也有相应的编译参数来处理这种情况. 这种占用空间可能比变量实际大小要大的情况, 有时对于处理数据会很不方便, 所以在 SystemVerilog 中, 可以用 packed 声名方式来避免这种问题.
        对于压缩结构体, 计算机会把其整体看作是一个向量来处理, 结构体中的成员在内存中是连续存放的. 所以压缩结构体的成员必须是整型数据, 不能是 real, shorreal 以及非压缩结构体, 非压缩的联合体, 非压缩数组.

SystemVerilog代码
  1. version ver_0, ver_1;  
  2. ver_0[23:16] = 8'h1;        // 用向量的方式来访问压缩结构体.  
  3. ver_0[15:0]  = 16'h0a;  
  4. ver_1 = ver_0 << 2;         // 把压缩结构体当作整体来参加运算.  

         因为压缩结构体是被当作向量来处理的, 所以压缩结构体还可以加上 signed, unsigned 标志. 这个符号标志是针对压缩结构体整体的, 不会影响到结构体内部的成员.

SystemVerilog代码
  1. typedef struct packed signed {  
  2.     bit [15:0] hi_bit;  
  3.     bit [15:0] lo_bit;  
  4. }data;  

 

Tags: SystemVerilog Verilog FPGA

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1829

SystemVerilog学习笔记(6) ------ 结构体(1)

        SystemVerilog的结构体声名和C中的声名类似, 有匿名结构体和自定义结构体. 和C不同的是, SystemVerilog在声名结构体时, 大括号左边不能像C可以有个标识符.

SystemVerilog代码
  1. struct [packed[signing]]{          // 匿名结构体
  2.     struct_members
  3. }struct_variable_name;
  4.  
  5. typedef struct [packed[signing]]{  // 自定义类型结构体
  6.     struct_members
  7. }struct_type;
  8. struct_type struct_variable_name;  // 声名结构体变量

         结构体中的成员变量在定义结构体时就可以一并赋上初值, 也可以在声名变量时赋初值.

SystemVerilog代码
  1. typedef struct{  
  2.     int  i_a = 0;          // 定义结构体时赋初值  
  3.     int  i_b = 1;  
  4.     real r_c;  
  5. }data_t;  
  6.   
  7. data_t data1 = '{2, 3, 4}; /* 定义变量时赋初值, 值的顺序要得结构体中 
  8.                             * 定义的顺序一致 */  
  9. data_t data2 = '{i_b:5, i_a:6, r_c:7.0};  
  10.                            /* 按成员名称来赋值, 用这种方式赋值时,  
  11.                             * 所有的量都要用成员名来赋值. */  
  12. data_t data3 = '{default:0};       // 所在成员设置成0.  
  13. data_t data4 = '{int:8, real:9.0}; // 按成员类型赋值.  
  14. data_t data5 = '{int:10, default:0, i_b:11};  
  15.                            /* 混合赋值时, 成员名优先级最高, 
  16.                             * 数据类型其次, default最低. */  

Tags: SystemVerilog Verilog FPGA

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1326

SystemVerilog学习笔记(5) ------ 枚举(2)

        SV 中的枚举类型是一种强类型, 不象 Verilog 中各种类型可以相互随意赋值. 在 SV 中对枚举类型赋值有 3 种方法:
        1. 用枚举类型中的标签对枚举变量赋值.
        2. 同一枚举类型定义的不同变量间相互赋值.
        3. 用强制类型转换.

SystemVerilog代码
  1. typedef enum {red, green, yellow} Colors;   
  2. Colors col_0, col_1, col_2;   
  3.   
  4. col_0 = red;   
  5. col_0 = green;   
  6. col_0 = yellow;      // 用标签对枚举变量赋值.   
  7.   
  8. col_1 = col_0;       // 同类型枚举变量间赋值.   
  9.   
  10. col_2 = Colors'(0);  // 强制类型转换赋值.   
  11. $cast(col_2, 1);     // 动态强制类型转换.   

         枚举类型中的标签可以被直接引用, 用来给其它变量赋值或参与运算.

SystemVerilog代码
  1. typedef enum {red, green, yellow} Colors;       
  2. typedef enum {Mo,Tu,We,Th,Fr,Sa,Su} Week;       
  3. Colors col_0;       
  4. Week week_0, week_1;       
  5. int i, j;       
  6.       
  7. col_0 = green;       
  8. week_0 = We;       
  9. i = col_0 + week_0;    // 枚举类型可以自动转换成 int 类型.       
  10. j = red+ We;           // 直接用标签进行赋值.       
  11.       
  12. week_1 = i;            // 错误的, int不能自动转换到枚举类型.   
  13. week_1 = week_0 + 1;   // 错误的, 等式右边在做运算时已经转换   
  14.                        // 成整形, 不能再直接赋值给枚举类型变量.  

        SV 中为了方便枚举类型的使用, 提供了一些方法.
        1. first()
                返回枚举类型的第一个值.
        2. last()
                返回枚举类型的最后一个值.
        3. next()
                返回枚举类型的下一个值. 如果当前值是最后一个则返回第一个值.
        4. prev()
                返回枚举类型的前一个值. 如果当前值是第一个则返回最后一个值.
        5. num()
                返回枚举类型中标签的个数.
        6. name()
                根据所给的值返回标签名称字符串, 如果值不在枚举类型中,则返回一个空字符串.

Tags: SystemVerilog Verilog FPGA

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1368

SystemVerilog学习笔记(4) ------ 枚举(1)

        SV 中的枚举类型和 C 中的枚举类型差不多, 但 SV 中的枚举的定义比 C 中的要多一种东西, SV 中的枚举可以定义枚举中成员的类型.
        和 C 中一样, SV 中的枚举在不定义数据类型时, 默认为 int. 当然也可以定义为 integer, bit 等整型.

enum {red, yellow, green} color1;
enum integer {red, yellow, green} color2;
enum bit [2:0]
{red, yellow, green} color3;

        枚举中的成员都是隐含有数值的, 默认第一个成员为 0, 后续成员依次递增, 则 color1, color2, color3 中的 red = 0, yellow = 1, green = 3.
        当然我们也可以手动的为这些成员设定值. 

enum {red = 1, yellow = 3, green} color4;

        在这种情况下, 没有赋值的量的值是在它前面一个量的基础上加一的.
        要注意的是, 一个枚举变量中的成员的值不能重复.  

enum {red = 1, yellow, green = 2} color5;     // 错误, 因为 yellow的值也为2

         枚举变量中的成员的值不能超过枚举数据类型的范围.如 int 类型的枚举成员不能赋值为 "z" 或 "x", 向量类型 bit [2:0] 不能表示大于 3'h7 的值. 当枚举成员中有被赋值为 "z" 或 "x" 的, 其后面的成员也必须赋值.
 

enum {red = 1, yellow = 'x, green = 'z} color6;    // int 类型不能赋值为"x"
                                                   // 或 "z"
enum bit [2:0] {red, yellow = 4'h9, green} color7; // 超过了bit[2:0]能表示
                                                   // 的范围
enum integer {red = 'x, yellow, green} color8;     // yellow, green 也必须
                                                  
// 赋值.

        枚举变量中的成员还有一种定义的方法. 语法类似于向量类型的声名 . 

name[N] 声名N个成员: name0, name1, ... , nameN-1. N只能是常量
name[N] = C 声名N个成员: name0, name1, ... , nameN-1, 它们的值从 C 依次递增.N只能是常量
name[N:M] 声名M - N + 1个成员: nameN, nameN+1, ... , nameM-2, nameM-1. N和M只能是常量.
name[N:M] = C 声名M - N + 1个成员: nameN, nameN+1, ... , nameM-2, nameM-1. 它们的值从 C 依次递增. N 和M只能是常量.

 

enum { add=10, sub[2], jmp[6:8] } E1;
enum
{ register[2] = 1, register[2:4] = 10 } E2;

        上面的代码实际可以扩展为:
 

enum { add=10, sub0, sub1, jmp6, jmp7, jmp8} E1;
enum
{ register0 = 1, register1, register2 = 10, register3, register4} E2;

 

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1491

SystemVerilog学习笔记(3) ------ string(2)

        string 所特有的几种操作符 ==, !=, >, <, >=, <= 和 C 中的字符串比较是一样的, 这6种操作符两边的量可以是 string, 或者是字符串文本.

        连接操作

   {Str1, Str2, ..., StrN}

        连接操作可以将多个字符串连接起来, StrN 可以是 string 类型的变量, 也可是以字符串文本.

 

        复制操作
 

   {multiplier{Str}}

        复制操作可以把一个字符串进行多次复制,并连接. multiplier 可是是常量, 也可是是变量, 但必须是整数. Str 可以是一个 string 类型的量, 也可是一个字符串文本, 甚至是一个整型的数. 要注意的是, 当 Str 是一个整数时, Str 会先按照整型隐式转换成 string 的方法进行转换, 然后再进行复制操作.例如:
 

   bit [11:0] bit_str= 12'h544;
 string b = {2{bit_str}};     
// b is 32'h05440544, not 24'h544544

 

        string 的一些常用的函数

  function int len() 返回字符串的长度, 空字符串返回0.
  task putc(int i, byte c) 设置第i 个字符为c, 和b[i] = c的效果一样.
  function byte getc(int i) 返回第i个字符, 和 c = b[i] 的效果一样.
  function string toupper() 小写字母转换成大写字母.
  function int compare(string s) 和 C 中的 strcmp 的功能一样.大小写不敏感
  function int icompare(string s) 和 C 中的 strcmp 的功能一样.但大小写敏感
  function string substr(int i, int j) 返回第i到第j之间的子字符串
  function integer atoi()
function integer atohex()
function integer atooct()
function integer atobin()
以十进制, 十六进制, 八进制或者二进制把字符串转换成整数.
  function real atoreal() 字符串转换成实数.
 

task itoa(integer i)
task hextoa(integer i)
task octtoa(integer i)
task bintoa(integer i)
 

将十进制, 十六进制, 八进制或者二进制的整数转换成字符串.
  task realtoa(real r) 将实数转换成字符串.

 

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1102

SystemVerilog学习笔记(2) ------ string(1)

         string 在 Verilog 中也有, 但是仅仅只是表现为一个8-bit整数倍的数组, 而在 SystemVerilog 中, string 是尺寸可变, 动态分配并且提供了很多操作字符串的方法的.

 

        string的声名方法

   string variable_name [= initial_value];

         variable_name 为变量名; initial_value 为初始值, 在声名时可有可无. 如果不给初始值, string 变量的默认初值为"", 即一个的空字符串. 例:

   string site_name = "blove_water";

 

         string 中的字符可以通过下标的方式来访问. 例如:

    site_name[0]
  site_name[6]
的值为 "b"
的值为 "w"

 

 

        string 中不能有 "\0", 所有的 "\0" 会被忽略掉. 例如: 

   bit [27:0]   i = 28'h0410042;
 string     str = string'(i);
 $display
("str = %s", str);

        得到的结果是: str = AB;

 

        string 是以 8-bit 为单位的. 当整型转换为 string 时, 如果整型的宽度不是 8-bit 的整数陪, 则在整数的左边补零, 直到宽度为 8-bit 的整数陪. 例如: 

   bit [11:0] b = 12’ha41;  
 string s2 = string’(b);      // sets s2 to 16’h0a41 

 

Tags: SystemVerilog Verilog FPGA

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1003

SystemVerilog学习笔记(1) ------ 整型

        SystemVerilog中的整型数据可以看作是Verilog和C中整型数据的一种杂交, 因些看起来有些象Verilog也有些象C.
        整型可分为基本整型和向量整型(直译的).下面是IEEE1800中定义的.

  integer_type ::= integer_vector_type | integer_atom_type
integer_atom_type ::= byte | shortint | int | longint | integer | time
integer_vector_type ::= bit | logic | reg

        基本整型有: byte, shortint, int, longint, integer, time.
        向量整型有: bit, logic, reg.

        这些整型又为分2态和4态数据类型. 2态即'0', '1'. 4态是在2态的基础上增加了 'Z'  和 'X'. 不论是基本整型还是向量类整型, 它们之中都有2态和4态之分.详细内容可看下表:

  byte 2 态 8-bit 整型, 相当于 C 中的 char signed
  shortint 2 态 16-bit 整型, 相当于 C 中的 short signed
  int 2 态 32-bit 整型, 相当于 C 中的 int signed
  longint 2 态 64-bit 整型 signed
  integer 4 态 32-bit 整型, Verilog 的数据类型 signed
  time 4 态 64-bit 整型, Verilog 的数据类型 unsigned
  bit 2 态向量类整型  
  logic 4 态向量类整型  
  reg 4 态向量类整型, Verilog 的数据类型  

        SystemVerilog 做为 Verilog 的扩展, 因此在 SystemVerilog 中这些数据类型仍可以使用. 在这些类型之中, int 和 integer 基本上可以看做一样, 只是一个是 2 态,一个是 4 态. (在能只用 2 态的情况下尽量用 int, 因为 2 态数据类型在仿真的过程中可以有更高的效率.) logic 和 reg 在 SystemVerilog 中是相等的, 因为 logic 在字面意义上能够更好的表示 4 态, 而不象 reg 给人感觉不清, 所以尽量的用 logic 代替  reg.
        在 4 态类型转换为 2 态类型时, 'Z' 和 'X' 会转换为 '0'.

        整型还为分有符号和无符号的.用关键字 signed 和 unsigned 表示. 在声名时一定要注意 SystemVerilog 和 C 的不同.
        在 C 中声名一个整数的方法为:
                                unsigned int a;
        而在 SystemVerilog 中声名的方法为:
                                int unsigned a;
 

Tags: SystemVerilog Verilog FPGA

分类:FPGA | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 910