前言
素手青颜光华发,半世尘缘半世沙。我唤青天睁开眼,风霜怎奈并蒂花
\;\\\;\\\;
目录
- 前言
- 字符串
- packed
- 组合型结构体
- 组合型数组
- 过程块
- initial & always
- function
- task
字符串
module chertanis;
initial begin
string s="hola,mundo!",s2;
$display(s.getc(0));//# # 104
$display(s[0]); //# 104
$display(s.toupper());//#全大写 # HOLA,MUNDO!
//#替换
s.putc(s.len() - 7, "#");
$display(s); //# hola#mundo!
//#显示子字符串
$display(s.substr(2,5)); //# la#m
//#字符串拼接
s = {s,"-0101"};
//#复制4次
s = {4{s}};
//#格式化打印
my_log($sformatf("%s %5d",s,42));//# @0: hola#mundo!-0101hola#mundo!-0101hola#mundo!-0101hola#mundo!-0101 42
end
task my_log(string _msg);
$display("@%0t: %s",$time,_msg);
endtask
endmodule
\;\\\;\\\;
packed
组合型结构体
声明都放在标识符左边就是组合型
module chertanis;
typedef struct packed {
logic [7:0] a;
logic [63:0] b;
} mydata;
mydata [7:0] arr;
initial begin
//#arr = {8{8'b1000_0000,64'h0000_0000_0001_0000}}; //#也行
arr = '{'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000},
'{8'b1000_0000,64'h0000_0000_0001_0000}};
foreach(arr[i])
$display("%h -> %h",arr[i].a,arr[i].b);
end
endmodule
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
# 80 -> 0000000000010000
\;\\\;\\\;
组合型数组
- 组合型数组的数据是连续存储的,即使复制语句两侧的维度不一样,都可以复制
- 非组合数组数据不连续,因此复制非常严格!两边的维度必须一样,而且非组合和组合型之间无法直接复制
module chertanis;
// 3 2 1 0
logic [3:0][7:0] a = {16'haaaa,16'hbbbb};//4X8=32
wire [31:0] b=a;//32
wire c = a[3][7]; //1
wire [3:0] d = a[0][3:0]; //4
byte e;//8
assign e = a[3];//8,1slice
logic [15:0] f;//16
assign f = a[1:0];//16,2slices
initial begin
$display("a is %h",a);//# aaaabbbb
$display("b is %x",b);//#
$display("c is %x",c);//#
$display("d is %x",d);//#
$display("e is %h",e);//# aa
$display("f is %h",f);//# bbbb
end
endmodule
\;\\\;\\\;
过程块
initial & always
initial只能做测试,不能做综合,只能执行一次!always是描述硬件行为的。
system verilog中一部分是硬件的,一部分是软件的;
硬件
module
...
endmodule
interface
...
endinterface
软件
program
...
endprogram
class
...
endcalss
always只能在硬件部分,即module/interface当中使用!
always是并行的,由时钟或非时钟驱动的
\;\\\;
initial可以放在module、interface和program中使用
\;\\\;\\\;
function
module chertanis;
function int dual_num(int _a);
$display("input %0d",_a);
return 2*_a;
endfunction
initial begin
$display("%0d",dual_num(10));
end
endmodule
# input 10
# 20
module chertanis;
typedef struct {
bit [1:0] cmd;
bit [7:0] addr;
bit [31:0] data;
}trans_t;
//#动态函数 动态automatic,静态static
function automatic void clone(output trans_t _dst,input trans_t _src);
_dst=_src;
endfunction
initial begin
trans_t a,b;
a='{2'b10,8'b0010_0010,32'haaaa_bbbb};
$display("%b-%b-%h",a.cmd,a.addr,a.data);
clone(b,a);
b.cmd='h3;
$display("%b-%b-%h",b.cmd,b.addr,b.data);
end
endmodule
# 10-00100010-aaaabbbb
# 11-00100010-aaaabbbb
动态函数就是局部函数,静态函数不是全局函数,静态函数是第三类,放在静态区的函数,就算全局的module结束了,静态函数也不会销毁,会被多个进程和方法共享;
sv中的变量默认声明就是static的
module chertanis;
//#动态函数,局部函数
function automatic int counter_1(input _step);
int cnt = 0;
cnt += _step;
return cnt;
endfunction
//#静态函数
function static int counter_2(input _step);
static int cnt = 0;
cnt += _step;
return cnt;
endfunction
//#普通函数,就是静态函数
function int counter_3(input _step);
static int cnt = 0;
cnt += _step;
return cnt;
endfunction
initial begin
$display("1-%d",counter_1(1));
$display("1-%d",counter_1(1));
$display("2-%d",counter_2(1));
$display("2-%d",counter_2(1));
$display("3-%d",counter_3(1));
$display("3-%d",counter_3(1));
end
endmodule
# 1- 1
# 1- 1
# 2- 1
# 2- 2
# 3- 1
# 3- 2
变量声明 在 module , interface 和 program 内部,在 task , process 和 function 外部 也默认是静态的
- 在 module , interface 和 program 中定义的 task ,function 默认就是静态的!
如果 task ,process 和 function 定义成静态的,那么其中定义的变量也默认是静态的
\;\\\;\\\;
task
task能调用function,但是function不能调用task
不能使用return返回,只能用output,inout或ref的参数返回
task中可以加入耗时语句,function中不能
- @event
- wait event
- # delay
\;\\\;\\\;