一、实验目的
- 了解函数的定义和在模块设计中的使用;
- 了解函数的可综合性问题;
- 了解许多综合器不能综合复杂的算术运算。
二、实验原理
与一般的程序设计语言一样,Veirlog HDL也可使用函数以适应对不同变量采取同一运算的操作。Veirlog HDL函数在综合时被理解成具有独立运算功能的电路,每调用一次函数相当于改变这部分电路的输人以得到相应的计算结果。
下例是函数调用的一个简单示范。它采用同步时钟触发运算的执行,每个clk时钟周期都会执行一次运算,并且在测试模块中,通过调用系统任务$display及在时钟的下降沿显示每次计算的结果。
模块源代码:
//-------------- tryfunct.v --------------
module tryfunct(clk,n,result,reset);
output [31:0] result;
input [3:0] n;
input reset,clk;
reg [31:0] result;
always@(posedge clk)
begin
if(!reset)
result<=0;
else
begin
result<=n*factorial(n)/((n*2)+1);
end
end
function [31:0] factorial;
input [3:0] operand;
reg [3:0] index;
begin
factorial=operand?1:0;
for(index=2;index<=operand;index=index+1)
factorial=index*factorial;
end
endfunction
endmodule
测试模块源代码:
//-------------- tryfunctTop.v --------------
`include "./tryfunct.v"
`timescale 1ns/100ps
`define clk_cycle 50
module tryfunctTop;
reg [3:0] n,i;
reg reset,clk;
wire [31:0] result;
initial
begin
clk=0;
n=0;
reset=1;
#100 reset=0;
#100 reset=1;
for(i=0;i<=15;i=i+1)
begin
#200 n=i;
end
#100 $stop;
end
always #`clk_cycle clk=~clk;
tryfunct m(.clk(clk),.n(n),.result(result),.reset(reset));
endmodule
(1)实验内容:
设计一个带控制端的逻辑运算电路,分别完成正整数的平方、立方和最大数为5的阶乘的运算,要求可综合。编写测试模块,并给出各种层次的仿真波形,比较它们的不同。
(2)实验代码:
模块源代码:
//-------------- logicoperation.v --------------
module logicoperation(clk,n,result,reset,sl);
output [6:0] result;
input [2:0] n;
input reset,clk;
input [1:0] sl;
reg [6:0] result;
always@(posedge clk)
begin
if(!reset)
result<=0;
else
begin
case(sl)
2'd0: result<=square(n);
2'd1: result<=cubic(n);
2'd2: result<=factorial(n);
endcase
end
end
function [6:0] square;
input [2:0] operand;
begin
square=operand*operand;
end
endfunction
function [6:0] cubic;
input [2:0] operand;
begin
cubic=operand*operand*operand;
end
endfunction
function [6:0] factorial;
input [2:0] operand;
reg [2:0] index;
begin
factorial = 1;
for(index = 2; index <= operand; index =index + 1)
factorial = index * factorial;
end
endfunction
endmodule
测试模块源代码:
//-------------- logicoperationTop.v --------------
`include "./logicoperation.v"
`timescale 1ns/100ps
`define clk_cycle 50
module logicoperationTop;
reg [2:0] n;
reg reset,clk;
reg [1:0] sl;
wire [6:0] result;
parameter times=20;
initial
begin
n=0;
reset=1;
clk=0;
sl=0;
#100 reset=0;
#100 reset=1;
repeat(times)
begin
#50 sl={$random}%3;
#50 n={$random}%6;
end
#1000 $stop;
end
always #`clk_cycle clk=~clk;
logicoperation m(.clk(clk),.n(n),.result(result),.reset(reset),.sl(sl));
endmodule
四、实验结果