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