1.Abstract
在同一個模塊被多次例化的時候,改變參數構建不同的硬件實體是一個很好的選擇。特別是今天幫一個朋友調試一個比較復雜的邏輯,深有體會。這個也是一個小技巧,回來也查了許多資料,強化了一下這方面的知識。前幾天也做了一個這樣的例子,可以拿過來作為驗證一下。
2.Content
2.1 語法說明
defparam 的語法說明如下:
defparam ParameterName = Constant Expression,
ParameterName = ConstantExpression;
使用范圍:module < Valid Place > endmodule
綜合問題:一般情況下是不可綜合的。
2.2 使用說明
跟其他的賦值語句是一樣的,這里值得說明一下的是 ParameterName 這個表達式。直接在本模塊中的參數,直接寫名字就可以了,前提是這個名字已經存在。例如:最開始想用12小時制來表示 paramter TIME = 12; 某個情況下,需要改成24小時制,可以用 defparam TIME = 24; 實現。改變已經例化后的模塊中的參數,就得需要明確寫出了,用英文小數點(.)表示層次邏輯關系。比如,在M0子模塊中有一個TIME參數,預先在設計之前是使用的是12小時制,現在想在主模塊中將它更改至24小時制,就可以用 defparam M0.TIME = 24; 就可以了。最后值得注明的一點是 默認是使用的無符號整數型,某些場合需要對它進行位寬限制,以避免因位寬導致的問題(不過,這樣的問題在編譯的時候,編譯器會友善的給出警告提示)。
2.3 實際驗證
一種較好的測試方法就是先用原理圖編輯好文件,然后讓系統自動地將原理圖文件轉換成為Verilog文件,通過對比最后的生成結果來對比就很容易理解了。
拿以前的那個超級流水燈作為測試(http://www.cnblogs.com/hechengfei/p/4115087.html)。將所有的文件都生成各自對應的符號文件,然后再在頂層block塊將各個模塊手工的連接起來,修改每個子呼吸燈的下降時間DN_TIME參,使它們不相同,以便在后邊的文件生成測試。
編譯通過以后,用RTL視圖看看計算機的連線是否和預期的一樣。
可以知道,這個是和預期的相同,只是最后的輸出引腳不是總線方式罷了,這個原因是因為在原理圖中沒有將它作為一個總線看待,功能是和原來的一樣。當然,為了更加可靠一些,我把最后的文件燒錄在FPGA板中,觀察實際的現象。
最后就是將這個原理圖文件轉換成Verilog文件。看看軟件將這些參數是怎樣與模塊設置的參數一一對應的。
// Copyright (C) 1991-2009 Altera Corporation // Your use of Altera Corporation's design tools, logic functions // and other software and tools, and its AMPP partner logic // functions, and any output files from any of the foregoing // (including device programming or simulation files), and any // associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License // Subscription Agreement, Altera MegaCore Function License // Agreement, or other applicable license agreement, including, // without limitation, that your use is for the sole purpose of // programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the // applicable agreement for further details. // PROGRAM "Quartus II" // VERSION "Version 9.1 Build 222 10/21/2009 SJ Full Version" // CREATED "Sun Nov 23 15:07:47 2014" module breath( CLK, RST, LED3, LED2, LED1, LED0 ); input CLK; input RST; output LED3; output LED2; output LED1; output LED0; wire SYNTHESIZED_WIRE_0; wire SYNTHESIZED_WIRE_1; wire SYNTHESIZED_WIRE_2; wire SYNTHESIZED_WIRE_3; wire SYNTHESIZED_WIRE_4; wire SYNTHESIZED_WIRE_5; wire SYNTHESIZED_WIRE_6; wire SYNTHESIZED_WIRE_7; breath_led b2v_inst( .CLK(CLK), .RST(SYNTHESIZED_WIRE_0), .LED(LED0), .S_END(SYNTHESIZED_WIRE_3)); defparam b2v_inst.CLK_50M = 50000000; defparam b2v_inst.DN_TIME = 1; defparam b2v_inst.H2_TIME = 1; defparam b2v_inst.HD_TIME = 1; defparam b2v_inst.S0 = 2'b00; defparam b2v_inst.S1 = 2'b01; defparam b2v_inst.S2 = 2'b10; defparam b2v_inst.S3 = 2'b11; defparam b2v_inst.UP_TIME = 1; breath_led b2v_inst1( .CLK(CLK), .RST(SYNTHESIZED_WIRE_1), .LED(LED1), .S_END(SYNTHESIZED_WIRE_4)); defparam b2v_inst1.CLK_50M = 50000000; defparam b2v_inst1.DN_TIME = 2; defparam b2v_inst1.H2_TIME = 1; defparam b2v_inst1.HD_TIME = 1; defparam b2v_inst1.S0 = 2'b00; defparam b2v_inst1.S1 = 2'b01; defparam b2v_inst1.S2 = 2'b10; defparam b2v_inst1.S3 = 2'b11; defparam b2v_inst1.UP_TIME = 1; breath_led b2v_inst2( .CLK(CLK), .RST(SYNTHESIZED_WIRE_2), .LED(LED2), .S_END(SYNTHESIZED_WIRE_5)); defparam b2v_inst2.CLK_50M = 50000000; defparam b2v_inst2.DN_TIME = 3; defparam b2v_inst2.H2_TIME = 1; defparam b2v_inst2.HD_TIME = 1; defparam b2v_inst2.S0 = 2'b00; defparam b2v_inst2.S1 = 2'b01; defparam b2v_inst2.S2 = 2'b10; defparam b2v_inst2.S3 = 2'b11; defparam b2v_inst2.UP_TIME = 1; breath_state b2v_inst3( .S_END0(SYNTHESIZED_WIRE_3), .S_END1(SYNTHESIZED_WIRE_4), .S_END2(SYNTHESIZED_WIRE_5), .S_END3(SYNTHESIZED_WIRE_6), .CLK(CLK), .RST(RST), .RST_LED0(SYNTHESIZED_WIRE_0), .RST_LED1(SYNTHESIZED_WIRE_1), .RST_LED2(SYNTHESIZED_WIRE_2), .RST_LED3(SYNTHESIZED_WIRE_7)); defparam b2v_inst3.S0 = 3'b000; defparam b2v_inst3.S1 = 3'b001; defparam b2v_inst3.S2 = 3'b010; defparam b2v_inst3.S3 = 3'b011; defparam b2v_inst3.S4 = 3'b100; defparam b2v_inst3.S5 = 3'b101; defparam b2v_inst3.S6 = 3'b110; defparam b2v_inst3.S7 = 3'b111; breath_led b2v_inst4( .CLK(CLK), .RST(SYNTHESIZED_WIRE_7), .LED(LED3), .S_END(SYNTHESIZED_WIRE_6)); defparam b2v_inst4.CLK_50M = 50000000; defparam b2v_inst4.DN_TIME = 4; defparam b2v_inst4.H2_TIME = 1; defparam b2v_inst4.HD_TIME = 1; defparam b2v_inst4.S0 = 2'b00; defparam b2v_inst4.S1 = 2'b01; defparam b2v_inst4.S2 = 2'b10; defparam b2v_inst4.S3 = 2'b11; defparam b2v_inst4.UP_TIME = 1; endmodule
可以看出,除去defparam的語句部分,其他的就跟原來的差不多了。可以得出的結論是原理圖的參數設置就是通過defparam語句對應的。
這樣,在以后遇到需要改變參數的文件,就可以考慮使用 defparam 了。補充一點的就是為了使邏輯更加的通用,將電路的一些參數進行仔細分析,然后將那些可變的參數提取出來,用 paramter 的方式聲明一下,然后使用。
3.Conclusion
defparam 對一些需要電路相同,而參數不盡相同的邏輯設計很有幫助,將它作為一個小知識點掌握和累積起來。
4.Reference
[1] Verilog 數字系統設計教程(第二版) 夏宇聞
5.Platform
1). Quartus II Version 9.1 Build 222