第一章 緒論
1.1 EDA簡介
EDA 技術就是依賴功能強大的計算機,在EDA工具軟件平臺上,對以硬件描述語言HDL為系統邏輯描述手段完成的設計文件,自動地完成邏輯編譯、化簡、分割、綜合、布局布線以及邏輯優化和仿真測試,直至實現既定的電子線路系統功能。EDA技術使得設計者的工作僅限于利用軟件的方式,即利用硬件描述語言和EDA軟件來完成對系統硬件功能的實現,這是電子設計技術的一個巨大進步。EDA技術在進入21世紀后,得到了更大的發展。嵌入式處理器軟核的成熟,使得SOPC步入大規模應用階段。電子技術領域全方位融入EDA技術,除了日益成熟的數字技術外,傳統的電路系統設計建模理念發生了重大的變化。同時,EDA使得電子領域各學科的界限更加模糊,更加互為包容。這些都利于設計人員利用EDA技術進行電子系統設計,如全定制或半定制ASIC設計,FPGA/CPLD開發應用和印制電路板。從EDA技術的特點不難看出,相比于傳統的數字電子系統或IC設計,EDA技術擁有獨特的優勢。在傳統的數字電子系統或IC設計中,手工設計占了較大的比例。因此,也存在很多缺點。例如:復雜電路的設計、調試十分困難;由于無法進行硬件系統仿真,如果某一過程存在錯誤,查找和修改十分不便;設計過程中產生大量文檔,不易管理;可移植性差等。相比之下,EDA技術有很大不同。它運用HDL對數字系統進行抽象的行為與功能描述到具體的內部線路結構描述,從而可以在電子設計的各個階段、各個層次進行計算機模擬驗證,保證設計過程的正確性,可以大大降低設計成本,縮短設計周期。由于有各類庫的支持,能夠完成各種自動設計過程。它極大地簡化了設計文檔的管理,邏輯設計仿真測試技術也日益強大。VHDL在現在的EDA設計中使用最多,也擁有幾乎所有主流EDA工具的支持。
EDA技術在硬件實現方面融合了大規模集成電路制造技術,IC版圖設計,ASIC測試和封裝以及FPGA/CPLD編程下載和自動測試等技術;在計算機輔助工程方面融合了計算機輔助設計(CAD),計算機輔助制造(CAM),計算機輔助測試(CAT),計算機輔助工程(CAE)技術以及多種計算機語言的設計概念;
1.2芯片介紹
主流產品:ALTERA公司 、FLEX公司
產品類型:CPLD:EPROM類型,掉電后程序不丟失。
FPGA:SRAM類型,掉電后程序丟失,必須重新編程。
工作電壓:5V/3.3V/2.5V/1.8V/1.5V
目前主要產品
MAX7000S/AE,MAX3000A系列、FLEX10KE/ACEX1K系列
APEX20K/20KE系列、APEXII系列、Stratix系列
Cyclone(颶風) 系列、Excalibur系列
1.3 Cyclone(颶風)系列介紹
Altera最新一代SRAM工藝中等規模FPGA:
與Stratix結構類似,是一種低成本FPGA系列:
是目前主流產品,其配置芯片業改用新的產品
可支持多種擴展模塊
攝像頭模塊
VGA模塊
2.4寸彩屏
3.2寸彩屏
7寸高清大屏
以太網模塊
網口模塊
USB模塊
高速AD DA
第二章 模塊介紹
2.1設計分析根據設計要求,由于樂曲自動演奏機和硬件電子琴的設計已經存在,我們對已有的設計進行修改,形成兩個不同功能的模塊,然后采用元件例化,拼接兩個模塊,同時附加一個選擇功能模塊,以實現樂曲自動演機和硬件電子琴兩個功能。 2.2硬件電子琴分析對于硬件電子琴,參考了實驗時使用的程序,已經達到的要求有: (1)按下key1~key7 分別表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 S; (2)按下相應的鍵有對應LED燈指示。 2.3 樂曲自動演奏機分析對于樂曲自動演奏機,參考了實驗時使用的程序,已經達到的要求有: (1)可以在電路上能自動演奏樂曲,在這里我們采用的是貝多芬的《歡樂頌》 (2)有相應的LED燈指示高低音。 而對于其他要求: (1)晶振為12 MHz. (2)采用CPLD 器件為ALTERA 的EPM7064SL-44。 我們在實驗箱驗證時,先按照實驗箱芯片和晶振進行就修改,在實驗箱上確認實驗相應功能之后,我們在對應模塊的頻率數值進行修改,并在對管腳重新鎖定即可 2.4整體設計分析整體設計要求:用key8實現兩個功能切換。添加一個選擇器,以實現兩個功能切換。當key8鍵沒有按下時,電路實現硬件電子琴功能,當key8鍵按下之后,電路實現樂曲自動演奏機。由于不存在現成可以借鑒的,于是,課程設計任務重心就放在了選擇器模塊的編寫以及整體電路的合成上。 頂層模塊輸入輸出: 圖2-1 頂層文件圖形 管腳說明:輸入:時鐘信號——clk ,按鍵——[6:0]key ,功能切換鍵——key7 輸出:LED燈——[6:0]led ,蜂鳴器——beep; Key0: DO key1: RE key2: ME key3:FA key4: SOL key5: LA key6: SI key7:功能切換鍵 2.5 設計流程
第三章 功能劃分與模塊劃分3.1自動演奏模塊自動演奏模塊功能:在按下key7鍵后,實現可以自動播放樂曲的功能。 3.2 自動演奏設計方案(1)根據樂曲自動演奏的基本原理設計出適合EDA多功能試驗箱的源程序,通過分頻模塊得到12MHZ的晶振;源程序編寫完成,編譯調試后,在實驗箱上驗證其功能; (2)驗證模塊是否能完成實踐要求的所有功能;然后去掉分頻模塊,將功能模塊做適當的修改,編譯調試成功后,將其下載到CPLD實驗板上。 方案設計步驟: (1)在Quartus Ⅱ中建立一個工程項目文件song.qpf,并在該項目下新建Verilog HDL源程序文件song.v輸入程序代碼并保存。完整的Verilog HDL程序參考程序清單。 (2)然后在該工程選擇目標器件并對相應的引腳進行鎖定,在這里所選擇器件為Alter公司的EPM7064SL-44芯片。 (3)對該工程文件進行全程編譯處理,若在編譯中發現錯誤,則找出錯誤并更正,直到編譯成功。 (4)最后拿出下載電纜,將此電纜的兩端分別接到PC機的打印機并口和核心板上的JTAG 接口上,打開電源執行下載命令,把程序下載到CPLD器件中。此時可以得到《歡樂頌》樂曲的演奏以及LED燈的明滅指示其高低音。 3.3硬件電子琴模塊硬件電子琴模塊功能:在按下功能切換鍵key7后,可以實現電子琴功能,即按下key1 到key7的過程中發出相應的高低音。 3.3.1硬件電子琴設計方案(1)根據硬件電子琴演奏的基本原理設計出適合EDA多功能試驗箱的源程序,通過分頻模塊得到12MHZ的晶振;源程序編寫完成,編譯調試后,在實驗箱上驗證其功能; (2)驗證模塊是否能完成實踐要求的所有功能;然后去掉分頻模塊,將功能模塊做適當的修改后,編譯調試成功后,將其下載到CPLD實驗板上。 3.3.2設計步驟(1)在Quarters II中建立一個工程項目文件beep1.qpf。并在該項目下新建Verilog HDL源程序文件beep1.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。 (2)選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。 (3)對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。 (4)將產生的beep1.sof輸出對FPGA進行配置。按下按鍵KEY1~KEY8就可以開始使用電子琴來演奏音樂了。
第四章 課程設計原理4.1硬件電子琴設計原理樂曲演奏的原理是:由于組成樂曲的每個音符的頻率值(音調)及其持續時間(音長)是樂曲演奏的2個基本數據,因此需要控制輸出到揚聲器的激勵信號的頻率高低和該頻率信號持續的時間。頻率的高低決定了音調的高低,而樂曲的簡譜與各音名的頻率對應關系在后面將給出。所有不同頻率的信號都是從一基準頻率分頻而得來的,由于音階頻率多為非整數,而分頻系數有不能為小數,故必須將計算得到的分頻數進行向下取整,基準頻率和分頻系數應綜合考慮加以選擇,從而保證音樂不會走調。如在48MHz 時鐘下,中音1(對應的頻率值是523.3Hz)的分頻系數應該為:48000000/(2*523.3)=45863,這樣只需對系統時鐘進行45863次分頻即可得到所要的中音M1(分頻系數計算公式為D=F/2K,由于F/2K之后,會使分頻系數D變小,所以功能模塊中語句:beep_r<=!beep_r,使得輸出取反,K=F/2count_end,消除了前面除以2K的影響) 。 4.2樂曲自動演奏設計原理硬件電路和自動演奏的原理同硬件電子琴實驗原理類似。至于其他音符,同樣可由一式求出對應的分頻系數。在程序中設置一個狀態機,每250ms改變一個狀態(即一個節拍),組成樂曲的每個音符的頻率值(音調)相對應于狀態機的每一個狀態。只要讓狀態機的狀態按順序轉換,就可以自動演奏播放音樂了。 《歡樂頌》樂曲的簡譜如圖所示: 圖4-1《歡樂頌》簡譜圖 4.3各模塊的實現方法4.3.1選擇器模塊實現方法我們可以對輸出進行控制。即讓兩個模塊都工作,但是輸出的部分添加選擇器,有選擇輸出信號。當KEY8沒有按下時,硬件電子琴的模塊輸出接到蜂鳴器和LED燈;當KEY8按下時,樂曲自動演奏模塊輸出接到蜂鳴器和LED燈。從輸出進行控制,通過將蜂鳴和LED燈的輸入和兩個模塊的輸出有選擇的匹配進行切換。通過編譯下載到實驗箱驗證可以實現功能,而且在兩種狀態的切換時,不會出現無法控制的狀況。 4.3.2自動演奏模塊實現方法通過參照實驗課本,我們根據相關實驗對試驗程序進行了簡單修改,得到了本次自動演奏模塊的歌曲《歡樂頌》,實現其自動演奏功能。 對于自動演奏模塊而言,要實現其功能,只需要在頂層模塊中添加觸發自動演奏模塊的觸發點,在本程序中,即按下key8按鍵,屏蔽掉硬件電子琴的時鐘信號,而使自動演奏模塊的電子時鐘信號作為使能信號。 在自動演奏模塊中,首先計算出各個音符所對應的參數,對參數進行定義和設計。通過對晶振的控制實現每個音響應時間的長短并且可以修改相關參數實現音長的改變。演奏過程中,設置循環體,即每次演奏結束,可以再從頭開始演奏,從而實現自動演奏的自動功能。程序中可以設置每次循環時間,也可以設置循環中斷。每個音符都需要驅動蜂鳴器實現其功能。 最后,自動演奏模塊中,需要有LED燈的指示,對于這樣的要求,我們在程序最后添加了assign賦值語句。實現了每個音符響時對應的LED燈點亮。對于在實驗中沒有出現的音符所對應的LED燈則設置為高阻態,從而屏蔽LED燈點亮。 在程序中,通過控制TIME從而得到每個音階所響應的時間,不同晶振所對應的的時間為1s,對應的時間可以控制振蕩次數實現控制時間的長短。 if(state == 8'd125) state = 8'd0;語句實現的是自動演奏循環和實現歌曲演奏長短。通過系應該參數從而使歌曲唱到想要唱到的部分。 4.3.3硬件電子琴模塊實現方法在原理部分我們已經知道了硬件電子琴和自動演奏樂曲的原理是相同的,因此在知道了如何實現樂曲演奏模塊的方法后,對于硬件電子琴只需要實現同樣的方法,就可以實現其模塊功能,只不過在硬件電子琴模塊中,需要的是利用按鍵實現其功能。對于每一個按鍵,在程序中設置各按鍵所對應的參數即可實現硬件電子琴的功能。 硬件電子琴的功能實現主要靠蜂鳴器和系數得到實現。在試驗程序的基礎上進行修改系數而得到?刂瞥绦虻难h體部分實現了計數和完成清零的操作。通過assign賦值語句實現LED燈的操作,在這里,我們添加了數碼管的功能,從而實現了再按下按鍵的同時,實現數碼管顯示相對應的音階大小。
第五章 實驗箱設計
5.1硬件電子琴模塊程序圖5-1 硬件電子琴模塊圖 module beep1(clk,key,beep,led); //模塊名稱beep input clk; //系統時鐘48MHz input[6:0]key; //按鍵輸入 output beep; //蜂鳴器輸出端 output[6:0]led; //LED輸出 reg beep_r; //寄存器 reg[15:0]count,count_end; reg[6:0]key_r; reg [13:0]a; //消抖寄存器 always@(posedge clk) begin count <= count + 1'b1; //計數器加1 if((count == count_end)&(!(count_end == 16'hffff))) begin count <= 16'h0; //計數器清零 beep_r <= !beep_r; //取反輸出信號 end end always @(key) begin a=2000; //消抖等待時間 key_r = key; //取鍵值 case(key_r) 7'b1111110:begin while(a>0) begin a=a-1; end count_end = 16'hb327; while(a>0) begin a=a-1; end end 7'b1111101:begin while(a>0)begin a=a-1 ;end count_end = 16'h9fa0;while(a>0)begin a=a-1; end end //中音2的分頻系數值 7'b1111011:begin while(a>0)begin a=a-1 ;end count_end = 16'h8e32;while(a>0)begin a=a-1; end end //中音3的分頻系數值 7'b1110111:begin while(a>0)begin a=a-1 ;end count_end16'h8637;while(a>0)begin a=a-1; end end//中音4的分頻系數值 7'b1101111:begin while(a>0)begin a=a-1 ;end count_end = 16'h7794;while(a>0)begin a=a-1; end end //中音5的分頻系數值 7'b1011111:begin while(a>0)begin a=a-1 ;end count_end = 16'h6a88;while(a>0)begin a=a-1; end end //中音6的分頻系數值 7'b0111111:begin while(a>0)begin a=a-1 ;end count_end = 16'h5ee8;while(a>0)begin a=a-1; end end //中音7的分頻系數值 default: begin while(a>0)begin a=a-1 ;end count_end = 16'hffff;while(a>0)begin a=a-1; end end endcase end assign beep =beep_r; //輸出音樂 assign led =key_r; //輸出按鍵狀態 endmodule 5.2樂曲自動演奏機程序圖5-2 樂曲自動演奏模塊圖 module song(clk,beep,led); //模塊名稱 input clk; //系統時鐘48Mhz output beep; //蜂鳴器輸出端 output[7:0] led; reg beep_r; //寄存器 reg[7:0] state; //樂譜狀態機 reg[15:0]count,count_end; reg[23:0]count1; //樂譜參數:D=F/2K (D:參數,F:時鐘頻率,K:音高頻率) //以下是12MHZ晶振狀態下的各音高對應的參數 /*parameter L_5 = 16'h3bca, //低音5 M_1 = 16'h2cc9, //中音1 M_2 = 16'h27f8, //中音2 M_3 = 16'h238c, //中音3 M_4 = 16'h218d, //中音4 M_5 = 16'h1de5, //中音5 M_6 = 16'h1aa2; //中音6 parameter TIME = 3000000; //控制每一個音的長短(250ms)*/ //樂譜參數:D=F/2K (D:參數,F:時鐘頻率,K:音高頻率) parameter L_5 = 16'd61224, //低音5 M_1 = 16'd45863, //中音1 M_2 = 16'd40864, //中音2 M_3 = 16'd36402, //中音3 M_4 = 16'd34359, //中音4 M_5 = 16'd30612; //中音5 parameter TIME = 12000000; //控制每一個音的長短(250ms) assign beep = beep_r; //輸出音樂 ,蜂鳴器 always@(posedge clk) begin count <= count + 1'b1; //計數器加1 if(count == count_end) begin count <= 16'h0; //計數器清零 beep_r <= !beep_r; //輸出取反 end end always @(posedge clk) begin if(count1 < TIME) //一個節拍250mS count1 = count1 + 1'b1; else begin count1 = 24'd0; if(state == 8'd125) //控制歌曲循環播放時間 state = 8'd0; //循環從頭開始 else state = state + 1'b1; //循環結構體 begin case(state) 8'd0,8'd1: count_end = M_3;//中音"3",持續2個節拍 8'd2,8'd3: count_end = M_3;//中音"3",持續2個節拍 8'd4,8'd5: count_end = M_4;//中音"4",持續2個節拍 8'd6,8'd7: count_end = M_5; 8'd8,8'd9: count_end = M_5; 8'd10,8'd11: count_end = M_4; 8'd12,8'd13: count_end = M_3; 8'd14,8'd15: count_end = M_2; 8'd16,8'd17: count_end = M_1; 8'd18,8'd19: count_end = M_1; 8'd20,8'd21: count_end = M_2; 8'd22,8'd23: count_end = M_3; 8'd24,8'd25,8'd26: count_end = M_3; 8'd27: count_end = M_2; 8'd28,8'd29,8'd30,8'd31: count_end = M_2; 8'd32,8'd33: count_end = M_3; 8'd34,8'd35: count_end = M_3; 8'd36,8'd37: count_end = M_4; 8'd38,8'd39: count_end = M_5; 8'd40,8'd41: count_end = M_5; 8'd42,8'd43: count_end = M_4; 8'd44,8'd45: count_end = M_3; 8'd46,8'd47: count_end = M_2; 8'd48,8'd49: count_end = M_1; 8'd50,8'd51: count_end = M_1; 8'd52,8'd53: count_end = M_2; 8'd54,8'd55: count_end = M_3; 8'd56,8'd57,8'd58: count_end = M_2; 8'd59: count_end = M_1; 8'd60,8'd61,8'd62,8'd63: count_end = M_1; 8'd64,8'd65: count_end = M_2; 8'd66,8'd67: count_end = M_2; 8'd68,8'd69: count_end = M_3; 8'd70,8'd71: count_end = M_1; 8'd72,8'd73: count_end = M_2; 8'd74: count_end = M_3; 8'd75: count_end = M_4; 8'd76,8'd77: count_end = M_3; 8'd78,8'd79: count_end = M_1; 8'd80,8'd81: count_end = M_2; 8'd82: count_end = M_3; 8'd83: count_end = M_4; 8'd84,8'd85: count_end = M_3; 8'd86,8'd87: count_end = M_2; 8'd88,8'd89: count_end = M_1; 8'd90,8'd91: count_end = M_2; //8'd92,8'd93: count_end = L_5; 8'd92,8'd93,8'd94,8'd95: count_end = L_5; //8'd94,8'd95: count_end = M_3; 8'd96,8'd97: count_end = M_3; 8'd98,8'd99: count_end = M_3; 8'd100,8'd101: count_end = M_4; 8'd102,8'd103: count_end = M_5; 8'd104,8'd105: count_end = M_5; 8'd106,8'd107: count_end = M_4; 8'd108: count_end = M_3; 8'd109: count_end = M_2; 8'd110,8'd111: count_end = M_1; 8'd112,8'd113: count_end = M_1; 8'd114,8'd115: count_end = M_2; 8'd116,8'd117: count_end = M_3; 8'd118,8'd119,8'd120: count_end = M_2; 8'd121: count_end = M_1; 8'd122,8'd123,8'd124,8'd125: count_end = M_1; default:count_end = 16'hffff; endcase end end end assign led[0]=(count_end == M_1)?0:1; //控制LED燈的語言 assign led[1]=(count_end == M_2)?0:1; assign led[2]=(count_end == M_3)?0:1; assign led[3]=(count_end == M_4)?0:1; assign led[4]=(count_end == M_5)?0:1; assign led[5]=(count_end == L_5)?0:1; assign led[6]=1; assign led[7]=1; endmodule
5.3 選擇模塊程序 圖5-3選擇模塊圖
module select(key,beep1,beep2,led1,led2,beep,led); input key,beep1,beep2; input [6:0]led1; input [6:0]led2; output beep; output [6:0]led; reg key_r; always @(negedge key) begin key_r = ~key_r; //將琴鍵開關轉換為乒乓開關 end assign beep=(key_r)?beep2:beep1; assign led=(key_r)?led2:led1; endmodule 5.4頂層文件程序
圖5-4頂層文件圖 module dzq(key,key7,beep,led,clk); input key7; input [6:0]key; input clk; output [6:0]led; output beep; reg dout1; reg dout2; reg dout3; reg led; reg key_r; wire a,b,key_l; wire [6:0]c; wire [6:0]d; assign key_l = (dout1 | dout2 | dout3); //按鍵消抖輸出 always @(posedge clk) begin dout1 <= key7; dout2 <= dout1; dout3 <= dout2; end song (.clk(clk),.beep(b),.led(c)); beep1 (.clk(clk),.key(key),.beep(a),.led(d)); select (.key(key_l),.beep1(a),.beep2(b),.beep(beep),.led(led),.led1(d),.led2(c)); endmodule 第六章 實驗圖形文件6.1管腳鎖定圖引腳鎖定:選擇Assignments-pin planer
圖6-1管腳鎖定圖 RTL圖:選擇Tools—netlist viewers—RTL viewers 圖6-2 RTL圖 6.2DXP原理圖及封裝DXP原理圖的設計: - 執行“文件”—“創建”—“項目”—“PCB項目”命令
- 在projects面板上新建一個項目文件,默認名為PCB_Projects.PrjPCB.
- 執行“文件”—“保存項目”命令
- 利用libiaries元件庫進行原理圖繪制

圖6-3 dxp原理圖 DXP封裝設計: - 執行“文件”—“創建”—“PCB文件”命令,新建PCB設計文件并保存
- 設置工作層:選擇機械層設置物理邊界,在禁止布線層設置電氣邊界。
- 加載網絡表:執行“設計”—Import Changes From DESIGN.PRJPCB命令,單擊“使變化生效”—“執行變化”
- 元件自動布局:執行“工具”—“放置元件”—“自動布局”命令
- 元件自動布線:執行“自動布線”—“設定”—“全部對象”命令,選擇默認設置,確認布線即可
圖6-4封裝圖 6.3任務完成情況說明 | | | | 按下KEY1—KEY7 分別表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 SI; | | | | | | 可以在電路上能自動演奏樂曲。在這里我們采用的是貝多芬的《歡樂頌》,且有相應的LED燈指示高低音; | | | | |
表6-5 任務完成情況表:
6.4硬件連接圖
圖6-6按鍵電路圖 圖6-6 LED燈電路圖 圖6-7 2X5下載插座 圖6-8 蜂鳴器電路圖 圖6-9 晶振電路圖 圖6-10 電源電路圖
總結
本次EDA課程設計進一步加深了我們對實驗課的認識和對EDA的了解,對于Verilog HDL語言的運用更加的熟練。同時對于課程設計過程中要進行的調試和編寫程序有了一定的認識。
電子琴使用按鍵的沖突,不得不消除原有模塊的高音階部分,而將其改造出現在的模塊和形式,對于硬件電子琴的改造,看似是對原功能塊的簡單的改進,而實際上是需要重新構造電路的,因為在演奏的過程中會有LED燈的使用沖突,如何調試和調用,才是本課程設計的重點,因為頂層文件的需要,我們需要對各自的程序進行調整和修改。目的是為了能夠在最后的開發平臺上得到我們想要的結果。
在這次的課程設計過程中,我們采取的分工合作的方式來進行課程設計是一件很好的事情。大家各有側重點但是同時都為課程設計做出應該做的努力,分工協作有時候不僅有利用于課程設計的快速進行,而且也有利于個人和小組的交流和促進,在分工的時候,每個人都各盡所長,實現了又快又好的完成課程任務的目標。最后,特別感謝本次課程設計給予我們指導的老師,在老師的知道和啟發下,我們才能正確的完成課程設計。
附錄:項目實物圖 |