function—— Verilog的函数_verilog function_ShareWow丶的博客-程序员秘密

技术标签: # Verilog HDL语言及设计  FPGA函数  FPGA  function  verilog  

function —— Verilog的函数

在程序中经常看到一个function,之前对其不太了解,正好趁着这个例子来看一下verilog中的函数功能——function。

举个例子

先以如下function为例:

它的主要功能是判断输入的字符是否为数字(包含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. 能否综合?

带着以上几个问题,开始拨开云雾,寻找答案;

开始寻找

此处省略寻找的过程(如何善用搜索引擎);

通过网上寻找,最后在《通信IC设计》一书中找到了合适的答案,刚好可以完美解释上面的几个问题;

接下来就进入解答环节:

function写法

function的标准写法如下:

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

语法

函数的语法为:

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

    function[63:0] alu (input[63:0] a, b, input [7:0] opcode);
    
  • 在函数的定义中必须有一条赋值语句给函数名具备相同名字的变量赋值;

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

  • 函数不能启动任务。

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

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触发存储部分。

如果只是简单的上述组合逻辑,工作频率不高,是完全可以使用该语法的。

但考虑到函数的复杂程度,比如许多超越函数,就需要进行分解;

时序模型

先前的问题2中,就是关于这方面的思考,既然只有组合逻辑,就肯定要涉及到时序的问题;

这一部分内容,在通信IC设计中有详细的介绍。

电路负载模型与时延关系

在这里插入图片描述

因此,如果较为复杂的函数功能,就会出现时序无法满足的情况;

此时,可以通过如下的方法进行解决;

基于算法视角的时序优化

函数f(x)过大,就会需要进行函数拆解,从而使单个函数负载和掩饰控制在一定的范围内。

在这里插入图片描述

  1. 累加拆解(第一种拆解)
  2. 累乘拆解(第二种拆解)
  3. 函数嵌套模式拆解(第三种拆解)

函数与通用描述的转换方法

函数其本身性质为组合逻辑,那么也一定可以与通用的描述进行转换;

在这里插入图片描述

函数其实是一种抽象形式描述,是一种需要实例对象才能功能生效的描述。如果将函数的定义替换为always @ ( * ) ,然后定义必要的变量,就可以直接将其转化为实际的组合电路。

因此要讲函数转化为实际电路描述,可以采用[email protected]直接例化的方法实现。

在这里插入图片描述

函数小结

站在Verilog综合器的角度,描述的任何一个组合电路块,或者组合always语句,以及所有赋值给D触发器之前的逻辑,都将抽象为多值函数:即多个输入与输出的组合。

前面的各种拆解方法,其目的都是为了优化时序,并便于让综合软件更加快速、更灵活地实现HDL到电路网表的转换。

原理图及仿真

Schematic

看一下Schematic,能明显看出是一堆组合逻辑的搭配:

在这里插入图片描述

vivado工程

vivado工程仿真:

在这里插入图片描述

判定0\~9

在这里插入图片描述

判定A\~F

在这里插入图片描述

判定a\~f

而且可以看出function本身耗时取决于函数功能的复杂程度;

工程文件

vivado 工程文件下载 ,设定的0积分,如果变动了,可以联系我修改;

After

That’s all.

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_31206523/article/details/106505878

智能推荐

【单片机笔记】keil c51编译环境不能跳转函数的解决办法_沉默的小宇宙的博客-程序员秘密

keil c51 不能使用:Go to Definition of....的解决方法      最近使用keil c51 开发usb固件,当向vc一样使用Go to Definition of....时,出现警告对话框:                               no browse information available in'工程目录'

求一个三位数,该三位数等于其每一位数字的阶乘之和。即 abc = a! + b! +c!_三位数等于每位数字的阶乘之和_Zhoujy1996的博客-程序员秘密

解题思路: 首先此题的程序主题为如何将一个三位数的每个数字拆分开,首先想到的是除以100得到百位数,除以10再减去百位数的十倍得到十位数。然而这样编出的程序过于繁琐,故想到了使用更简洁的语句执行。十位由三位数除10再对10取余数得到十位数;个位数直接对10取余数,这样更加简洁清晰。难点 本题中要对 a , b , c ,进行阶乘,如果将阶乘的语句直接编写,程序将会变得冗长复杂,并且

生化环材四大天坑劝退指南_布客飞龙的博客-程序员秘密

作者:弗兰克扬十几年前我还在玩论坛的时候,我们作为有管理权限的小版主都知道,一个优秀的经验交流社区最重要的一个帖子就是FAQ,这个帖子被置顶放在一个版面的最上面是一种无声的宣告,新来者若想在本版进行深入有效有趣的交流,请首先进来学习FAQ,不要问重复的问题,不要做无脑伸手党。但是这些年我渐渐发现,许多网站都消失了FAQ这种东西,大家像月经一样问着每月都有人问,每年都有人问的问题,然后重复着同...

红米Note3刷机教程(升级安卓9)_android bootloader interface_压码路的博客-程序员秘密

想用手头闲置的红米note3做开发机,但是官方的miui的安卓版本最新的只到6,想要用安卓6以上的只能刷非官方的rom,接下里就开始折腾。

Python学习笔记5---最最最重要的正则表达式_python的正则表达式重要吗_一川晚照人闲立的博客-程序员秘密

正则表达式是PYTHON最为重要的一个环节,因为掌握了正则表达式,相当于掌握了筛选数据的方法,在数据量特别大的情况下,正则表达式根据是否和表达式匹配的方式筛选掉大部分的数据。基础的正则表达式的表示是一个范例,把筛选的标准写成一个正则表达式,例如我想筛选所有整数,把非整数的都筛选掉,就用’\d’或0-9来匹配,同样’\w’匹配字母或数字,’a-zA-Z’匹配所有字母,’\s’匹配空格字符,’

谁是2020年最强Python库?年度Top10出炉_QbitAl的博客-程序员秘密

蕾师师 发自 凹非寺量子位 报道 | 公众号 QbitAI2020年已经过去了,国外的一家专门提供Python服务的网站Troy Labs,盘点出了2020年发布的Python库Top...

随便推点

tampermonkey油猴+chrome,在浏览器中运行自己写的js脚本_js脚本怎么在tapermonkry_河海哥yyds的博客-程序员秘密

前言最近再看犀牛书《JavaScript权威指南》,当中的小例子我发现自己没法调试它zzz,于是就想到把它嵌入到浏览器里面,主要是使用的油猴再加上自己的js脚本环境tampermonkey v4.6 油猴 ubuntu 18 chrome油猴添加脚本 点击这边的添加脚本,然后在界面的脚本页面中输入自己的脚本代码,就可以了。测试代码// ==UserSc...

完整版:献给初学者的Java学习方法_weixin_34318326的博客-程序员秘密

2019独角兽企业重金招聘Python工程师标准&gt;&gt;&gt; ...

MVP 设计模式理解,实战理解MVP_夏至的稻穗的博客-程序员秘密

作者: 夏至 欢迎转载,也请保留这份申明,谢谢。1、什么是MVPMVP,全称 Model-View-Presenter。它是从 MVC中演变过来的,它的基本思想是相通的;在MVP中,View更加专注于处理数据的可视化以及用户交互,让Model专注于数据的处理,而Presenter则,提供 View 与 Model 之间数据的纽带,用于交互与数据传输;如下面这张图: 可以看到,在View 与 Mod

Vue用router.push(传参)跳转页面,参数改变,跳转页面数据不自动刷新需手动刷新的解决办法_千里独行女侠的博客-程序员秘密

项目场景:在vue前端工程里,存在通过点击连接传参,到另一个页面,并根据参数进行刷新页面问题描述:vue跳转时通过使用router进行跳转,跳转后参数传到了,但是页面还是上一个参数的数据,页面的数据并没有更新,点击刷新后,数据才是最新的参数传进来的总页面,点击调转方法:gotoGpProcess(row) { let sync_id = row.sync_id; sessionStorage.setItem("gpsync_id", sync_id);

Pyqt5系列(五)-基本界面组件之inputDialog_祝丰年的博客-程序员秘密

QInputDialog类提供了一种简单方面的对话框来获得用户的单个输入信息,可以是一个字符串,一个Int类型数据,一个double类型数据或是一个下拉列表框的条目。 对应的Dialog其中包括一个提示标签,一个输入控件(若是调用字符串输入框,则为一个QLineEdit,若是调用Int类型或double类型,则为一个QSpinBox,若是调用列表条目输入框,则为一个QComboBox),还包括

access百科 pc_PC Access SMART_房东家的狗的博客-程序员秘密

PC Access SMART是用于S7-200 SMART的OPC软件。已实现了它自带的客户机测试功能,和组态王与S7-200 SMART CPU的OPC通信。感觉PC Access SMART 有以下优点:1)PC Access V1.0 SP6不能用于Win7,PC Access SMART可用于32位和64位的Win7。PC Access SMART和PC Access可以安装在同一操作系...

推荐文章

热门文章

相关标签