1 Verilog簡(jiǎn)介(Verilog語法學(xué)習(xí)者可跳過該節(jié))
Verilog是一門類C語言
Verilog是一門類C語言籽暇,語法與C接近,但Verilog是硬件設(shè)計(jì)語言养铸,與C實(shí)質(zhì)不同雁芙。
- Verilog代碼對(duì)應(yīng)硬件實(shí)體轧膘。比如在Verilog里寫的
a+b
,最后會(huì)得到由硬件實(shí)現(xiàn)的加法器 - Verilog代碼到硬件的過程叫綜合兔甘。綜合就是將Verilog代碼轉(zhuǎn)化為硬件實(shí)現(xiàn)
- Verilog并行執(zhí)行
HDL: Hardware Description Language
Verilog HDL使硬件設(shè)計(jì)師們得以專注于邏輯谎碍,而不需要考慮硬件層面的實(shí)現(xiàn)。同樣的代碼只要經(jīng)過不同的庫(kù)綜合洞焙,就可以在不同的硬件上運(yùn)行蟆淀。因此Verilog的代碼具有極高的可復(fù)用性。
使用Verilog的絕大多數(shù)開發(fā)都處于寄存器傳輸級(jí)澡匪。
軟核熔任、固核與硬核
- 軟核(Softcore):功能經(jīng)過驗(yàn)證的、可綜合的唁情、實(shí)現(xiàn)后電路結(jié)構(gòu)總門數(shù)在5000門以上的Verilog HDL模型疑苔。
- 固核:在某一種現(xiàn)場(chǎng)可編程門陣列(FPGA)器件上實(shí)現(xiàn)的,經(jīng)驗(yàn)證是正確的總門數(shù)在5000以上的電路結(jié)構(gòu)編碼文件甸鸟。
- 硬核:在某一種專用的半導(dǎo)體集成工藝(ASIC)的器件上實(shí)現(xiàn)的惦费,經(jīng)驗(yàn)證是正確的總門數(shù)在5000以上的電路結(jié)構(gòu)掩膜
顯然,在具體實(shí)現(xiàn)手段和工藝技術(shù)尚未確定的邏輯設(shè)計(jì)階段哀墓,軟核具有最大的靈活性趁餐。因此,發(fā)展軟核的設(shè)計(jì)和推廣軟核的重用技術(shù)是非常有必要的篮绰。
自頂向下(Top-Down)設(shè)計(jì)
(對(duì)上圖的講解:P2 | 2:55)
2 Verilog基本語法
Verilog語法概述
- 行為級(jí)描述/寄存器傳輸級(jí)(RTL)描述/系統(tǒng)級(jí)描述:把module當(dāng)成黑盒后雷,描述module輸入與輸出的關(guān)系。門級(jí)實(shí)現(xiàn)由綜合工具推斷吠各,常常能做到最優(yōu)臀突。
- 結(jié)構(gòu)級(jí)描述/門級(jí)描述:把module作為白盒,而描述組成module的門電路(部件)
module <module_name> (in1, in2, ..., out1, out2)
input in1, in2, ...;
output out1, out2, ...;
...
endmodule
// 注釋1
/* 注釋2 */
基本語法
- Verilog區(qū)分大小寫
- Verilog的關(guān)鍵字都是小寫
-
module, endmodule
定義一個(gè)基本模塊贾漏,兩個(gè)關(guān)鍵字間的語句是對(duì)該模塊的描述候学。定義模塊方便復(fù)用。 -
parameter
關(guān)鍵字定義一個(gè)參數(shù)纵散,增強(qiáng)模塊的通用性 -
output, input
關(guān)鍵字指定輸入輸出 -
always @(posedge/negedge clk)
語句梳码,每當(dāng)clk出現(xiàn)上升/下降沿時(shí),就執(zhí)行接下來的語句塊(begin, end
標(biāo)志一個(gè)語句塊)伍掀。這種語句構(gòu)成時(shí)序邏輯掰茶,當(dāng)前輸出與上一個(gè)時(shí)刻的值有關(guān) -
reg
類的變量用<=
賦值,賦值符號(hào)左側(cè)是寄存器蜜笤,右側(cè)是更新的值 -
&q
語句輸出q
每一位相與的結(jié)果濒蒋,即&q=q[1]&q[2]&...&q[N]
-
assign
關(guān)鍵字描述組合邏輯,輸出只與當(dāng)前輸入有關(guān) - input/output如果沒有顯示聲明類型,默認(rèn)為
wire
類型沪伙。如果需要reg
類型以存儲(chǔ)值瓮顽,需要顯示聲明 -
wire
類型只是一根導(dǎo)線,只能用來組合邏輯围橡。assign
語句等號(hào)右側(cè)一旦發(fā)生變化暖混,等號(hào)左側(cè)立刻得到結(jié)果;而always
語句塊中的值改變只能發(fā)生在每一時(shí)刻(由@
符號(hào)后的語句描述時(shí)刻) -
initial begin, end
語句塊指明初始化語句翁授,這部分指令在系統(tǒng)上電后直接執(zhí)行 -
'timescale 1ns/1ps
指定測(cè)試的單位是1ns儒恋,精度是1ps -
#100
指令指明延時(shí),單位由之前的代碼指定 -
$stop
指令使仿真停止 - 時(shí)序邏輯:
<=
賦值黔漂;組合邏輯:-
賦值
數(shù)據(jù)類型及常量诫尽、變量
常量
語法:<位寬>'<進(jìn)制><數(shù)值>
- 位寬:對(duì)應(yīng)二進(jìn)制的寬度
- 進(jìn)制
變量
有兩種類型:
- nets type
- register type
- nets type
wire
- register type
上表的后面三種類型不可以綜合,主要用在算法級(jí)的開發(fā)
reg
運(yùn)算符
注:==
和===
的區(qū)別在于怎么處理z
和x
的位炬守。一般來說用==
就足夠了
優(yōu)先級(jí)
【重要】語句
Part 0 概述
- 賦值語句
- 連續(xù)賦值語句:
assign
語句 - 過程賦值語句:
always
開頭牧嫉,@
引導(dǎo)一個(gè)敏感列表
- 條件語句
if-else
case
(條件語句必須在順序執(zhí)行塊中使用。所謂順序執(zhí)行塊是指由 initial 和always語句引導(dǎo)的執(zhí)行語句集合减途。除了這兩種語句引導(dǎo)的begin_end塊中可以編寫條件語句外酣藻,模塊中的其他地方都不能編寫。)
- 循環(huán)語句
forever
repeat
while
for
- 結(jié)構(gòu)說明語句
initial
always
task
function
- 編譯預(yù)處理語句
- `define語句
- `include語句
- `timescale語句
Part 1 賦值鳍置、條件語句詳解
always過程塊
always @(<敏感信號(hào)表達(dá)式>)
begin
...
end
-
always
語句塊不能嵌套 - 在敏感信號(hào)表達(dá)式前加
posedge
或negedge
關(guān)鍵字可以指定上升沿或下降沿觸發(fā)辽剧。否則每當(dāng)表達(dá)式的值發(fā)生改變,就會(huì)執(zhí)行語句塊
initial過程塊
-
initial
過程塊模擬上電之后的行為税产,不可綜合怕轿,通常用于功能模擬的初始化,寫在測(cè)試文件(testbench)中 - 同一模塊中的
initial
過程塊辟拷,在上電時(shí)并行執(zhí)行 -
initial
過程塊不能嵌套
連續(xù)賦值語句assign
-
assign
語句常用于對(duì)wire
類型變量進(jìn)行賦值 - 等式左邊的
wire
變量隨等式右邊的值一起變化
過程賦值語句
- 常用于對(duì)
reg
型變量進(jìn)行賦值 - 阻塞賦值(
=
)與非阻塞賦值(<=
)
- 一個(gè)例子
// For e.g.
...
always @(posedge clk)
begin
b <= a
c <= b
end
...
// 上升沿來前撞羽,假設(shè)b=1,a=2
// 則上升沿來時(shí),b=2衫冻,c=1诀紊,即c獲得b的舊值
// 原因是非阻塞賦值下,兩個(gè)賦值語句并行執(zhí)行
// 若將<=全部改為=隅俘,則c=2邻奠,因?yàn)樽枞x值是順序執(zhí)行的
對(duì)于過程賦值語句,如果是邊沿觸發(fā)为居,我們?cè)?code>always語句塊里用
<=
賦值碌宴,期望綜合后生成寄存器;如果是電平觸發(fā)颜骤,那么這個(gè)語句塊實(shí)際上描述的是一段組合邏輯唧喉,我們使用=
賦值捣卤,期望綜合后不使用寄存器忍抽,而生成一個(gè)組合邏輯電路
case語句
case (<敏感值表達(dá)式>)
value_1: ...;
value_2: ...;
...
default: ...; //可省略
endcase
執(zhí)行哪一個(gè)語句塊取決于敏感值表達(dá)式的值與哪一個(gè)情況(value_i)匹配八孝,如果都不匹配,則執(zhí)行default后面的語句
- 在敏感信號(hào)表達(dá)式的位置寫
*
鸠项,綜合器會(huì)推斷表達(dá)式干跛。推斷的主要依據(jù)是賦值語句的右側(cè)值
小結(jié)
語法要點(diǎn):
(1) always
里面賦值左邊必須聲明成reg
(Verilog的語法規(guī)定。這一條引出了后續(xù)的很多要點(diǎn))
(2) assign
表達(dá)式左邊必須聲明成wire
(3) 阻塞賦值用=
(4) 非阻塞賦值用<=
(1) 邊沿觸發(fā)生成寄存器的時(shí)序邏輯
(2) 電平觸發(fā)且條件完整祟绊,生成組合邏輯
(3) 電平觸發(fā)但條件不完整(寫了if沒寫else楼入,或case不完整),生成鎖存器的時(shí)序邏輯
結(jié)論:
聲明成reg
牧抽,不一定得到寄存器
聲明成reg
嘉熊,也可能得到鎖存器
Coding要點(diǎn):
如果是邊沿觸發(fā)的邏輯
比如always @(posedge clk)
,里面一律用<=
賦值如果是電平觸發(fā)的邏輯扬舒,一律用
=
賦值
邏輯簡(jiǎn)單用assign
語句阐肤;邏輯復(fù)雜用always
語句
分支條件寫完整,防治出現(xiàn)鎖存器
Part 2 循環(huán)語句詳解
for語句(可綜合)
語法(和C一樣):
for (<變量賦初值語句>; <條件表達(dá)式>; <變量增值語句>)
循環(huán)體;
repeat語句
repeat語句常用于仿真
語法:
repeat(<循環(huán)次數(shù)表達(dá)式>)
循環(huán)體;
Part 3 結(jié)構(gòu)語句詳解
主要講解function(函數(shù))與task(任務(wù))
function(可綜合)
function常用于實(shí)現(xiàn)簡(jiǎn)單的函數(shù)讲坎,module里可以調(diào)用function孕惜。而function在一定意義上相當(dāng)于一個(gè)module。
例子
task(不可綜合)
task常用于仿真驗(yàn)證晨炕,語句塊里可以寫各種高級(jí)語句
例子(例子中的task的作用是等待number_of_edges
個(gè)下降沿)
function和task的不同
task中可以使用的高級(jí)系統(tǒng)函數(shù)
看到這里了衫画?恭喜,你已經(jīng)學(xué)會(huì)了Verilog的基本語法瓮栗,你已經(jīng)能夠handle不少電路設(shè)計(jì)了削罩!接下來是關(guān)于執(zhí)行順序的知識(shí)。設(shè)計(jì)一個(gè)電路费奸,不僅要知道邏輯鲸郊,也要知道執(zhí)行順序。
3 執(zhí)行順序
- 順序執(zhí)行塊:
begin - end
(例外:always
語句塊中用begin - end
和非阻塞賦值<=
時(shí)货邓,這時(shí)是并行執(zhí)行) - 并行執(zhí)行塊:
fork - join
舉一個(gè)例子(假設(shè)例子里的時(shí)間單位是ns)秆撮,
由于fork - join
語句塊是并行執(zhí)行的,上圖中的兩個(gè)語句塊描述的是同一個(gè)過程:
上電(系統(tǒng)啟動(dòng))后50ns换况,r='h35'
职辨;再過50ns,r='hE2'
戈二;再過50ns舒裤,r='h00'
;以此類推觉吭。
延伸該例子腾供,將語句塊改為
fork
begin
#50 r='h35';
#100 r='hE2';
end
#150 r='h00';
#200 r='hF7';
#250 r='h00';
end
則依據(jù)begin - end
語句塊的順序執(zhí)行性,r
的值在150ns時(shí)是不確定的,因?yàn)橥瑫r(shí)有兩個(gè)賦值發(fā)生伴鳖。
簡(jiǎn)單總結(jié)节值,如果想要串行執(zhí)行,需要滿足兩個(gè)條件:
-
begin - end
語句塊 - 阻塞賦值
=
(完結(jié)撒花)