verilog設(shè)計(jì)--基礎(chǔ)部分:概述转晰、設(shè)計(jì)方法流程芦拿、語法
各種電路從本質(zhì)上來講是為了解決特定的數(shù)學(xué)問題而存在士飒。目前,通用處理器能解決大部分的問題蔗崎,如濾波酵幕、加密、解密缓苛、編碼芳撒、解碼、糾檢錯(cuò)等未桥,那為什么還需要通過Verilog HDL來設(shè)計(jì)復(fù)雜數(shù)字邏輯系統(tǒng)呢笔刹?因?yàn)橥ㄓ锰幚砥鞯目偩€帶寬、指令周期等已經(jīng)被固化冬耿,而不會(huì)加入一些有相當(dāng)嚴(yán)格的特殊要求(如嚴(yán)格時(shí)延舌菜、并發(fā)等速度性能方面)電路。
1- 設(shè)計(jì)流程:
設(shè)計(jì)-->驗(yàn)證
Verilog HDL設(shè)計(jì)需要從算法亦镶、編程語言日月、計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)以及仿真驗(yàn)證幾個(gè)方面入手。
首先缤骨,為準(zhǔn)確表達(dá)要分析的問題信息爱咬,我們往往需要抽象出數(shù)學(xué)模型,而這些數(shù)學(xué)模型也就是數(shù)據(jù)結(jié)構(gòu)绊起;接著精拟,我們使用編程語言把數(shù)據(jù)結(jié)構(gòu)串起來,表述問題的求解過程虱歪,在這類復(fù)雜電路設(shè)計(jì)過程中蜂绎,我們盡量避免迭代、遞歸实蔽、指針等不易于通過簡單物理單元電路(可綜合)搭建的高級(jí)編程語言語法荡碾,從而產(chǎn)生更簡化、方便重復(fù)調(diào)用的Verilog語言局装;另外坛吁,由于專用電路設(shè)計(jì)仍是基于計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)高性能硬件邏輯系統(tǒng),Verilog HDL設(shè)計(jì)用來砌墻的磚頭就是微機(jī)系統(tǒng)結(jié)構(gòu)铐尚;然后拨脉,設(shè)計(jì)初步完成后,可通過仿真分析工具來進(jìn)行仿真驗(yàn)證宣增,降低了復(fù)雜數(shù)字電路系統(tǒng)的設(shè)計(jì)風(fēng)險(xiǎn)玫膀。
2- 設(shè)計(jì)方案主體
通常·Verilog HDL設(shè)計(jì)有如下幾種方案:
1)以已有微處理器為中心爹脾,一般在其C程序代碼已驗(yàn)證條件下將編譯好的代碼加載到RAM進(jìn)行算法仿真驗(yàn)證帖旨,周期短箕昭、受限微處理器及其外圍電路;
2)以 FPGA(從幾萬門到百萬門)為中心解阅,需配備 FPGA 開發(fā)環(huán)境(仿真綜合)落竹、布局布線和編程工具,仍屬于通用可編程器件货抄,在更嚴(yán)苛的條件下可使用ASIC述召;
3)以專用的大規(guī)模集成電路(ASIC)為中心,利用現(xiàn)有IP核輔之專門設(shè)計(jì)的高速ASIC 運(yùn)算電路蟹地,需熟悉半導(dǎo)體廠家基本器件庫和 IP 庫积暖、配備開發(fā)環(huán)境(仿真綜合),周期長、投入大怪与,適合高預(yù)算夺刑、大批量生產(chǎn);
由于電路結(jié)構(gòu)對運(yùn)算速度影響巨大琼梆,常常需要多輪仿真驗(yàn)證才能投產(chǎn):
C 語言功能仿真性誉;
C 語言并行結(jié)構(gòu)仿真窿吩;
Verilog HDL 行為仿真茎杂;
Verilog HDL RTL 級(jí)仿真;
綜合后門級(jí)結(jié)構(gòu)仿真纫雁;
布局布線后仿真煌往;
電路實(shí)驗(yàn)驗(yàn)證;
隨著制造技術(shù)進(jìn)步轧邪,設(shè)計(jì)效率跟不上而分解出邏輯設(shè)計(jì)(前端)和電路實(shí)現(xiàn)(后端)刽脖,優(yōu)秀的常用數(shù)字邏輯電路和系統(tǒng)部件(如FFT、DCT)被建成宏單元(Megcell)或軟核(Soft-Core)庫供設(shè)計(jì)者引用忌愚,電路實(shí)現(xiàn)則由綜合工具和布局布線工具完成曲管。
我們也常常會(huì)聽說硬核、軟核這樣的概念硕糊,硬核是指固定的5000門以上電路結(jié)構(gòu)編碼文件院水,軟核功能經(jīng)過驗(yàn)證的、可綜合的简十、實(shí)現(xiàn)后電路結(jié)構(gòu)總門數(shù)在5000門以上的Verilog HDL模型檬某。它們的區(qū)別在與軟核可以根據(jù)電路工藝來微調(diào),硬核是固化的螟蝙。
3- 設(shè)計(jì)方法
3-1 設(shè)計(jì)方法:
設(shè)計(jì)方法上恢恼,復(fù)雜數(shù)字系統(tǒng)的設(shè)計(jì)通過層次化(自頂向下/自底向上)、結(jié)構(gòu)化設(shè)計(jì)可以細(xì)化分解不同的模塊胰默,利于工程管理场斑。
設(shè)計(jì)層級(jí):
系統(tǒng)級(jí)(system):用高級(jí)語言結(jié)構(gòu)實(shí)現(xiàn)設(shè)計(jì)模塊的外部性能的模型漓踢。
算法級(jí)(algorithm):用高級(jí)語言結(jié)構(gòu)實(shí)現(xiàn)設(shè)計(jì)算法的模型。
RTL級(jí)(Register Transfer Level):描述數(shù)據(jù)在寄存器之間流動(dòng)和如何處理這些數(shù)據(jù)的模型漏隐。
門級(jí)(gate-level):描述邏輯門以及邏輯門之間的連接的模型彭雾。
開關(guān)級(jí)(switch-level):描述器件中三極管和儲(chǔ)存節(jié)點(diǎn)以及它們之間連接的模型。
3-2 模塊結(jié)構(gòu):
接口描述+功能邏輯
1- 模塊端口定義:
module 模塊名(口1锁保,口2薯酝,口3,口4, ………);
2- I/O說明:
輸入口: input 端口名1爽柒,端口名2吴菠, ………,端口名i; //(共有i個(gè)輸入口)
輸出口: output 端口名1,端口名2浩村, ………,端口名j; //(共有j個(gè)輸出口)
3- 內(nèi)部信號(hào)說明:
在模塊內(nèi)用到的和與端口有關(guān)的wire 和 reg 變量的聲明做葵。
如:
reg [width-1 : 0] R變量1,R變量2 心墅。酿矢。。怎燥。瘫筐;
wire [width-1 : 0] W變量1,W變量2 铐姚。策肝。。隐绵。之众;
4- 功能定義:
模塊中最重要的部分是邏輯功能定義部分。有三種方法可在模塊中產(chǎn)生邏輯依许。
1).用“assign”聲明語句
如: assign a = b & c;
2).用實(shí)例元件
如: and and_inst( q, a, b );
采用實(shí)例元件的方法象在電路圖輸入方式下棺禾,調(diào)入庫元件一樣。鍵入元件的名字和相連的引腳即可峭跳, 表示在設(shè)計(jì)中用到一個(gè)跟與門(and)一樣的名為and_inst的與門膘婶,其輸入端為a, b,輸出為q坦康。要求 每個(gè)實(shí)例元件的名字必須是唯一的竣付,以避免與其他調(diào)用與門(and) 的實(shí)例混淆。
3).用“always”塊
如:always @(posedge clk or posedge clr) begin
if(clr) q <= 0; else if(en) q <= d;
end
----assign描述組合邏輯滞欠,always既可以描述組合邏輯古胆,也可以描述時(shí)序電路;
4- 數(shù)據(jù)類型&運(yùn)算
4-1 數(shù)據(jù)類型、變量逸绎、常量惹恃、參數(shù)化
parameter格式:
parameter 參數(shù)名1=表達(dá)式,參數(shù)名2=表達(dá)式, …棺牧, 參數(shù)名n=表達(dá)式;
如:
parameter msb=7; //定義參數(shù)msb為常量7
parameter e=25, f=29; //定義二個(gè)常數(shù)參數(shù)
parameter r=5.7; //聲明r為一個(gè)實(shí)型參數(shù)
parameter byte_size=8, byte_msb=byte_size-1; //用常數(shù)表達(dá)式賦值
parameter average_delay = (r+f)/2; //用常數(shù)表達(dá)式賦值
多層次模塊構(gòu)成的電路巫糙,在一個(gè)模塊中改變另一個(gè)模塊的參數(shù)時(shí),需要使用defparam命令
wire\reg\memery
memory型數(shù)據(jù)和reg型數(shù)據(jù)的定義格式很相似颊乘, 但要注意其不同之處参淹。如一個(gè)由n個(gè)1位寄存器構(gòu) 成的存儲(chǔ)器組是不同于一個(gè)n位的寄存器的。見下例:
reg [n-1:0] rega; //一個(gè)n位的寄存器
reg mema [n-1:0]; //一個(gè)由n個(gè)1位寄存器構(gòu)成的存儲(chǔ)器組
一個(gè)n位的寄存器可以在一條賦值語句里進(jìn)行賦值乏悄,而一個(gè)完整的存儲(chǔ)器則不行浙值。 見下例:
rega =0; //合法賦值語句 mema =0; //非法賦值語句
如果想對memory中的存儲(chǔ)單元進(jìn)行讀寫操作,必須指定該單元在存儲(chǔ)器中的地址檩小。下面的寫法是正確 的开呐。
mema[3]=0; //給memory中的第3個(gè)存儲(chǔ)單元賦值為0
4-2 運(yùn)算符
4-2-1 運(yùn)算符
算術(shù)運(yùn)算符(+,-,×,/,%)
賦值運(yùn)算符(=,<=)
關(guān)系運(yùn)算符(>,<,>=,<=)
邏輯運(yùn)算符(&&,||,!)
條件運(yùn)算符(?:)
位運(yùn)算符(,|,^,&,^)
移位運(yùn)算符(<<,>>)
拼接運(yùn)算符({ })
4-2-2 賦值
注意事項(xiàng):
(1)時(shí)序電路建模時(shí),用非阻塞賦值规求。
(2)鎖存器電路建模時(shí),用非阻塞賦值
(3)用always 塊建立組合邏輯模型時(shí),用阻塞賦值筐付。
(4)在同一個(gè)always 塊中建立時(shí)序和組合邏輯電路時(shí),用非阻塞賦值。
(5)在同一個(gè) always 塊中不要既用非阻塞賦值又用阻塞賦值阻肿。
(6)不要在一個(gè)以上的 always塊中為同一個(gè)變量賦值瓦戚。
(7)用$strobe系統(tǒng)任務(wù)來顯示用非阻塞賦值的變量值,
(8)在賦值時(shí)不要使用#0延遲冕茅。
(1).非阻塞
非阻塞(Non_Blocking)賦值方式( 如 b <= a; )
塊結(jié)束后才完成賦值操作伤极。
b的值并不是立刻就改變的。
這是一種比較常用的賦值方法姨伤。(特別在編寫可綜合模塊時(shí))
(2).阻塞
阻塞(Blocking)賦值方式( 如 b = a; )
賦值語句執(zhí)行完后,塊才結(jié)束。
b的值在賦值語句執(zhí)行完后立刻就改變的庸疾。
可能會(huì)產(chǎn)生意想不到的結(jié)果乍楚。
[例1]:
always @( posedge clk )
begin
b<=a;
c<=b;
end
[例1] 中的"always"塊中用了非阻塞賦值方式,定義了兩個(gè)reg型信號(hào)b和c届慈,clk信號(hào)的上升沿到來時(shí)徒溪,b就等于a,c就等于b金顿,這里應(yīng)該用到了兩個(gè)觸發(fā)器臊泌。請注意:賦值是在"always"塊結(jié)束后執(zhí)行的,c應(yīng)為原來b的值揍拆。這個(gè)"always"塊實(shí)際描述的電路功能如下圖所示:
[例2]:
always @(posedge clk)
begin
b=a;
c=b;
end
[例2]中的 "always"塊用了阻塞賦值方式渠概。clk信號(hào)的上升沿到來時(shí),將發(fā)生如下的變化:b馬上取a的值,c馬上取b的值(即等于a)播揪,生成的電路圖如下所示只用了一個(gè)觸發(fā)器來寄存器a的值贮喧,又輸出給b和c。
4-2-3 語句
if else
case
assign
(1) case
case分支項(xiàng)的一般格式如下:
分支表達(dá)式: 語句
缺省項(xiàng)(default項(xiàng)): 語句
case語句與if_else_if語句的區(qū)別主要有兩點(diǎn):
與case語句中的控制表達(dá)式和多分支表達(dá)式這種比較結(jié)構(gòu)相比猪狈,if_else_if結(jié)構(gòu)中的條件表達(dá)式更為直觀一些箱沦。
對于那些分支表達(dá)式中存在不定值x和高阻值z位時(shí),case語句提供了處理這種情況的手段。
下面例子介紹了處理x,z值位的case語句雇庙。
例1]:case ( select[1:2] )
2 'b00: result = 0;
2 'b01: result = flaga;
2 'b0x,2 'b0z: result = flaga? 'bx : 0;
2 'b10: result = flagb;
2 'bx0,2 'bz0: result = flagb? 'bx : 0;
default: result = 'bx;
endcase
(2) 鎖存器
1)在"always"塊內(nèi)谓形,如果在給定的條件下變量沒有賦值,這個(gè)變量將保持原值疆前,也就是說會(huì)生成一個(gè)鎖存器套耕!
[圖片上傳失敗...(image-f7547e-1724403082957)]
2)另一種偶然生成鎖存器是在使用case語句時(shí)缺少default項(xiàng)的情況下發(fā)生的。
[圖片上傳失敗...(image-8db69-1724403082957)]
為避免鎖存器生成峡继,應(yīng)保證語句條件完備冯袍;
(3) always
always 的時(shí)間控制可以是沿觸發(fā)也可以是電平觸發(fā)的,可以單個(gè)信號(hào)也可以多個(gè)信號(hào)碾牌,中間需要用關(guān)鍵字 or 連接康愤,如:
沿觸發(fā):
always @(posedge clock or posedge reset) //由兩個(gè)沿觸發(fā)的always塊
begin ……
end
電平觸發(fā):
always @( a or b or c ) //由多個(gè)電平觸發(fā)的always塊
begin
……
end
沿觸發(fā)的always塊常常描述時(shí)序邏輯, 如果符合可綜合風(fēng)格要求可用綜合工具自動(dòng)轉(zhuǎn)換為表示時(shí)序邏輯的寄存器組和門級(jí)邏輯舶吗,而電平觸發(fā)的always塊常常用來描述組合邏輯和帶鎖存器的組合邏輯征冷,如果符合可綜合風(fēng)格要求可轉(zhuǎn)換為表示組合邏輯的門級(jí)邏輯或帶鎖存器的組合邏輯。
(4) 條件編譯
條件編譯命令ifdef誓琼、
else检激、`endif
條件編譯命令有以下幾種形式:
`ifdef 宏名 (標(biāo)識(shí)符)程序段1
`else程序段2
`endif
它的作用是當(dāng)宏名已經(jīng)被定義過(用`define命令定義),則對程序段1進(jìn)行編譯腹侣,程序段2將被忽略;否則編譯程序段2叔收,程序段1被忽略。
小結(jié):本文從Verilog HD發(fā)展起因傲隶、設(shè)計(jì)方案饺律、仿真類型、基礎(chǔ)語法等方面進(jìn)行了概括性描述跺株。