




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第四章組合邏輯設(shè)計(jì)4.1基本操作符4.2組合邏輯描述4.3條件控制語句4.4.條件控制語句的布線結(jié)構(gòu)4.5always語句的編程指導(dǎo)4.6工程實(shí)踐本章小結(jié) 4.1基?本?操?作?符
Verilog語言包括兩種操作符。一種是在第三章簡(jiǎn)單講述過的位操作,另外還有用于算術(shù)、移位、關(guān)系等的運(yùn)算操作,這些運(yùn)算符與描述Verilog基本數(shù)字模塊緊密相關(guān),比如加法器、比較器等。本節(jié)討論VerilogHDL語言的運(yùn)算符操作,同時(shí)覆蓋所有的RTL級(jí)描述。表4-1列舉了所有的操作符,同時(shí)表4-2列舉了這些操作的優(yōu)先級(jí)。4.1.1算術(shù)操作符
算術(shù)操作符包括六種:加法(?+?)、減法(?-?)、乘法(?*?)、除法(?/?)、取模(?%?)和求冪運(yùn)算(?**?)。其中,加法(?+?)和減法(?-?)操作符可以被用作一元操作符。例如,“-a”在綜合時(shí),“+”與“-”操作符可以代表加法與減法而被FPGA的邏輯單元所綜合。
乘法運(yùn)算符(?*?)相對(duì)來說比較復(fù)雜,其綜合時(shí)需要依賴于所用的軟件綜合工具以及所選配的目標(biāo)硬件。Xilinx公司的Spartan-3FPGA系列內(nèi)部含有預(yù)制的乘法器模塊,XilinxXST軟件可以提供將“*”號(hào)乘法操作適配綜合到FPGA的乘法器模塊當(dāng)中,在以上兩個(gè)條件滿足的情況下,可以在HDL設(shè)計(jì)中使用“?*?”符號(hào)。針對(duì)S3板來說,XC3S200這款FPGA含有20個(gè)18?×?18的乘法器資源,所以盡管硬件支持乘法器綜合,我們還需要考慮資源包含的數(shù)目。
除法(?/?)、取模(?%?)和求冪運(yùn)算(?**?)操作符通常不可以直接被綜合。
4.1.2移位操作符
移位操作符有四種:邏輯右移(?>>?),邏輯左移(?<<?),算術(shù)右移(?>>>?)和算術(shù)左移(?<<<?)。
在邏輯移位運(yùn)算中,無論是左移還是右移都是用“0”來填補(bǔ)移出的空位。而在算術(shù)移位運(yùn)算時(shí),右移“>>>”操作是用符號(hào)位來填補(bǔ)移出的空位;左移“<<<”操作是用“0”來填補(bǔ)移位的空位。對(duì)于邏輯左移(?<<?)和算術(shù)左移(?<<<?)是沒有區(qū)別的,具體可參考表4-3中的例子。4.1.3關(guān)系運(yùn)算符與相等運(yùn)算符
關(guān)系運(yùn)算符有四種:大于(?>?)、小于(?<?)、大于等于(?>=?)和小于等于(?<=?)。
關(guān)系運(yùn)算符通過比較操作,然后返回布爾值結(jié)果,如果值為正確,則返回“1”,否則返回“0”。
相等運(yùn)算符也有四種:等于(?==?)、不等于(?!=?)、條件相等(?===?)和條件不相等(?!==?)。
等于運(yùn)算符(?==?)和不等于運(yùn)算符(?!=?)與關(guān)系運(yùn)算符相似,也是返回false和ture的布爾值。需要注意的是,針對(duì)X和Z的嚴(yán)格按位比較,是不能被綜合的。例如:
if(a==1‘bx)
$display(aisx);//當(dāng)a等于x時(shí),這個(gè)語句不執(zhí)行
if(a===1’bx)
$display(aisx); //當(dāng)a等于x時(shí),這個(gè)語句執(zhí)行4.1.4位操作、復(fù)制和邏輯操作運(yùn)算符
位操作、復(fù)制和邏輯操作運(yùn)算在許多情況下頗為相似,都針對(duì)與、或、異或和非操作。下面分別討論這三種運(yùn)算符的用法。
1.位運(yùn)算操作
有四種基本的位操作運(yùn)算:與(&)、或(?|?)、異或(?^?)和非(?~?)。
前三種操作都需要兩個(gè)操作對(duì)象,另外,異或與非操作,可以組合在一起構(gòu)成“異或非”,如“~^”或“^~”。
這些操作都是針對(duì)位來操作的。所以稱為位操作符。下面舉例來說明位操作符的用法。例:a,b,c為我們定義的三個(gè)位寬為4的信號(hào):
wire[3:0]a,b,c;
執(zhí)行如下語句:
assignc=a|b;
相當(dāng)于:
assignc[3]=a[3]|b[3];
assignc[2]=a[2]|b[2];
assignc[1]=a[1]|b[1];
assignc[0]=a[0]|b[0];
2.縮減運(yùn)算符
縮減運(yùn)算符包括與、或、非運(yùn)算。
與位運(yùn)算操作符不同的是,縮減運(yùn)算符是單操作數(shù)運(yùn)算符,并且最后的結(jié)果是1位的二進(jìn)制數(shù)。單個(gè)操作數(shù)一般是同一個(gè)數(shù)據(jù)類型。縮減運(yùn)算的具體運(yùn)算過程是:第一步先將操作數(shù)的第1位與第2位進(jìn)行與、或、非運(yùn)算。第二步將運(yùn)算結(jié)果與第3位進(jìn)行與、或、非運(yùn)算,依次類推,直至最后1位。比如說輸入a為4bit信號(hào),那么對(duì)于輸出y卻是1bit信號(hào):
wire[3:0]a;
wirey;用語句描述為
assigny=|a;等同于:
assigny=a[3]|a[2]|a[1]|a[0];
3.邏輯運(yùn)算符
邏輯運(yùn)算符包含三種:邏輯與(&&)、邏輯或(?||?)、邏輯非(?!?)。
邏輯運(yùn)算操作與位操作不一樣,如果假設(shè)x與z不用,當(dāng)所有位都為0時(shí),則操作為false。當(dāng)至少有一位為1時(shí),則操作為ture。運(yùn)算結(jié)果通常為1bit。邏輯運(yùn)算符一般用在布爾表達(dá)式中的邏輯關(guān)系,如下面的例子:
(state==start)||(state==operator)&&(cnt>100)如表4-4所示,將邏輯運(yùn)算符和位操作運(yùn)算符的例子放在一起對(duì)比,我們可以很好比較這兩種運(yùn)算符的不同之處。
由于Verilog用“0”和“1”分別代表false和ture,所以在很多情況下,位操作和邏輯操作可以互相替換。然而,當(dāng)針對(duì)布爾表達(dá)式時(shí)用邏輯操作,而當(dāng)針對(duì)信號(hào)操作時(shí)用位操作。4.1.5連接與復(fù)制運(yùn)算符
連接運(yùn)算符?{}?能夠?qū)⒃鼗蛘咝〉臄?shù)組連接成一個(gè)大的數(shù)組。下面的例子表達(dá)了連接的含義:
wirea1;
wire[3:0]a4
wire[7:0]b8,c8,d8;
assignb8={a4,a4};
assignc8={a1,a1,a4,2'b00};
assignd8={b8[3:0],c8[3:0]};
連接運(yùn)算符同時(shí)也可以對(duì)input和output類型進(jìn)行連接操作,只需要“配線”就可以了。連接操作另外一種使用是可以對(duì)一個(gè)信號(hào)經(jīng)過移位和旋轉(zhuǎn)后再操作,如下例:
wire[7:0]a;
wire[7:0]rot,shl,sha;
assignrot={a[2:0],a[8:3]};//信號(hào)a左移3bit
assignsh1={3'b00,a[8:3]}; //信號(hào)a右移3bit并給高位插入0
assignsha={a[8],a[8],a[8],a[8:3]}; //信號(hào)a右移3bit并給高位插入a[8]
連接運(yùn)算符N{},表示復(fù)制括號(hào)里面的部分。N表示要復(fù)制的次數(shù),如{4{2'b01}}和8'01010101是一樣的。4.1.6條件運(yùn)算符
條件運(yùn)算符“?:”需要三個(gè)操作數(shù),一般的形式為
[信號(hào)]=[布爾表達(dá)式]?[操作數(shù)1]:[操作數(shù)2];
布爾表達(dá)式返回值為真(1‘b1)或者假為(1’b0)。如果返回值為“1”,[信號(hào)]返回[操作數(shù)1],否則返回[操作數(shù)2]。
也可以簡(jiǎn)單理解為
if[布爾表達(dá)式]then
[信號(hào)]=[操作數(shù)1];
else
[信號(hào)]=[操作數(shù)2];雖然描述方式簡(jiǎn)單,條件表達(dá)式還可以用來級(jí)聯(lián)操作,非常方便,比如下面的表達(dá)式:
assigneq=(~i1&~i0)?1‘b1:
(~i1&i0)?1’b1:
(i1&~i0)?z‘b1:
1’b1;
通過i1和i0的輸入進(jìn)行選擇eq信號(hào)的輸出,描述為一個(gè)兩輸入的數(shù)據(jù)選擇器。
下面電路表達(dá)式求a,b,c三個(gè)數(shù)中最大值:
assignmax=(a>b)?((a>c)?a:c);
(b>c)?((b>c)?b:c);
在綜合時(shí),條件運(yùn)算符映射為一個(gè)2選1電路。4.1.7位寬調(diào)整操作
在實(shí)際的硬件環(huán)境中,在VerilogHDL描述中的網(wǎng)線(net)和變量(variables),通常包含數(shù)值的位寬。在位寬不同時(shí),一定要注意根據(jù)如下規(guī)則進(jìn)行位寬的調(diào)整和變化:
(1)最長(zhǎng)的比特位由操作數(shù)來確定,包括左邊的操作數(shù)和右邊操作數(shù)。
(2)擴(kuò)展右邊的操作數(shù)位數(shù)為比特位數(shù)最大值,然后再進(jìn)行操作。
(3)在信號(hào)比特位數(shù)少的情況下,高位將被截掉,然后再賦值給左邊信號(hào)。下面考慮一個(gè)簡(jiǎn)單的例子:
wire[7:0]a,b;
assigna=8‘b00000000;
assignb=0;
語句1中,賦值a為一個(gè)8bit的值“00000000”,語句2中定義整數(shù)0給b,在Verilog語句中“integer”類型位寬為32bit,所以b的值相當(dāng)于“00…0000”(32個(gè))。由于定義b為8bit寬,那么高位被裁減最后為“00000000”,所以雖然兩條語句都是表示全0操作,依然要考慮到底給它賦了何值。下面再考慮另外一個(gè)例子:
wire[7:0]a,b;
wire[7:0]sum8;
wire[8:0]sum9;
assignsum8=a+b;
assignsum9=a+b;在第一條賦值語句中所有操作數(shù)位寬都是8,進(jìn)行加法運(yùn)算操作之后,進(jìn)位就被忽略掉了。第二條賦值語句中,a,b擴(kuò)展至9bit和sum9的比特位數(shù)一致。進(jìn)行加法運(yùn)算后,sum9[9]得到了進(jìn)位值。也可以用如下的形式進(jìn)行表示:
assign{c_out,sum8}=a+b;
雖然基本轉(zhuǎn)換規(guī)律非常簡(jiǎn)單和直觀,但是小的錯(cuò)誤還是難免的。比如定義a,b,sum1,和sum2為8bit的信號(hào),下面兩條語句將產(chǎn)生不同的結(jié)果:
assignsuml=(a+b)>>1; //sum1的最高位填0移位
assignsum2=(0+a+b)>>1;//將a+b之和的進(jìn)位結(jié)果移位到sum2最高位在第一條語句中,所有操作數(shù)為8bit位寬,并且進(jìn)行了一次加法運(yùn)算,那么進(jìn)位被丟棄掉。當(dāng)移位操作執(zhí)行后,0被移至最高位。在第二條語句中,0是integer類型,為32bit的位寬,所以a與b被擴(kuò)展至32位寬。然后將加法運(yùn)算的結(jié)果進(jìn)行移位。最后結(jié)果被高位裁掉至8bit后,sum2[7]得到進(jìn)位值。所以可以得出結(jié)論,如果考慮到信號(hào)類型就比較復(fù)雜了。
一種安全又笨拙的轉(zhuǎn)換方法,就是用人工的方式進(jìn)行轉(zhuǎn)換,如下面的例子所示:
wire[8:0]sum_ext; //將sum擴(kuò)展至9bit
…
assignsum_ext={1'b0,a}+{1'b0,b};
assignsum=sum_ext[9:1];4.1.8關(guān)于Z和X的綜合
除了0和1之外,線網(wǎng)和變量類型可以包含Z和X,雖然它們不是操作數(shù),但在綜合方面有著廣泛應(yīng)用。圖4-1三態(tài)緩沖器的符號(hào)標(biāo)志和功能表
1.關(guān)于Z的綜合
Z值表示高阻或者開漏極電路,不同于普通的邏輯值,只可被綜合為三態(tài)緩沖器。如圖4-1所示反映了其原件符號(hào)和功能表,緩沖器的操作由使能端控制,如果oe端為1,則輸出為輸入,否則輸出為高阻狀態(tài)。用語言表示如下:
assigny=(oe)?a_in:1'bz;
三態(tài)緩沖器最常用在雙端口,可以提高I/O口的利用率。如圖4-2所示,dir信號(hào)控制信號(hào)傳輸方向,當(dāng)dir為0時(shí),三態(tài)緩沖器為高阻狀態(tài)。sig_out被阻塞掉,管腳用作輸入,輸入信號(hào)到達(dá)sig_in。當(dāng)dir為1時(shí),管腳用作輸出端口,sig_out輸出到外部電路。圖4-2單緩沖器構(gòu)成的雙向IO口用HDL語言描述如下:
modulebi_demo(
inoutwirebi;
assignsig_out=output_expression;
assignsome_signal=expression_with_sig_in;
…
assignbi=(dir)?sig_out:q'bz;
assignsig_in=bi;
注意,bi端口一定要聲明為inout模式,以方便雙向傳輸操作。
對(duì)于XilinxSpartan-3器件來說,I/O模塊中包含三態(tài)緩沖器,所以,三態(tài)緩沖器可以被應(yīng)用在FPGA管腳上。
2.關(guān)于X的綜合
在一些組合邏輯電路中,有一些輸入模塊永遠(yuǎn)不會(huì)發(fā)生,即與輸出沒有任何關(guān)系。我們經(jīng)常認(rèn)為此輸出“無須關(guān)注”,在綜合時(shí),無須關(guān)注值要么賦值為1要么賦值為0。根據(jù)優(yōu)化情況而定??紤]4-5表的真值表,該值不會(huì)為11,所示output為不關(guān)注,綜合時(shí)我們用X表示不關(guān)注的值。如下面代碼所示:
assigny=(i==2‘b00)?1’b0:
(i==2‘b01)?1’b1:
(i==2‘b10)?1’b1:
1'bx;//i==1'b11;雖然這種方法簡(jiǎn)化了電路,卻給仿真和綜合之間制造了矛盾。在仿真時(shí),x只能被認(rèn)為是0或者1,若輸入為11,輸出為x,不會(huì)被認(rèn)為是綜合的結(jié)果。而是有可能被認(rèn)為是0也有可能被認(rèn)為是1,然而,因?yàn)?1不會(huì)發(fā)生,所以x將在TestBench時(shí)被認(rèn)為是錯(cuò)誤的。 4.2組合邏輯描述
4.2.1使用always模塊描述組合邏輯
為了促使模塊化,Verilog通常將大量的順序執(zhí)行的過程語句封裝在always模塊和initial模塊當(dāng)中。initial語句用在仿真文件中,只是在開始時(shí)執(zhí)行一次,而always模塊可以被綜合,由于過程語句比較抽象,所以通常也稱為行為描述。
always模塊可以被認(rèn)為是黑盒子。其行為是由封裝在它里面的過程語句組成的。過程語句構(gòu)造形式多樣,所以不規(guī)范的語句描述往往會(huì)導(dǎo)致沒有對(duì)應(yīng)的硬件模型與之對(duì)應(yīng),或者可導(dǎo)致不必要的邏輯被執(zhí)行,從而無法被綜合工具所綜合。在always模塊中使用的行為描述語句一般包括如下三類:過程賦值語句、if語句和case語句。帶有敏感量列表的always模塊的基本結(jié)構(gòu)如下:
always(【敏感量列表】)
begin[塊內(nèi)變量聲明
[順序執(zhí)行語句];
[順序執(zhí)行語句];
…
end
敏感量列表中列舉了always語句在執(zhí)行過程中相對(duì)比較“敏感”的信號(hào)。這些“敏感信號(hào)”可以決定always語句的掛起和激活。always語句內(nèi)部順序執(zhí)行語句一旦開始執(zhí)行,就不受其他任何因素所控制,直到執(zhí)行完所有語句,當(dāng)有新的敏感量信號(hào)改變時(shí),always語句才重新被激活。所以always模塊是在敏態(tài)量列表控制下永遠(yuǎn)循環(huán)執(zhí)行的。
對(duì)于組合邏輯電路來說,所有的輸入信號(hào)都要放在敏感量列表中。主體部分由多條過程語句組成。如果只有一條過程語句,則begin和end可以被省略掉。4.2.2使用賦值語句描述組合邏輯
賦值語句只能被用在always模塊或initial模塊當(dāng)中。有兩種類型的賦值,一種是阻塞賦值,另外一種是非阻塞賦值。其語法格式為
[變量名]=[表達(dá)式]; //阻塞賦值語句
[變量名]<=[表達(dá)式]; //非阻塞賦值語句
根據(jù)阻塞賦值的概念,在執(zhí)行下條語句之前。表達(dá)式先被估計(jì),然后立即賦值給變量,其行為與C語言中變量的賦值是一樣的。在非阻塞賦值中,表達(dá)式的估計(jì)值在所有語句執(zhí)行完之后才進(jìn)行賦值操作(即本次賦值并未阻止其它語句的執(zhí)行)。對(duì)于初學(xué)者來說,阻塞賦值與非阻塞賦值兩者非常容易搞混。其一般原則是:
(1)在時(shí)序邏輯中用非阻塞賦值;
(2)在組合邏輯中用阻塞賦值。
兩者之間的區(qū)別在第七章將詳細(xì)講解。4.2.3舉例說明
【程序4-1】采用always塊語句描述第三章講過的1位比較器電路。
moduleeq1_always
(
inputwirei0,i1,
outputregeq //eq定義為reg型
);
regp0,p1; //p0和p1聲明為reg型
always@(i0,i1) //i0和i1必須要在敏感量列表當(dāng)中
begin
//下面語句的順序是非常關(guān)鍵的
p0=~i0&~i1;
p1=i0&i1;
eq=p0|p1;
end
endmodule
由于eq、p0和p1在always模塊里面賦值,所以聲明為reg數(shù)據(jù)類型。敏感量列表中有i0和i1,用逗號(hào)隔開,當(dāng)它們之間有一個(gè)改變后,always模塊被激活,三條阻塞語句順序執(zhí)行。這和C語言當(dāng)中是一樣的。此時(shí)語句的順序非常重要,p0和p1在使用之前必須要先賦值,否則就會(huì)出錯(cuò)。
在verilog-1995版本中,敏感量列表中用關(guān)鍵字or來替代逗號(hào)。比如說:
always@(a,b,c)
被寫為
always@(aorborc);組合邏輯電路要將所有的輸入信號(hào)都包含在敏感量列表當(dāng)中,缺少一個(gè)信號(hào)都會(huì)在綜合和仿真中造成差別,而在Verilog-2001中,可以使用下面的表達(dá)式來表示覆蓋所有的敏感量:
always@*
本書都采用這種表達(dá)方式。如此一來,既方便還可以避免敏感量列舉不全。
前面舉的例子都是持續(xù)賦值語句。然而持續(xù)賦值語句和過程語句是有區(qū)別的,如程序4-2,程序執(zhí)行的功能是完成輸入信號(hào)a、b、c相與。
【程序4-2】三輸入與門電路。
moduleand_block_assign
(
inputwirea,b,c,
outputregy
);
always@*
begin
y=a;
y=y&b;
y=y&c;
end
endmodule
程序4-2所對(duì)應(yīng)的電路如圖4-3(a)所示,用同樣的方式將always塊用賦值語句死板代替,就成了程序4-3。
【程序4-3】對(duì)程序4-2進(jìn)行always塊替換之后的程序。
moduleand_cont_assign
(
inputwirea,b,c,
outputwirey
);
assigny=a;
assigny=y&b;
assigny=y&c;
endmodule圖4-3不同編碼方式所綜合得到的電路圖 4.3條件控制語句
4.3.1if-else語句
1.語法格式
if-else語句的語法格式如下:
if[布爾表達(dá)式]
begin
[過程語句];
[過程語句];
…
end
else
begin
[過程語句];
[過程語句];
…
end
布爾表達(dá)式首先被執(zhí)行,當(dāng)它為真時(shí),執(zhí)行順序分支,否則執(zhí)行else分支。else分支是可選的,不需要時(shí)可以略去,如果有多個(gè)條件,則可以使用if語句級(jí)聯(lián),并能確定條件的優(yōu)先級(jí)。比如有下面的例子:
if[布爾表達(dá)式1]
…
elseif[布爾表達(dá)式2]
elseif[布爾表達(dá)式3]
…
else
…
在綜合時(shí),布爾表達(dá)式1優(yōu)先級(jí)最高,布爾表達(dá)式2次之,依次論推。
2.舉例
【程序4-4】?jī)?yōu)先級(jí)譯碼器。優(yōu)先級(jí)譯碼器有四個(gè)條件信號(hào),分別是r信號(hào)的四個(gè)比特位:r[4]、r[3]、r[2]和r[1],其中r[4]的優(yōu)先級(jí)最高,輸出為高優(yōu)先級(jí)條件下的二進(jìn)制碼,其真值表如表4-6所示。對(duì)應(yīng)的HDL代碼如下所示:
moduleprio_encoder_if
(
inputwire[4:1]r,
outputreg[2:0]y
);
always@*
if(r[4]==1'b1)//也可以是(r[4])
y=3'b100;
else
if(r[3]==1'b1)//也可以是(r[3])
y=3'b011;
elseif(r[2]==1'b1)//也可以是(r[2])
y=3'b010;
elseif(r[1]==1'b1)//也可以是(r[1])
y=3'b001;
else
y=3'b000;
endmodule
代碼首先檢查r[4]條件是否滿足。如果滿足,則y賦值為“3'b100”;如果r[4]條件不滿足,則繼續(xù)檢查r[3]信號(hào);如果r[3]信號(hào)滿足,則y賦值為“3'b011”,否則繼續(xù)檢查下一位信號(hào),依次類推,直到所有的條件都檢查一遍。注意的是,當(dāng)r[4]為1時(shí),布爾表達(dá)式(r[4]==1'b1)為真,所以可以直接將布爾表達(dá)式寫為(r[4])。
【程序4-5】二進(jìn)制解碼器。一個(gè)n-2n二進(jìn)制解碼器,根據(jù)輸入n值將對(duì)應(yīng)的2n輸出位置1,如果n為2,則其真值表如表4-7所示。電路同時(shí)需要一個(gè)使能信號(hào)en,代碼如下所示:
moduledecoder_2_4_if
(
inputwire[1:0]a,
inputwireen,
outputreg[3:0]y
);
always@*
if(en==1'b0) //也可以為(~en)
y=4'b0000;
elseif(a==2'b00)
y=4'b0001;
elseif(a==2'b01)
y=4'b0010;
elseif(a==2'b10)
y=4'b0100;
else
y=4'b1000;
endmodule4.3.2case語句
1.語法格式
case語句的語法格式如下:
case[控制表達(dá)式]
[分支表達(dá)式值1]:
begin
[過程語句];
…
end
[分支表達(dá)式值2]:
begin
[過程語句];
…
end
…
default:
begin
[過程語句];
end
endcase
case語句是多分支選擇語句。前面講的if語句只有兩個(gè)分支可供選擇,case語句根據(jù)控制表達(dá)式的值來選擇分支,如果控制表達(dá)式的值與某個(gè)分支表達(dá)式值相等,則選擇執(zhí)行該分支的語句;如果控制表達(dá)式的值和所有分支表達(dá)式值都不相等,則選擇default分支語句執(zhí)行。如果某個(gè)分支執(zhí)行語句僅由一條語句組成,則begin和end可以省略。default項(xiàng)可以省略,但是容易產(chǎn)生鎖存器,所以建議讀者盡量保持default語句的存在。
case語句的各個(gè)分支是獨(dú)立且互不相同的,不然就會(huì)失去多路選擇的意義。
2.舉例
我們同樣用case語句實(shí)現(xiàn)優(yōu)先級(jí)編碼和譯碼電路來舉例,2-4譯碼器真值表如表4-7所示,HDL代碼如程序4-6所示。
【程序4-6】使用case語句實(shí)現(xiàn)2-to-4譯碼器。
moduledecoder_2_4_case
(
inputwire[1:0]a,
inputwireen,
outputreg[3:0]y
);
always@*
case({en,a})
3'b000,3'b001,3'b010,3'b011:y=4'b0000;
3'b100:y=4'b0001;
3'b101:y=4'b0010;
3'b110:y=4'b0100;
3'b111:y=4'b1000; //也可以作為default項(xiàng)
endcase
endmodule
在case語句中,如果多個(gè)條件表達(dá)式對(duì)應(yīng)同一條執(zhí)行語句,我們可以將多個(gè)分支值列舉在一起,比如程序4-6。需要注意一點(diǎn),如果控制表達(dá)式為{en,a},即所有的狀態(tài)都列舉到了,那么default語句可以省略。
【程序4-7】使用case語句描述2-4譯碼器。
moduleprio_encoder_case
(
inputwire[4:1]r,
outputreg[2:0]y
);
always@*
case(r)
4'b1000,4'b1001,4'b1010,4'b1011,
4'b1100,4'b1101,4'b1110,4'b1111:y=3'b100;
4'b0100,4'b0101,4'b0110,4'b0111:y=3'b011;
4'b0010,4'b0011:y=3'b010;
4'b0001:y=3'b001;
4'b0000:y=3'b000; //也可以作為default項(xiàng)
endcase
endmodule4.3.3casez和casex語句
在casez語句中,分支表達(dá)式值中包含有z和?,都不用理睬(don'tcare);在casex語句中,分支表達(dá)式值中包含有z、x和?,也都不理睬(don'tcare)。
比如將優(yōu)先級(jí)編碼器電路用casez語句描述,如程序4-8所示。
【程序4-8】使用casez語句描述優(yōu)先級(jí)編碼器電路。
moduleprio_encoder_casez
(
inputwire[4:1]r,
outputreg[2:0]y
);
always@*
casez(r)
4'b1???:y=3'b100;
4'b01??:y=3'b011;
4'b001?:y=3'b010;
4'b0001:y=3'b001;
4'b0000:y=3'b000; //default同樣可以被省略
endcase
endmodule
4.3.4“fullcase”和“parallelcase”語句
在Verilog中,分支表達(dá)式不必覆蓋所有控制表達(dá)式的值,而且某些分支表達(dá)式值可以匹配多次,比如下面的例子:
reg[2:0]:s
…
casez(s)
3‘b111: y=l’bl;
3‘bl??: y=l’b0;
3'b000: y=l'bl;
endcase
在上例中,3'b111匹配了兩次,但是當(dāng)s為3'b111時(shí),由于第一條語句優(yōu)先級(jí)高,所以y的值為1'b1;當(dāng)s為3'b001、3'b010或者3'b011時(shí),y的值只能保持原來的值,這樣y就不會(huì)得到一個(gè)確定的值。如此一來,就容易綜合成鎖存器。在數(shù)字電路中對(duì)鎖存器一定要慎用。
當(dāng)控制表達(dá)式的所有可能值都被分支表達(dá)式所覆蓋時(shí),此表達(dá)式稱為“fullcase”表達(dá)式。在組合邏輯電路中,必須用“fullcase”語句,因?yàn)槊總€(gè)輸入都對(duì)應(yīng)一個(gè)輸出值。如果不能完全覆蓋所有列舉項(xiàng)的情況下,需要增加default項(xiàng)來確定沒有覆蓋值的狀態(tài),比如前面舉例可以修改為
casez(s)
3‘b111:y=l’bl;
3‘b1??:y=l’b0;
default:y=l‘bl; //當(dāng)s不為以上兩種情況時(shí)y賦值為1
endcase
或者
casez(s)
3’blll:y=l‘bl;
3’bl??:y=l‘b0;
3'b000:y=l'bl;
default:y=l'bx; //y值為不確定
endcase
當(dāng)所有分支項(xiàng)值是互相不相同時(shí),稱為“parallelcase”語句。比如前面舉例s的值3'b111出現(xiàn)兩次,就不屬于“parallelcase”語句,而程序4-6和程序4-7都屬于“parallelcase”語句。
在綜合時(shí),“parallelcase”語句綜合成多路布線網(wǎng)絡(luò),而“non-parallelcase”語句傾向于綜合成優(yōu)先級(jí)布線網(wǎng)絡(luò)。許多綜合軟件中都有是否選擇“fullcasedirective”和“parallelcasedirective”的選項(xiàng)。如果選擇有效,所有case語句則都按照fullcase和parallelcase的原則來綜合。大家在使用綜合工具進(jìn)行綜合時(shí),要注意選擇合適的綜合選項(xiàng),這樣可有效提高設(shè)計(jì)的質(zhì)量。 4.4.條件控制語句的布線結(jié)構(gòu)
4.4.1優(yōu)先級(jí)布線網(wǎng)絡(luò)
首先舉一個(gè)2選1選擇器的例子,其真值表和框圖如4-4(a)所示。采用if-else語句實(shí)現(xiàn)優(yōu)先級(jí)布線網(wǎng)絡(luò),代碼如下:
if(m==n)
r=a+b+c;
elseif(m>n)
r=a-b;
else
r=c+1:圖4-42選1選擇器圖4-4(b)描述了2選1選擇器的基本結(jié)構(gòu)。兩個(gè)2選1選擇器實(shí)現(xiàn)布線優(yōu)先級(jí)網(wǎng)絡(luò),其它模塊實(shí)現(xiàn)布爾變量和數(shù)學(xué)表達(dá)。如果第一個(gè)布爾表達(dá)式條件滿足(如m=n),則端口1的值(a+b+c)賦給r,否則端口0的值將賦給r;端口0的值由另外一個(gè)布爾表達(dá)式?jīng)Q定,當(dāng)m>n時(shí)為a-b,否則為c+1。
需要注意的是,所有布爾表達(dá)式和數(shù)學(xué)表達(dá)式都是并行執(zhí)行的。布爾表達(dá)式的輸出決定r的賦值。隨著if-else分支增多,優(yōu)先級(jí)級(jí)聯(lián)層數(shù)越多,同時(shí)也會(huì)產(chǎn)生越長(zhǎng)時(shí)間的延時(shí)。4.4.2多路選擇布線網(wǎng)絡(luò)
多路選擇網(wǎng)絡(luò)最終實(shí)現(xiàn)為一個(gè)n到1的多路選擇器,選擇信號(hào)選擇決定n個(gè)輸入端口中的1個(gè)到輸出端口,多路選擇器的結(jié)構(gòu)和功能表如圖4-5所示。在并行case語句中,可以使case語句的每一個(gè)條件表達(dá)式對(duì)應(yīng)多路選擇器中的一個(gè)條件,將輸入和輸出端口映射起來。比如上小節(jié)講述的例子,可以表示如下:
wire[1:0]sel;
…
case(sel)
2'b00:r=a+b+c;
2'b10:r=a-b;
default:r=r+1;
endcase
圖4-54選1選擇器結(jié)構(gòu)圖和功能表圖4-6case語句執(zhí)行詳細(xì)邏輯電路框圖同樣需要注意的是,所有的表達(dá)式都是并行執(zhí)行的。sel變量作為選擇信號(hào)來選擇合適的輸出值。sel的位寬增加意味著多路選擇器的輸入端口增多。
通常來說,當(dāng)描述在某種情況下對(duì)輸出有偏愛時(shí)采用優(yōu)先級(jí)布線網(wǎng)絡(luò),如優(yōu)先編碼器等;當(dāng)描述基于真值表或者函數(shù)表時(shí)采用多路選擇布線網(wǎng)絡(luò),如二進(jìn)制解碼器等。 4.5always語句的編程指導(dǎo)
編寫可綜合的Verilog代碼,必須考慮到代碼在硬件結(jié)構(gòu)上具體綜合成怎樣的電路而不能像編寫C語言代碼一樣僅僅考慮數(shù)學(xué)上的邏輯。在使用always語句時(shí),尤其要考慮這一點(diǎn),因?yàn)樵赼lways模塊中變量和過程語句可以同時(shí)存在。下面分析在組合邏輯電路設(shè)計(jì)中,幾條大家非常容易犯錯(cuò)誤的地方:
(1)在多個(gè)always模塊中對(duì)同一變量賦值;
(2)不完全列舉敏感量列表;
(3)分支列舉不完全和輸出賦值不完全。
1.在多個(gè)always模塊中對(duì)同一變量賦值
在Verilog中,變量可以在多個(gè)always模塊中賦值,也可以理解為可以同時(shí)出現(xiàn)在多個(gè)always模塊中的賦值語句左邊。如下面的例子,變量y同時(shí)被兩個(gè)always語句共享:
regy;
rega,b,clear;
always@*
if(clear)y=l'b0;
always@*
y=a&b;此電路雖然語法沒有問題,并且可以仿真,但是無法綜合的。因?yàn)槊總€(gè)always模塊是一個(gè)電路,如果y同時(shí)被兩個(gè)電路所賦值,那么y的值可以被兩塊電路同時(shí)修改,從物理角度上理解是沒有實(shí)際電路能夠?qū)崿F(xiàn)這一功能的。解決這個(gè)問題的辦法是將所有的情況放在一個(gè)always模塊中。比如上面舉例,可以修改為
always@*
if(clear)
y=l‘b0;
else
y=a&b;
2.不完全列舉敏感量列表
對(duì)于組合邏輯電路來說,輸出是輸入的函數(shù),對(duì)于輸入信號(hào)的任何改變都會(huì)引起輸出值的改變,所以我們要將所有本模塊用到的輸入都寫在敏感量列表當(dāng)中。比如兩輸入的與電路可以寫為
always@(a,b) //a和b都在敏感量列表中
y=a&b;
如果忘記了將b寫入敏感量列表當(dāng)中,代碼變成了:
always@(a) //敏感量列表中少寫了b變量
y=a&b;雖然后者可以順利通過語法檢查,但是執(zhí)行起來就費(fèi)勁了。當(dāng)a改變時(shí),always模塊被激活,y等于a&b的值;當(dāng)b改變時(shí),always模塊依然保持原來的值,因?yàn)樗鼘?duì)b并不敏感,顯然不符合我們的設(shè)計(jì)意圖。此時(shí)許多綜合軟件都會(huì)提出告警,但是不會(huì)報(bào)錯(cuò),所以大家需要切記這一點(diǎn)。
在Verilog-2001中,用到一個(gè)特殊的符號(hào)@*,表示所有的本always塊中的輸入都列舉在敏感量列表當(dāng)中,建議大家盡量使用@*?描述。
3.分支列舉不完全和輸出賦值不完全
組合邏輯電路的輸出僅僅是輸入的函數(shù),所以組合邏輯電路不包含任何內(nèi)部狀態(tài)(比如memory)。然而根據(jù)Verilog標(biāo)準(zhǔn)規(guī)定,變量在always語句中如果沒有賦值,則會(huì)保持原來的值不變,這時(shí)它就會(huì)綜合成一個(gè)內(nèi)部狀態(tài)(通過閉環(huán)反饋)或者一個(gè)寄存狀態(tài)(比如鎖存器),這在組合邏輯電路中是不允許的。
為了避免在always模塊中不確定寄存器的出現(xiàn),所有輸出信號(hào)在任何時(shí)候都要有確定的賦值。if或者case語句條件分支列舉不完全或者輸出賦值不完全是兩種常見的導(dǎo)致不確定寄存器出現(xiàn)的情況,所以在開發(fā)組合邏輯電路時(shí)應(yīng)把握以下兩點(diǎn):
(1)在if和case語句中列舉所有的分支;
(2)在每個(gè)分支條件下對(duì)每一個(gè)輸出信號(hào)都要賦值。
如下面的代碼:
always@*
if(a>b) //此分支中沒有給eq賦值
gt=l‘bl;
elseif(a==b) //此分支中沒有給gt賦值
eq=l’bl;
//else分支也被省略掉了這段電路的目的是描述一個(gè)這樣的功能:當(dāng)a大于b時(shí),gt輸出為1;當(dāng)a等于b時(shí),eq輸出為1。這種電路我們平時(shí)用的非常多,如果簡(jiǎn)單的翻譯過來就是上面這段代碼,但是用剛才的兩條原則來分析,發(fā)現(xiàn)兩條原則全部被破壞了。
首先是不完全分支電路,電路中沒有考慮當(dāng)a小于b時(shí),gt和eq到底輸出什么,那么根據(jù)Verilog語法規(guī)定,只能是保持原來的值,這樣顯然形成鎖存器。
其次我們考慮不完全輸出錯(cuò)誤,比如說,當(dāng)a大于b時(shí),eq沒有賦值,所以eq也會(huì)保持原來的值不變,同樣也會(huì)形成一個(gè)鎖存器。所以為了解決上面的錯(cuò)誤,代碼就需要改動(dòng)。首先加上沒考慮到的分支,并給輸出賦值,代碼修改為
always@*
if(a>b)
begin
gt=l‘bl;
eq=1’b0;
end
elseif(a==b)
begin
gt=l‘b0;
eq=l’bl;
end
else //a<b
begin
gt=l‘b0;
eq=l'b0;
end
另外一種修改錯(cuò)誤的方法是在always模塊的開始將所有信號(hào)賦默認(rèn)值,以防發(fā)生不完全賦值,代碼相對(duì)簡(jiǎn)潔,比如:
always@*
begin
gt=l‘b0; //為gt賦默認(rèn)值
eq=l’b0; //為eq賦默認(rèn)值
if(a>b)
gt=l‘bl;
elseif(a==b)
eq=l'bl;
end
case語句也很容易出現(xiàn)上述的錯(cuò)誤。在控制表達(dá)式的所有值沒有被完全覆蓋的情況下就會(huì)出現(xiàn)上述錯(cuò)誤,比如下面的例子:
reg[1:0]s
…
case(s)
2'b00:y=l'bl;
2'bl0:y=l'b0;
2'bll:y=l'bl;
endcase
2'b01值沒有在表達(dá)式值中覆蓋,那么在此條件下,y值保持原來的值就會(huì)形成意料不到的鎖存器。為了避免這個(gè)錯(cuò)誤,要確定y在所有情況下都有確定的值,采用的方法就是在case語句最后加default語句:
case(s)
2’b00:y=l‘bl;
2’bl0:y=l‘b0;
default:y=l'bl; //當(dāng)s為2'b0l時(shí),y為1
endcase或者增加條件表達(dá)式,并賦值為無關(guān)值:
case(s)
2‘b00:y=l’bl;
2‘bl0:y=l’b0;
2‘bll:y=l’bl;
default:y=l‘bx; //s為2’b01時(shí)y賦值為x
endcase
或者可以選擇在always塊開始給y賦一個(gè)默認(rèn)值:
y=1‘b0; //也可以賦值y=1’bx
case(s)
2‘b00:y=l’bl;
2‘bl0:y=l’b0;
2'bll:y=l'bl;
endcase 4.6工程實(shí)踐
4.6.1十六進(jìn)制數(shù)到七段數(shù)碼管譯碼器
七段數(shù)碼管結(jié)構(gòu)如圖4-7所示,它包含七個(gè)LED發(fā)光二極管。本書以共陰極七段數(shù)碼管為例,即如果LED的發(fā)光二極管控制端為低,則對(duì)應(yīng)發(fā)光二極管亮。圖4-7七段數(shù)碼管顯示及其十六進(jìn)制數(shù)值表示如果還有小數(shù)點(diǎn),那么對(duì)于七段數(shù)碼管實(shí)際成八段了。按照?qǐng)D4-7(a)所示,數(shù)碼管控制信號(hào)為a、b、c、d、e、f、g和dp,我們可以定義為一條總線,命名為sseg,輸入為4bit的十六進(jìn)制數(shù),比如輸入為“0001”,那么數(shù)碼管顯示值應(yīng)該為1;按照?qǐng)D4-7(b)所示,應(yīng)該點(diǎn)亮b和c段,因?yàn)槭枪碴帢O電路連接方式,所以給數(shù)碼管控制總線的譯碼值為:“10011111”。代碼如程序4-9所示。
【程序4-9】七段數(shù)碼管譯碼電路。
modulehex_to_sseg
(
inputwire[3:0]hex,
inputwiredp,
outputreg[7:0]sseg//輸出低有效
);
always@*
begin
case(hex)
4'h0:sseg[6:0]=7'b0000001;
4'h1:sseg[6:0]=7'b1001111;
4'h2:sseg[6:0]=7'b0010010;
4'h3:sseg[6:0]=7'b0000110;
4'h4:sseg[6:0]=7'b1001100;
4'h5:sseg[6:0]=7'b0100100;
4'h6:sseg[6:0]=7'b0100000;
4'h7:sseg[6:0]=7'b0001111;
4'h8:sseg[6:0]=7'b0000000;
4'h9:sseg[6:0]=7'b0000100;
4'ha:sseg[6:0]=7'b0001000;
4'hb:sseg[6:0]=7'b1100000;
4'hc:sseg[6:0]=7'b0110001;
4'hd:sseg[6:0]=7'b1000010;
4'he:sseg[6:0]=7'b0110000;
default:sseg[6:0]=7'b0111000;//4'hf
endcase
sseg[7]=dp;
end
endmodule
驗(yàn)證板上有4個(gè)七段數(shù)碼管,它們共用數(shù)據(jù)控制端。為了4個(gè)數(shù)碼管能夠正確顯示,需要一個(gè)時(shí)序分配模塊。時(shí)序分配模塊如圖4-8(a)所示。4個(gè)七段數(shù)碼管的控制端(sseg)對(duì)應(yīng)連接在時(shí)序分配模塊的輸入端:in0、in1、in2和in3,時(shí)序分配模塊按照一定的時(shí)間優(yōu)先級(jí)通過控制4個(gè)七段數(shù)碼管的使能信號(hào),控制4個(gè)輸入輪換有效,這就是動(dòng)態(tài)掃描的原理。只要輪換刷新的速率能夠“欺騙”人眼(大于24Hz),人們就可以看到每個(gè)數(shù)碼管的數(shù)字都不一樣。詳細(xì)內(nèi)容第五章再講,目前大家當(dāng)黑盒子使用就可以了。測(cè)試電路如下:
我們采用8bit加法電路對(duì)剛才的設(shè)計(jì)進(jìn)行驗(yàn)證,設(shè)計(jì)框架如圖4-8(b)所示。驗(yàn)證板的輸入撥碼開關(guān)sw為8bit,設(shè)計(jì)兩個(gè)數(shù)碼管分別顯示撥碼開關(guān)指示的高四位值和低四位值,另外兩個(gè)數(shù)碼管分別顯示撥碼開關(guān)指示值加1之后的高四位值和低四位值。代碼如程序4-10所示。圖4-8LED動(dòng)態(tài)掃描電路以及測(cè)試電路框圖
【程序4-10】七段數(shù)碼管測(cè)試電路。
modulehex_to_sseg_test
(
inputwireclk,
inputwire[7:0]sw,
outputwire[3:0]an,
outputwire[7:0]sseg
);
//信號(hào)聲明
wire[7:0]inc;
wire[7:0]led0,led1,led2,led3;
//增加輸入
assigninc=sw+1;
//例化四輸入十六進(jìn)制譯碼器
//例化低四位輸入
hex_to_ssegsseg_unit_0
(.hex(sw[3:0]),.dp(1'b0),.sseg(led0));
//例化高四位輸入
hex_to_ssegsseg_unit_1
(.hex(sw[7:4]),.dp(1'b0),.sseg(led1));
//例化低四位加法值
hex_to_ssegsseg_unit_2
(.hex(inc[3:0]),.dp(1'b1),.sseg(led2));
//例化高四位加法值
hex_to_ssegsseg_unit_3
(.hex(inc[7:4]),.dp(1'b1),.sseg(led3));
//例化7段數(shù)碼管多路選擇模塊
disp_muxdisp_unit
(.clk(clk),.reset(1'b0),.in0(led0),.in1(led1),
.in2(led2),.in3(led3),.an(an),.sseg(sseg));
endmodule
4.6.2帶符號(hào)加法器設(shè)計(jì)
整數(shù)可以表示成帶符號(hào)形式,最高位表示符號(hào)位。如果為1,則表示負(fù)數(shù),如果為0,則表示正數(shù),剩下位數(shù)表示數(shù)值。比如在四位帶符號(hào)數(shù)下表示:2表示為“0010”,-2表示為“1010”。
帶符號(hào)加法器需要執(zhí)行加法操作,可以根據(jù)這種特殊數(shù)據(jù)表示方法分情況討論:
(1)如果兩個(gè)操作數(shù)都是正的,直接對(duì)值進(jìn)行相加,并保持符號(hào)位;
(2)如果兩個(gè)操作數(shù)符號(hào)位不同,即一正一負(fù),那么用值相對(duì)大的操作數(shù)減去值小的操作數(shù),并保留值大的操作數(shù)的符號(hào)位為最終結(jié)果的符號(hào)位。設(shè)計(jì)過程可以分成兩個(gè)步驟:①將輸入值進(jìn)行分類,按照它們的值大小標(biāo)記為max和min信號(hào);②檢查符號(hào)位對(duì)值進(jìn)行加法或者減法操作。應(yīng)注意到,只要兩個(gè)輸入數(shù)經(jīng)過分類,最終結(jié)果的符號(hào)位就已確定為max的符號(hào)位。測(cè)試框圖如圖4-8所示。
代碼如程序4-11所示。為了描述清晰,可以讓輸入信號(hào)由內(nèi)部產(chǎn)生,并且符號(hào)位和數(shù)值信號(hào)分開,并定義參數(shù)N,表示加法器的位數(shù)。
【程序4-11】帶符號(hào)加法器。
modulesign_mag_add
#(
parameterN=4
)
(
inputwire[N-1:0]a,b,
outputreg[N-1:0]sum
);
//信號(hào)聲明
reg[N-2:0]mag_a,mag_b,mag_sum,max,min;
regsign_a,sign_b,sign_sum;
//主體部分
always@*
begin
//符號(hào)和數(shù)值位分開
mag_a=a[N-2:0];
mag_b=b[N-2:0];
sign_a=a[N-1];
sign_b=b[N-1];
//根據(jù)符號(hào)分類
if(mag_a>mag_b)
begin
max=mag_a;
min=mag_b;
sign_sum=sign_a;
end
else
begin
max=mag_b;
min=mag_a;
sign_sum=sign_b;
end
//符號(hào)位進(jìn)行加減
if(sign_a==sign_b)
mag_sum=max+min;
else
mag_sum=max-min;
//輸出邏輯
sum={sign_sum,mag_sum};
end
endmodule
測(cè)試電路如下:
我們采用4位帶符號(hào)加法器來驗(yàn)證電路操作,測(cè)試框架如圖4-9所示。兩個(gè)輸入數(shù)值由8位撥碼開關(guān)來輸入,符號(hào)位和數(shù)值位顯示在兩個(gè)七段數(shù)碼管上,兩個(gè)按鍵作為多路選擇器的輸入,從而選擇發(fā)送操作數(shù)或者結(jié)果值送數(shù)碼管顯示。第一個(gè)數(shù)碼管顯示結(jié)果值,通過將3bit值高位填0,送到十六進(jìn)制數(shù)到七段數(shù)碼管模塊,來顯示結(jié)果值。另外一個(gè)數(shù)碼管顯示符號(hào)位,如果為正,則不顯示任何值;如果為負(fù),則顯示數(shù)碼管中間一段,如圖4-7所示g段。兩個(gè)數(shù)碼管數(shù)值反饋到時(shí)序選擇模塊,也就是disp_mux。第五章將詳細(xì)講解。具體代碼如程序4-12所示。圖4-9帶符號(hào)加法器測(cè)試電路圖
【程序4-12】帶符號(hào)加法器測(cè)試電路。
modulesm_add_test
(
inputwireclk,
inputwire[1:0]btn,
inputwire[7:0]sw,
outputwire[3:0]an,
outputwire[7:0]sseg
);
//信號(hào)聲明
wire[3:0]sum,mout,oct;
wire[7:0]led3,led2,led1,led0;
//初始化加法器
sign_mag_add#(.N(4))sm_adder_unit
(.a(sw[3:0]),.b(sw[7:4]),.sum(sum));
//幅度顯示在最右端7-segLED上
assignmout=(btn==2‘b00)?sw[3:0]:
(btn==2’b01)?sw[7:4]:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 樁基冬季施工方案
- 農(nóng)業(yè)項(xiàng)目資金籌措方案
- 汽車行業(yè)基礎(chǔ)知識(shí)
- 大理石樓地面施工方案
- 紅磚建筑加固施工方案
- 2025年非調(diào)質(zhì)鋼項(xiàng)目發(fā)展計(jì)劃
- 山東省濱州市鄒平市2024-2025學(xué)年七年級(jí)上學(xué)期期末考試數(shù)學(xué)試卷(原卷版+解析版)
- 非機(jī)動(dòng)車棚工程施工方案
- 隨州鋼結(jié)構(gòu)農(nóng)村房施工方案
- 沂源公路標(biāo)志牌施工方案
- 《復(fù)雜系統(tǒng)理論》課件
- 人教版(2025新版)七年級(jí)下冊(cè)數(shù)學(xué)第七章 相交線與平行線 單元測(cè)試卷(含答案)
- 汽輪機(jī)輔機(jī)培訓(xùn)
- 國(guó)之重器:如何突破關(guān)鍵技術(shù)-筆記
- 早產(chǎn)兒和低出生體重兒袋鼠式護(hù)理臨床實(shí)踐指南(2024)解讀1
- 三廢環(huán)保管理培訓(xùn)
- 第四章 特殊條件下的駕駛ppt課件
- 特種設(shè)備變更登記申請(qǐng)表
- 鉆孔樁施工橫道圖
- (最新)金鑰匙科技競(jìng)賽試題及答案
- 《檢驗(yàn)檢測(cè)機(jī)構(gòu)資質(zhì)認(rèn)定評(píng)審準(zhǔn)則》及釋義
評(píng)論
0/150
提交評(píng)論