Verilog中的任务与函数【已改正源地址代码中的若干错误】
来源:互联网 发布:数据同步是什么意思 编辑:程序博客网 时间:2024/06/05 18:55
任务和函数有助于简化程序,有点类似与Fortran语言的subroutine和function。
任务和函数的共同点:
1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。
2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。
3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。
任务和函数的不同点:
函数任务函数能调用另一个函数,但是不能调用任务任务可以调用另一个任务,也可以调用函数函数总是在仿真时刻0开始任务可以在非零时刻开始执行函数一定不能包含任何延迟,事件或者时序控制声明语句任务可以包含延迟,事件或者时序控制声明语句函数至少要有一个输入变量,也可以有多个输入变量任务可以没有或者有多个输入,输出,输入输出变量函数只能返回一个值,函数不能有输出或者双向变量任务不返回任何值,或者返回多个输出或双向变量值由上述的特点决定:函数用于替代纯组合逻辑的verilog代码,而任务可以代替verilog的任何代码。
8.2任务
任务使用关键字task和endtask来进行声明,如果子程序满足下面任何一个条件,则必须使用任务而不能使用函数。
1.子程序中包含有延迟,时序或者事件控制结构
2.没有输出或者输出变量超过一个
3.没有输入变量
例:【该模块修改于源地址代码,已修正源地址中存在的若干错误,Quartus II 11.0下可全编译综合成功!】
module task_operation_fuzhi(
//输入输出端口声明
clk, clk2,
A, B,
AB_AND,AB_OR,AB_XOR,//组合输出1:AB_AND=A&B, AB_OR=A|B, AB_XOR=A^B
A2, B2,
AB_AND2,AB_OR2,AB_XOR2,//组合输出2:AB_AND2=A2&B2, AB_OR2=A2|B2, AB_XOR2=A2^B2
c, d, e, f,
ef_xor, cd_xor//同步输出1和2:ef_xor=e^f, cd_xor=c^d
);
input clk, clk2;
/**********↓↓↓↓↓↓↓↓↓↓以下是组合逻辑端口声明↓↓↓↓↓↓↓↓↓↓*************/
input [7:0] A, B;
output reg [7:0] AB_AND,AB_OR,AB_XOR;
input [7:0] A2, B2;
output reg [7:0] AB_AND2,AB_OR2,AB_XOR2;
/**********↓↓↓↓↓↓↓↓↓↓以下是时序逻辑端口声明↓↓↓↓↓↓↓↓↓↓*************/
input [3:0] c, d, e, f;
output reg [3:0] ef_xor, cd_xor;
parameter delay=10;
/**********↓↓↓↓↓↓↓↓↓↓以下是组合逻辑输出↓↓↓↓↓↓↓↓↓↓*************/
//////////// bitwise_oper【task】 ///////////////
always @(A or B)
begin
bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B);
//【RTL视图综合出仅供A、B输入及相应输出使用的 8个二输入与门、8个二输入或门、8个二输入异或门】
end
always @(A2 or B2)
begin
bitwise_oper(AB_AND2, AB_OR2, AB_XOR2, A2, B2);
//【RTL视图综合出仅供A2、B输入及相应输出使用的 8个二输入与门、8个二输入或门、8个二输入异或门】
end
//【将 task 定义为 automatic ,使该task变为可重入的task,
//这样该task才可被多个always块同时调用!】
//【 Quartus II 11.0 下直接写 task bitwise_xor; 而不加 automatic 声明,综合器也自动将其作为 可重入的,
//从而允许多处同时调用该task(实际上是把task这块组合逻辑电路复制多份,供多处使用)】
task automaticbitwise_oper;
//task的输出声明,【task内定义的输出必须是reg型,也可再加入 reg [7:0] ab_and,ab_or,ab_xor;这句】
output [7:0] ab_and,ab_or,ab_xor;
input [7:0] a,b;
begin
#delay ab_and=a&b;//#延时不可综合(或者说:综合时忽略延时!直接是:ab_and=a&b;)
ab_or=a|b;
ab_xor=a^b;
end
endtask
/**********↓↓↓↓↓↓↓↓↓↓以下是时序逻辑输出↓↓↓↓↓↓↓↓↓↓*************/
///////////// bitwise_xor 【task autumatic】 //////////////
always @(posedge clk)
bitwise_xor(ef_xor,e,f);
//【RTL视图综合出仅供e、f输入及相应输出使用的 4个二输入异或门,异或门输出的4位数据作为相应D触发器(clk驱动)的数据输入】
always @(posedge clk2)
bitwise_xor(cd_xor,c,d);
//【RTL视图综合出仅供c、d输入及相应输出使用的 4个二输入异或门,异或门输出的4位数据作为相应D触发器(clk2驱动)的数据输入】
//【将 task 定义为 automatic ,使该task变为可重入的task,
//这样该task才可被多个always块同时调用!】
//【 Quartus II 11.0 下直接写 task bitwise_xor; 而不加 automatic 声明,综合器也自动将其作为 可重入的,
//从而允许多处同时调用该task(实际上是把task这块组合逻辑电路复制多份,供多处使用)】
task automaticbitwise_xor;
output [3:0] ab_xor;
input [3:0] a,b;
begin
ab_xor=a^b;
end
endtask
endmodule
自动(可重入)任务:verilog任务中所有声明的变量地址空间都是静态分配的,因此如果在一个模块中多次调用任务时,可能会造成地址空间的冲突,为了避免这个问题,verilog通过在task关键字后面添加automatic使任务称为可重入的,这时在调用任务时,会自动给任务声明变量分配动态地址空间,这样有效避免了地址空间的冲突。
8.3 函数
函数使用关键字function和endfunction定义,对于子程序,如果满足下述所有条件则可以用函数来完成:
1.在子程序中不含有延迟时序或者控制结构
2.子程序只有一个返回值
3.至少有一个输入变量
4.没有输出或者双向变量
5.不含有非阻塞赋值语句
例:
module parity;
reg [31:0] addr;
reg parity;
always @(addr)
begin
end
function calc_parity;
input [31:0] addr;
begin
calc_parity=^addr;
end
endfunction
endmodule
跟任务调用一样,在模块中如果调用多次函数,也会碰到地址冲突的问题,因此也引入automatic关键字来对函数可重用性声明。没有进行可重用性声明的函数不可以多次或者递归调用,进行了可重用性声明的函数可以递归调用。
常量函数和带符号函数(函数声明时加signed关键字说明)
module ram;
parameter RAM_DEPTH=256;
input [clogb2(RAM_DEPTH)-1:0] addr;//clogb2函数返回值为8
function integer clogb2(input integer depth);
begin
end
endfunction
endmodule
练习:用两种不同的方法设计一个功能相同的模块,完成4个8位2进制输入数据的冒泡排序。第一种,用纯组合逻辑实现;第二种,假设8位数据按照时钟节拍串行输入,要求时钟触发任务的执行,每个时钟周期完成一次数据交换的操作。
//----------------- 第一种 ------------------
module sort4(ra,rb,rc,rd,a,b,c,d);
output[7:0] ra,rb,rc,rd;
input[7:0] a,b,c,d;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (a or b or c or d)
task change;
inout[7:0] x,y;
reg[7:0] tmp;
endtask
endmodule
//----------------- 第二种 ------------------
module sort4(clk,reset,ra,rb,rc,rd,a);
output[7:0] ra,rb,rc,rd;
input[7:0] a;
input clk,reset;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (posedge clk)
always @ (posedge clk)
task change;
inout[7:0] x,y;
reg[7:0] tmp;
endtask
endmodule
- Verilog中的任务与函数【已改正源地址代码中的若干错误】
- Verilog中的函数和任务
- CC2530中的源地址匹配
- Verilog中的关于文件操作的函数和任务
- Verilog中的函数
- verilog代码中的"parameter" "#" "localparam"
- Verilog中的$display和$write任务
- Verilog中函数与任务比较
- verilog 中任务与函数的区别
- verilog中的向量与数组
- 【已解决】onCreateViewHolder中的代码错误,导致程序崩溃
- 一个错误与改正 hibernate
- Verilog基础知识10(verilog中的综合与不可综合 )
- 关于strcpy中的目标/源地址重叠问题
- 目的地址和ARP地址应答中的源地址
- Verilog中的wire与reg类型
- verilog中的function用法与例子
- verilog中的function用法与例子
- word插入向上向下取整符号
- OpenWRT in the role of upstream
- Java中 部分字符类型用法
- 关于OOM问题(提高系统分配内存)
- Linux内核MTD子系统六之分区介绍
- Verilog中的任务与函数【已改正源地址代码中的若干错误】
- android每日面试题1
- Oracle数据库中的锁机制
- LeetCode Merge k Sorted Lists 解题报告
- android与服务器通讯方式
- linux下script命令记录终端会话
- 宏定义的黑魔法 - 宏菜鸟起飞手册
- 深入剖析Android音频之AudioSystem
- 问题及代码