SystemVerilog学习笔记(7) ------ 结构体(2)
作者:蓝水映像 日期:2009-01-11
SystemVerilog 中的结构体分为压缩和非压缩结构体.
- typedef struct packed {
- bit [7:0] main_ver;
- bit [15:0] sub_ver;
- }version;
计算机在处理一般的结构体时, 对于结构体中的成员处理的方式仍是按一般的数据类型对待的. 如在处理 byte 类型的数据时, 计算机可能按照 32 bit 处理, 因为对于一般的 32 位操作系统来说,处理 32 位数据比 8 位数据可能要简单, 因此, 8 bit 的数据所占的内存空间可能不是 8 bit, 而是 32 bit. 这种情况实际在 C 语言中也有的. C 中也有相应的编译参数来处理这种情况. 这种占用空间可能比变量实际大小要大的情况, 有时对于处理数据会很不方便, 所以在 SystemVerilog 中, 可以用 packed 声名方式来避免这种问题.
对于压缩结构体, 计算机会把其整体看作是一个向量来处理, 结构体中的成员在内存中是连续存放的. 所以压缩结构体的成员必须是整型数据, 不能是 real, shorreal 以及非压缩结构体, 非压缩的联合体, 非压缩数组.
- version ver_0, ver_1;
- ver_0[23:16] = 8'h1; // 用向量的方式来访问压缩结构体.
- ver_0[15:0] = 16'h0a;
- ver_1 = ver_0 << 2; // 把压缩结构体当作整体来参加运算.
因为压缩结构体是被当作向量来处理的, 所以压缩结构体还可以加上 signed, unsigned 标志. 这个符号标志是针对压缩结构体整体的, 不会影响到结构体内部的成员.
- typedef struct packed signed {
- bit [15:0] hi_bit;
- bit [15:0] lo_bit;
- }data;
Tags: SystemVerilog Verilog FPGA
SystemVerilog学习笔记(6) ------ 结构体(1)
作者:蓝水映像 日期:2009-01-09
SystemVerilog的结构体声名和C中的声名类似, 有匿名结构体和自定义结构体. 和C不同的是, SystemVerilog在声名结构体时, 大括号左边不能像C可以有个标识符.
- struct [packed[signing]]{ // 匿名结构体
- struct_members
- }struct_variable_name;
- typedef struct [packed[signing]]{ // 自定义类型结构体
- struct_members
- }struct_type;
- struct_type struct_variable_name; // 声名结构体变量
结构体中的成员变量在定义结构体时就可以一并赋上初值, 也可以在声名变量时赋初值.
- typedef struct{
- int i_a = 0; // 定义结构体时赋初值
- int i_b = 1;
- real r_c;
- }data_t;
- data_t data1 = '{2, 3, 4}; /* 定义变量时赋初值, 值的顺序要得结构体中
- * 定义的顺序一致 */
- data_t data2 = '{i_b:5, i_a:6, r_c:7.0};
- /* 按成员名称来赋值, 用这种方式赋值时,
- * 所有的量都要用成员名来赋值. */
- data_t data3 = '{default:0}; // 所在成员设置成0.
- data_t data4 = '{int:8, real:9.0}; // 按成员类型赋值.
- data_t data5 = '{int:10, default:0, i_b:11};
- /* 混合赋值时, 成员名优先级最高,
- * 数据类型其次, default最低. */
Tags: SystemVerilog Verilog FPGA
SystemVerilog学习笔记(5) ------ 枚举(2)
作者:蓝水映像 日期:2009-01-03
SV 中的枚举类型是一种强类型, 不象 Verilog 中各种类型可以相互随意赋值. 在 SV 中对枚举类型赋值有 3 种方法:
1. 用枚举类型中的标签对枚举变量赋值.
2. 同一枚举类型定义的不同变量间相互赋值.
3. 用强制类型转换.
- typedef enum {red, green, yellow} Colors;
- Colors col_0, col_1, col_2;
- col_0 = red;
- col_0 = green;
- col_0 = yellow; // 用标签对枚举变量赋值.
- col_1 = col_0; // 同类型枚举变量间赋值.
- col_2 = Colors'(0); // 强制类型转换赋值.
- $cast(col_2, 1); // 动态强制类型转换.
枚举类型中的标签可以被直接引用, 用来给其它变量赋值或参与运算.
- typedef enum {red, green, yellow} Colors;
- typedef enum {Mo,Tu,We,Th,Fr,Sa,Su} Week;
- Colors col_0;
- Week week_0, week_1;
- int i, j;
- col_0 = green;
- week_0 = We;
- i = col_0 + week_0; // 枚举类型可以自动转换成 int 类型.
- j = red+ We; // 直接用标签进行赋值.
- week_1 = i; // 错误的, int不能自动转换到枚举类型.
- week_1 = week_0 + 1; // 错误的, 等式右边在做运算时已经转换
- // 成整形, 不能再直接赋值给枚举类型变量.
SV 中为了方便枚举类型的使用, 提供了一些方法.
1. first()
返回枚举类型的第一个值.
2. last()
返回枚举类型的最后一个值.
3. next()
返回枚举类型的下一个值. 如果当前值是最后一个则返回第一个值.
4. prev()
返回枚举类型的前一个值. 如果当前值是第一个则返回最后一个值.
5. num()
返回枚举类型中标签的个数.
6. name()
根据所给的值返回标签名称字符串, 如果值不在枚举类型中,则返回一个空字符串.
Tags: SystemVerilog Verilog FPGA
SystemVerilog学习笔记(4) ------ 枚举(1)
作者:蓝水映像 日期:2008-12-27
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" |
枚举变量中的成员还有一种定义的方法. 语法类似于向量类型的声名 .
| 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; |
SystemVerilog学习笔记(3) ------ string(2)
作者:蓝水映像 日期:2008-12-24
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 realtoa(real r) | 将实数转换成字符串. |
SystemVerilog学习笔记(2) ------ string(1)
作者:蓝水映像 日期:2008-12-23
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
SystemVerilog学习笔记(1) ------ 整型
作者:蓝水映像 日期:2008-12-22
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













