自己做电影下载网站/东莞seo优化排名
A.5 赋值语句、结构语句和程序块
阻塞和非阻塞赋值语句
- 阻塞赋值
前面语句执行完,才可执行下一条语句。
always @(posedge clk) beginb = a;c = b;
end
上面代码综合后产生1个触发器,在时钟clk上升沿到来时进行触发,此时会先将输入端a的值赋给输出端b,然后等待赋值完成后,将输出端b的新值再赋给c,最终相当于将a的值同时赋给了b和c。
- 非阻塞赋值
语句同时执行。
always @( posedge clk ) beginb <= a;c <= b;
end
上面代码综合后产生两个触发器,在时钟clk上升沿到来时进行触发,此时输入端a的值会赋给输出端b,从而使b的旧值更新为新值(b的新值为a),与此同时输出端b的旧值会赋给输出端c。
程序块语句
- 顺序执行
begin…end中的所有语句按照顺序依次从上到下进行执行。
begin:块名语句1;语句2;...语句n;
end
- 并行执行
fork:块名语句1;语句2;...语句n;
join
fork…join中的所有语句并行地同时执行。
- 混合执行
还可以混合使用,fork…join中的两个begin…end语句并行执行,而begin…end中的所有语句顺序执行。
fork:块名begin:块名语句1;语句2;...语句n;endbegin:块名语句1;语句2;...语句n;end
join
注意可以给程序块通过:添加程序块名,从而可以方便调用disable来终止程序块的执行。
结构语句
- initial 语句
在仿真开始时刻执行,且只执行一次,通常配合begin…end程序块使用。
即在仿真开始时顺序执行一次这里的begin…end中的语句。
通常用于控制仿真过程,做初始化配置和执行仿真。
initial begin语句1;语句2;...语句n;
end
- always 语句
在仿真开始时刻执行,但会不断地重复执行,直到仿真过程结束。
通常用于实现逻辑运算。
//实现时钟的简单翻转
always #half_period clk = ~clk;//由两个沿触发的always块,时序逻辑电路
always @(posedge clock or posedge reset) begin ...
end//由多个电平触发的always块,组合逻辑电路
always @( a or b or c ) begin...
end
注意以下几点:
(1)当用always块来描述组合逻辑时,应当使用阻塞赋值。
(2)当用always块来描述时序逻辑时,应当使用非阻塞赋值。
(3)在同一个always模块中,最好不要混合使用阻塞赋值和非阻塞赋值,对同一变量既进行阻塞赋值,又进行非阻塞赋值,在综合时会出错。所以always中要么全部使用非阻塞赋值,要么把阻塞赋值和非阻塞赋值分在不同的always中书写。
至于什么是组合逻辑,什么是时序逻辑,后面再讲,这里先了解一下。
任务和函数语句
- task任务
//语法格式
task <任务名>;<端口说明语句><变量类型说明语句><语句1><语句2>.....<语句n>
endtask//示例task get_random_number;input mode;output int random_number;if(mode)beginrandom_number = $urandom_range(10,0);endelse beginrandom_number = $urandom_range(20,10);endendtask//调用
get_random_number(1,random_number);
get_random_number(0,random_number);
- function函数
//语法格式
function <返回值类型> (函数名);<端口说明语句><变量类型说明语句><语句1><语句2>.....<语句n>
endfunction//示例function int get_random_number1;input mode;if(mode)beginget_random_number1 = $urandom_range(10,0);endelse beginget_random_number1 = $urandom_range(20,10);endendfunction//调用
get_random_number1(0);
get_random_number1(1);function int get_random_number2;input mode;if(mode)beginreturn $urandom_range(10,0);endelse beginreturn $urandom_range(20,10);endendfunction//调用
get_random_number2(0);
get_random_number2(1);function void get_random_number3;input mode;output int random_number;if(mode)beginrandom_number = $urandom_range(10,0);endelse beginrandom_number = $urandom_range(20,10);endendfunction//调用
get_random_number3(0,random_number);
get_random_number3(1,random_number);
注意以下几点:
(1)函数是不消耗仿真时间的,而任务可以消耗仿真时间。
(2)函数既可以通过返回值的方式输出,也可以通过定义output类型端口来输出,而任务只能通过output类型端口来输出。
(3)函数如果有返回值则必须声明返回值的数据类型,如果没有返回值,则需要声明为void类型。
(4)任务里可以调用函数,而函数里最好不要调用任务(否则仿真时会报warning)
公众号:程序员Marshall