




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第6章基于EDA的組合電路設計、
?綜合及驗證
6.1基本邏輯門電路6.2編碼器6.3譯碼器6.4數(shù)據(jù)選擇器6.5數(shù)值比較器6.6加法器6.7乘法器6.8組合邏輯電路的競爭冒險問題6.9組合邏輯電路的綜合性實例
學習基礎:
第2章介紹了組合邏輯電路的基礎知識,組合邏輯電路在數(shù)字系統(tǒng)中起著基本組件的作用。
第4章介紹了VerilogHDL的基本語法及簡單設計的建模方法。
5.5節(jié)~5.7節(jié)的綜合實例,介紹了EDA工具LiberoIDE的使用方法。本章所有綜合和驗證均基于LiberoIDE環(huán)境實現(xiàn)。閱讀指南:
本章講述內容對應第2章的知識,把相應組合邏輯電路的功能通過VerilogHDL語言進行實現(xiàn)。對每個電路設計的基礎知識和理解請參考第2章。
本章多處對同一個設計提供了多種設計思路和實現(xiàn)方法,并不是所有都是最優(yōu)的方法,只是方便對比和學習。讀者可根據(jù)情況選擇合適的方法。
6.9節(jié)中設計了多個綜合例子(第2章中沒有與這些例子相對應的設計),這些例子綜合性強,相對較難理解但卻很實用,對于想進入數(shù)字系統(tǒng)設計實踐階段的讀者來說很有實際意義。
6.1基本邏輯門電路
基本邏輯門電路的Verilog描述是代碼設計的基礎,下面給出了部分門電路的設計描述及仿真實例。
6.1.1基本邏輯門電路的Verilog設計
以下程序中設計了5種基本的2輸入門電路:與、或、異或、與非、或非。
modulegates(a,b,y1,y2,y3,y4,y5);
inputa,b;
outputy1,y2,y3,y4,y5;
//連續(xù)賦值語句一般用于描述組合邏輯
assigny1=a&b; //與
assigny2=a|b; //或
assigny3=a^b; //異或
assigny4=~(a&b); //與非
assigny5=~(a|b); //或非
endmodule
6.1.2基本邏輯門電路的綜合
在Synplify綜合工具中進行綜合操作,將前述Verilog程序轉化為門級電路。電路圖由綜合工具自動生成,點擊Synplify的工具欄按鈕,可查看“RTLView”(如圖6-1所示)。圖6-1基本邏輯門電路的RTL視圖6.1.3測試平臺設計
基本邏輯門電路測試平臺的代碼設計如下,針對不同階段(綜合前設計仿真、綜合后仿真、布局布線后仿真)的驗證,測試平臺是一樣的。
`timescale1ns/1ns
moduletestbench();
rega,b;
wirey1,y2,y3,y4,y5;
gatestest_gates(a,b,y1,y2,y3,y4,y5); //調用前述的gates模塊,按端口連接
initial
begin //a,b的值將按00-01-11-10的順序產生
a=0;b=0;
#10b=1;
#10a=1;
#10b=0;
#10;
end
endmodule
6.1.4基本邏輯門電路的驗證
功能驗證即前述的綜合前仿真,在暫時不考慮延遲等因素的情況下,通過仿真驗證功能設計是否正確。仿真波形如圖6-2所示。圖6-2基本邏輯門電路功能仿真波形
6.2編碼器
6.2.18-3編碼器(一)
1.使用Verilog進行描述
以下程序設計了一個具有基本功能的8-3編碼器,無優(yōu)先級;同時設計了一個輸出使能端EO(低電平有效)。
moduleencoder8_3_1(DataIn,EO,Dataout);
input[7:0]DataIn;
outputEO;
output[2:0]Dataout;
reg[2:0]Dataout;
regEO;
integerI;always@(DataIn) //如輸入發(fā)生變化,則進行編碼
begin
Dataout=0; //初始化數(shù)據(jù),讓輸出為0
EO=1; //置輸出使能端EO為高電平,即無輸出
for(I=0;I<8;I=I+1)
begin
if(DataIn[I]) //逐位檢查是否為1
begin
Dataout=I;
EO=0;
//輸出結果的同時,置輸出使能端EO為低電平
end
end
end
endmodule程序逐位(從低位到高位)對輸入進行檢查,如果輸入信號有多位為1,則以最后一個1為準,如輸入信號為“10001000”,則計算過程其實有2次,最終以最高位的“1”為準,輸出為111。
2.測試平臺設計
測試平臺的代碼設計如下:
`timescale1ns/10ps
moduletestbench_8_3encoder;
reg[7:0]in;
wire[2:0]out;
wireEO;
initial
begin
in=‘b00000001;
repeat(9)
#20in=in<<1;
//每循環(huán)1次,in被左移1位,如00000001將移位為00000010
end
encoder8_3_1testbench_8_3encoder(in,EO,out);
endmodule
3.功能驗證
仿真波形如圖6-3所示。圖6-38-3編碼器(一)的仿真波形6.2.28-3編碼器(二)
1.使用Verilog進行描述
以下程序設計了一個具有基本功能的8-3編碼器,并具有高位優(yōu)先編碼功能,有8個輸入端口,3個輸出端口和1個輸出使能端EO(低電平有效)。
moduleencoder8_3_2(DataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7,EO,Dataout0,Dataout1,Dataout2);
inputDataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7;
outputEO;
outputDataout0,Dataout1,Dataout2;
reg[3:0]Outvec;assign{EO,Dataout2,Dataout1,Dataout0}=Outvec;//語句1
always@(DataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7)
begin
if(DataIn7)Outvec=4'b0111; //語句組2
elseif(DataIn6)Outvec=4'b0110;
elseif(DataIn5)Outvec=4'b0101;
elseif(DataIn4)Outvec=4'b0100;
elseif(DataIn3)Outvec=4'b0011;
elseif(DataIn2)Outvec=4'b0010;
elseif(DataIn1)Outvec=4'b0001;
elseif(DataIn0)Outvec=4'b0000;
elseOutvec=4'b1000; //使得輸出使能端EO為1,即無效
end
endmodule程序說明:
(1)當輸入數(shù)據(jù)中任一個發(fā)生變化時,程序將重新進行編碼,并將相應結果賦予向量Outvec。如Datain4值為1(更高位的值不為1),則Outvec值就是4‘b0100。
(2)語句1使用拼接運算符獲取各個值,當Outvec值為4’b0100時,EO值變?yōu)?,Dataout2值變?yōu)?,Dataout1值變?yōu)?,Dataout0值變?yōu)?。
(3)語句組2通過if…elseif語句,實現(xiàn)了優(yōu)先編碼功能。
2.測試平臺設計
測試平臺的代碼設計如下:
`timescale1ns/10ps
moduletestbench_8_3encoder;
reg[7:0]invec;
regDataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7;
wireDataout1,Dataout2,EO;
initial
begin
invec='b00000001;
repeat(9)
begin
{DataIn7,DataIn6,DataIn5,DataIn4,DataIn3,DataIn2,DataIn1,DataIn0}=invec;
#20invec=invec<<1;
end
end
encoder8_3_2testbench_8_3encoder(DataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7,EO,Dataout0,Dataout1,Dataout2);
endmodule
3.功能驗證
仿真結果如圖6-4所示。圖6-48-3編碼器(二)的仿真波形6.2.38-3編碼器(三)
以下程序的結構和計算思路與8-3編碼器設計(二)基本一致。
moduleencoder8_3_3(DataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7,
EO,Dataout0,Dataout1,Dataout2);
inputDataIn0,DataIn1,DataIn2,DataIn3,DataIn4,DataIn5,DataIn6,DataIn7;
outputEO;Dataout0,Dataout1,Dataout2;
wire[3:0]Outvec;
assignOutvec=DataIn7?4‘b0111:DataIn6?4’b0110:DataIn5?4‘b0101:DataIn4?4’b0100:DataIn3?4‘b0011:DataIn2?4’b0010:DataIn1?4‘b0001:DataIn0?4’b0000:4‘b1000; //語句1
assignEO=Outvec[3]; //語句組2(4行)
assignDataout2=Outvec[2];
assignDataout1=Outvec[1];
assignDataout0=Outvec[0];
endmodule
程序說明:
(1)語句1與8-3編碼器(二)的語句組2功能是一致的,采用了條件操作符的嵌套調用:當DataIn0為1時,向量Outvec的值為4‘b0000;當DataIn1為1時,向量Outvec的值為4’b0001;當沒有輸入時,向量Outvec的值為4‘b1000。
(2)語句組2中,從向量Outvec中按位獲取輸出值,如向量Outvec的值為4’b1000時,EO獲得值為1,表示沒有輸出。
(3)該設計的測試平臺和功能驗證結果與編碼器(二)一樣。
對于8-3編碼器的三種不同設計方法,分別使用綜合工具進行綜合操作,會看到不同的結果,對于讀者理解不同的程序編寫方法對綜合結果的影響很有幫助,請讀者自行進行對比和分析。6.2.474HC148設計
第2章中(2.3.1節(jié))討論了74HC148芯片(集成8線-3線優(yōu)先編碼器),在此按照該芯片的功能(表2-6),編寫其VerilogHDL代碼(HC148.V)。需要注意的是,在表2-6中,只要是低電平有效的信號,都會寫成的形式,而在編寫代碼時沒有這個必要。例如,在以下的代碼中,EI就相當于表2-6中的。//HC148.v
moduleencoder8_3_1(DataIn,EO,Dataout,EI,GS);
input[7:0]DataIn;
inputEI;
outputEO;
output[2:0]Dataout;
outputGS;
reg[2:0]Dataout;
regEO;
regGS;
integerI;always@(DataInorEI)
begin:local
if(EI)
begin
Dataout=7;
EO=1;
GS=1;
end
elseif(DataIn==16'b11111111)
begin
Dataout=7;
EO=0;
GS=1;
end
else
begin
for(I=0;I<8;I=I+1)
begin
if(~DataIn[I])
begin
Dataout=~I;
EO=1;
GS=0;
end
end
end
endmodule在后面的綜合實例中,該設計將作為基本模塊進行調用。在此不列出測試平臺和綜合結果,讀者可自行設計和驗證。
6.3譯碼器
6.3.13-8譯碼器(一)
1.使用Verilog進行描述
moduledecoder3_8_1(DataIn,Enable,Eq);
input[2:0]DataIn;
inputEnable;
output[7:0]Eq;
reg[7:0]Eq;
wire[2:0]DataIn;
integerI;always@(DataInorEnable) //當輸入或使能端發(fā)生變化時,開始進行譯碼
begin
if(Enable) //Enable為1時,輸出為0
Eq=0;
else
for(I=0;I<=7;I=I+1)
if(DataIn==I) //語句組1(4行)
Eq[I]=1;
else
Eq[I]=0;
end
endmodule程序說明:
(1)程序采用行為風格描述。
(2)輸入為3位二進制(000~111)向量DataIn,表示0~7。
(3)使能端Enable被優(yōu)先處理,Enable為1時輸出為0,Enable為0時才進行譯碼輸出。
(4)語句組1根據(jù)DataIn的值為向量Eq賦值。如DataIn為5,使能端Enable為0,則Eq[5]=1,其它位為0,輸出Eq為00100000。
2.測試平臺設計
測試平臺的設計代碼如下:
`timescale1ns/10ps
moduletestbench;
reg[2:0]in;
regenable;
wire[7:0]eq;
decoder3_8_1decoder_tb( //按端口名稱連接,可不按照端口順序寫出
.DataIn(in),
.Eq(eq));
.Enable(enable),initial
begin
in=0;
repeat(20)
#20in=$random; //采用隨機函數(shù)生成3位的輸入數(shù)據(jù)
end
initial
begin
enable=1;
#40enable=0;
end
endmodule
3.功能驗證
功能仿真波形如圖6-5所示。
說明:
(1)?40ns前enable的值為1,譯碼無效。
(2)應列出所有的值(000~111)進行測試,在此采用隨機函數(shù)產生了20個輸入,未能覆蓋所有的輸入情況。
(3)在顯示波形時默認是二進制數(shù)字顯示,如需改變?yōu)槠渌M制的數(shù)字形式,可在“Wave”窗口中對著對應的變量按右鍵,在彈出的菜單中選擇“Radix”菜單下的不同顯示方式。圖6-53-8譯碼器(一)的仿真波形6.3.23-8譯碼器(二)
1.使用Verilog進行描述
moduledecoder3_8_2(DataIn,Enable,Eq);
input[2:0]DataIn;
inputEnable;
output[7:0]Eq;
reg[7:0]Eq;
always@(DataInorEnable)
if(Enable)
Eq=0;
else
Eq=1‘b1<<DataIn;//將1’b1左移DataIn位,并賦予Eq
endmodule程序說明:
(1)程序結構與3-8譯碼器設計(一)類似,采用行為風格描述,只是對于譯碼部分(語句1)的處理方法不同。
(2)語句“Eq=1‘b1<<DataIn;”采用了移位操作符,通過對1’b1的邏輯左移,實現(xiàn)譯碼。如DataIn值為5,則1‘b1左移5位得到100000,而由于Eq為8位,故Eq的值為8’b00100000。
2.綜合結果
綜合結果如圖6-6所示。
該設計的測試平臺和功能驗證結果與3-8譯碼器設計(一)一樣。圖6-6RTL視圖6.3.3擴展型4511設計
第2章中(2.3.2節(jié))討論了74HC4511芯片(集成數(shù)碼顯示譯碼器),但該芯片僅支持數(shù)字0~9的顯示,而其實共陰極數(shù)碼顯示器還可顯示字母和小數(shù)點,如圖6-7所示。
該圖中6和9的顯示與圖2-18中定義的稍有不同,使用時須注意。
在此用VerilogHDL編寫實現(xiàn)HC4511芯片功能的代碼,并且按照圖6-7的顯示效果進行擴展。圖6-7擴展顯示內容//74HC4511.v
moduleHC4511(A,Seg,LT_N,BI_N,LE);
inputLT_N,BI_N,LE;
input[3:0]A;
output[7:0]Seg;
reg[7:0]SM_8S;
assignSeg=SM_8S;
always@(AorLT_NorBI_NorLE)
begin
if(!LT_N)SM_8S=8'b11111111; //根據(jù)4511真值表寫出
elseif(!BI_N)SM_8S=8'b00000000;
elseif(LE)SM_8S=SM_8S;else
case(A)
4'd0:SM_8S=8'b00111111; //3f(00111111對應的十六進制數(shù)),方便結果查看
//數(shù)字按gfedcba順序,最高位0表示小數(shù)點不顯示
4'd1:SM_8S=8'b00000110; //06
4'd2:SM_8S=8'b01011011; //5b
4'd3:SM_8S=8'b01001111; //4f
4'd4:SM_8S=8'b01100110; //66
4'd5:SM_8S=8'b01101101; //6d
4'd6:SM_8S=8'b01111101; //7d
4'd7:SM_8S=8'b00000111; //07
4'd8:SM_8S=8'b01111111; //7f
4‘d9:SM_8S=8’b01101111;//6f,用1100111表示9也是可以的
4‘d10:SM_8S=8’b01110111; //77
4‘d11:SM_8S=8’b01111100; //7c
4‘d12:SM_8S=8’b00111001; //39
4‘d13:SM_8S=8’b01011110; //5e
4‘d14:SM_8S=8’b01111001; //79
4‘d15:SM_8S=8’b01110001; //71
default:;
endcase
end
endmodule
在后面的綜合實例中,該設計將作為基本模塊進行調用。在此不列出測試平臺和綜合結果,讀者可自行設計和驗證。
6.4數(shù)據(jù)選擇器
6.4.14選1數(shù)據(jù)選擇器(一)
1.使用Verilog進行描述
modulemux4_1_a(D0,D1,D2,D3,Sel0,Sel1,Result);
inputD0,D1,D2,D3;
inputSel0,Sel1;
outputResult;
regResult;
always@(D0orD1orD2orD3orSel1orSel0)
//任一輸入或選擇項發(fā)生變化時執(zhí)行
begin
case({Sel1,Sel0}) //根據(jù)選擇項進行分支控制
0:Result=D0;
1:Result=D1; //語句1
2:Result=D2;
3:Result=D3;
default:Result=1'bx; //其它情況下輸出x
endcase
end
endmodule程序說明:
(1)程序采用行為風格描述。
(2)?case語句中,一旦D0、D1、D2、D3、Sel1、Sel0任一項發(fā)生變化,則進行下面的選擇操作。
(3)?case語句中,根據(jù){Sel1,Sel0}的結果進行分支控制。如Sel1為0,Sel0為1時,{Sel1,Sel0}連接結果為01,執(zhí)行語句1,輸出結果Result獲得輸入D1。
2.測試平臺設計
`timescale1ns/1ps
moduletestbench_mux4_1;
regD0,D1,D2,D3,Sel1,Sel0;
wireResult;
mux4_1_aDUT(D0,D1,D2,D3,Sel0,Sel1,Result);
initial
begin
D0=0;D1=0;D2=0;D3=0;Sel1=0;Sel0=0;
#100D0=1;D1=0;D2=0;D3=1;
#100Sel1=0;Sel0=1;
#100Sel1=1;Sel0=0;
#100Sel1=1;Sel0=1;
#100; //加入一些延遲,以便波形顯示效果更好
end
endmodule
3.功能驗證
仿真波形如圖6-8所示。圖6-84選1數(shù)據(jù)選擇器(一)的仿真波形6.4.24選1數(shù)據(jù)選擇器(二)
modulemux4_1_b(D0,D1,D2,D3,Sel0,Sel1,Result);
inputD0,D1,D2,D3;
inputSel0,Sel1;
outputResult;
regResult;
reg[1:0]SEL;
always@(D0,D1,D2,D3,Sel1,Sel0)
begin
SEL={Sel1,Sel0}; //將2個選擇輸入連接為SEL
if(SEL==0)Result=D0;
elseif(SEL==1)Result=D1;
elseif(SEL==2)Result=D2;
elseif(SEL==3)Result=D3;
elseResult=1‘bx;
end
endmodule
測試平臺和驗證結果與設計方法(一)一致,實例名稱等稍作改動即可。
6.5數(shù)?值?比?較?器
6.5.14位數(shù)值比較器
1.使用Verilog進行描述
modulecomparator_4_a(DataA,DataB,AGEB);
input[3:0]DataA,DataB;
outputAGEB;
regAGEB;
always@(DataAorDataB)
begin
if(DataA>=DataB)
AGEB=1;
else
AGEB=0;
end
endmodule
該4位數(shù)值比較器處理大于等于的情況,與第2章介紹的稍有不同。begin和end語句之間的語句,可濃縮為一句“AGEB=DataA>=DataB;”。
2.綜合結果
綜合結果RTL視圖如圖6-9所示,雖然看起來很簡單明晰,但其工藝視圖已經較為復雜。篇幅所限,請讀者自行在綜合工具中查看。圖6-94位數(shù)值比較器的RTL視圖
3.測試平臺設計
`timescale1ns/10ps
moduletestbench;
reg[3:0]ina,inb;
wireAGEB;
comparator_4_acomparator_testbench(ina,inb,AGEB);
initial
begin
ina=0;
repeat(20)
#20ina=$random;
#20$finish;
end
initial
begin
inb=0;
repeat(10)
#40inb=$random;
end
endmodule
4.功能驗證
仿真結果如圖6-10所示。
在顯示波形時默認是二進制數(shù)字顯示,如需改變?yōu)槠渌M制的數(shù)字形式,可在“Wave”窗口中對著對應的變量按右鍵,在彈出菜單中選擇“Radix”菜單下的不同顯示方式。圖6-104位數(shù)值比較器的仿真波形6.5.274HC85設計
第2章中(2.3.4節(jié))討論了74HC85芯片(集成4位數(shù)值比較器),在此按照該芯片的功能,編寫其VerilogHDL代碼。
//74HC85.v
moduleHC85(A3,A2,A1,A0,B3,B2,B1,B0,QAGB,QASB,QAEB,IAGB,IASB,IAEB);
inputA3,A2,A1,A0,B3,B2,B1,B0,IAGB,IASB,IAEB;
outputQAGB,QASB,QAEB;
regQAGB,QASB,QAEB;
wire[3:0]DataA,DataB;
assignDataA={A3,A2,A1,A0};
assignDataB={B3,B2,B1,B0};always@(DataAorDataB)
begin
if(DataA>DataB)
begin
QAGB=1;QASB=0;QAEB=0;
end
elseif(DataA<DataB)
begin
QAGB=0;QASB=1;QAEB=0;
end
elseif(IAGB&!IASB&!IAEB)
begin
QAGB=1;QASB=0;QAEB=0;
end
elseif(!IAGB&IASB&!IAEB)
begin
QAGB=0;QASB=1;QAEB=0;
end
elseif(IAEB)
begin
QAEB=1;QASB=0;QAGB=0;
end
elseif(IAGB&IASB&!IAEB)
begin
QAGB=0;QASB=0;QAEB=0;
end
elseif(!IAGB&!IASB&!IAEB)
begin
QAGB=1;QASB=1;QAEB=0;
end
end
endmodule
在后面的綜合實例中,該設計將作為基本模塊進行調用。在此不列出測試平臺和綜合結果,讀者可自行設計和驗證。
6.6加法器
在所有的算術運算電路中,加法器(減法器)是使用最多的,因此整個運算電路的性能往往由加法器決定。而對于加法器來說,最關鍵的部分是如何對進位進行處理。在前面章節(jié)的例子中已經對全加器的設計進行了反復的討論,本節(jié)主要討論多位加法器的設計方法。6.6.11位半加器(一)
1.使用Verilog進行描述
modulehalfadder_1(DataA,DataB,Sum,Cout);
inputDataA,DataB;
outputSum,Cout;
assign{Cout,Sum}=DataA+DataB;
endmodule
2.綜合結果
代碼中使用了連接運算符,因此綜合結果(如圖6-11和圖6-12所示)中也反饋出該結構。圖6-111位半加器(一)的RTL視圖圖6-121位半加器(一)的工藝視圖
3.測試平臺設計
下面給出1位半加器的測試平臺代碼。
`timescale1ns/10ps
moduletestbench;
rega,b;
wiresum,cout;
halfadder_1adder_te(a,b,sum,cout);
initial
begin
a=0;b=0;
#20b=1;
#20a=1;
#20b=0;
#20;
end
endmodule
4.功能驗證
仿真結果如圖6-13所示。圖6-131位半加器的仿真波形6.6.21位半加器(二)
1.使用Verilog進行描述
modulehalfadder_2(DataA,DataB,Sum,Cout);
inputDataA,DataB;
outputSum,Cout;
regSum,Cout;
always@(DataA,DataB)
begin
case({DataA,DataB})//真值表描述
2'b00:beginSum=0;Cout=0;end
2'b01:beginSum=1;Cout=0;end
2'b10:beginSum=1;Cout=0;end
2'b11:beginSum=0;Cout=1;end
endcase
end
endmodule
程序說明:
(1)程序采用行為風格描述。
(2)通過真值表(參考第2章的內容)可寫出case語句中的分支選擇及輸出結果。
(3)根據(jù){DataA,DataB}的值選擇相應的分支,如DataA為1,DataB為1,則{DataA,DataB}的值為3,選擇分支3得到Sum為0,Cout為1。
測試平臺和驗證結果與設計方法(一)一致。
2.綜合結果
綜合結果如圖6-14和圖6-15所示。
綜合結果分析:
(1)對比兩個設計的RTL視圖:圖6-11的綜合結果,是一個標準的半加器設計;而圖6-14中,卻是一個標準的選擇器設計(也能實現(xiàn)半加器的功能)。
(2)對比兩個設計的工藝視圖:圖6-12和圖6-15所用到的元件一樣,而連線方式稍有不同。
(3)將兩種半加器的代碼設計及綜合結果進行對比,可發(fā)現(xiàn)對于同一個設計要求,用不同的程序編寫方式,會得到不同的綜合結果。因此,理解代碼與綜合的關系和技巧,對于實際開發(fā)是非常重要的。圖6-141位半加器(二)的RTL視圖圖6-151位半加器(二)的工藝視圖6.6.34位串行(行波)進位加法器(一)
1.使用Verilog進行描述
串行進位也叫行波(Ripple)進位。以下只是對1位全加器的代碼稍作修改,將輸入輸出標量改為向量,就可實現(xiàn)多位串行進位加法器。
modulefulladder_4_a(DataA,DataB,Cin,Sum,Cout);
input[3:0]DataA,DataB;
inputCin;
output[3:0]Sum;
reg[3:0]Sum;
outputCout;
regCout;
always@(DataAorDataBorCin)
begin
{Cout,Sum}=DataA+DataB+Cin;
end
endmodule
2.綜合結果
綜合結果的RTL視圖如圖6-16所示。圖6-164位串行進位加法器(一)的RTL視圖
3.測試平臺設計
`timescale1ns/10ps
moduleadder4_testbench;
reg[3:0]ina,inb;
regcin;
wire[3:0]sum;
wirecout;
fulladder_4_badder4_tb(ina,inb,cin,sum,cout);
initial
begin
ina=0;
repeat(20)
#20ina=$random;
end
initial
begin
inb=0;
repeat(10)
#40inb=$random;
end
initial
begin
cin=0;
#200cin=1;
end
endmodule
4.功能驗證
仿真結果如圖6-17所示。圖6-174位串行進位加法器(一)的仿真波形6.6.44位串行進位加法器(二)
1.使用Verilog進行描述
在此用另一種程序設計思路來組織代碼,程序顯式地表述其串行進位邏輯。
modulefulladder_4_b(DataA,DataB,Cin,Sum,Cout);
parameterN=4;
input[N-1:0]DataA,DataB;
inputCin;
output[N-1:0]Sum;
reg[N-1:0]Sum;
outputCout;regCout;
reg[N:0]q;
always@(DataAorDataBorCin)
begin:adder //語句塊中定義了局部變量i,因此該塊必須命名
integeri;
q[0]=Cin;
for(i=0;i<=N-1;i=i+1)
begin
q[i+1]=(DataA[i]&DataB[i])|(DataA[i]&q[i])|(DataB[i]&q[i]);
Sum[i]=DataA[i]^DataB[i]^q[i];
end
Cout=q[N];
end
endmodule
2.綜合結果
綜合結果的RTL視圖如圖6-18所示。
綜合結果分析:
(1)讀者可從該RTL視圖的結構上看出其進位的實現(xiàn)過程。
(2)設計(二)的RTL視圖看起來會比設計(一)的復雜得多,但工藝視圖差別不大(篇幅所限未列出)。也就是兩種不同設計方法,實際所用到的元器件其實差不多。
(3)讀者可把程序中的N改為8、16位試一下,比較一下綜合后的結果。圖6-184位串行進位加法器(二)的RTL視圖6.6.54位超前進位加法器
第2章(2.3.5節(jié))討論了超前進位加法器的設計思路,在此按照該思路,編寫其VerilogHDL代碼。
moduleAdd_prop_gen(sum,c_out,a,b,c_in,shiftedcarry);
output[3:0]sum;
output[4:0]shiftedcarry;
outputc_out;
input[3:0]a,b;
inputc_in;
reg[3:0]carrychain;
wire[3:0]g=a&b;//按位與,生成函數(shù)Gi
wire[3:0]p=a^b;//按位異或,生成進位傳送函數(shù)Pialways@(aorborc_inorporg)
begin:carry_generation //塊中定義了局部變量i,不命名該塊的話綜合會出錯
integeri;
carrychain[0]=g[0]+(p[0]&c_in);
for(i=1;i<=3;i=i+1)
carrychain[i]=g[i]|(p[i]&carrychain[i-1]);
end
wire[4:0]shiftedcarry={carrychain,c_in};
wire[3:0]sum=p^shiftedcarry; //求和運算
wirec_out=shiftedcarry[4]; //進位輸出
endmodule在后面的綜合實例中,該設計將作為基本模塊進行調用。在此不列出測試平臺和綜合結果,讀者可自行設計和驗證。
6.7乘法器
6.7.1無符號4位乘法器
1.使用Verilog進行描述
moduleunsign_mult_4bit(DataA,DataB,Mult);
input[3:0]DataA,DataB;
output[7:0]Mult;
reg[7:0]Mult;
always@(DataAorDataB)
Mult<=DataA*DataB;
endmodule
2.綜合結果
綜合結果如圖6-19所示。圖6-19無符號4位乘法器的RTL視圖
3.測試平臺設計
`timescale1ns/10ps
modulemult_testbench;
reg[3:0]ina,inb;
wire[7:0]mult;
unsign_mult_4bitunsign_mult_tb(ina,inb,mult);
initial
begin
ina=0;
repeat(20)
#20ina=$random;
end
initial
begin
inb=0;
repeat(10)
#40inb=$random;
end
endmodule
4.功能驗證
仿真結果如圖6-20所示。
在顯示波形時默認的是二進制數(shù)字顯示,選擇“Wave”窗口中,對著對應的變量按右鍵,選擇“Radix”菜單下的“Unsigned”,可使得顯示數(shù)字為十進制無符號數(shù)。圖6-20無符號4位乘法器的仿真波形6.7.2有符號4位乘法器
1.使用Verilog進行描述
modulesign_mult_4(DataA,DataB,Mult);
input[3:0]DataA,DataB;
output[7:0]Mult;
reg[7:0]Mult;
always@(DataA,DataB)
Mult=SignedMultiplier(DataA,DataB);function[7:0]SignedMultiplier;
input[3:0]A,B;
reg[3:0]DA,DB;
integerMulti,DataAi,DataBi;
begin
DA=4'b1111;
DB=4'b1111;
if(A[3]) //語句1
DataAi=-(DA-A+1); //語句2
else
DataAi=A;
if(B[3])
DataBi=-(DB-B+1);
else
DataBi=B;
Multi=DataAi*DataBi;
SignedMultiplier=Multi;
end
endfunction
endmodule
程序說明:
(1)定義了名為SignedMultiplier的函數(shù),在DataA或DataB發(fā)生變化時調用。
(2)語句1判斷向量首位是否為1,如果是1,則表示A是一個負數(shù)的補碼,應另外處理。
(3)有符號數(shù)必須進行處理,否則計算結果將出現(xiàn)錯誤:如有符號數(shù)4‘sb1011表示-5,3’sb010表示2,相乘結果應為-10;但如果被當做無符號運算,就變成4‘b1011*3’b010,結果為10110(即22)。
(4)語句2中,對于負數(shù)的補碼,不能通過直接執(zhí)行DataAi=A來獲值。這是由于A是線網類型(隱式),作無符號數(shù)處理。如輸入有符號數(shù)1011本表示-5,但被當做無符號數(shù)后變成11來處理了。
(5)語句2中,通過補碼的定義(A補?=?2n+?A真值)計算該補碼數(shù)的真值,把式子變?yōu)锳真值=-(2n-A補)進行計算。如輸入A?=?4‘b1011,首位為1,表示A為補碼數(shù),執(zhí)行-(DA-A+1)=-(4’b1111-4‘b1011+1)=-(4’b0101),最后真值-5被賦值給整數(shù)(有符號)變量DataAi。
2.綜合結果
綜合結果如圖6-21所示。圖6-21有符號4位乘法器的RTL視圖
3.測試平臺設計
`timescale1ns/10ps
modulemult_testbench;
reg[3:0]ina,inb;
wire[7:0]mult;
sign_mult_4sign_mult_tb(ina,inb,mult);
initial
begin
ina=0;
repeat(20)
#20ina=$random;
end
initial
begin
inb=0;
repeat(10)
#40inb=$random;
end
endmodule
4.功能驗證
仿真結果如圖6-22所示。
在“Wave”窗口中,對著對應的變量按右鍵,選擇“Radix”菜單下的“Decimal”,可使得顯示數(shù)字為十進制有符號數(shù)。圖6-22功能仿真(綜合前)波形
6.8組合邏輯電路的競爭冒險問題
在第2章(2.5節(jié))中討論了組合邏輯電路的競爭冒險問題,并列出了幾種解決方法。在此以乘法器作為例子,以求讓讀者對競爭冒險的出現(xiàn)及解決有更深的體會。
6.8.1競爭冒險分析
6.7.2節(jié)中,實現(xiàn)了有符號數(shù)的乘法運算,從圖6-21中看,該設計的邏輯圖非常簡單,但如果從工藝視圖看(如圖6-23所示),該設計的具體實現(xiàn)相當復雜(該圖的細節(jié)讀者可暫不關注)。圖6-23有符號4位乘法器的工藝視圖復雜的實際電路,加上多位輸入信號可能同時發(fā)生變化,這樣就會產生毛刺(競爭冒險),在綜合前仿真(功能仿真)看不到,要在綜合后仿真才能看到,如圖6-24所示。
在圖6-24中,可看到mult的輸出,每次數(shù)值變化之間都有毛刺,因為波形縮略顯示,故看起來就像一條黑邊。把毛刺部分放大,即可看到競爭冒險的出現(xiàn),如圖6-25所示。
圖6-25中,mult變量的值-20、-60,76,都是由于競爭冒險而產生的錯誤數(shù)據(jù)。圖6-24綜合后仿真中出現(xiàn)毛刺毛刺圖6-25波形放大顯示6.8.2競爭冒險的解決方法
以下采用時鐘控制方法,消除競爭冒險帶來的影響。將時鐘信號加入有符號4位乘法器的設計中。
1.使用Verilog進行描述
modulesign_mult_4_clk(DataA,DataB,Mult,Clock);
input[3:0]DataA;
input[3:0]DataB;
output[7:0]Mult;
inputClock;
reg[7:0]Mult;
always@(posedgeClock)
Mult<=SignedMultiplier(DataA,DataB);function[7:0]SignedMultiplier;
input[3:0]A;
input[3:0]B;
reg[3:0]DA;
reg[3:0]DB;
integerMulti;
integerDataAi;
integerDataBi;
begin
DA=4'b1111;
DB=4'b1111;
if(A[3])
DataAi=-(DA-A+1);else
DataAi=A;
if(B[3])
DataBi=-(DB-B+1);
else
DataBi=B;
Multi=DataAi*DataBi;
SignedMultiplier=Multi;
end
endfunction
endmodule程序說明:程序與前例(有符號4位乘法器)基本一樣,只是always的觸發(fā)條件由“DataA,DataB”改為“posedgeClock”;在組合電路基礎上加入了時序控制。
2.綜合結果
綜合結果如圖6-26所示。圖6-26帶時鐘控制的有符號4位乘法器的RTL視圖
3.測試平臺設計
`timescale1ns/10ps
modulemult_testbench;
reg[3:0]ina,inb;
wire[7:0]mult;
regclock;
sign_mult_4_clksign_mult_tb(ina,inb,mult,clock);
initial //生成時鐘信號
begin
clock=0;
#30;forever
begin
clock=1;
#30;
clock=0;
#10;
end
end
initial
begin
ina=0;
repeat(20)
#20ina=$random;
end
initial
begin
inb=0;
repeat(10)
#40inb=$random;
end
initial
//控制在固定時間內停止(否則時鐘信號永不停止)
#400$finish;
endmodule
4.功能驗證
綜合后仿真的結果如圖6-27所示。圖6-27仿真(綜合后)波形6.8.3更進一步的分析
通過設置時鐘信號,解決了(或者說躲開了)有符號乘法器的競爭冒險問題。但時鐘信號如何設置也是一個需要注意的問題。如將上例中帶時鐘乘法器的設計進行布局布線操作,布局布線后仿真的結果如圖6-28所示,波形局部放大顯示效果如圖6-29所示。
從波形中可看到,即使在時鐘信號控制下,仍然有毛刺產生。那是因為進一步考慮布局布線后的線路延遲,組合電路中有更大的延遲產生,而目前測試平臺的時鐘設置過短,未能在信號穩(wěn)定后才進行選通。請讀者自行驗證并改正。圖6-28仿真(布局布線后)波形圖6-29波形放大顯示
6.9組合邏輯電路的綜合性實例
6.9.1實例一:補碼生成電路
1.設計說明
在通過VerilogHDL編程時,一個變量被賦值后,該變量保存的就是該值的補碼,這種處理是仿真環(huán)境自動進行的。如執(zhí)行語句“i=-12;”,則8位的i變量中就會保存了-12的補碼“11110100”,而不是保存原碼“10001100”,這也是為什么在6.7.2節(jié)中要把帶符號的數(shù)進行相應處理后才能計算的原因。但在實際電路設計中,輸入數(shù)據(jù)一般為原碼形式(要求使用者直接輸入補碼是不大現(xiàn)實的),而大多IP核均要求采用補碼進行數(shù)據(jù)通信。因此,補碼的轉換需要邏輯電路設計者自行加入。
本例以8位二進制數(shù)(最高位為符號位)為例,希望幫助讀者真正理解補碼的含義及其使用場合,并理解編程工具及綜合工具對負數(shù)的處理。
2.使用Verilog進行描述
moduleCom_2C(DataIn,DataOut);
input[7:0]DataIn; //原碼數(shù)據(jù)輸入端
output[7:0]DataOut; //補碼數(shù)據(jù)輸出端
reg[7:0]DataOut;
reg[7:0]S;
always@(DataIn)
begin
S=8'b10000000; //用于符號位的轉換
if(DataIn[7]) //判斷首位是否為1,即是否負數(shù)
DataOut=-DataIn+S; //“-”操作對包括符號位在內的所有位取反再加1
else
DataOut=DataIn; //首位為0時表示正數(shù),補碼與原碼相同
end
endmodule
程序說明:
(1)首先應注意的是,8位輸入數(shù)據(jù)“DataIn”,是原碼數(shù)據(jù)的輸入。
(2)“-DataIn”操作可“把DataIn的8位數(shù)據(jù)包括符號位在內的所有位取反再加1”,該操作比較難以理解:在執(zhí)行“-DataIn”操作時,仿真器會把DataIn中的數(shù)據(jù)當成補碼來處理,如DataIn中存放的是“11110100”,那么仿真器會認為該數(shù)是-12的補碼,因此“-DataIn”操作會得到值12,即“00001100”,就是“11110100”所有位取反再加1的結果。
(3)“-DataIn”得到的是包括符號位在內所有位取反再加1的結果,因此再加上S(8‘b10000000)就可把最高位(符號位)從0變?yōu)?,最終得到補碼結果。
3.綜合結果
綜合結果如圖6-30所示。圖6-30補碼生成電路的RTL視圖
4.測試平臺設計
`timescale1ns/10ps
moduletestbench;
reg[7:0]dataIn;
wire[7:0]dataOut;
Com_2CCom_2C_1(.DataOut(dataOut),
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 紡織原料新興市場開發(fā)考核試卷
- 花生成長生成課程
- 畜牧養(yǎng)殖技術培訓體系建設與完善考核試卷
- 大學生創(chuàng)新創(chuàng)業(yè)教育:推動高質量就業(yè)與經濟發(fā)展
- 宴會活動策劃書
- 職業(yè)教育的價值與實施路徑
- 蘇教版第27課《水》教學講義
- 2025店面租賃合同范本
- 2025授權開發(fā)企業(yè)資源規(guī)劃軟件合同范本
- 2025授權調查合同模板
- 2022年12月18日浙江?。ㄊ校┘墮C關面向基層遴選筆試真題及答案深度解析
- 慢性血栓栓塞性肺動脈高壓
- 兒童早期綜合發(fā)展課件
- 剪力墻平法識圖講義(PPT格式105)
- 北京中考英語詞匯表(1600詞匯)
- 專業(yè)工程分包業(yè)主審批表
- 藥劑科終止妊娠藥品管理制度
- 除草劑分類和使用方法
- 中遠集團養(yǎng)老保險工作管理程序
- 留守兒童幫扶記錄表
- 變電站第二種工作票
評論
0/150
提交評論