文章目錄
對讀者的假設
已經掌握:
- 可程式化邏輯基礎
- Verilog HDL基礎
- 使用Verilog設計的Quartus II入門指南
- 使用Verilog設計的ModelSIm入門指南
內容1 概述
在Verilog的模組裡,有些運算式也許會出現很多次。為了不重複輸入這些代碼,我們可以把常用的這部分抽象為一個routine,模組內的function可以實現這一點。Verilog的函數有一個或多個的輸入參數,僅返回單值。在綜合期間,函數被展開,以映射為相應的硬體。因此,出於綜合的考慮,函數應該保持簡單,可以當作一些複雜運算式的縮減寫法。函數的基本寫法如下:
module . . .. . .// function defined within modulefunction [result_type] [func_id] ([input_arg]);begin [statement]endendfunction. . .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 declarationlocalparam N = log2(M); // number of bits in counterreg [N-1:0] r_reg;wire [N-1:0] r_next;// body// registeralways@(posedge clk, negedge rst_n) if(!rst_n) r_reg <= 0; else r_reg <= r_next; // next-state logicassign r_next = (r_reg == (M-1)) ? 0 : r_reg + 1'b1;//output logicassign q = r_reg;assign max_tick = (r_reg == (M-1)) ? 1'b1 : 1'b0;assign min_tick = (r_reg == 0) ? 1'b1 : 1'b0;// log2 constant functionfunction integer log2(input integer n); integer i;begin log2 = 1; for(i=0; 2**i<n; i = i + 1) log2 = i + 1;endendfunction endmodule
定義在模組內的函數log2(),用於求取局部變數N的值。由於在綜合之前的預先處理中,函數已執行計算;因此函數將不引用任何物理電路。
參考
1 Pong P. Chu.FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version.Wiley
另見
[與艾米一起學FPGA/SOPC].[邏輯實驗文檔連載計劃]