@[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) beginif(!reset)result <= 0;elseresult <= n * factorial(n)/((n * 2) + 1);// verilog在整数除法运算结果中不考虑余数
endfunction [31:0] factorial; // 函数定义,返回的是一个32位的数
input [3:0] operand; // 输入只有一个4位的操作数
reg [3:0] index; // 函数内部计数用中间变量beginfactorial = operand ? 1 : 0; // 先定义操作数为0时,函数的输出是0;不是0时,是1for(index = 2; index <= operand; index = index + 1)factorial = index * factorial; // 表示阶乘的算术迭代运算end
endfunctionendmodule
3,测试代码
// 测试模块
// `include "./tryfunct.v"
`timescale 1ns/100 ps
`define clk_cycle 50module 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; // 复位信号恢复高电平后才开始输入nfor(i = 0; i<=15; i=i+1) begin#200 n = i;end#100; $stop;
endalways #`clk_cycle clk = ~clk;try_funct u_try_funct(
.clk (clk),
.n (n),
.result (result),
.reset (reset)
);endmodule
4,输出波形
注意:
这是在Questasim下跑的,在Vivado下仿真也可以得到同样的结果。
但是,vivado下不可以将其生成 RTL netlist,如下图所示,