@[TOC](使用Questasim来用verilog使用function函数
- 1,verilog中使用函数function
- 2,RTL代码
- 3,测试代码
- 4,输出波形
1,verilog中使用函数function
目的:
(1)了解函数的定义和在模块设计中的使用;
(2)了解函数的可综合性问题;
(3)了解许多综合器不能综合复杂的算术运算;
下例是函数调用的一个简单示范。
采用同步时钟触发运算的执行,每个clk时钟周期都会执行一次运算,并且在测试模块中,通过调用系统任务$display及在时钟的下降沿显示每次计算的结果。
2,RTL代码
//
module try_funct(
input clk,
input reset,
input [3:0] n,
output reg [31:0] result
);
always@(posedge clk) begin
if(!reset)
result <= 0;
else
result <= n * factorial(n)/((n * 2) + 1);
// verilog在整数除法运算结果中不考虑余数
end
function [31:0] factorial; // 函数定义,返回的是一个32位的数
input [3:0] operand; // 输入只有一个4位的操作数
reg [3:0] index; // 函数内部计数用中间变量
begin
factorial = operand ? 1 : 0; // 先定义操作数为0时,函数的输出是0;不是0时,是1
for(index = 2; index <= operand; index = index + 1)
factorial = index * factorial; // 表示阶乘的算术迭代运算
end
endfunction
endmodule
3,测试代码
// 测试模块
// `include "./tryfunct.v"
`timescale 1ns/100 ps
`define clk_cycle 50
module tryfunct_top;
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; // 复位信号恢复高电平后才开始输入n
for(i = 0; i<=15; i=i+1) begin
#200 n = i;
end
#100; $stop;
end
always #`clk_cycle clk = ~clk;
try_funct u_try_funct(
.clk (clk),
.n (n),
.result (result),
.reset (reset)
);
endmodule
4,输出波形
注意:
这是在Questasim下跑的,在Vivado下仿真也可以得到同样的结果。
但是,vivado下不可以将其生成 RTL netlist,如下图所示,