数据类型
Verilog-->register-reg
|->net-wire/…
SV-->logic----不关心对应的逻辑如何综合,单纯作为变量
logic 四值逻辑 表示0,1,x,z --> SV的硬件世界
bit 二值逻辑 表示0,1 --> SV的软件世界(验证环境)
2-state | shortint | int | longint | byte | bit |
| 16-bit | 32-bit | 64-bit | 8-bit | vec. |
4-state | logic | reg | integer | time | net-type |
| vec. | vec. | 32-bit | 64-bit | vec. |
bit --- unsigned
logic [7:0] logic_vec = 8'b1000_0000; // 128
bit [7:0] bit_vec = 8'b1000_0000; //128
byte signed_byte = 8'b1000_0000; //-128
*有符号类型byte范围为127~-128
byte unsigned signed_byte = 8'b1000_0000; // 128
类型转换
module datatype;
bit [8:0] bit_vec;
byte signed_byte = 8'b1000_0000;
initial begin
$display("signed_byte = '%x", signed_byte); //'h80='d-128
bit_vec = signed_byte;
$display("bit_vec = '%x", bit_vec);//'h180='d384
bit_vec = unsigned'(signed_byte);
$display("bit_vec = '%x", bit_vec);//'h080='d128
signed_byte = bit_vec;
$display("signed_byte = '%x", signed_byte);//'h80='d-128
signed_byte = unsigned'(bit_vec);
$display("signed_byte = '%x", signed_byte);//'h80='d-128
end
endmodule
隐式转换 bit_vec = signed_byte;
显式转换 | 静态转换 bit_vec = unsigned'(signed_byte); |
| 动态转换 $cast(tgt, src); |
定宽数组
- 声明与初始化
一维数组--16个int的数组
int lo_hi[0:15];
int c_style[16];
多维数组--八行四列的数组
非合并型数组:赋值用'{}
int arr2[0:7][0:3];
int arr3[2][3] = '{'{0,1,2},'{3,4,5}};
bit [7:0] b_unpack[3] = '{0,1,2}
// 三个8bit
b_unpack[0]
| ||||
b_unpack[1] | ||||
b_unpack[2] |
合并型数组:赋值用{}
bit [3][7:0] b_pack = {0,1,2};
b_unpack[0]
| |
b_unpack[1] | |
b_unpack[2] |
- 操作
赋值
for和foreach
bit [31:0] src[5], dst[5];
for (int i = 0; i < $size(src); i++) src[i] = i;
foreach(dst[j]) dst[j] = src[j]*2;
foreach(src[i,j]) $dispaly("src[%0d][%0d] = %0d", i, j, src[i][j]);
foreach(src[i]) begin
foreach(src[,j]) $dispaly("src[%0d][%0d] = %0d", i, j, src[i][j]);
end
复制和比较
用"="进行复制
用"=="或"!="进行比较
动态数组
用"[]"声明,用new[num]分配空间
delete()和size()是动态数组的内建方法
bit [7:0] bit_arr [];
bit_arr = new[3];
foreach(bit_arr[i]) bit_arr[i] = i;
bit_arr = new[bit_arr.size()](bit_arr);
bit_arr.delete();
队列
|
|
|
|
|
|
|
|
|
用"[$]"声明,元素编号0至$,
[a:$]==>第a个索引到最后一个索引----|-->$在左边表最小值,在右边表最大值
[$:b]==>第一个索引到第b个索引-------|
最常用的方法对是push_back()和pop_front()
int q[$]={0,2,3}; // {0,2,3},看出来是合并型数组
bit j = 1;
q.insert(1,j); // 在索引1处插入j ==> {0,1,2,3}
q.delete(1); // 删除索引1的元素 ==> {0,2,3}
q.push_front(j); // 在队列最前插入j ==> {1,0,2,3}
j = q.pop_back(); // 从队列最后取出一个数 {1,0,2} j=3
q.push_back(j); // 在队列最后插入j ==> {1,0,2,3}
j = q.pop_front(); // 从队列最前取出一个数 {0,2,3} j=1
q.delete(); // 删除整个队列
关联数组
大容量数组中其实相当多的数据不会被存储和访问
关联数组只对实际写入的元素分配空间
用"[index_type]"声明 data_type arr_id[index_type];
bit[63:0] assoc[int], idx = 1;
repeat (64) begin //稀疏矩阵元素初始化
assoc(idx) = idx;
idx = idx << 1;
end
// 用foreach遍历
foreach (assoc[i]) $display("[%h] = %h", i, assoc[i]);
// 用函数遍历
if (assoc.first(idx)) begin
//若稀疏阵第一个索引为0,该阵为空
do
$display("[%h] = %h", idx, assoc[idx]);
while (assoc.next(idx));
end
// 找到第一个元素,idx为返回的第一个元素的标号
assoc.first(idx);
assoc.delete(idx); // 删除对应标号,即第一元素
结构体
typedef-->创建新类型
struct-->定义结构
// 创建pixel结构体
struct {bit [7:0] r, g, b;} pixel;
typedef struct packed {bit [7:0] r, g, b;} pixel_s;
// 声明变量,该变量有r/g/b三个变量
pixel_s my_pixel;
// 结构体类型赋值,是非合并型数组
my_pixel = '{'h10, 'h10, 'h10};
枚举类型
一般和typedef连用
// 实质{}内对应的是0,1,2(d)
typedef enum {INIT, IDLE, DECODE} fsmstate_e;
fsmstate_e ps, ns;
case(ps)
// 直接给ns用0,1,2赋值,不合法
// 枚举类型可以直接赋值给整型,
// 反之不行,一定要做类型转化
IDLE: ns = INIT;
INIT: ns = DECODE;
default: ns = IDLE;
endcase
$display("next state: %s", ns.name());
字符串
打印输出用 $display();形成字符串可以用$sformatf();
string s;
initial begin
s = "IEEE ";
$display(s.getc(0)); //I
$display(s.tolower()); // ieee
s.putc(s.len()-1,"-"); // IEEE-
// 字符串长度用.len()而不是size()
s = {s, "P1800"}; // IEEE-P1800
$display(s.substr(2,5)); // 拿到第2-5位的子字符串EE-P
my_log($sformatf("%s %5d", s, 42)); // 打印消息
task my_log (string message);
$display("@%0t:$s",$time,message);
endtask
end