Verilog 主要用于數(shù)字電路設(shè)計(jì)的描述,但不是所有的描述方式都可以被綜合成實(shí)際的硬件電路。例如一些用于仿真驗(yàn)證的關(guān)鍵字,屬于仿真驗(yàn)證語言,只能在仿真時(shí)使用,不能被綜合成電路,如系統(tǒng)任務(wù) $dsiplay, initial 語句等。所以使用 Verilog 設(shè)計(jì)數(shù)字電路時(shí),一定要注意電路的可綜合性。testbench 可以隨心所欲,只要能構(gòu)造出需要的仿真激勵(lì)條件即可。
所有綜合工具都支持的結(jié)構(gòu)
結(jié)構(gòu)類型 | 關(guān)鍵字 | 描述 |
---|---|---|
端口信號 | inout,input,output | 端口信號只有 3 種 |
參數(shù) | parameter, localparam | --- |
信號變量 | wire, reg, tri, integer | --- |
模塊 | module | --- |
門級原語 | and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,supply0,supply1 | 直接調(diào)用例化即可 |
例化 | --- | 支持模塊例化、門級原語例化等 |
函數(shù)與任務(wù) | function, task | 支持不含時(shí)序結(jié)構(gòu)的表述 |
連續(xù)賦值 | assign | 不支持帶有延遲的表述 |
過程賦值 | always, begin, end | 可設(shè)計(jì)時(shí)序邏輯或組合邏輯 |
條件語句 | if, case, default | 條件中不能包含"z"或"x"的比較 |
循環(huán)語句 | for, while, forever | while, forever 必須包含 @(posedge clk) 或 @(negedge clk), 避免組合邏輯回路 |
邊沿觸發(fā) | negedge,posedge | --- |
操作符 | --- | 支持除 "===" 與 "!==" 以外的所有操作符 |
所有綜合工具都不支持的結(jié)構(gòu)
結(jié)構(gòu)類型 | 關(guān)鍵字 | 描述 |
---|---|---|
變量類型 | time | 仿真時(shí)使用的時(shí)間型變量 |
系統(tǒng)任務(wù) | --- | 大多數(shù)系統(tǒng)任務(wù)都是輔助仿真,不能綜合為實(shí)際電路
例如 $display, $fopen, $finish 等。 |
過程結(jié)構(gòu) | initial | initial 常用作仿真時(shí)信號賦初值操作
或控制激勵(lì)信號的時(shí)序 |
并行語句 | fork, join | 常用作仿真時(shí)并行結(jié)構(gòu)的描述
always @(posedge clk) 描述的并行結(jié)構(gòu)可綜合 |
延遲語句 | # | 所有帶延遲標(biāo)志"#"的表述均不可綜合
但仿真時(shí)電路中會有延時(shí),綜合時(shí)也不會報(bào)錯(cuò) |
電平敏感觸發(fā) | wait | 多用于仿真中信號的檢測啟動 |
強(qiáng)制賦值和釋放 | force, release | 多用于仿真中阻斷其他驅(qū)動源,對信號進(jìn)行強(qiáng)制賦值 |
綜合工具可能支持的結(jié)構(gòu)
結(jié)構(gòu)類型 | 關(guān)鍵字 | 描述 |
---|---|---|
x/z 條件語句 | casex, casez | 有些綜合工具能識別該語句中的非"x/z"比較邏輯 |
不同強(qiáng)度的線網(wǎng) | wand,triand,wor,trior | 當(dāng)信號有多個(gè)驅(qū)動源時(shí)需要使用
但現(xiàn)在數(shù)字設(shè)計(jì)基本摒棄了這些變量類型 |
實(shí)數(shù)變量 | real | 往往用于仿真時(shí)的精確計(jì)算 |
過程終止 | disable | 終止過程塊執(zhí)行,大多數(shù)綜合工具不支持該命令 |
循環(huán)語句 | repeat, while, forever | repeat 常用作仿真中語句循環(huán)執(zhí)行固定次數(shù)
while, forever 循環(huán)次數(shù)為常量時(shí)也可能可綜合 |
用戶自定義原語 | UDP | 其實(shí)目前大多數(shù)綜合工具都支持 UDP
只是某些古老的綜合工具不會識別 |
過程連續(xù)賦值 | assign, deassign | 工具大多不支持該操作下 reg 數(shù)據(jù)類型的綜合
支持該操作下 wire 數(shù)據(jù)類型的綜合 |
使用 Verilog 進(jìn)行數(shù)字設(shè)計(jì)時(shí),需要遵循以下原則:可綜合的結(jié)構(gòu)可大膽使用,不可綜合的結(jié)構(gòu)仿真中使用,有些綜合工具支持有些不支持的結(jié)構(gòu)盡量不使用。
除非某些特殊設(shè)計(jì),例如 clkgate, 時(shí)鐘切換等電路等,否則設(shè)計(jì)中不要編寫潛在的會被綜合成 Latch 的邏輯。詳見《Verilog 教程》章節(jié)《Verilog 避免 Latch》。
變量聲明時(shí)不要學(xué) C 語言格式對寄存器變量進(jìn)行賦初值操作。仿真時(shí)變量會有設(shè)置的初值,綜合后寄存器初值是不確定的。如果信號初值會影響邏輯功能,則仿真過程可能會因驗(yàn)證不充分而錯(cuò)過查找出邏輯錯(cuò)誤的機(jī)會。
所有內(nèi)部寄存器都應(yīng)該使用復(fù)位進(jìn)行賦初值操作,以確保系統(tǒng)復(fù)位時(shí)各寄存器都有穩(wěn)定的狀態(tài)。因?yàn)闆]有復(fù)位端,綜合后電路中寄存器的初始值不能確定,可能會導(dǎo)致功能錯(cuò)誤。
組合邏輯使用阻塞賦值,時(shí)序邏輯使用非阻塞賦值。組合邏輯一般使用連續(xù)賦值語句 assign 描述,always 描述的電路也能被綜合成組合邏輯,例如"與邏輯"可以描述如下:
reg F ; //注意一定要是 reg 型變量
always @(*) begin
F = A & B ;
end
always 語句中被賦值的信號一定要聲明為 reg 型,在組合邏輯中該 reg 變量會被綜合成線網(wǎng),在時(shí)序邏輯中該 reg 變量會被綜合成觸發(fā)器。
同一個(gè)變量不能受多個(gè)時(shí)鐘(或 always 塊)控制,也不能受時(shí)鐘的雙邊沿控制。此類描述也是不可綜合的。
避免設(shè)計(jì)中出現(xiàn) ?X
? 或 ?Z
? 值,因?yàn)榫C合工具只能識別 ?0
? 或 ?1
? 的邏輯值。
更多建議: