編寫可綜合的FPGA代碼
在接觸Verilog 語(yǔ)法參考手冊(cè)的時(shí)候,我們發(fā)現(xiàn)其提供了一組非常豐富的功能來(lái)描述硬件。所以大家往往會(huì)疑惑那些Verilog語(yǔ)句是可綜合的,那些是只能用于寫Testbench的,其實(shí),參考手冊(cè)中只有一小部分語(yǔ)句是可綜合的,但是這一小部分可綜合的語(yǔ)法確是我們應(yīng)用最為頻繁的,可綜合的意思就是可以通過(guò)物理工具進(jìn)行編譯、綜合、布局布線,最終在FPGA上實(shí)現(xiàn)。
參考下面的例子。
reg [7:0] memory[1:2**22];
Initial begin
memory[1]=8’h1;
memory[2]=8’h2;
end
該示例雖然可以正常的仿真,但是用FPGA工具編譯綜合,最終在FPGA上實(shí)現(xiàn)。代碼中定義了一個(gè)4M Byte的存儲(chǔ)器,其實(shí)在FPGA中時(shí)沒(méi)有這樣的物理資源可以與其對(duì)應(yīng)的,另外,F(xiàn)PGA編譯綜合工具在編譯的時(shí)候也將忽略Initial塊語(yǔ)句。
本文重點(diǎn)介紹如何設(shè)計(jì)可綜合的Verilog代碼。在設(shè)計(jì)可綜合的Verilog代碼的時(shí)候,我們應(yīng)該遵循怎樣的原則。
1. 堅(jiān)持FPGA的同步設(shè)計(jì)原則
包括以下幾個(gè)方面:
使用同步復(fù)位電路。
避免使用鎖存器; 盡可能使用同步寄存器。
避免使用門控,派生或分頻時(shí)鐘。
使用時(shí)鐘使能,而不是多個(gè)時(shí)鐘。
實(shí)現(xiàn)所有異步信號(hào)的正確同步。
2. 理解綜合工具的能力和局限性
充分了解綜合工具的能力和局限性將有助于提高FPGA設(shè)計(jì)的性能、邏輯性、以及資源利用率和可生產(chǎn)性。熟悉特定FPGA系列的內(nèi)部構(gòu)造,以及綜合工具所忽略或不支持的語(yǔ)言以及建議的寄存器,狀態(tài)機(jī),三態(tài)和其他推薦的編碼風(fēng)格非常重要。
3. 忽略語(yǔ)言結(jié)構(gòu)
FPGA綜合工具會(huì)忽略延遲值和時(shí)間標(biāo)度編譯器指令。設(shè)計(jì)人員經(jīng)常利用延遲來(lái)使分析仿真波形變得更容易,如下例所示。
`define DLY 1
always @(posedge clk) begin
Data_out
end
因?yàn)闈撛诘木C合和仿真失配,所以不鼓勵(lì)使用這樣的結(jié)構(gòu)。例如,如果上例中的“DLY超過(guò)時(shí)鐘周期,則綜合電路可能在功能上不正確,因?yàn)樗粫?huì)匹配仿真結(jié)果。絕大多數(shù)FPGA綜合工具都忽略編譯器指令,例如celldefine和endcelldefine。
FPGA綜合工具忽略initial塊描述。
綜合工具為Verilog門級(jí)原語(yǔ)(如nmos,pmos,cmos,pullup,pulldown,
tranif0,tranif1,tran等)提供各種級(jí)別的支持。例如,XST不支持Verilog tranif原語(yǔ),而Synplify則支持。 盡管Xilinx FPGA體系結(jié)構(gòu)不具有門級(jí)原語(yǔ)的直接等價(jià)物,但一些綜合工具將其轉(zhuǎn)換為功能等效的門級(jí)開關(guān)。 以下是nmos轉(zhuǎn)換的一個(gè)例子。
module nmos_switch(output out,intput data,control);
Assign out =control?Data :1’bz ;
endmoudle
4. 不支持的語(yǔ)句結(jié)構(gòu)
不支持的語(yǔ)句結(jié)構(gòu)包括有:用戶自定義的原語(yǔ)(UDP),repeat,wait,
fork/join,deassign ,event,force/release 語(yǔ)句。也不支持模塊內(nèi)寄存器和網(wǎng)絡(luò)的分層引用,如:
module mymodule1;
assign my_net =top.my_mudule2.my_net ;
endmoudle
相等和不相等運(yùn)算符(===和!==)的支持級(jí)別取決于綜合工具。有些綜合工具在遇到一個(gè)等式和不等式運(yùn)算符時(shí)會(huì)產(chǎn)生一個(gè)錯(cuò)誤,而另一些則會(huì)將運(yùn)算符轉(zhuǎn)換為邏輯等式(==和!=)。
5. 2種狀態(tài)和4種狀態(tài)的比較
4態(tài)值(‘0’,‘1’,‘x’,‘z’)本質(zhì)上是不可綜合的。 FPGA架構(gòu)僅支持2態(tài)值(邏輯“0”和“1”),綜合工具將應(yīng)用不同的規(guī)則來(lái)優(yōu)化“z”和“x”綜合的過(guò)程。這將導(dǎo)致綜合和仿真結(jié)果之間的不匹配和其他錯(cuò)誤。 在實(shí)現(xiàn)三態(tài)IO緩沖區(qū)的時(shí)候只使用‘z’值。
6. translate_on/translate_off
translate_off和translate_on表示讓綜合工具忽略Verilog代碼的一部分。這些指令通常用于忽略IP核模型中的行為代碼部分。以下是使用這些指令的示例。
module bram_2k_9 ( input clka, input [0 : 0] wea,
input [10 : 0] addra,
output [8 : 0] douta,
input [8 : 0] dina);
// synthesis translate_off
// behavioral description of bram_2k_9
// synthesis translate_on
endmodule // bram_2k_9
7. 特殊的編譯指令也無(wú)法被綜合
syn_keep指令可防止綜合工具刪除指定的信號(hào)。它適用于網(wǎng)絡(luò)和組合邏輯。 該指令通常用于禁用不需要的優(yōu)化,并保留手動(dòng)創(chuàng)建的復(fù)制。綜合工具不同syn_keep的作用可能會(huì)不同。例如,XST不會(huì)將約束傳播到綜合網(wǎng)表,這并不妨礙物理實(shí)現(xiàn)工具的優(yōu)化。syn_preserve防止寄存器優(yōu)化。XST還支持“Equivalent Register Removal”選項(xiàng),相當(dāng)于syn_preserve。syn_noprune確保如果未使用實(shí)例化原型的輸出,則原型未被優(yōu)化。XST也支持“Optimize Instantiated Primittives”選項(xiàng),相當(dāng)于syn_noprune。
8. parallel_case和full_case
如果在case,casex或casez語(yǔ)句中指定了full_case指令,則會(huì)阻止綜合工具創(chuàng)建其他邏輯以涵蓋未描述的條件。使用full_case指令可能會(huì)有更緊湊的效果。parallel_case指令強(qiáng)制將case語(yǔ)句綜合成為并行復(fù)用器而不是優(yōu)先級(jí)編碼結(jié)構(gòu)。使用parallel_case指令可能會(huì)提高電路的時(shí)序性能。
full_case和parallel_case指令的確切作用取決于綜合工具。而且,使用這些指令也會(huì)導(dǎo)致綜合和仿真不匹配。出于這些原因,不建議在FPGA設(shè)計(jì)中使用full_case和parallel_case指令。相反,設(shè)計(jì)師可以通過(guò)一個(gè)case語(yǔ)句的實(shí)現(xiàn)來(lái)達(dá)到同樣的效果。例如,刪除重疊的大小寫條件會(huì)導(dǎo)致不必要的parallel_case指令。
9. 編譯器指令 `default_nettype
Verilog-2001標(biāo)準(zhǔn)定義了一個(gè)`default_nettype編譯器指令。 如果該指令被分配為“無(wú)”,則必須聲明所有的1bit 信號(hào)網(wǎng)絡(luò)。
// no `default_nettype
wire sum; // declaration is not required
assign sum = a + b;
`default_nettype none
wire sum; // must be declared
assign sum = a + b;
評(píng)論