Verilog设计技巧:function、generate的用法

function

函数,我们可以按照C语言的函数的那样进行理解。软件的函数,我们在使用或设计的时候,函数名、输入和返回值是我们最为关注的。而对应硬件,函数名、输入、返回值,只不过一个是软件实现,一个是硬件电路。
在这里插入图片描述
因此Verilog的函数的相关思想与软件非常相似,

  • 特点:
    1)不能有always块,也就是不考虑延时,一般都是使用for、case、if-else完成函数功能。
    2)至少有一个输入变量。
    3)只有一个返回值,且没有输出。
    5)函数可以调用其他函数,但是不能调用任务。
  • 用途:可用于仿真代码,也可用于实现大型可重配置的组合逻辑。
    总而言之,在进行function编写时,把内部电路按照组合逻辑进行设计就好。不能进行时序逻辑设计。
    如下为Verilog的函数一般编写格式。
    for和if的使用
wire [range-1:0] data = function_id(data_in,...);
function [range-1:0]     function_id ;   //定义函数名function_id   ,同时也是返回值的存储器位宽为range
	input [data_width-1:0] data_in;  //输入定义
	input ...;
	integer i;
	for(i=0;i<range;i++)//for格式
	begin
		if(data_in[i])  //if格式
		begin
			function_id[i] = data_in ... ; //内部数据处理
			... ;
		end
		else
		begin
			function_id[i] = data_in ... ; //内部数据处理
			... ;
		end
	end
	
endfunction

case的用法

function [range-1:0]     function_id ;   //定义函数名function_id   ,同时也是返回值的存储器位宽为range
	input [data_width-1:0] data_in;  //输入定义
	input ...;
	begin
		case(data_in)
			0:function_id = ...;
			1:function_id = ...;
			2:function_id = ...;
			default:function_id = ...;
			endcase
	end
endfunction

Verilog的函数也可以实现递归调用,不过需要添加一个前缀
代码来自菜鸟教程

function automatic   integer  factorial ;
    input integer     data ;
    integer           i ;
    begin
        factorial = (data>=2)? data * factorial(data-1) : 1 ;
    end
endfunction

generate

当相同功能的电路较多时,我们就可以使用generate进行设计,可以减少我们的重复性设计。
其主要可以对module、reg、assign、always、task等语句或者模块进行复制。
而generate主要有for、if和case三种用法,通常我们一般都是用generate的for功能,来减少我们的代码量,而if和case则类似于条件编译,所以我觉得基本用不到哈哈。

generate-for

在generate-for的设计中,可以进行时序逻辑设计也可以进行组合逻辑设计。如下为一般的写法

genvar	i;								//利用genvar声明for循环计数器变量
generate for(i=0;i<4;i=i+1)		//复制模块
	begin : generate_name					//该generate块的名字
		always@(posedge clk)			//时序逻辑
		begin
			reg1[i] <= reg0[i];
		end		
		assign net1[i] = net0[i];   //组合逻辑
	end
endgenerate

generate-if和case

generate-if和case的功能类似于条件编译,即根据参数定义,有选择的生成对应的generate中的电路
当参数条件少的时候,我们可以用if

localparam    def = 0;	            //参数定义
generate 
	if(def == 0)		
		assign a = 0;  //将a赋值为0
	else
		assign a = 1;  //将a赋值为1
endgenerate

当条件多的时候,我们可以用case

localparam    def = 0;	            //参数定义
generate 
	case(def)		
		0:assign a = 0;  //将a赋值为0
		1:assign a = 1;  //将a赋值为1
		2:assign a = 2;  //将a赋值为2
	default:assign a= 3;
	endcase
endgenerate
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值