(原創)defparam的應用(Verilog,CPLD/FPGA)


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參,使它們不相同,以便在后邊的文件生成測試。

image FIG2.1 頂層block塊

    編譯通過以后,用RTL視圖看看計算機的連線是否和預期的一樣。

image FIG2.2 綜合后的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM