[文档].艾米电子 - 在综合中使用函数,Verilog
0赞
发表于 12/16/2010 12:40:18 PM
阅读(2022)
对读者的假设
已经掌握:
内容
1 概述
在Verilog的模块里,有些表达式也许会出现很多次。为了不重复输入这些代码,我们可以把常用的这部分抽象为一个routine,模块内的 function可以实现这一点。Verilog的函数有一个或多个的输入参数,仅返回单值。在综合期间,函数被展开,以映射为相应的硬件。因此,出于综 合的考虑,函数应该保持简单,可以当作一些复杂表达式的缩略写法。函数的基本写法如下:
module . . . . . . // function defined within module function [result_type] [func_id] ([input_arg]); begin [statement] end endfunction . . . endmodule
函数需要被定义在function和endfunction限定词内部。可选的[result_type]指定返回值得数据类型,常选用带范围的reg或 integer类型。[input_arg]被用来声明输入的参数,[func_id]被用来指定函数的名称。函数通过表达式来返回的结果,如
[func_id] = ... ;
2 范例
在二进制计数器那一节,我们讨论了模-m计数器。有两个参数:M,指定计数的范围为[0, M-1];N,指定M个数需要多少位宽来存储,其值为大于或等于log2(M)的整数。N的值不应该一个独立的参数,一个更好的做法定义一个局部常量,然 后在模块内部计算它的值。通过使用函数可以实现,修改后的代码如下:
module mod_m_bin_counter #(parameter M=10) // mod-M ( // global clock and asyn reset input clk, input rst_n, // counter interface output max_tick, output min_tick, output [N-1:0] q ); // signal declaration localparam N = log2(M); // number of bits in counter reg [N-1:0] r_reg; wire [N-1:0] r_next; // body // register always@(posedge clk, negedge rst_n) if(!rst_n) r_reg <= 0; else r_reg <= r_next; // next-state logic assign r_next = (r_reg == (M-1)) ? 0 : r_reg + 1'b1; //output logic assign q = r_reg; assign max_tick = (r_reg == (M-1)) ? 1'b1 : 1'b0; // log2 constant function function integer log2(input integer n); integer i; begin log2 = 1; for(i=0; 2**i
定义在模块内的函数log2(),用于求取局部变量N的值。由于在综合之前的预处理中,函数已执行计算;因此函数将不引用任何物理电路。
参考
1 Pong P. Chu.FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version.Wiley