




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
VerilogHDL高級程序設(shè)計(jì)舉例6.1數(shù)字電路系統(tǒng)設(shè)計(jì)的層次化描述方法
6.2典型電路設(shè)計(jì)
6.3總線控制器設(shè)計(jì)本章小結(jié)
集成電路設(shè)計(jì)中大量采用的是結(jié)構(gòu)性的描述方法,歸納起來主要有兩種:自下而上(Bottom-Up)的設(shè)計(jì)方法與自上而下(Top-Down)的設(shè)計(jì)方法。在實(shí)際運(yùn)用中,可以根據(jù)實(shí)際設(shè)計(jì)的情況選擇這兩種方法相結(jié)合的設(shè)計(jì)方法,即混合設(shè)計(jì)方法。6.1數(shù)字電路系統(tǒng)設(shè)計(jì)的層次化描述方法Top-Down方法主要是從系統(tǒng)設(shè)計(jì)的角度進(jìn)行,系統(tǒng)工程師往往會(huì)在項(xiàng)目的規(guī)劃階段將數(shù)字電路系統(tǒng)進(jìn)行劃分,明確主要單元模塊的功能、時(shí)序和接口參數(shù)等系統(tǒng)方案,這種方法可以有效協(xié)調(diào)ULSI和VLSI芯片設(shè)計(jì)中眾多開發(fā)人員的工作。Bottom-Up方法主要是在實(shí)際系統(tǒng)執(zhí)行過程中,底層設(shè)計(jì)人員提出底層功能模塊的優(yōu)化方案,系統(tǒng)設(shè)計(jì)人員分析這些優(yōu)化對系統(tǒng)的影響,通過調(diào)整系統(tǒng)結(jié)構(gòu),提高芯片整體性能。
1.
Bottom-Up設(shè)計(jì)方法
Bottom-Up設(shè)計(jì)方法是一種傳統(tǒng)的設(shè)計(jì)方法,它要求電路設(shè)計(jì)者將系統(tǒng)進(jìn)行模塊劃分,從底層模塊設(shè)計(jì)開始,運(yùn)用各底層模塊搭建一個(gè)完整的系統(tǒng)。在這種設(shè)計(jì)方法中,首先根據(jù)系統(tǒng)設(shè)計(jì)的要求,定義并建立所需要的葉子模塊,通過模塊連接方式建成較大的模塊,然后把這些比較大的模塊組合成具有一定功能的模塊,最后將這些功能模塊組合,直到完成整個(gè)系統(tǒng)。這就如同搭積木,用小的模塊不斷組合,最后完成系統(tǒng)的設(shè)計(jì)。其設(shè)計(jì)方法示意圖如圖6.1-1所示。圖6.1-1Bottom-Up設(shè)計(jì)方法示意圖一個(gè)典型的Bottom-Up設(shè)計(jì)例子是在第4章中提到的串行加法器的設(shè)計(jì)。一個(gè)4位串行加法器由4個(gè)全加器構(gòu)成,如圖6.1-2所示。全加器是串行加法器的子模塊,而全加器是由基本的邏輯門構(gòu)成的,如圖6.1-3所示,這些基本的邏輯門就是所說的葉子模塊。這個(gè)設(shè)計(jì)中運(yùn)用葉子模塊(基本邏輯門)搭建成子模塊(全加器),再用子模塊搭建成所需要的電路(串行加法器)。
圖6.1-24位串行加法器
圖6.1-3全加器邏輯電路顯然,Bottom-Up設(shè)計(jì)方法沒有明顯的規(guī)律可循,主要依靠設(shè)計(jì)者的實(shí)踐經(jīng)驗(yàn)和熟練的設(shè)計(jì)技巧,用逐步試探的方法最后設(shè)計(jì)出一個(gè)完整的數(shù)字系統(tǒng)。系統(tǒng)的各項(xiàng)性能指標(biāo)只有在系統(tǒng)構(gòu)成后才能分析測試。
Bottom-Up設(shè)計(jì)方法常用于原理圖的設(shè)計(jì)中,相比于其它方法,該方法對于實(shí)現(xiàn)各個(gè)子模塊電路所需的時(shí)間較短。但是該方法仍存在著許多不足之處,例如采用該設(shè)計(jì)方法容易對系統(tǒng)的整體功能把握不足,整個(gè)系統(tǒng)的設(shè)計(jì)周期比較長、效率低、設(shè)計(jì)質(zhì)量難以保證等。因此,這種方法只適用于小規(guī)模電路的設(shè)計(jì)。
2.?Top-Down設(shè)計(jì)方法
隨著電子技術(shù)的快速發(fā)展,傳統(tǒng)的設(shè)計(jì)方法已經(jīng)不能滿足日益增長的系統(tǒng)要求,Top-Down設(shè)計(jì)方法成為數(shù)字系統(tǒng)設(shè)計(jì)的主流設(shè)計(jì)方法。在這種設(shè)計(jì)方法中,首先從系統(tǒng)級入手,把系統(tǒng)劃分為若干個(gè)子功能單元,并編制出相應(yīng)的行為或結(jié)構(gòu)模型;再將這些子功能單元進(jìn)一步進(jìn)行拆分,就這樣不斷地拆分直到整個(gè)系統(tǒng)中各個(gè)模塊的邏輯關(guān)系合理,便于邏輯電路級的設(shè)計(jì)和實(shí)現(xiàn),這種最底層的功能模塊被稱為葉子模塊。其設(shè)計(jì)方法示意圖如圖6.1-4所示。
圖6.1-4Top-Down設(shè)計(jì)方法示意圖例如,使用Top-Down設(shè)計(jì)方法對一個(gè)典型CPU進(jìn)行設(shè)計(jì),如圖6.1-5所示。根據(jù)CPU的功能將CPU分為控制單元、邏輯運(yùn)算單元、存儲(chǔ)單元??刂茊卧饕刂普麄€(gè)CPU的工作,用于調(diào)控整個(gè)CPU按照指令執(zhí)行相應(yīng)的規(guī)定動(dòng)作,控制單元又由指令控制器、時(shí)序控制器、總線控制器和中斷控制器構(gòu)成。邏輯運(yùn)算單元可以分為算術(shù)邏輯運(yùn)算單元ALU和浮點(diǎn)運(yùn)算單元FPU。存儲(chǔ)單元可以分為通用寄存器和專用寄存器。這樣通過功能的不斷細(xì)化,將大模塊劃分成了更小的模塊,當(dāng)劃分到指令控制器這一級時(shí),就可以通過各種邏輯電路來實(shí)現(xiàn)了。
圖6.1-5Top-Down設(shè)計(jì)CPU流程
Top-Down設(shè)計(jì)方法的優(yōu)點(diǎn)是顯而易見的,在整個(gè)設(shè)計(jì)過程中主要的仿真和調(diào)試過程是在高層次完成的,所以能夠在設(shè)計(jì)的早期發(fā)現(xiàn)結(jié)構(gòu)設(shè)計(jì)上的錯(cuò)誤,及時(shí)進(jìn)行調(diào)整,最大限度地不將錯(cuò)誤帶入到后續(xù)的設(shè)計(jì)環(huán)節(jié)中。同時(shí)方便了從系統(tǒng)進(jìn)行劃分和管理整個(gè)項(xiàng)目,使得大規(guī)模的復(fù)雜的數(shù)字電路實(shí)現(xiàn)成為可能,避免了不必要的重復(fù)設(shè)計(jì),提高了設(shè)計(jì)效率。然而這種設(shè)計(jì)方法仍然存在著不足,在設(shè)計(jì)的開始并不能準(zhǔn)確地確定最終功能單元的設(shè)計(jì),需要根據(jù)具體的設(shè)計(jì)情況,不斷進(jìn)行系統(tǒng)設(shè)計(jì)的修正?,F(xiàn)在的數(shù)字電路設(shè)計(jì)越來越復(fù)雜,單一的設(shè)計(jì)方法往往很難滿足設(shè)計(jì)要求,因此通常將這兩種設(shè)計(jì)方法結(jié)合起來,即采用混合的設(shè)計(jì)方法來進(jìn)行設(shè)計(jì)。這樣可以綜合每種方法的優(yōu)點(diǎn),在高層系統(tǒng)設(shè)計(jì)時(shí)采用Top-Down設(shè)計(jì)方法,便于系統(tǒng)的劃分;而在底層的設(shè)計(jì)時(shí)采用Top-Down設(shè)計(jì)方法,這樣可以縮短各個(gè)模塊的設(shè)計(jì)時(shí)間。例6.1-1采用模塊層次化設(shè)計(jì)方法,設(shè)計(jì)4維向量點(diǎn)積乘法器,其中向量a
=
(a1,a2,a3,a44),b
=
(b1,b2,b3,b4)。點(diǎn)積乘法的規(guī)則為
(6.1-1)向量點(diǎn)積乘法是將向量的對應(yīng)位置的值相乘,然后相加。其對應(yīng)電路結(jié)構(gòu)如圖6.1-6所示。
圖6.1-6向量點(diǎn)積乘法器電路結(jié)構(gòu)可以看出,4位點(diǎn)積向量乘法器由4個(gè)乘法器和3個(gè)加法器構(gòu)成,而加法器和乘法器又由半加器和全加器構(gòu)成,其中半加器和全加器又由基本的邏輯門組成,其構(gòu)成關(guān)系如圖6.1-7所示。
圖6.1-7向量點(diǎn)積乘法器層次化功能模塊具體的VerilogHDL設(shè)計(jì)包括頂層模塊vector、加法器模塊add和乘法器模塊mul_addtree。VerilogHDL程序代碼如下:
modulevector(a1,a2,a3,a4,b1,b2,b3,b4,out);
input[3:0]a1,a2,a3,a4,b1,b2,b3,b4;
output[9:0]out;
wire[7:0]out1,out2,out3,out4;
wire[8:0]out5,out6;
wire[9:0]out;
mul_addtreeU1(.x(a1),.y(b1),.out(out1));
mul_addtreeU2(.x(a2),.y(b2),.out(out2));
mul_addtreeU3(.x(a3),.y(b3),.out(out3));
mul_addtreeU4(.x(a4),.y(b4),.out(out4));
add#(8)U5(.a(out1),.b(out2),.out(out5));
add#(8)U6(.a(out3),.b(out4),.out(out6));
add#(9)U7(.a(out5),.b(out6),.out(out));
endmodule
//加法器
moduleadd(a,b,out);
parametersize=8;
input[size-1:0]a,b;
output[size:0]out;
assignout=a+b;
endmodule
//乘法器
modulemul_addtree(mul_a,mul_b,mul_out);
input[3:0]mul_a,mul_b;//IO端口聲明
output[7:0]mul_out;
wire[3:0]mul_out;//連線類型聲明
wire[3:0]stored0,stored1,stored2,stored3;
wire[3:0]add01,add23;
assignstored3=mul_b[3]?{1'b0,mul_a,3'b0}:8'b0;//邏輯設(shè)計(jì)
assignstored2=mul_b[2]?{2'b0,mul_a,2'b0}:8'b0;
assignstored1=mul_b[1]?{3'b0,mul_a,1'b0}:8'b0;
assignstored0=mul_b[0]?{4'b0,mul_a}:8'b0;
assignadd01=stored1+stored0;
assignadd23=stored3+stored2;
assignmul_out=add01+add23;
endmodule
可以看到,在這個(gè)電路設(shè)計(jì)中,vector、add和mul_addtree三個(gè)模塊共同構(gòu)成了向量點(diǎn)積乘法器。頂層模塊vector采用結(jié)構(gòu)描述方式分別使用了4個(gè)mul_addtree和3個(gè)add模塊,分兩層實(shí)現(xiàn)了電路功能。
6.2.1加法器樹乘法器
加法器樹乘法器的設(shè)計(jì)思想是“移位后加”,并且加法運(yùn)算采用加法器樹的形式。乘法運(yùn)算的過程是,被乘數(shù)與乘數(shù)的每一位相乘并且乘以相應(yīng)的權(quán)值,最后將所得的結(jié)果相加,便得到了最終的乘法結(jié)果。6.2典型電路設(shè)計(jì)加法器樹乘法器在計(jì)算被乘數(shù)與乘數(shù)及與其權(quán)值相乘時(shí)采用“判斷移位”的形式,即通過判斷乘數(shù)位是否為1來決定結(jié)果為0或者進(jìn)行移位。當(dāng)乘數(shù)位為1時(shí)被乘數(shù)根據(jù)該位的權(quán)值將被乘數(shù)移位,權(quán)值為0不移位,權(quán)值為2左移1位,權(quán)值為4左移2位,權(quán)值為8左移3位……;當(dāng)乘數(shù)位為0時(shí)直接輸出0。而加法器樹乘法器的加法運(yùn)算是通過加法器樹來實(shí)現(xiàn)的,如圖6.2-1所示。加法器樹所需要的加法器的數(shù)目是操作數(shù)的位數(shù)減1。
圖6.2-14位的加法器樹乘法器結(jié)構(gòu)例6.2-1圖6.2-1是一個(gè)4位的加法器樹乘法器結(jié)構(gòu),用VerilogHDL設(shè)計(jì)一個(gè)4位加法器樹乘法器。
modulemul_addtree(mul_a,mul_b,mul_out);
input[3:0]mul_a,mul_b; //IO端口聲明
output[7:0]mul_out;
wire[7:0]mul_out; //連線類型聲明
wire[7:0]stored0,stored1,stored2,stored3;
wire[7:0]add01,add23;
assignstored3=mul_b[3]?{1'b0,mul_a,3'b0}:8'b0; //邏輯設(shè)計(jì)
assignstored2=mul_b[2]?{2'b0,mul_a,2'b0}:8'b0;
assignstored1=mul_b[1]?{3'b0,mul_a,1'b0}:8'b0;
assignstored0=mul_b[0]?{4'b0,mul_a}:8'b0;
assignadd01=stored1+stored0;
assignadd23=stored3+stored2;
assignmul_out=add01+add23;
endmodule
//****************************測試代碼********************************
modulemult_addtree_tb;
reg[3:0]mult_a;
reg[3:0]mult_b;
wire[7:0]mult_out;
//模塊例化
mul_addtreeU1(.mul_a(mult_a),.mul_b(mult_b),.mul_out(mult_out));
initial//測試信號
begin
mult_a=0;mult_b=0;
repeat(9)
begin
#20mult_a=mult_a+1;
mult_b=mult_b+1;
end
end
endmodule
圖6.2-2加法器樹乘法器測試結(jié)果圖6.2-3兩級流水線4位加法器樹乘法器結(jié)構(gòu)加法器樹乘法器可以通過流水線提高電路速度。其基本思想是加法器樹中插入寄存器,將加法器樹乘法器設(shè)計(jì)成流水線型。
例6.2-2用VerilogHDL設(shè)計(jì)一個(gè)兩級流水線4位加法器樹乘法器。
兩級流水線4位加法器樹乘法器結(jié)構(gòu)如圖6.2-3所示。
通過在第一級與第二級、第二級與第三級加法器之間插入D觸發(fā)器組,可以實(shí)現(xiàn)兩級流水線設(shè)計(jì),其VerilogHDL代碼如下:
modulemul_addtree_2_stage(clk,clr,mul_a,mul_b,mul_out);
inputclk,clr;
input[3:0]mul_a,mul_b; //IO端口聲明
output[7:0]mul_out;
reg[7:0]add_tmp_1,add_tmp_2,mul_out;
wire[7:0]stored0,stored1,stored2,stored3;
assignstored3=mul_b[3]?{1'b0,mul_a,3'b0}:8'b0; //邏輯設(shè)計(jì)
assignstored2=mul_b[2]?{2'b0,mul_a,2'b0}:8'b0;
assignstored1=mul_b[1]?{3'b0,mul_a,1'b0}:8'b0;
assignstored0=mul_b[0]?{4'b0,mul_a}:8'b0;
always@(posedgeclkornegedgeclr) //時(shí)序控制
begin
if(!clr)
begin
add_tmp_1<=8'b0000_0000;
add_tmp_2<=8'b0000_0000;
mul_out<=8'b0000_0000;
end
else
begin
add_tmp_1<=stored3+stored2;
add_tmp_2<=stored1+stored0;
mul_out<=add_tmp_1+add_tmp_2;
end
end
endmodule
應(yīng)該指出,在這個(gè)VerilogHDL代碼中,使用非阻塞賦值方式可以直接實(shí)現(xiàn)寄存器的插入,相關(guān)內(nèi)容參照3.2.3節(jié)。
//****************************測試代碼****************************//
modulemult_addtree_2_stag_tb;
regclk,clr;
reg[3:0]mult_a,mult_b;
wire[7:0]mult_out;
mul_addtree_2_stage U1(.mul_a(mult_a),.mul_b(mult_b),
.mul_out(mult_out),.clk(clk),.clr(clr));
initial
begin
clk=0;clr=0;mult_a=1;mult_b=1;
#5clr=1;
end
always#10clk=~clk;
initial
begin
repeat(5)
begin
#20mult_a=mult_a+1;mult_b=mult_b+1;
end
end
endmodule
測試結(jié)果如圖6.2-4所示。
圖6.2-4兩級流水線4位加法器樹乘法器的測試結(jié)果6.2.2Wallace樹乘法器
在乘法器的設(shè)計(jì)中,采用樹形乘法器可以減少關(guān)鍵路徑和所需的加法器單元數(shù)目。Wallace樹乘法器就是其中一種。下面以一個(gè)4
×
4位的乘法器為例來介紹Wallace樹乘法器。Wallace樹乘法器原理圖如圖6.2-5所示,其中FA為全加器,HA為半加器。其基本原理是,加法從數(shù)據(jù)最密集的地方開始,不斷地反復(fù)使用全加器、半加器來覆蓋“樹”。這一級全加器是一個(gè)3輸入2輸出的器件,因此全加器又稱為3-2壓縮器。通過全加器將樹的深度不斷縮減,最終縮減為一個(gè)深度為2的樹。最后一級則采用一個(gè)簡單的2輸入加法器組成。
圖6.2-5Wallace樹乘法器原理圖
圖6.2-6Wallace樹乘法器電路結(jié)構(gòu)例6.2-3用VerilogHDL設(shè)計(jì)如圖6.2-6所示的4位Wallace樹乘法器。
modulewallace(x,y,out);
parametersize=4; //參數(shù)定義
input[size-1:0]x,y;
output[2*size-1:0]out; //端口聲明
wire[size*size-1:0]a;
wire[1:0]b0,b1,c0,c1,c2,c3; //連線類型聲明
wire[5:0]add_a,add_b;
wire[6:0]add_out;
wire[2*size-1:0]out;
assign
a={x[3],x[3],x[2],x[2],x[1],x[3],x[1],x[0],x[3],
x[2],x[1],x[0],x[2],x[1],x[0],x[0]}&
{y[3],y[2],y[3],y[2],y[3],y[1],y[2]
,y[3],y[0],y[1],y[1],y[2],y[0],y[0],y[1],y[0]};//部分積
haddU1(.x(a[8]),.y(a[9]),.out(b0)); //2輸入半加器
haddU2(.x(a[11]),.y(a[12]),.out(b1));
haddU3(.x(a[4]),.y(a[5]),.out(c0));
faddU4(.x(a[6]),.y(a[7]),.z(b0[0]),.out(c1)); //3輸入全加器
faddU5(.x(a[13]),.y(a[14]),.z(b0[1]),.out(c2));
faddU6(.x(b1[0]),.y(a[10]),.z(b1[1]),.out(c3));
assignadd_a={c3[1],c2[1],c1[1],c0[1],a[3],a[1]}; //加數(shù)
assignadd_b={a[15],c3[0],c2[0],c1[0],c0[0],a[2]};
assignadd_out=add_a+add_b;
assignout={add_out,a[0]};
endmodule
modulefadd(x,y,z,out);
output[1:0]out;
inputx,y,z;
assignout=x+y+z;
endmodule
modulehadd(x,y,out);
output[1:0]out;
inputx,y;
assignout=x+y;
endmodule
//***************************測試代碼*********************//
modulewallace_tb;
reg[3:0]x,y;
wire[7:0]out;
wallacem(.x(x),.y(y),.out(out)); //模塊例化
initial //測試信號
begin
x=3;y=4;
#20x=2;y=3;
#20x=6;y=8;
end
endmodule
測試結(jié)果如圖6.2-7所示。
圖6.2-7Wallace樹乘法器的測試結(jié)果6.2.3復(fù)數(shù)乘法器
復(fù)數(shù)乘法的算法是:設(shè)復(fù)數(shù),則復(fù)數(shù)乘法結(jié)果為
(6.2-1)
復(fù)數(shù)乘法器的電路結(jié)構(gòu)如圖6.2-8所示。將復(fù)數(shù)x的實(shí)部與復(fù)數(shù)y的實(shí)部相乘,減去x的虛部與y的虛部相乘,得到輸出結(jié)果的實(shí)部。將x的實(shí)部與y的虛部相乘,加上x的虛部與y的實(shí)部相乘,得到輸出結(jié)果的虛部。
圖6.2-8復(fù)數(shù)乘法器的電路結(jié)構(gòu)例6.2-4用VerilogHDL設(shè)計(jì)實(shí)部和虛部均為4位二進(jìn)制數(shù)的復(fù)數(shù)乘法器。
modulecomplex(a,b,c,d,out_real,out_im);
input[3:0]a,b,c,d;
output[8:0]out_real,out_im;
wire[7:0]sub1,sub2,add1,add2;
wallace U1(.x(a),.y(c),.out(sub1));
wallace U2(.x(b),.y(d),.out(sub2));
wallace U3(.x(a),.y(d),.out(add1));
wallace U4(.x(b),.y(c),.out(add2));
assign out_real=sub1-sub2;
assign out_im=add1+add2;
endmodule
//***********************測試模塊*********************//
modulecomplex_tb;
reg[3:0]a,b,c,d;
wire[8:0]out_real;
wire[8:0]out_im;
complexU1(.a(a),.b(b),.c(c),.d(d),.out_real(out_real),.out_im(out_im));
initial
begin
a=2; b=2;c=5;d=4;
#10
a=4;b=3;c=2;d=1;
#10
a=3;b=2;c=3;d=4;
end
endmodule
測試結(jié)果如圖6.2-9所示。
圖6.2-9復(fù)數(shù)乘法器的測試結(jié)果6.2.4FIR濾波器的設(shè)計(jì)
濾波器就是對特定的頻率或者特定頻率以外的頻率進(jìn)行消除的電路,被廣泛用于通信系統(tǒng)和信號處理系統(tǒng)中。從功能角度而言,數(shù)字濾波器對輸入離散信號的數(shù)字代碼進(jìn)行運(yùn)算處理,以達(dá)到濾除頻帶外信號的目的。
有限沖激響應(yīng)(FIR)濾波器就是一種常用的數(shù)字濾波器,采用對已輸入樣值的加權(quán)和來形成它的輸出。其系統(tǒng)函數(shù)為
(6.2-2)其中z-1表示延遲一個(gè)時(shí)鐘周期,z-2表示延遲兩個(gè)時(shí)鐘周期。
對于輸入序列X[n]的FIR濾波器,可用圖6.2-10所示的結(jié)構(gòu)示意圖來表示,其中X[n]是輸入數(shù)據(jù)流。各級的輸入連接和輸出連接被稱為抽頭,系數(shù)(b0,b1,…,bn)被稱為抽頭系數(shù)。一個(gè)M階的FIR濾波器將會(huì)有M
+
1個(gè)抽頭。通過移位寄存器用每個(gè)時(shí)鐘邊沿n(時(shí)間下標(biāo))處的數(shù)據(jù)流采樣值乘以抽頭系數(shù),并將它們加起來形成輸出Y[n]。
圖6.2-10FIR濾波器結(jié)構(gòu)示意圖例6.2-5用VerilogHDL設(shè)計(jì)一個(gè)輸入信號位寬為4bit的8階FIR濾波器。
如圖6.2-10所示,F(xiàn)IR濾波器電路有兩個(gè)主要功能模塊:移位寄存器組模塊shift_register用于存儲(chǔ)串行進(jìn)入濾波器的數(shù)據(jù);乘加計(jì)算模塊caculator用于進(jìn)行FIR計(jì)算(見式(6.2-2))。因此,在頂層模塊中采用結(jié)構(gòu)性的描述方式設(shè)計(jì)。
moduleFIR(Data_out,Data_in,clock,reset);
output[9:0]Data_out;
input[3:0]Data_in;
inputclock,reset;
wire[9:0]Data_out;
wire[3:0]samples_0,samples_1,samples_2,samples_3,samples_4,
samples_5,samples_6,samples_7,samples_8;
shift_registerU1(.Data_in(Data_in),.clock(clock),.reset(reset),
.samples_0(samples_0),.samples_1(samples_1),
.samples_2(samples_2),.samples_3(samples_3),
.samples_4(samples_4),.samples_5(samples_5),
.samples_6(samples_6),.samples_7(samples_7),
.samples_8(samples_8));
caculatorU2(.samples_0(samples_0),.samples_1(samples_1),
.samples_2(samples_2),.samples_3(samples_3),
.samples_4(samples_4),.samples_5(samples_5),
.samples_6(samples_6),.samples_7(samples_7),
.samples_8(samples_8),.Data_out(Data_out));
endmodule
shift_register模塊用于存儲(chǔ)輸入的數(shù)據(jù)流,本例中主要負(fù)責(zé)存儲(chǔ)8個(gè)位寬為4bit的輸入數(shù)據(jù)信號,用于caculator模塊的輸入。
moduleshift_register(Data_in,clock,reset,samples_0,samples_1,samples_2,
samples_3,samples_4,samples_5,samples_6,
samples_7,samples_8);
input[3:0]Data_in;
inputclock,reset;
output[3:0]samples_0,samples_1,samples_2,samples_3,samples_4,
samples_5,samples_6,samples_7,samples_8;
reg[3:0]samples_0,samples_1,samples_2,samples_3,samples_4,
samples_5,samples_6,samples_7,samples_8;
always@(posedgeclockornegedgereset)
begin
if(reset)
begin
samples_0<=4'b0;
samples_1<=4'b0;
samples_2<=4'b0;
samples_3<=4'b0;
samples_4<=4'b0;
samples_5<=4'b0;
samples_6<=4'b0;
samples_7<=4'b0;
samples_8<=4'b0;
end
else
begin
samples_0<=Data_in;
samples_1<=samples_0;
samples_2<=samples_1;
samples_3<=samples_2;
samples_4<=samples_3;
samples_5<=samples_4;
samples_6<=samples_5;
samples_7<=samples_6;
samples_8<=samples_7;
end
end
endmodule
caculator模塊用于進(jìn)行8輸入信號與抽頭系數(shù)的乘法和累加,并產(chǎn)生濾波之后的輸出信號Data_out。應(yīng)該指出的是,F(xiàn)IR濾波器系數(shù)具有對稱性,在本例中,b0
=
b8,b1
=
b7,b2
=
b6,b3
=
b5,因此,可以采用先將輸入信號相加再與抽頭系數(shù)相乘的方式,減少乘法器電路的數(shù)量和芯片面積。
modulecaculator(samples_0,samples_1,samples_2,samples_3,samples_4,samples_5,
samples_6,samples_7,samples_8,Data_out);
input[3:0]samples_0,samples_1,samples_2,samples_3,samples_4,samples_5,
samples_6,samples_7,samples_8;
output[9:0]Data_out;
wire[9:0]Data_out;
wire[3:0]out_tmp_1,out_tmp_2,out_tmp_3,out_tmp_4,out_tmp_5;
wire[7:0]out1,out2,out3,out4,out5;
parameterb0=4'b0010;
parameterb1=4'b0011;
parameterb2=4'b0110;
parameterb3=4'b1010;
parameterb4=4'b1100;
mul_addtreeU1(.mul_a(b0),.mul_b(out_tmp_1),.mul_out(out1));
mul_addtreeU2(.mul_a(b1),.mul_b(out_tmp_2),.mul_out(out2));
mul_addtreeU3(.mul_a(b2),.mul_b(out_tmp_3),.mul_out(out3));
mul_addtreeU4(.mul_a(b3),.mul_b(out_tmp_4),.mul_out(out4));
mul_addtreeU5(.mul_a(b4),.mul_b(samples_4),.mul_out(out5));
assignout_tmp_1=samples_0+samples_8;
assignout_tmp_2=samples_1+samples_7;
assignout_tmp_3=samples_2+samples_6;
assignout_tmp_4=samples_3+samples_5;
assignData_out=out1+out2+out3+out4+out5;
endmodule
乘法器模塊mul_addtree的代碼見例6.2-2。
//***********************測試模塊*********************//
moduleFIR_tb;
regclock,reset;
reg[3:0]Data_in;
wire[9:0]Data_out;
FIR U1(.Data_out(Data_out),.Data_in(Data_in),.clock(clock),.reset(reset));
initial
begin
Data_in=0;clock=0;reset=1;
#10reset=0;
end
always
begin
#5clock<=~clock;
#5Data_in<=Data_in+1;
end
endmodule
測試結(jié)果如圖6.2-11所示。
圖6.2-11FIR濾波器的測試結(jié)果圖6.2-12RAM的內(nèi)部結(jié)構(gòu)示意圖6.2.5片內(nèi)存儲(chǔ)器的設(shè)計(jì)
片內(nèi)存儲(chǔ)器分為RAM和ROM兩大類。本節(jié)將分別介紹RAM和ROM的VerilogHDL描述方式。
1.?RAM的VerilogHDL描述
RAM是隨機(jī)存儲(chǔ)器,存儲(chǔ)單元的內(nèi)容可按需隨意取出或存入。這種存儲(chǔ)器在斷電后將丟失所有數(shù)據(jù),因此一般用來存儲(chǔ)一些短時(shí)間內(nèi)使用的程序和數(shù)據(jù)。其內(nèi)部結(jié)構(gòu)如圖6.2-12所示。根據(jù)地址總線、數(shù)據(jù)總線以及讀寫控制線的數(shù)目,可以將RAM分為單端口RAM和雙端口RAM兩大類。
例6.2-6用VerilogHDL設(shè)計(jì)深度為8、位寬為8bit的單端口RAM。
單端口RAM只有一套地址總線,讀操作和寫操作是分開的。其VerilogHDL程序如下:
moduleram_single(clk,addm,cs_n,we_n,din,dout);
input clk; //時(shí)鐘信號
input[2:0] addm; //地址信號
input cs_n; //片選信號
input we_n; //寫使能信號
input[7:0]din; //輸入數(shù)據(jù)
output[7:0]dout; //輸出數(shù)據(jù)
reg[7:0]dout;
reg[7:0]raml[7:0]; //8*8bit寄存器
always@(posedgeclk)
begin
if(cs_n)
dout<=8'bzzzz_zzzz;
else
if(we_n) //讀數(shù)據(jù)
dout<=raml[addm];
else //寫數(shù)據(jù)
raml[addm]<=din;
end
endmodule
//******************************測試程序*******************************
moduleram_single_tb;
regclk,we_n,cs_n;
reg[2:0]addm;
reg[7:0]din;
wire[7:0]dout;
ram_singleU1(.clk(clk),.addm(addm),.cs_n(cs_n),.we_n(we_n),
.din(din),.dout(dout));
initial
begin
clk=0;addm=0;cs_n=1;we_n=0;din=0;
#5cs_n=0;
#315we_n=1;
end
always#10clk=~clk;
initial
begin
repeat(7)
begin
#40addm=addm+1;
din=din+1;
end
#40
repeat(7)
#40addm=addm-1;
end
endmodule
測試結(jié)果如圖6.2-13所示。
圖6.2-13單端口RAM的測試結(jié)果例6.2-7用VerilogHDL設(shè)計(jì)深度為8、位寬為8bit的雙端口RAM。
雙端口RAM具有兩套地址總線,一套用于讀數(shù)據(jù),另一套用于寫數(shù)據(jù)。二者可以分別進(jìn)行操作。其VerilegHDL程序如下:
moduleram_dual(q,addr_in,addr_out,d,we,rd,clk1,clk2);
output[7:0]q; //輸出數(shù)據(jù)
input[7:0]d; //輸入數(shù)據(jù)
input[2:0]addr_in; //寫數(shù)據(jù)地址信號
input[2:0]addr_out; //輸出數(shù)據(jù)地址信號
inputwe; //寫數(shù)據(jù)控制信號
inputrd; //讀數(shù)據(jù)控制信號
inputclk1; //寫數(shù)據(jù)時(shí)鐘信號
inputclk2; //讀數(shù)據(jù)時(shí)鐘信號
reg[7:0]q;
reg[7:0]mem[7:0]; //8*8bit寄存器
always@(posedgeclk1)
begin
if(we)
mem[addr_in]<=d;
end
always@(posedgeclk2)
begin
if(rd)
q<=mem[addr_out];
end
endmodule
//*******************************測試代碼*****************************
moduleram_dual_tb;
regclk1,clk2,we,rd;
reg[2:0]addr_in;
reg[2:0]addr_out;
reg[7:0]d;
wire[7:0]q;
ram_dualU1(.q(q),.addr_in(addr_in),.addr_out(addr_out),.d(d),.we(we),
.rd(rd),.clk1(clk1),.clk2(clk2));
initial
begin
clk1=0;clk2=0;we=1;rd=0;addr_in=0;addr_out=0;d=0;
#320we=0;
rd=1;
end
always
begin
#10clk1=~clk1;clk2=~clk2;
end
initial
begin
repeat(7)
begin
#40addr_in=addr_in+1;d=d+1;
end
#40
repeat(7)#40addr_out=addr_out+1;
end
endmodule
測試結(jié)果如圖6.2-14所示。
圖6.2-14雙端口RAM的測試結(jié)果
2.?ROM的VerilogHDL描述
ROM即只讀存儲(chǔ)器,是一種只能讀出事先存儲(chǔ)的數(shù)據(jù)的存儲(chǔ)器,其特性是存入的數(shù)據(jù)無法改變。也就是說,這種存儲(chǔ)器只能讀不能寫。由于ROM在斷電之后數(shù)據(jù)不會(huì)丟失,所以通常用在不需經(jīng)常變更資料的電子或電腦系統(tǒng)中,資料并不會(huì)因?yàn)殡娫吹年P(guān)閉而消失。
例6.2-8用VerilogHDL設(shè)計(jì)深度為8、位寬為8bit的ROM。
modulerom(dout,clk,addm,cs_n);
inputclk,cs_n;
input[2:0]addm;
output[7:0]dout;
reg[7:0]dout;
reg[7:0]rom[7:0];
initial
begin
rom[0]=8'b0000_0000;
rom[1]=8'b0000_0001;
rom[2]=8'b0000_0010;
rom[3]=8'b0000_0011;
rom[4]=8'b0000_0100;
rom[5]=8'b0000_0101;
rom[6]=8'b0000_0110;
rom[7]=8'b0000_0111;
end
always@(posedgeclk)
begin
if(cs_n) dout<=8'bzzzz_zzzz;
else dout<=rom[addm];
end
endmodule
//*****************************測試代碼***************************
modulerom_tb;
regclk,cs_n;
reg[2:0]addm;
wire[7:0]dout;
romU1(.dout(dout),.clk(clk),.addm(addm),.cs_n(cs_n));
initial
begin
clk=0;addm=0;cs_n=0;
end
always#10clk=~clk;
initial
begin
repeat(7)
#20addm=addm+1;
end
endmodule
測試結(jié)果如圖6.2-15所示。
圖6.2-15ROM的測試結(jié)果6.2.6FIFO設(shè)計(jì)
FIFO(FirstInFirstOut)是一種先進(jìn)先出的數(shù)據(jù)緩存器,通常用于接口電路的數(shù)據(jù)緩存。與普通存儲(chǔ)器的區(qū)別是,沒有外部讀寫地址線,可以使用兩個(gè)時(shí)鐘分別進(jìn)行寫操作和讀操作。FIFO只能順序?qū)懭霐?shù)據(jù)和順序讀出數(shù)據(jù),其數(shù)據(jù)地址由內(nèi)部讀寫指針自動(dòng)加1完成,不能像普通存儲(chǔ)器那樣可以由地址線決定讀取或?qū)懭肽硞€(gè)指定的地址。
FIFO由存儲(chǔ)器塊和對數(shù)據(jù)進(jìn)出FIFO的通道進(jìn)行管理的控制器構(gòu)成,每次只對一個(gè)寄存器提供存取操作,而不是對整個(gè)寄存器陣列進(jìn)行。FIFO有兩個(gè)地址指針,一個(gè)用于將數(shù)據(jù)寫入下一個(gè)可用的存儲(chǔ)單元,一個(gè)用于讀取下一個(gè)未讀存儲(chǔ)單元的操作。讀寫數(shù)據(jù)必須一次進(jìn)行。其讀寫過程如圖6.2-16所示。
圖6.2-16FIFO的讀寫過程當(dāng)一個(gè)堆棧為空時(shí)(圖6.2-16(a)),讀數(shù)據(jù)指針和寫數(shù)據(jù)指針都指向第一個(gè)存儲(chǔ)單元;當(dāng)寫入一個(gè)數(shù)據(jù)時(shí)(圖6.2-16(b)),寫數(shù)據(jù)指針將指向下一個(gè)存儲(chǔ)單元;經(jīng)過七次寫數(shù)據(jù)操作后(圖6.2-16(c)),寫指針將指向最后一個(gè)存儲(chǔ)單元;當(dāng)經(jīng)過連續(xù)八次寫操作之后,寫指針將回到首單元并且顯示堆棧狀態(tài)為滿(圖6.2-16(d))。數(shù)據(jù)的讀操作和寫操作相似,當(dāng)讀出一個(gè)數(shù)據(jù)時(shí),讀數(shù)據(jù)指針將移向下一個(gè)存儲(chǔ)單元,直到讀出全部的數(shù)據(jù),此時(shí)讀指針回到首單元,堆棧狀態(tài)顯示為空。一個(gè)FIFO的組成一般包括兩部分:地址控制部分和存儲(chǔ)數(shù)據(jù)的RAM部分,如圖6.2-17所示。地址控制部分可以根據(jù)讀寫指令生成RAM地址。RAM用于存儲(chǔ)堆棧數(shù)據(jù),并根據(jù)控制部分生成的地址信號進(jìn)行數(shù)據(jù)的存儲(chǔ)和讀取操作。這里的RAM采用的是前面提到的雙端口RAM。
圖6.2-17FIFO結(jié)構(gòu)圖例6.2-9用VerilogHDL設(shè)計(jì)深度為8、位寬為8bit的FIFO。
//頂層模塊
moduleFIFO_buffer(clk,rst,write_to_stack,read_from_stack,Data_in,Data_out);
inputclk,rst;
inputwrite_to_stack,read_from_stack;
input[7:0]Data_in;
output[7:0]Data_out;
wire[7:0]Data_out;
wirestack_full,stack_empty;
wire[2:0]addr_in,addr_out;
FIFO_controlU1(.stack_full(stack_full),.stack_empty(stack_empty),
.write_to_stack(write_to_stack),.write_ptr(addr_in),
.read_ptr(addr_out),.read_from_stack(read_from_stack),
.clk(clk),.rst(rst));
ram_dualU2(.q(Data_out),.addr_in(addr_in),.addr_out(addr_out),
.d(Data_in),.we(write_to_stack),.rd(read_from_stack),
.clk1(clk),.clk2(clk));
endmodule
//控制模塊
moduleFIFO_control(write_ptr,read_ptr,stack_full,stack_empty,write_to_stack,
read_from_stack,clk,rst);
parameterstack_width=8;
parameterstack_height=8;
parameterstack_ptr_width=3;
outputstack_full; //堆棧滿標(biāo)志
outputstack_empty; //堆??諛?biāo)志
output[stack_ptr_width-1:0]read_ptr; //讀數(shù)據(jù)地址
output[stack_ptr_width-1:0]write_ptr; //寫數(shù)據(jù)地址
inputwrite_to_stack; //將數(shù)據(jù)寫入堆棧
inputread_from_stack; //從堆棧讀出數(shù)據(jù)
inputclk;
inputrst;
reg[stack_ptr_width-1:0]read_ptr;
reg[stack_ptr_width-1:0]write_ptr;
reg[stack_ptr_width:0]ptr_gap;
reg[stack_width-1:0]Data_out;
reg[stack_width-1:0]stack[stack_height-1:0];
//堆棧狀態(tài)信號
assignstack_full=(ptr_gap==stack_height);
assignstack_empty=(ptr_gap==0);
always@(posedgeclkorposedgerst)
begin
if(rst)
begin
Data_out<=0;
read_ptr<=0;
write_ptr<=0;
ptr_gap<=0;
end
elseif(write_to_stack&&(!stack_full)&&(!read_from_stack))
begin
write_ptr<=write_ptr+1;
ptr_gap<=ptr_gap+1;
end
elseif(!write_to_stack&&(!stack_empty)&&(read_from_stack))
begin
read_ptr<=read_ptr+1;
ptr_gap<=ptr_gap-1;
end
elseif(write_to_stack&&stack_empty&&read_from_stack)
begin
write_ptr<=write_ptr+1;
ptr_gap<=ptr_gap+1;
end
elseif(write_to_stack&&stack_full&&read_from_stack)
begin
read_ptr<=read_ptr+1;
ptr_gap<=ptr_gap-1;
end
elseif(write_to_stack&&read_from_stack
&&(!stack_full)&&(!stack_empty))
begin
read_ptr<=read_ptr+1;
write_ptr<=write_ptr+1;
end
end
endmodule
RAM模塊參考例6.2-7。
//*****************************測試代碼***************************
moduleFIFO_tb;
regclk,rst;
reg[7:0]Data_in;
regwrite_to_stack,read_from_stack;
wire[7:0]Data_out;
FIFO_bufferU1(.clk(clk),.rst(rst),.write_to_stack(write_to_stack),
.read_from_stack(read_from_stack),.Data_in(Data_in),
.Data_out(Data_out));
initial
begin
clk=0;rst=1;Data_in=0;write_to_stack=1;read_from_stack=0;
#5rst=0;
#155write_to_stack=0;
read_from_stack=1;
end
always#10clk=~clk;
initial
begin
repeat(7)
#20Data_in=Data_in+1;
end
endmodule圖6.2-18FIFO的測試結(jié)果6.2.7鍵盤掃描和編碼器
鍵盤掃描和編碼器用于在擁有鍵盤的數(shù)字系統(tǒng)中手工輸入數(shù)據(jù),通過檢測按鍵是否按下來產(chǎn)生一個(gè)唯一對應(yīng)此按鍵的掃描碼。
例6.2-10用VerilogHDL設(shè)計(jì)一個(gè)十六進(jìn)制鍵盤電路的鍵盤掃描和編碼器。
圖6.2-19是十六進(jìn)制鍵盤電路的鍵盤掃描和編碼器的一種設(shè)計(jì)方案。
圖6.2-19十六進(jìn)制鍵盤電路的鍵盤掃描和編碼器鍵盤的每一行都會(huì)通過一個(gè)下拉電阻連接到地,而行和列之間有一個(gè)以按鍵為開關(guān)的連接,當(dāng)按下按鍵時(shí)行和列之間就建立了連接。如果列線的值為1,則由按鍵連接到的那個(gè)列的行值也將會(huì)被拉升為1,反之行線將會(huì)被下拉至0。通過鍵盤掃描碼發(fā)生器單元來控制列線,使列線上的電壓有規(guī)律而有效地檢測行線的電壓值,進(jìn)而來確定按下按鍵的位置。鍵盤掃描碼發(fā)生器必須具備檢測識別按鍵,并產(chǎn)生一個(gè)與按鍵唯一對應(yīng)掃描碼輸出的功能。為此可以設(shè)計(jì)一個(gè)時(shí)序狀態(tài)機(jī),通過不同狀態(tài)之間的轉(zhuǎn)換來實(shí)現(xiàn)信號的檢測識別以及對應(yīng)掃描碼的輸出。首先,令所有的列線同時(shí)為1來檢測行線的值,直到發(fā)現(xiàn)一條行線的值被上拉為1,此時(shí)說明有按鍵被按下,但是仍然不能確定按鍵的位置;然后,通過依次將列線的值拉高來檢測各個(gè)行線的值,直到檢測到一條行線的值為1為止??刂菩盘枲顟B(tài)機(jī)轉(zhuǎn)移圖如圖6.2-20所示。
圖6.2-20十六進(jìn)制鍵盤電路的鍵盤掃描和編碼器的控制信號狀態(tài)轉(zhuǎn)移圖此時(shí)行線和列線的交叉處就是按鍵的位置。根據(jù)已確定的按鍵的位置輸出其對應(yīng)的編碼信息。其鍵盤編碼表如表6.2-1所示。表6.2-1十六進(jìn)制鍵盤電路的編碼器碼表為了使測試更接近于真實(shí)的物理環(huán)境,測試平臺中必須包括模擬按鍵狀態(tài)的信號發(fā)生器,能確認(rèn)按鍵對應(yīng)行線的模塊row_signal和被測試模塊hex_keypad_grayhill_072。模擬按鍵狀態(tài)的信號發(fā)生器可以嵌入在測試平臺中,通過不斷地給key信號賦值,模擬產(chǎn)生不同的按鍵信號。row_signal模塊用于檢測按鍵的有效性并確定按鍵所處的行。而synchronizer模塊通過檢測各個(gè)行線值的或來確定是否有按鍵按下,當(dāng)此模塊的輸出發(fā)生變化時(shí),被測模塊hex_keypad_grayhill_072將會(huì)確定按鍵的位置并輸出相應(yīng)的代碼。其VerilogHDL程序代碼如下:
//頂層模塊
modulekeypad(clock,reset,row,code,valid,col);
inputclock,reset;
input[3:0]row;
output[3:0]code;
outputvalid;
output[3:0]col;
wires_row;
hex_keypad_grayhillU1(.code(code),.col(col),.valid(valid),
.row(row),.s_row(s_row),.clock(clock),
.reset(reset));
synchronizerU2(.s_row(s_row),.row(row),.clock(clock),.reset(reset));
endmodule
//編碼模塊
modulehex_keypad_grayhill(code,col,valid,row,s_row,clock,reset);
output[3:0] code;
output valid;
output[3:0] col;
input[3:0] row;
input s_row;
input clock,reset;
reg[3:0] col;
reg[3:0] code;
reg[5:0] state,next_state;
parameters_0=6'b000001,s_1=6'b000010,s_2=6'b000100;
parameters_3=6'b001000,s_4=6'b010000,s_5=6'b100000;
assignvalid=((state==s_1)||(state==s_2)||(state==s_3)||(state==s_4))
&&row;
always@(roworcol)
case({row,col})
8'b0001_0001:code=0;//0
8'b0001_0010:code=1;//1
8'b0001_0100:code=2;//2
8'b0001_1000:code=3;//3
8'b0010_0001:code=4;//4
8'b0010_0010
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 監(jiān)測與檢測協(xié)議書
- 科研材料采購協(xié)議
- 防水工程項(xiàng)目招投標(biāo)合同
- 防水施工配合協(xié)議
- 2025至2030年中國便攜式水質(zhì)檢測儀行業(yè)市場調(diào)查研究及投資風(fēng)險(xiǎn)評估報(bào)告
- 門禁系統(tǒng)工程施工合同
- 黃金制品購銷合同
- 善與惡的童話故事作文8篇
- 敘事作文如今才知道什么是義無反顧800字14篇
- 一個(gè)普通值日生的不平凡一天記我的校園記事作文13篇
- 《一輪復(fù)習(xí)動(dòng)員》主題班會(huì)課件1
- 會(huì)計(jì)學(xué)專業(yè)導(dǎo)論
- ZJ17ZB45卷接包設(shè)備點(diǎn)巡檢作業(yè)規(guī)程
- 降低壓力性損傷發(fā)生率品管圈課件
- 《嘭嘭嘭》閱讀測試題(附答案)
- 《生活環(huán)境和健康》課件
- 《集體經(jīng)營性建設(shè)用地使用權(quán)出讓監(jiān)管協(xié)議》示范文本(試點(diǎn)試行)
- 工作與個(gè)人生活平衡安排
- 深圳律師法律服務(wù)產(chǎn)品清單(第二版)
- 會(huì)務(wù)服務(wù)投標(biāo)方案(技術(shù)標(biāo))
- 施工組織設(shè)計(jì)(橫道圖+平面圖)
評論
0/150
提交評論