Verilog中函数function的使用

函数的功能和任务的功能类似,但二者还存在很大的不同。

1.函数的定义

函数通过关键词 function 和 endfunction 定义,不允许输出端口声明(包括输出和双向端口) ,但可以有多个输入端口。函数定义的语法如下:

function [range] function_id; 
   input_declaration 
   other_declarations 
   procedural_statement 
endfunction

其中,

function 语句标志着函数定义结构的开始;

[range]参数指定函数返回值的类型或位宽,是一个可选项,若没有指定,默认缺省值为 1 比特的寄存器数据;

function_id 为所定义函数的名称,对函数的调用也是通过函数名完成的,并在函数结构体内部代表一个内部变量,函数调用的返回值就是通过函数名变量传递给调用语句;

input_declaration 用于对寒暑各个输入端口的位宽和类型进行说明,在函数定义中至少要有一个输入端口;

endfunction为函数结构体结束标志。下面给出一个函数定义实例。它的主要功能是判断输入的字符是否为数字(包含0~9,A~F,a~f);如果是,就输出数字;如果不是,就将最MSB置位;源码及注释为:

//***************************************************************************
// Tasks and Functions
//***************************************************************************

	// This function takes the lower 7 bits of a character and converts them
	// to a hex digit. It returns 5 bits - the upper bit is set if the character
	// is not a valid hex digit (i.e. is not 0-9,a-f, A-F), and the remaining
	// 4 bits are the digit
	function [4:0] to_val;
    	input [6:0] char;
	begin
    	if ((char >= 7'h30) && (char <= 7'h39)) // 0-9
    	begin
      		to_val[4]   = 1'b0;
			to_val[3:0] = char[3:0];
    	end 
        else if (((char >= 7'h41) && (char <= 7'h46)) || // A-F
			((char >= 7'h61) && (char <= 7'h66)) )  // a-f
		begin
    		to_val[4]   = 1'b0;
    		to_val[3:0] = char[3:0] + 4'h9; // gives 10 - 15
    	end 
        else begin
			to_val      = 5'b1_0000;
    	end
	end
	endfunction

关于这个function,有几个问题;

  1. 这段代码在电路上是如何实现的?是像描述那样,完全的组合电路吗?
  2. 电路的复杂程度,需要考虑单周期内的电路延迟吗?
  3. 能否综合?

function写法

function的标准写法如下:

function <返回值的类型或范围>(函数名);
    <端口说明语句>		// input XXX
    <变量类型说明语句>		// reg YYY
    ......
begin
    <语句>
    ......
    函数名 = ZZZ;			// 函数名就相当于输出变量;
end
endfunction

语法

函数的语法为:

1. 定义函数时至少要有一个输入参量;可以按照ANSI和module形式直接定义输入端口。例如:

function[63:0] alu (input[63:0] a, b, input [7:0] opcode);

2. 在函数的定义必须有一条赋值语句函数名具备相同名字的变量赋值

3. 在函数的定义中不能有任何的时间控制语句,即任何用#,@或wait来标识的语句。

4. 函数不能启动任务。

如果描述语句是可综合的,则必须所有分支均赋值,不予存在不赋值的情况,只能按照组合逻辑方式描述。

function与触发器电路结合

function本身表述的是组合电路,但可以赋值给某个触发器;

module func_test(
    input 			rst_n,
    input 			clk,
    input [6:0] 	func_i,
    output reg [4:0] 	func_o
    );

//***************************************************************************
// Tasks and Functions
//***************************************************************************

	// This function takes the lower 7 bits of a character and converts them
	// to a hex digit. It returns 5 bits - the upper bit is set if the character
	// is not a valid hex digit (i.e. is not 0-9,a-f, A-F), and the remaining
	// 4 bits are the digit
	function [4:0] to_val;
    	input [6:0] char;
	begin
    	if ((char >= 7'h30) && (char <= 7'h39)) // 0-9
    	begin
      		to_val[4]   = 1'b0;
			to_val[3:0] = char[3:0];
    	end else if (((char >= 7'h41) && (char <= 7'h46)) || // A-F
			((char >= 7'h61) && (char <= 7'h66)) )  // a-f
		begin
    		to_val[4]   = 1'b0;
    		to_val[3:0] = char[3:0] + 4'h9; // gives 10 - 15
    	end else begin
			to_val      = 5'b1_0000;
    	end
	end
	endfunction


wire [4:0] func_wire;

assign func_wire = to_val(func_i); //函数的调用

always @ (posedge clk or negedge rst_n ) begin
	if ( !rst_n ) begin
		func_o <= 5'b0;
	end else begin
		func_o <= func_wire;
	end
end

endmodule

电路中,function对应的功能为判断输入字符是否为数字;而always描述数据的存储过程。于是电路被清晰地划分为两部分:

1. 计算函数部分,此部分为纯组合电路实现;
2. D触发存储部分。
如果只是简单的上述组合逻辑,工作频率不高,是完全可以使用该语法的。但考虑到函数的复杂程度,比如许多超越函数,就需要进行分解;

函数调用中,有下列几点需要注意:
(1)函数调用可以在过程块中完成,也可以在assign 这样的连续赋值语句中出现。
(2)函数调用语句不能单独作为一条语句出现,只能作为赋值语句的右端操作数。

verilog 中function定义是里面能用always吗?
不能,

函数function的定义不能包含有任何的时间控制语句,即任何用#、@、或wait来标识的语句。

Verilog HDL中什么叫做过程块?
过程块有两种:initial块(只执行一次) 、always块(只要条件满足,就循环执行)
 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无牙大白鲨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值