Verilog HDL学习笔记四
编写一个4位的ALU,实现8种逻辑运算功能
在设计ALU的代码之前,首先应学会任务task和函数function,利用任务和函数可以把一个很大的程序模块分解成许多较小的任务和函数便于理解和调试。
task和function的相同点和不同点:
相同点:
- 任务和函数必须在module内调用
- 在任务和函数中不能声明wire,所有输入/输出都是局部寄存器
- 任务和函数只能使用行为级语句,但是不能包含always和initial块。
- 任务/函数执行完成后才返回结果。
例如,若任务/函数中有forever语句,则永远不会返回结果
不同点:
1.任务(task)
- 通常用于调试,或对硬件进行行为描述 可以包含时序控制(#延迟,@, wait)
- 可以有 input,output,和inout参数
- 可以调用其他任务或函数
2.函数(function)
- 通常用于计算,或描述组合逻辑 不能包含任何延迟;
- 函数仿真时间为0 只含有input参数并由函数名返回一个结果;
- 可以调用其他函数,但不能调用任务 ;
- 函数返回一个值,而任务没有返回值。
本设计代码将函数和任务结合在一起使用,以便更清楚地理解task和function的异同点。
oper | data |
---|---|
000 | a + b |
001 | a - b |
010 | a * b |
011 | a & b |
100 | a | b |
101 | ~a ,~b |
110 | a ^ b |
111 | a~^b |
设计代码:
module ALU_4bit(data,a,b,oper,EN);
input [3:0] a,b; //输入操作数
input [2:0] oper; //运算功能控制
input EN; //运算使能端,“1”允许运算
output reg[7:0] data; //输出
always @(*)
begin
if(!EN)
data=8'b0;
else
ALUtask(a,b,oper,data); //调用任务
end
task ALUtask; //ALU任务块
input [3:0] a,b;
input [2:0] oper;
output reg[7:0] data;
begin
case(oper)
3'b000:data = a + b;
3'b001:data = a - b;
3'b010:data=multi(a,b); //调用函数,实现a*b的运算
3'b011:data = a & b;
3'b100:data = a | b;
3'b101:data = {~a,~b};
3'b110:data = a ^ b;
3'b111:data = a ~^ b;
default:data={a,b};
endcase
end
endtask
//funtion multi
function [7:0]multi;
input [3:0] A,B;
reg [7:0] count;
integer i;
begin
count=0;
for(i=1;i<4;i=i+1)
begin
if(A[i])
count = count + (B << i-1);
end
multi=count; //返回值通过函数名返回
end
endfunction
endmodule
测试代码:
module ALU_4bit_tb;
reg[3:0]a,b;
reg[2:0]oper;
reg EN;
wire [7:0]data;
ALU_4bit unit(
.a(a),
.b(b),
.oper(oper),
.EN(EN),
.data(data)
);
initial
begin
a=4'b0000;b=4'b0000;EN=0;oper=3'b000;
#10 EN=1;
#10 a=4'b1000;b=4'b0111;
for(oper=3'b000;oper<3'b111;oper=oper+1)
#10;
end
endmodule