第一篇:FPGA實驗報告
FPGA實驗報告
專業:XXX 姓名:XXX 學號:XX
一:實驗目的
1.熟悉Modelsim和Quartus II軟件的運行環境和使用
2.熟練使用Quartus II仿真軟件生成網表。
3.熟悉FPGA前仿真和后仿真的整個流程。二:實驗內容
編寫counter計數器,在Quartus II仿真軟件中生成網表,再在Modelsim中進行后仿真。三: 實驗步驟
1.在Modelsim編寫源程序(counter計數器及激勵),編譯源文件,確保程序的正確性,并進行前仿真,生成波形圖如下:
附:源程序如下:
module counter(q,clk,reset);
input clk,reset;
output [3:0] q;
reg [3:0] q;
always @(posedge reset or negedge clk)
if(reset)
q <= 4'b0;
else
q <= q + 1;endmodule module top;
reg CLK,RESET;
wire [3:0] Q;
counter c1(Q,CLK,RESET);
initial
CLK=1'b0;
always
#1 CLK=~CLK;
initial
$monitor($time,“Q=%d”,Q);
initial
begin
RESET=1'b1;
#5 RESET=1'b0;
#180 RESET=1'b1;
end endmodule 2.新建文件夾,將源程序counter.v放進去。然后啟動Quartus II仿真軟件,生成網表。
1).在【File】下拉菜單中選中New Project Wizard選項,出現對話框。并指定工程工作目錄、工程名稱和頂層模塊名,如圖(a)所示。
2).添加(Add)counter.v文件。如圖(b)所示。
3).選擇器件系列
4).指定其它EDA工具,如圖(d)所示。
5).完成工程設置,如圖(e)所示。
6).單擊啟動編譯按鈕,完成工程的編譯。
7).選中【processing】-【Start】-【Start analysis & synthesis】進行綜合和分析。
(a)
(b)
(c)
(d)
(e)
8).選中【Tools】-【Netlist viewer】-【RTL viewer】生成網表如下圖所示:
3.新建文件夾,將生成的vo,sdo文件,altera時延文件cyclone-atoms.v及編寫的top.v文件拷入,在Modelsim中進行后仿真。
1).新建工程,向工程中添加vo,top,及時延文件。
2).將vo文件時延尺寸改為ns,并在top程序的首部添加命令:`timescale 1 ns / 1 ns。
3).編譯并進行仿真,生成波形圖如下:
四:心得體會
通過本次實驗,我基本熟悉掌握了前仿真、后仿真的整個實驗步驟及流程,熟練掌握了Modelsim和Quartus仿真軟件的使用方法。
第二篇:FPGA交通燈實驗報告
交通燈實驗報告
一,實驗目的
實現兩路信號燈交替亮起,并利用兩組數碼管分別對兩路信號進行倒計時。
兩路信號時間分別為:
V:綠燈(30S)
H:紅燈(35S)
黃燈(5s)
綠燈(30S)
紅燈(35S)
黃燈(5S)
二,實驗步驟 建立工程
可在歡迎界面點擊“Creat a New Project”進入工程建立界面,亦可關閉歡迎界面,點擊菜單欄的“File”,點擊“New Project Wizard”進入建立工程界面。右側為建立工程界面,點擊next。
在此界面選定工程路徑,取好工程名,點擊“Next”。注意:路徑中不能有中文,工程名也不能有中文。
一直點擊“Next”進入器件設置界面,DE2-70開發工具采用的Cyclone II系列的EP2C70F896C6N。點擊“Finish”,完成工程建立
1、點擊“File”,點擊“New” 選擇“Verilog HDL” 2,點擊主界面工具欄中的 選擇“Verilog HDL”
3、寫入verilog代碼。
代碼如下:
module traffic(Clk_50M,Rst,LedR_H,LedG_H,LedY_H,LedR_V,LedG_V,LedY_V,Seg7_VH,Seg7_VL,Seg7_HH,Seg7_HL,led15);
parameter S1=2'b00;parameter S2=2'b01;parameter S3=2'b10;parameter S4=2'b11;
input Clk_50M,Rst;output LedR_H,LedG_H,LedY_H,LedR_V,LedG_V,LedY_V;output[6:0] Seg7_VH,Seg7_VL,Seg7_HH,Seg7_HL;output led15;
//-------------div for 1Hz-------start----reg Clk_1Hz;reg [31:0] Cnt_1Hz;always@(posedge Clk_50M or negedge Rst)begin
if(!Rst)
begin
Cnt_1Hz<=1;
Clk_1Hz<=1;
end
else
begin
if(Cnt_1Hz>=25000000)
end
//-----------div for 1Hz------end-----reg[7:0] Cnt30,CntH,CntV,CntHH,CntVV;reg[7:0] CntDis,CntDiss;//-----------30 counter and seg7---start---reg LedR_H,LedG_H,LedY_H,LedR_V,LedG_V,LedY_V;always@(posedge Clk_1Hz)begin
end
begin
Cnt_1Hz<=1;
Clk_1Hz<=~Clk_1Hz;
end
else
Cnt_1Hz<=Cnt_1Hz + 1;
case(state)
S1:
end
always@(posedge Clk_1Hz)begin
case(stateV)
S1:
begin
if(CntV>=30)
CntV<=1;
begin
if(Cnt30>=30)
Cnt30<=1;
else
Cnt30<=Cnt30 + 1;S2:
begin
if(Cnt30>=5)
Cnt30<=1;end
else
Cnt30<=Cnt30 + 1;S3:
begin
if(Cnt30>=30)
Cnt30<=1;end
else
Cnt30<=Cnt30 + 1;S4:
begin
if(Cnt30>=5)
Cnt30<=1;end
else
Cnt30<=Cnt30 + 1;end endcase
else
CntV<=CntV + 1;
S2: begin
end
end if(CntV>=5)
CntV<=1;
else
CntV<=CntV + 1;end
S3:
begin
if(CntV>=35)
CntV<=1;
else
CntV<=CntV + 1;end endcase always@(posedge Clk_1Hz)begin
case(stateH)
S1:
end
always@(negedge Clk_50M or negedge Rst)begin
begin
if(CntH>=35)
CntH<=1;
else
CntH<=CntH + 1;
S2:
begin
if(CntH>=30)
CntH<=1;end
else
CntH<=CntH + 1;end
S3:
begin
if(CntH>=5)
CntH<=1;
else
CntH<=CntH + 1;end endcase
case(state)
S1:
end always@(negedge Clk_50M or negedge Rst)begin
case(state)
S1:
end
//16進制計數器轉換為用于顯示的10進制計數器 always@(posedge Clk_50M)begin
if(CntVV>29)
begin
CntDis[7:4]<=3;
CntDis[3:0]<=CntVV20;end else if(CntVV>9)begin
CntDis[7:4]<=1;
CntDis[3:0]<=CntVV30;end else if(CntHH>19)begin
CntDiss[7:4]<=2;
CntDiss[3:0]<=CntHH10;end else
CntDiss<=CntHH;
end
if(Cnt30>=5)
end
end S3:
begin
state<=S4;
end S4:
begin
state<=S1;
end default:
begin
state<=S1;
end endcase
if(Cnt30>=30)
if(Cnt30>=5)always@(posedge Clk_1Hz)begin
case(state)
S1:
end
always@(posedge Clk_50M or negedge Rst)
begin
stateH<=S1;
stateV<=S1;
end S2:
begin
stateH<=S1;
stateV<=S2;
end S3:
begin
stateH<=S2;
stateV<=S3;
end S4:
begin
stateH<=S3;
stateV<=S3;
end endcase begin
if(!Rst)
begin
LedR_H<=0;
else
LedG_H<=0;LedY_H<=0;
LedR_V<=0;
LedG_V<=0;end LedY_V<=0;
begin
case(state)
S1:
begin
LedR_H<=1;LedG_H<=0;LedY_H<=0;LedR_V<=0;LedG_V<=1;LedY_V<=0;end
S2:
begin
LedR_H<=1;LedG_H<=0;LedY_H<=0;LedR_V<=0;LedG_V<=0;LedY_V<=1;end
S3:
begin
LedR_H<=0;LedG_H<=1;LedY_H<=0;LedR_V<=1;LedG_V<=0;LedY_V<=0;end
S4:
begin LedR_H<=0;LedG_H<=0;
end
LedY_H<=1;LedR_V<=1;LedG_V<=0;LedY_V<=0;end
default:
begin
end LedR_H<=0;LedG_H<=0;LedY_H<=0;LedR_V<=0;LedG_V<=0;LedY_V<=0;end
endcase assign led15=state;
endmodule
module SEG7_LUT input [3:0] iDIG;output reg
always @(iDIG)begin
case(iDIG)4'h1: oSEG = 7'b1111001;
//---t----4'h2: oSEG = 7'b0100100;// |
| 4'h3: oSEG = 7'b0110000;// lt rt
4'h4: oSEG = 7'b0011001;// |
| 4'h5: oSEG = 7'b0010010;//---m----4'h6: oSEG = 7'b0000010;// |
| 4'h7: oSEG = 7'b1111000;// lb rb 4'h8: oSEG = 7'b0000000;// |
| 4'h9: oSEG = 7'b0011000;//---b----4'ha: oSEG = 7'b0001000;4'hb: oSEG = 7'b0000011;4'hc: oSEG = 7'b1000110;4'hd: oSEG = 7'b0100001;4'he: oSEG = 7'b0000110;[6:0] oSEG;[6:0] oSEG;(oSEG,iDIG);
end
4'hf: oSEG = 7'b0001110;4'h0: oSEG = 7'b1000000;endcase endmodule 編譯工程
保存文件,將文件放在所建工程所在路徑下 點擊主界面工具欄中的圖標
也可點擊菜單欄中“Processing”,點擊“Start Compilation”
分配關鍵如下:
Clk_50M Input PIN_AD15 LedG_H Output PIN_AD9 LedG_V Output PIN_AJ6 LedR_H Output PIN_AJ7)LedR_V Output PIN_AJ5)LedY_H Output PIN_AD8 LedY_V Output PIN_AK5 Rst Input PIN_AA23 Seg7_HH[6] Output PIN_G1 Seg7_HH[5] Output PIN_H3 Seg7_HH[4] Output PIN_H2 Seg7_HH[3] Output PIN_H1 Seg7_HH[2] Output PIN_J2 Seg7_HH[1] Output PIN_J1 Seg7_HH[0] Output PIN_K3
Seg7_HL[6] Seg7_HL[5] Seg7_HL[4] Seg7_HL[3] Seg7_HL[2] Seg7_HL[1] Seg7_HL[0] Seg7_VH[6] Seg7_VH[5] Seg7_VH[4] Seg7_VH[3] Seg7_VH[2] Seg7_VH[1] Seg7_VH[0] Seg7_VL[6] Seg7_VL[5] Seg7_VL[4] Seg7_VL[3] Seg7_VL[2] Seg7_VL[1] Seg7_VL[0] Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output Output PIN_E4 PIN_F4 PIN_G4 PIN_H8 PIN_H7 PIN_H4 PIN_H6 PIN_AD17 PIN_AF17 7 PIN_AE17 7 PIN_AG16 PIN_AF16 7 PIN_AE16 7 PIN_AG13 PIN_AD12 PIN_AD11 PIN_AF10 8 PIN_AD10 PIN_AH9 8 PIN_AF9 8 PIN_AE8 8
燒寫代碼
在管腳配置完成后,還需將工程再編譯一次,成功后,點擊主界面工具欄中的亦可點擊主界面菜單欄中“Tools”,點擊“Programmer”
進入代碼燒寫界面后,點擊“Start”,當“Progress”為100%時,表示燒寫完成,這是可觀察DE2-70板現象
獲得預期的效果,兩組的信號紅黃綠燈交替切換,計數器記為零時信號燈切換狀態,紅燈35s,黃燈5s,綠燈30s。三,心得體會
通過本次實驗初步了解了EDA技術,熟悉了FPGA開發板的開發流程,鍛煉了動手能力。
第三篇:FPGA秒表實驗報告
課程設計報告
專業班級 課 程 題 目 秒表的設計 學 號 姓 名 同 組 人 成 績
2013年5月
一、設計目的
1.進一步熟悉七段碼譯碼器的硬件接口。2.掌握用掃描方法驅動多個數碼管硬件接口。3.掌握秒表VHDL的編程方法。
二、系統總體設計(1).設計要求:
1.秒表共有6個輸出顯示,分別為百分之一秒、十分之一秒、秒、十秒、分、十分,所以共有6個計數器與之相對應,6個計數器的輸出全都為BCD碼輸出,這樣便于和顯示譯碼器的連接。當計時達60分鐘后,蜂鳴器鳴響10聲。
2.整個秒表還需有一個啟動信號和一個歸零信號,以便秒表能隨意停止及啟動。3.秒表的邏輯結構較簡單,它主要由顯示譯碼器、分頻器、十進制計數器、六進制計數器和報警器組成。在整個秒表中最關鍵的是如何獲得一個精確的100HZ計時脈沖。
(2).實驗原理: 秒表由于其計時精確,分辨率高(0.01秒),在各種競技場所得到了廣泛的應用。秒表的工作原理與數字時基本相同,唯一不同的是秒表的計時時鐘信號,由于其分辨率為0.01秒,所以整個秒表的工作時鐘是在100Hz的時鐘信號下完成。當秒表的計時小于1個小時時,顯示的格式是mm-ss-xx(mm表示分鐘:0~59;ss表示秒:0~59;xx表示百分之一秒:0~99),當秒表的計時大于或等于一個小時時,顯示的和多功能時鐘是一樣的,就是hh-mm-ss(hh表示小時:0~99),由于秒表的功能和鐘表有所不同,所以秒表的hh表示的范圍不是0~23,而是0~99,這也是和多功能時鐘不一樣的地方。在設計秒表的時候,時鐘的選擇為100Hz。變量的選擇:因為xx(0.01秒)和hh(小時)表示的范圍都是0~99,所以用兩個4位二進制碼(BCD碼)表示;而ss(秒鐘)和mm(分鐘)表示的范圍是0~59,所以用一個3位的二進制碼和一個4位的二進制碼(BCD)碼表示。顯示的時候要注意的問題就是小時的判斷,如果小時是00,則顯示格式為mm-ss-xx,如果小時不為00,則顯示hh-mm-ss。
三、詳細設計
1.計時模塊:計時模塊執行計時功能,計時方法和計算機一樣是對標準時鐘脈沖計數。他是由四個十進制計數器和倆個六進制計數器構成,其中毫秒位、十毫秒位、秒位和分位采用十進制計數器,十秒位和十分位采用六進制計數器。
COUNT10CLKSTARTCLRCOUTDAOUT[3..0]源程序:inst2
(1)十進制計數器(count_10)library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;
entity COUNT10 is port(CLK,START,CLR : in std_logic;
COUT : out std_logic;
DAOUT : out std_logic_vector(3 downto 0));end COUNT10;architecture one of COUNT10 is signal h0 : std_logic_vector(3 downto 0);signal h1 : std_logic;begin process(CLK,CLR)begin if CLR='1' then h0<=“0000”;elsif CLK'event and CLK='1' then
if START='1' then
if h0=“1001” then
h0<=“0000”;
h1<='1';
else h0<=h0+1;
h1<='0';
end if;
end if;
end if;end process;DAOUT<=h0;COUT<=h1;end one;
(2)六進制計數器(count_6)
COUNT6CLKSTARTCLRinst1COUTDAOUT[3..0]
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity COUNT6 is port(CLK,START,CLR : in std_logic;
COUT : out std_logic;
DAOUT: out std_logic_vector(3 downto 0));end COUNT6;architecture two of COUNT6 is signal h0 : std_logic_vector(3 downto 0);signal h1 : std_logic;begin process(CLK,CLR)begin if CLR='1' then h0<=“0000”;elsif CLK'event and CLK='1' then
if START='1' then
if h0=“0101” then
h0<=“0000”;
h1<='1';
else h0<=h0+1;
h1<='0';
end if;
end if;
end if;end process;DAOUT<=h0;COUT<=h1;end two
2.計時顯示器(deled)
計時顯示電路的作用是將計時值在LED數碼管上顯示出來。計時電路產生的值經過BCD七段譯碼后,驅動LED數碼管。計時顯示電路的實現方案采用掃描顯示。部分源程序:
delednum[3..0]led[6..0]inst3
Library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity deled is port(num: in std_logic_vector(3 downto 0);led:out std_logic_vector(6 downto 0));end deled;architecture a of deled is begin process(num)begin case num is when“0000”=>led<=“1111110”;when “0001”=>led<=“0110000”;when “0010”=>led<=“1101101”;when “0011”=>led<=“1111001”;when “0100”=>led<=“0110011”;when “0101”=>led<=“1011011”;when “0110”=>led<=“1011111”;when “0111”=>led<=“1110000”;when “1000”=>led<=“1111111”;when “1001”=>led<=“1111011”;when OTHERS=>led<=“0000000”;end case;end process;end a;
3.分頻
fenpinclrclkqinst4
library ieee;use ieee.std_logic_1164.all;
entity fenpin is
port(clr,clk: in std_logic;q: buffer std_logic);end fenpin;architecture b of fenpin is
signal counter:integer range 0 to 49999;begin
process(clr,clk)
begin
if(clk='1' and clk'event)then
if clr='1' then
counter<=0;
elsif counter=49999 then
counter<=0;
q<= not q;
else
counter<=counter+1;
end if;
end if;
end process;end b;
4.位選
seltimeclkclrdain0[3..0]dain1[3..0]dain2[3..0]dain3[3..0]dain4[3..0]dain5[3..0]daout[3..0]sel[2..0]inst5 library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;
entity seltime is port(clk:in std_logic;
clr:in std_logic;
dain0:in std_logic_vector(3 downto 0);
dain1:in std_logic_vector(3 downto 0);
dain2:in std_logic_vector(3 downto 0);
dain3:in std_logic_vector(3 downto 0);
dain4:in std_logic_vector(3 downto 0);
dain5:in std_logic_vector(3 downto 0);
daout:buffer std_logic_vector(3 downto 0);
sel:buffer std_logic_vector(2 downto 0));end seltime;architecture three of seltime is signal m:std_logic_vector(2 downto 0);signal n:std_logic_vector(3 downto 0);begin n<=“0000” when clr='1' else
dain0 when m=“000” else dain1 when m=“001”else dain2 when m=“010”else dain3 when m=“011”else dain4 when m=“100” else dain5;process(clr,clk,dain0,dain1,dain2,dain3,dain4,dain5)begin if clk 'event and clk='1'then if m=“101” then m<=“000”;else m <=m+1;end if;end if;sel<=m;end process;daout<=n;end three;
5.警告
ALARMCLKdainqinst
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity ALARM is port(CLK: in std_logic;
dain: in std_logic;
q: out std_logic);end ALARM;architecture four of ALARM is signal count: std_logic_vector(1 downto 0);begin process(clk)begin q<=count(1);if(clk'event and clk='1')then
if(dain='1')then
if(count=“10”)then
count<=“00”;
else
count<=count+1;
end if;
end if;
end if;
end process;
q<=count(1);end four;原理圖:
四、仿真分析 1.仿真結果:
2.管腳分配:
五.設計中遇到的問題及解決方法
問題:
1.對秒表設計的原理理解不到位,試驗不能正常進行。2.因為程序輸入不正確,導致程序編譯不成功。
3.管腳分配不合理,導致結果不能顯示或者不能正常顯示。解決方法:
1.進一步理解實驗的原理,各部分的組成以及功能。2.運行程序之前仔細檢查程序,并適當注釋。3.按照規定分配管腳,注意區別不能定義的管腳。
六.心得體會:
因為對EDA技術及Quartus軟件的相關知識知道的不夠深入,在設計過程
中我們遇到了很多困難,但通過從網上找一些相關資料,最終完成了設計任務。開始做設計時總是會出現各種錯誤,經過不停的編譯及改錯最終得到了正確的程序。其實這些錯誤的主要原因是自己的粗心造成的,如果細心一些這些錯誤時可以避免的。在編程時,要使用層次化結構的思想,這樣程序檢查起來也比較方便,調試時也給了自己很大的方便,只要一個模塊一個模塊的進行調就可以了,充分體現了結構化編程的優勢。在設計中要求我們要有耐心和毅力,還要細心,稍有不慎,一個小小的錯誤就會導致結果的不正確,而對錯誤的檢查要求我們要有足夠的耐心,通過這次設計和設計中遇到的問題,也積累了一定的經驗,對以后從事集成電路設計工作會有一定的幫助。
在應用VHDL的過程中讓我真正領會到了其并行運行與其他軟件順序執行的差別及其在電路設計上的優越性。用VHDL硬件描述語言的形式來進行數字系統的設計方便靈活,利用EDA軟件進行編譯優化仿真極大地減少了電路設計時間和可能發生的錯誤,降低了開發成本,這種設計方法在數字系統設計中發揮越來越重要的作用。總之這次的設計受益匪淺。
第四篇:FPGA可調數字時鐘實驗報告
浙江大學城市學院
實驗報告紙
一、實驗要求
1、用vhdl編程,實現10進制計數器
2、用vhdl編程,實現60進制計數器
3、用vhdl編程,實現數字時鐘,時、分、秒、毫秒分別顯示在數碼管上。
4、實現可調數字時鐘的程序設計,用按鍵實現時、分、秒、毫秒的調整。
二、實驗原理
用VHDL,行為級描述語言實現實驗要求。思路如下:
1、分頻部分:由50MHZ分頻實現1ms的技術,需要對50MHZ采取500000分頻。
2、計數部分:采用低級影響高級的想法,類似進位加1的思路。對8個寄存器進行計數,同步數碼管輸出。
3、數碼管輸出部分:用一個撥碼開關控制顯示,當sw0=0時,四位數碼管顯示秒、毫秒的計數。當sw0=1時,四位數碼管顯示時、分得計數。
4、調整部分:分別用四個按鍵控制時、分、秒、毫秒的數值。先由一個開關控制計數暫停,然后,當按鍵按下一次,對應的數碼管相對之前的數值加1,,通過按鍵實現時間控制,最后開關控制恢復計數,完成時間調整。
5、整個實現過程由一個文件實現。
三、實驗過程
各個引腳說明: Clk:50MHZ SW:數碼管切換,SW=’0’時,數碼管顯示為秒,毫秒。SW=’1’時,數碼管顯示為時,分。
SW1:暫停與啟動。SW1=’0’時,時鐘啟動,SW=’1’時,時鐘暫停。
SW2:時鐘調整接通按鈕,當SW2=’0’時,不進行調整,當SW=’1’時,通過按鍵調整時間。
KEY0: 毫秒調整,按一次實現+1功能 KEY1:秒調整,按一次實現+1功能
浙江大學城市學院 實 驗 報 告 紙
KEY2:分調整,按一次實現+1功能 KEY3:時調整,按一次實現+1功能 Q0;第一個數碼管 Q1;第二個數碼管 Q2: 第三個數碼管 Q3: 第四個數碼管
1、源代碼如下:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity paobiao is port(clk,sw,key0,key1,key2,key3,sw1,sw2:in std_logic;
q0:out std_logic_vector(6 downto 0);
q1:out std_logic_vector(6 downto 0);
q2:out std_logic_vector(6 downto 0);
q3:out std_logic_vector(6 downto 0));end paobiao;architecture behave of paobiao is signal cntt1 :integer range 0 to 10;signal cntt2 :integer range 0 to 10;signal cntt3 :integer range 0 to 10;signal cntt4 :integer range 0 to 6;signal cntt5 :integer range 0 to 10;signal cntt6 :integer range 0 to 10;signal cntt7 :integer range 0 to 10;signal cntt8 :integer range 0 to 6;浙江大學城市學院 實 驗 報 告 紙
signal cntttt1 :integer range 0 to 10;signal cntttt2 :integer range 0 to 10;signal cntttt3 :integer range 0 to 10;signal cntttt4 :integer range 0 to 6;signal cntttt5 :integer range 0 to 10;signal cntttt6 :integer range 0 to 10;signal cntttt7 :integer range 0 to 10;signal cntttt8 :integer range 0 to 6;
begin
process(clk)--,key0,key1,key2,key3)
variable cnt :integer range 0 to 500000;
--variable cnt9 :integer range 0 to 3000000000;
variable cnt1 :integer range 0 to 10;
variable cnt2 :integer range 0 to 10;
variable cnt3 :integer range 0 to 10;
variable cnt4 :integer range 0 to 6;
variable cnt5 :integer range 0 to 10;
variable cnt6 :integer range 0 to 10;
variable cnt7 :integer range 0 to 10;
variable cnt8:integer range 0 to 6;
begin if(clk'event and clk='1')then
if(sw1='0')then if(cnt>=2)then
cnt:=0;
cnt1:=cnt1+1;浙江大學城市學院 實 驗 報 告 紙
if(cnt1=10)then
cnt1:=0;
cnt2:=cnt2+1;
if(cnt2=10)then
cnt1:=0;
cnt2:=0;
cnt3:=cnt3+1;
if(cnt3=10)then
cnt1:=0;
cnt2:=0;
cnt3:=0;
cnt4:=cnt4+1;
if(cnt4=6)then
cnt1:=0;
cnt2:=0;
cnt3:=0;
cnt4:=0;
cnt5:=cnt5+1;
if(cnt5=10)then
cnt5:=0;
cnt6:=cnt6+1;
if(cnt6=6)then
cnt5:=0;
cnt6:=0;
cnt7:=cnt7+1;
if(cnt7=4)then
cnt5:=0;
cnt6:=0;
cnt7:=0;浙江大學城市學院 實 驗 報 告 紙
cnt8:=cnt8+1;
if(cnt8=3)then
cnt5:=0;
cnt6:=0;
cnt7:=0;
cnt8:=0;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
else cnt:=cnt+1;
end if;
if(sw2='0')then
cntt1<=cnt1;
cntt2<=cnt2;
cntt3<=cnt3;
cntt4<=cnt4;
cntt5<=cnt5;
cntt6<=cnt6;
cntt7<=cnt7;
cntt8<=cnt8;
else
cnt1:=cntttt1;
cnt2:=cntttt2;
cnt3:=cntttt3;浙江大學城市學院 實 驗 報 告 紙
cnt4:=cntttt4;
cnt5:=cntttt5;
cnt6:=cntttt6;
cnt7:=cntttt7;
cnt8:=cntttt8;
cntt1<=cnt1;
cntt2<=cnt2;
cntt3<=cnt3;
cntt4<=cnt4;
cntt5<=cnt5;
cntt6<=cnt6;
cntt7<=cnt7;
cntt8<=cnt8;
end if;
end if;end if;end process;
process(key0)variable cnttt1 :integer range 0 to 10;variable cnttt2 :integer range 0 to 10;begin if(key0'event and key0='0')then
cnttt1:=cnttt1+1;
if(cnttt1=10)then
cnttt1:=0;
cnttt2:=cnttt2+1;
if(cnttt2=10)then 浙江大學城市學院 實 驗 報 告 紙
cnttt2:=0;
end if;
end if;
cntttt1<=cnttt1;
cntttt2<=cnttt2;end if;
end process;process(key1)variable cnttt3 :integer range 0 to 10;variable cnttt4 :integer range 0 to 10;begin if(key1'event and key1='0')then
cnttt3:=cnttt3+1;
if(cnttt3=10)then
cnttt3:=0;
cnttt4:=cnttt4+1;
if(cnttt4=6)then
cnttt4:=0;
end if;
end if;cntttt3<=cnttt3;
cntttt4<=cnttt4;end if;end process;process(key2)variable cnttt5 :integer range 0 to 10;variable cnttt6 :integer range 0 to 10;begin
if(key2'event and key2='0')then 浙江大學城市學院 實 驗 報 告 紙
cnttt5:=cnttt5+1;
if(cnttt5=10)then
cnttt5:=0;
cnttt6:=cnttt6+1;
if(cnttt6=6)then
cnttt6:=0;
end if;
end if;cntttt5<=cnttt5;
cntttt6<=cnttt6;
end if;end process;process(key3)variable cnttt7 :integer range 0 to 10;variable cnttt8 :integer range 0 to 10;begin
if(key3'event and key3='0')then
cnttt7:=cnttt7+1;
if(cnttt7=4)then
cnttt7:=0;
cnttt8:=cnttt8+1;
if(cnttt8=3)then
cnttt8:=0;
end if;
end if;
cntttt7<=cnttt7;
cntttt8<=cnttt8;
end if;浙江大學城市學院 實 驗 報 告 紙
end process;
--end if;--end process;
process(cntt1,cntt5)
begin
if(sw='0')then
case cntt1 is
when 0=>q0<=“1000000”;
when 1=>q0<=“1111001”;
when 2=>q0<=“0100100”;
when 3=>q0<=“0110000”;
when 4=>q0<=“0011001”;
when 5=>q0<=“0010010”;
when 6=>q0<=“0000010”;
when 7=>q0<=“1011000”;
when 8=>q0<=“0000000”;
when 9=>q0<=“0010000”;
when others=>q0<=NULL;end case;else
case cntt5 is
when 0=>q0<=“1000000”;
when 1=>q0<=“1111001”;
when 2=>q0<=“0100100”;
when 3=>q0<=“0110000”;
when 4=>q0<=“0011001”;
when 5=>q0<=“0010010”;
when 6=>q0<=“0000010”;
浙江大學城市學院 實 驗 報 告 紙
when 7=>q0<=“1011000”;
when 8=>q0<=“0000000”;
when 9=>q0<=“0010000”;
when others=>q0<=NULL;end case;
end if;
end process;
process(cntt2,cntt6)
begin if(sw='0')then
case cntt2 is
when 0=>q1<=“1000000”;
when 1=>q1<=“1111001”;
when 2=>q1<=“0100100”;
when 3=>q1<=“0110000”;
when 4=>q1<=“0011001”;
when 5=>q1<=“0010010”;
when 6=>q1<=“0000010”;
when 7=>q1<=“1011000”;
when 8=>q1<=“0000000”;
when 9=>q1<=“0010000”;
when others=>q1<=NULL;end case;else
case cntt6 is
when 0=>q1<=“1000000”;
when 1=>q1<=“1111001”;
when 2=>q1<=“0100100”;浙江大學城市學院 實 驗 報 告 紙
when 3=>q1<=“0110000”;
when 4=>q1<=“0011001”;
when 5=>q1<=“0010010”;
when 6=>q1<=“0000010”;
when 7=>q1<=“1011000”;
when 8=>q1<=“0000000”;
when 9=>q1<=“0010000”;
when others=>q1<=NULL;end case;end if;
end process;process(cntt3,cntt7)
begin
if(sw='0')then
case cntt3 is
when 0=>q2<=“1000000”;
when 1=>q2<=“1111001”;
when 2=>q2<=“0100100”;
when 3=>q2<=“0110000”;
when 4=>q2<=“0011001”;
when 5=>q2<=“0010010”;
when 6=>q2<=“0000010”;
when 7=>q2<=“1011000”;
when 8=>q2<=“0000000”;
when 9=>q2<=“0010000”;
when others=>q2<=NULL;end case;else
case cntt7 is 浙江大學城市學院 實 驗 報 告 紙
when 0=>q2<=“1000000”;
when 1=>q2<=“1111001”;
when 2=>q2<=“0100100”;
when 3=>q2<=“0110000”;
when 4=>q2<=“0011001”;
when 5=>q2<=“0010010”;
when 6=>q2<=“0000010”;
when 7=>q2<=“1011000”;
when 8=>q2<=“0000000”;
when 9=>q2<=“0010000”;
when others=>q2<=NULL;end case;end if;
end process;
process(cntt4,cntt8)
begin if(sw='0')then
case cntt4 is
when 0=>q3<=“1000000”;
when 1=>q3<=“1111001”;
when 2=>q3<=“0100100”;
when 3=>q3<=“0110000”;
when 4=>q3<=“0011001”;
when 5=>q3<=“0010010”;
when others=>q3<=NULL;end case;else
case cntt8 is
when 0=>q3<=“1000000”;浙江大學城市學院 實 驗 報 告 紙
when 1=>q3<=“1111001”;
when 2=>q3<=“0100100”;
when 3=>q3<=“0110000”;
when 4=>q3<=“0011001”;
when 5=>q3<=“0010010”;
when 6=>q3<=“0000010”;
--when 7=>q3<=“1011000”;--when 8=>q3<=“0000000”;--when 9=>q3<=“0010000”;
when others=>q3<=NULL;end case;end if;
end process;end behave;
2、原理圖如下:
浙江大學城市學院 實 驗 報 告 紙
3、功能仿真如下
1、秒、毫秒計數仿真
2、分、時計數仿真
注釋:由于仿真時間限制,小時不能顯示。注意SW由0變成1;
浙江大學城市學院 實 驗 報 告 紙
3、暫停的仿真,數碼管顯示用秒,毫秒。
4、按鍵調整的仿真,主要仿真毫秒的仿真
四、實驗結果
實驗結果均完成所有要求,但有一個bug,在實現調整功能的時候,不能實時調整數碼管暫停下來的數字,只能從之前調整過的數值起開始調整,不過能實現調整之后,開啟時鐘,時鐘即在設定的時間開始跑。當然找到解決的方法,當由于思路和已經 寫好的程序沖突性較大,所以此處不再修改。
五、心得體會
本次實驗在分頻的基礎上進行拓展,同時應用數碼管顯示,開關和按鍵的控制,比較系統的做了一個實驗,對自身的提高還是很有幫助的。
說到心得,此次實驗告訴我一下經驗:
1、在開始寫程序之前最好先評估好自己的思路,簡易畫出想象中的原理圖,再進行編程,對之后的修改有很大的幫助。
2、程序寫長了,發現錯得時候,修改比較麻煩,所有注意編程習慣很重要,適當的加一些注釋,提高程序的可讀性。
3、程序最好分模塊寫,比較清晰。
浙江大學城市學院 實 驗 報 告 紙
第五篇:FPGA實驗報告北航電氣技術實驗
FPGA電氣技術實踐
實驗報告
院(系)名稱 專業名稱 學生學號 學生姓名 指導教師
宇航學院
飛行器設計與工程(航天)
XXXXXXXX
XXXXXX
XXXX
2017年11月XX日
`
` 實驗一
四位二進制加法計數器與一位半加器的設計 實驗時間:2017.11.08(周三)晚
實驗編號20
一、實驗目的
1、熟悉QuartusII的VHDL的文本編程及圖形編程流程全過程。
2、掌握簡單邏輯電路的設計方法與功能仿真技巧。
3、學習并掌握VHDL語言、語法規則。
4、參照指導書實例實現四位二進制加法計數器及一位半加器的設計。
二、實驗原理
.略
三、實驗設備
1可編程邏輯實驗箱EP3C55F484C8 一臺(包含若干LED指示燈,撥碼開關等)2計算機及開發軟件QuartusII 一臺套
四、調試步驟
1四位二進制加法計數器
(1)參照指導書實例1進行工程建立與命名。(2)VHDL源文件編輯
由于實驗箱上LED指示燈的顯示性質為“高電平滅,低電平亮”,為實現預期顯示效果應將原參考程序改寫為減法器,且”q1<= q1+1”對應改為”q1<= q1-1”,以實現每輸入一個脈沖“亮為1,滅為0”。
由于參考程序中的rst清零輸入作用并未實現,所以應將程序主體部分的最外部嵌套關于rst輸入是否為1的判斷,且當rst為1時,給四位指示燈置數”1111”實現全滅,當rst為0時,運行原計數部分。
(3)參照指導書進行波形仿真與管腳綁定等操作,鏈接實驗箱并生成下載文件(4)將文件下載至實驗箱運行,觀察計數器工作現象,調試撥動開關查看是否清零。可以通過改變與PIN_P20(工程中綁定為clk輸入的I/O接口)相連導線的另一端所選擇的實驗箱頻率時鐘的輸出口位置,改變LED燈顯示變化頻率。
并且對照指導書上對實驗箱自帶時鐘頻率的介紹,可以通過改變導線接口轉換輸入快慢,排查由于clk輸入管腳損壞而可能引起的故障。
` 2一位半加器
(1)參照指導書實例1進行工程建立與命名。
(2)圖形源文件編輯:由于實驗箱上LED指示燈的顯示性質為“高電平滅,低電平亮”,為實現預期顯示效果應將原電路圖中兩個輸出管腳與非門串聯以實現原參考輸出“高電平亮,低電平滅”。
(3)參照指導書進行波形仿真與管腳綁定等操作,鏈接實驗箱并生成下載文件(4)將文件下載至實驗箱運行,觀察半加器工作現象,調試撥動開關查看進位與置數指示是否正常工作。
五、實驗現象
1.四位二進制加法計數器
SW1下撥為0時,四個LED指示燈可以對輸入脈沖從”0000”到”1111”進行十六位循環計數(其中亮為1,滅為0)。SW1上撥為1時可以實現四個LED燈保持全滅清零。且四位二進制加法計數器功能成功實現
2.一位半加器
SW1與SW2輸入分別為”00”、”01”、”10”、”11”時,進位指示與置數指示燈分別顯示”00”、”01”、”01”、”10”(其中亮為1,滅為0)。且一位半加器功能成功實現。
六、實驗代碼
1四位二進制加法計數器(已修改)
entity count4 is
port(clk:in std_logic;--waishizhong,fpga_ex2_6
rst:in std_logic;--F1 pin-ab15
q:out std_logic_vector(3 downto 0));--led4-1
end;architecture b1 of count4 is
signal q1:std_logic_vector(3 downto 0);
begin
process(clk,rst)
begin
if(rst='0')then
if(clk'event and clk='1')then q1<= q1-1;
end if;
else q1<=“1111”;
end if;
end process;`
q<=q1;end 2一位半加器
七、結果分析
1若在加載運行文件后實驗箱上無反應,可以通過更換不同頻率輸入管腳查看是否為實驗箱自帶時鐘的故障。
2實驗箱上LED顯示燈與設計邏輯相反時可以通過修改程序邏輯或給電路圖添加非門實現正邏輯顯示。
` 實驗二
16×16LED點陣四字循環顯示 實驗時間:2017.11.08(周三)晚
實驗編號20
一、實驗目的
1、掌握VHDL編程技巧和各種輸入輸出顯示方法。
2、學習并分析指導書中實例,從中發現感興趣的題目,并以此自設計一個有內容,功能稍復雜的主、子程序綜合應用例程,實現調試與驗證。
3、實現LED點陣“高山仰止”四字清晰循環顯示。
二、實驗原理
.1 LED顯示原理
16×16掃描LED點陣的工作原理同8位掃描數碼管類似,其結構示意圖(圖1)與等效電路圖(圖2)如下。它有16個共陰極輸出端口,每個共陰極對應有16個 LED顯示燈,所以其掃描譯碼地址需4位信號線(管腳對應COL1-COL4),從右起為第一列且COL1-4對應”0000”。其漢字掃描碼由16位段地址(從下至上管腳對應ROW1-ROW16)輸入。本設計選用的LED列掃描,漢字信號行輸入的方式,顯示完整漢字。
圖1 16×16LED點陣 圖2 16×16點陣LED等效電路
列循環掃描,通過對每一列的掃描來完成對字母的現實,本設計為使列掃描符合視覺暫留要求,掃描頻率至少大于16×8=128Hz,周期小于7.8ms,以此給人以連續的感覺。漢字的信息儲存
用動態分時掃描技術使LED點陣模塊顯示圖像,需要進行兩步工作。第一步是在程序中建立漢字數據庫。第二步是在掃描模塊的控制下,配合列掃描的次序正確地輸出這些數據。獲得圖像數據的步驟是,先將要顯示的每一幅圖像畫在一個如(圖3)所示的被分成16×16共256個小方格的矩形框中,再在有筆劃下落處的小方格里填上“1”,無筆劃處填上“0”,這樣就形成了與這個漢字所對應的二進制數據在該矩形框上的分布,漢字取模可由專用軟件進行。
`
圖3 16*16點陣顯示模塊
由于本實驗箱為從右至左依次對應”0000”列到”1111”列,從下至上為最高位到最低位,于平時習慣的認字方向相反,所以注意在逐列掃描的設計中要對字取“反模”。
例如要在右邊起第2列的從上到下數2、4、6、8行亮,則列編號為”0001”、行輸入為”***0”就可以實現了。
3延時環節
為使漢字不斷地循環顯示,并且使每個漢子顯示后停留,就需要在中間加一定的延時和循環環節。在這一環節中,可以通過修改每個顯示和停留周期包含的總時鐘脈沖數值來控制每個字的顯示時間,運用狀態機設計方法給四個漢字對應的不同輸入狀態進行編碼,即可使漢字依次清晰顯示。
三、實驗設備
1可編程邏輯實驗箱EP3C55F484C8 一臺(包含16×16LED點陣一組等)2計算機及開發軟件QuartusII 一臺套
四、調試步驟
1建立工程,命名為ledgrq1616。建立VHDL程序文件命名為1ed1616grq.vhd。2按照第六部分原程序輸入代碼,并按所示表格綁定管腳。編寫程序及綁定管腳時時注意第二部分中所敘述的掃描顯示順序以及對應取反字模的方法。
3編譯無誤后開啟實驗箱,生成.sof傳輸文件并下載至實驗箱,確保運行模式為1,且CPRL_SW撥碼開關為”00XX”。
4觀察實驗箱上現象,通過改接不同頻率的脈沖輸入管腳或改變每個字符停留周期包含的總脈沖數來保證有足夠快的掃描頻率與大約每個字大約一秒多的充足停留時間,并查看是否有“高山仰止”四字依次有停頓的清晰的循環顯示。
五、實驗現象
當時鐘輸入線接FRQH_Q2(3000000Hz)管腳時,設定每個周期為5000000個脈沖時,` 實現“高山仰止”在16×16LED點陣上清晰循環顯示。
六、實驗代碼
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity led1616grq is port(clk: in std_logic;--時鐘
data: out std_logic_vector(15 downto 0);--行輸入
addrs: out std_logic_vector(3 downto 0));--列地址 end led1616grq;
architecture chw_arc of led1616grq is signal fenpin:std_logic_vector(1 downto 0);--分頻信號 signal ad:std_logic_vector(3 downto 0);--地址中轉信號 begin
process(clk)--產生一個大約1s的分頻信號模塊
variable cnt:integer:=0;
variable tmp:std_logic_vector(1 downto 0);
begin
if clk'event and clk='1' then
if cnt<5000000 then
cnt:=cnt+1;
else
cnt:=0;
if tmp=“11” then
tmp:=“00”;
else
tmp:=tmp+1;
end if;
end if;
end if;
fenpin<=tmp;end process;
process(clk)--送16位地址程序
variable js:integer:=0;
variable cnt:std_logic_vector(3 downto 0);
begin
if clk'event and clk='1' then
if js<10000 then
js:=js+1;
else
js:=0;`
if cnt=“1111” then
cnt:=“0000”;
else cnt:=cnt+1;
end if;
end if;
end if;ad<=cnt;
end process;process(fenpin,ad)
begin
case fenpin is--besure to get the opposite model of the word--and exchange the hight 8bit to the low 8bit
--then write begin 1111 to 0000
when “00”=>
case ad is
--”高”的字模
when “0000”=>data<=“***0”;--00 00 when “0001”=>data<=“***0”;--04 00
when “0010”=>data<=“***0”;--04 FE
when “0011”=>data<=“***0”;--04 82
when “0100”=>data<=“***0”;--04 02
when “0101”=>data<=“***0”;--F4 7A
when “0110”=>data<=“***0”;--94 4A
when “0111”=>data<=“***0”;--94 4A
when “1000”=>data<=“***0”;--96 4A
when “1001”=>data<=“***1”;--95 4A
when “1010”=>data<=“***0”;--94 4A
when “1011”=>data<=“***0”;--F4 7A
when “1100”=>data<=“***0”;--04 02
when “1101”=>data<=“***0”;--04 02
when “1110”=>data<=“***0”;--04 FE
when “1111”=>data<=“***0”;--04 00
when others=>null;
end case;
when “01”=>
case ad is
when “0000”=>data<=“***0”;--0000 “山”的字模
when “0001”=>data<=“***0”;--0000
when “0010”=>data<=“***0”;--7FF0
when “0011”=>data<=“***0”;--2000
when “0100”=>data<=“***0”;--2000 `
when “0101”=>data<=“***0”;--2000
when “0110”=>data<=“***0”;--2000
when “0111”=>data<=“***1”;--3FFF
when “1000”=>data<=“***0”;--2000
when “1001”=>data<=“***0”;--2000
when “1010”=>data<=“***0”;--2000
when “1011”=>data<=“***0”;--2000
when “1100”=>data<=“***0”;--3FF0
when “1101”=>data<=“***0”;--0000
when “1110”=>data<=“***0”;--0000
when “1111”=>data<=“***0”;--0000
when others=>null;
end case;
when “10”=>
case ad is
when “0000”=>data<=“***0”;--0000 “仰”的字模
when “0001”=>data<=“***0”;--0000
when “0010”=>data<=“***0”;--07FC
when “0011”=>data<=“***0”;--0804
when “0100”=>data<=“***0”;--0404
when “0101”=>data<=“***1”;--FFCF
when “0110”=>data<=“***0”;--0000
when “0111”=>data<=“***0”;--0402
when “1000”=>data<=“***0”;--0804
when “1001”=>data<=“***1”;--1FCF
when “1010”=>data<=“***0”;--0000
when “1011”=>data<=“***1”;--0007
when “1100”=>data<=“***0”;--FFF8
when “1101”=>data<=“***0”;--0060
when “1110”=>data<=“***0”;--0080
when “1111”=>data<=“***0”;--0100
when others=>null;
end case;
when “11”=>
case ad is
when “0000”=>data<=“***0”;--0000“止”的字模
when “0001”=>data<=“***0”;--4000
when “0010”=>data<=“***0”;--4000
when “0011”=>data<=“***0”;--4040
when “0100”=>data<=“***0”;--4040
when “0101”=>data<=“***0”;--4040
when “0110”=>data<=“***0”;--4040
when “0111”=>data<=“***0”;--4040 `
when “1000”=>data<=“***1”;--7FFF
when “1001”=>data<=“***0”;--0400
when “1010”=>data<=“***0”;--0400
when “1011”=>data<=“***0”;--0400
when “1100”=>data<=“***1”;--7FFF
when “1101”=>data<=“***0”;--4000
when “1110”=>data<=“***0”;--4000
when “1111”=>data<=“***0”;--4000
when others=>null;
end case;
when others=>null;
end case;end process;addrs<=ad;end chw_arc;
管腳綁定如下:
七、結果分析
設備調試與程序調試一樣均為FPGA目標器件功能實現的必須工作,根據加載后實際顯示情況,同樣可以反推出QuartusII無法直接報錯的引腳綁定方面的問題以及程序書寫邏輯問題,實驗中具體出現的情況如下:
(1)顯示為一團不斷閃爍的重疊形狀 原因:可能為間隔時間太短 措施:應增大間隔周期數,延長停頓
`(2)字符形狀與設計不同/錯位
原因:如果為行順序錯位或亂序,但每一列仍為從右至左掃描,可能為ROW1-15管腳綁定錯位:如果為列出現順序及顯示正確但位置錯位,可能為CLK1-3管腳綁定錯位;上述兩種情況也可同時發生。
措施:將時鐘輸入頻率放緩至可以看清每一列出現的順序位置及顯示內容,與所設計的字模對照,判斷是哪幾個ROW管腳及CLK錯位,重新綁定即可。
(3)實驗箱開啟后毫無顯示
原因:可能是工作模式的撥碼開關并非”00XX”,或時鐘管腳故障。
措施:選用其他頻率的管腳試接;若排除管腳問題,查看模式顯示數碼管數值是否為1,如不是,改變工作模式,重新加載文件。
` 實驗三
蜂鳴器/揚聲器電子音樂演奏
實驗時間:2017.11.15(周三)晚
實驗編號20
一、實驗目的
1、熟練掌握QuartusII平臺各模塊操作及實驗箱調試方法。
2、用元件例化語句調用方式,任意自選題設計一個有內容,功能較復雜的主、子程序綜合應用的多模塊集成例程,并實現調試與驗證。
3、實現電子音樂《天空之城》的主旋律循環播放,并通過LED燈指示音符。
二、實驗原理
.1、電子音符演奏
樂曲硬件電路產生音樂是和音樂頻率和音樂的持續時間有關;音符的持續時間需根據樂曲的速度和每個音符的節拍數來確定。設計所用簡譜及音符和頻率的關系如下:
2、演奏節拍控制
該演奏電路演奏的樂曲是《天空之城》,其最小的節拍為1拍,將1拍的時長定位0.25S,則只需要再提供一個4Hz的時鐘頻率即可產生1拍的時長(5Hz由24MHz的基準頻率分頻產生),對于占用時間較長的節拍,(一定是節拍的整數倍),如全音符為4拍,2/4音符為2拍,1/4音符為1拍。
3、演奏電路模塊
樂曲硬件演奏電路系統主要有音調分頻器和樂曲存儲模塊兩個部分組成,其余還有音樂節拍發生器等等。音調分頻器對24MHz(由基準頻率產生)的頻率進行分頻,得到與各個音節對應的頻率輸出。樂曲存儲模塊產生節拍控制和音階選擇信號,即在此模塊中寫入一個樂曲曲譜真值序列,由一個計數器來控制此序列的輸出,而由計數器的計` 數時鐘信號作為樂曲節拍控制信號。
4程序設計思路
實驗中采用層次化設計思路,音樂發生器的設計包括四個模塊:時鐘分頻模塊、自動演奏模塊、音符顯示模塊、音調分頻模塊。分好層次之后,編寫每個模塊的程序。
時鐘分頻模塊通過基準時鐘頻率clk(24MHz)產生兩個時鐘信號。自動演奏模塊接收4hz的時鐘信號,輸出音調代碼。顯示模塊利用音調代碼查找并輸出對應LED燈顯示情況。同時將音調對應的給8盞LED指示燈,分別顯示高中低音符。音調分頻模塊接收音調代碼對應的分頻系數,并據此分頻,將對應頻率的信號輸出給揚聲器供其發聲。
三、實驗設備
1可編程邏輯實驗箱EP3C55F484C8 一臺(含蜂鳴器、揚聲器、若干LED燈等)2計算機及開發軟件QuartusII 一臺套
四、調試步驟
1建立工程,命名為grqbeep01。建立VerilogHDL程序文件命名為grqbeep01.v。2按照第六部分原程序輸入代碼,并按所示表格綁定管腳。
3編譯無誤后開啟實驗箱,將時鐘輸入管腳P20接Q0(24000000Hz)。
4生成.sof傳輸文件并下載至實驗箱,確保運行模式為3,且CPRL_SW撥碼開關為”0110”。
5觀察實驗箱上現象,確定蜂鳴器與揚聲器的器件使用設定方法,對比其效果差異。
五、實驗現象
1跳線BZ1未調整時
下載完畢,聽到完整的由蜂鳴器播放的循環《天空之城》音樂,可是聲音很小,LED指示燈顯示沒有錯誤。
2跳線BZ1由23調整到12時
下載測試,聽到聲音洪亮的循環播放的《天空之城》音樂,并且音調很好,數碼管顯示音符正常,實現預期功能。
六、實驗代碼
`timescale 1ns / 1ps module grqbeep01(clk,beep,led);input clk;//時鐘管腳
` output beep;//蜂鳴器管腳 output [7:0]led;//led指示管腳 reg beep;reg [22:0]i;reg clk_4hz;reg [7:0]led;
reg [16:0]count,div_num;reg [6:0]music;//以下為主體
always@(posedge clk)//4hz生成部分
begin if(i==23'h47868c)begin i<=0;
clk_4hz=~clk_4hz;end else i=i+1'b1;end
always@(posedge clk_4hz)begin
if(music==7'd122)//總共的音符節拍數 music<=0;else
music<=music+1'b1;end always@(posedge clk)begin
if(count==div_num)begin
count<=0;beep=~beep;end else
count<=count+1'b1;end parameter//輸入查表可得的低中高音符赫茲數 L0=17'h00000, L1=17'h1754e, L2=17'h14c81, L3=17'h1284a, L4=17'h117A8, L5=17'h14e70, L6=17'h0ddf2, L7=17'h0c5ba, M1=17'h0ba9e, ` M2=17'h0a648, M3=17'h0941f, M4=17'h08bcf, M5=17'h07c90, M6=17'h06ef9, M7=17'h062dd, H1=17'h05d68, H2=17'h05322, H3=17'h04a11, H4=17'h045e9, H5=17'h3e48, H6=17'h377d, H7=17'h316f;always@(posedge clk_4hz)begin case(music)//樂譜輸入 7'd0:div_num=M6;7'd1:div_num=M7;7'd2:div_num=H1;7'd3:div_num=H1;7'd4:div_num=H1;7'd5:div_num=M7;7'd6:div_num=H1;7'd7:div_num=H1;7'd8:div_num=H3;7'd9:div_num=H3;7'd10:div_num=M7;7'd11:div_num=M7;7'd12:div_num=M7;7'd13:div_num=M7;7'd14:div_num=M7;7'd15:div_num=M7;7'd16:div_num=M3;7'd17:div_num=M3;7'd18:div_num=M6;7'd19:div_num=M6;7'd20:div_num=M6;7'd21:div_num=M5;7'd22:div_num=M6;7'd23:div_num=M6;7'd24:div_num=H1;7'd25:div_num=H1;7'd26:div_num=M5;7'd27:div_num=M5;7'd28:div_num=M5;7'd29:div_num=M5;` 7'd30:div_num=M5;7'd31:div_num=M5;7'd32:div_num=M2;7'd33:div_num=M3;7'd34:div_num=M4;7'd35:div_num=M4;7'd36:div_num=M4;7'd37:div_num=M3;7'd38:div_num=M4;7'd39:div_num=M4;7'd40:div_num=H1;7'd41:div_num=H1;7'd42:div_num=M3;7'd43:div_num=M3;7'd44:div_num=M3;7'd45:div_num=M3;7'd46:div_num=H1;7'd47:div_num=H1;7'd48:div_num=M7;7'd49:div_num=M7;7'd50:div_num=M7;7'd51:div_num=M3;7'd52:div_num=M4;7'd53:div_num=H1;7'd54:div_num=H1;7'd55:div_num=M7;7'd56:div_num=M7;7'd57:div_num=M7;7'd58:div_num=M7;7'd59:div_num=M7;7'd60:div_num=M7;//第二段樂譜
7'd61:div_num=M6;7'd62:div_num=M7;7'd63:div_num=H1;7'd64:div_num=H1;7'd65:div_num=H1;7'd66:div_num=M7;7'd67:div_num=H1;7'd68:div_num=H1;7'd69:div_num=H3;7'd70:div_num=H3;7'd71:div_num=M7;7'd72:div_num=M7;` 7'd73:div_num=M7;7'd74:div_num=M7;7'd75:div_num=M7;7'd76:div_num=M7;7'd77:div_num=M3;7'd78:div_num=M4;7'd79:div_num=M6;7'd80:div_num=M6;7'd81:div_num=M6;7'd82:div_num=M5;7'd83:div_num=M6;7'd84:div_num=M6;7'd85:div_num=H1;7'd86:div_num=H1;7'd87:div_num=M5;7'd88:div_num=M5;7'd89:div_num=M5;7'd90:div_num=M5;7'd91:div_num=M5;7'd92:div_num=M5;7'd93:div_num=M2;7'd94:div_num=M3;7'd95:div_num=M4;7'd96:div_num=M4;7'd97:div_num=H1;7'd98:div_num=H1;7'd99:div_num=H1;7'd100:div_num=M7;7'd101:div_num=H1;7'd102:div_num=H2;7'd103:div_num=H2;7'd104:div_num=H3;7'd105:div_num=H3;7'd106:div_num=H1;7'd107:div_num=H1;7'd108:div_num=H1;7'd109:div_num=M7;7'd110:div_num=M6;7'd111:div_num=M6;7'd112:div_num=M7;7'd113:div_num=M7;7'd114:div_num=M5;7'd115:div_num=M5;7'd116:div_num=M6;` 7'd117:div_num=M6;7'd118:div_num=M6;7'd119:div_num=M6;7'd120:div_num=M6;7'd121:div_num=M6;endcase end
always@(div_num)//定義每一種音符的LED指示方案
begin case(div_num)
L5,H5:led=8'b1111_1111;L6,H6:led=8'b0111_1111;L7,M1:led=8'b0011_1111;M2,M3:led=8'b0001_1111;M4,L4,H4,M5:led=8'b0000_1111;M6,M7:led=8'b0000_0111;H1,L1:led=8'b0000_0011;H2,L2:led=8'b0000_0001;H3,L3:led=8'b0000_0000;default: led=8'bx;endcase end endmodule 管腳綁定如下:
七、結果分析
1實驗指導書由于篇幅有限,并未介紹全部硬件的管腳連接與使用方法,但是實驗室中的完整實驗箱說明書可以查閱到所有硬件資料。例如本實驗中,指導書上只是概略提及了模式3中有BZSP接口可以實現蜂鳴器/揚聲器放音,卻并未提及調用切換方法,在老師幫助下在實驗箱完整說明書中找到BZ1跳線使用方法,最終實現揚聲器響亮播放。
2實驗中的實際運行輸入時鐘頻率必須與程序設計頻率完全一致,設計程序也要優先參考實驗箱所提供的自身時鐘,否則輸出音調和分頻后的輸出節拍均會因基準頻率不符而有明顯變化,可能有完全變調或頻率過低而聲音失真的情況。
`
實驗感想
本次實驗前后時間跨度有三周,從中收獲的不僅僅是指導書中的一種新的Ada類編程語言的使用方法,更是一種對于短時間內接納新的理論并迅速結合已知儲備,實現實踐運用與二次創新的能力鍛煉。
能夠借此機會下定決心,實現很久之前就有的學習Verilog的目標,更加深刻感受到C類編程語法的強大之處,同時也再一次鍛煉了查找學習資源與閱讀自學的能力。
為了能夠深刻學習并學以致用,以上三個實驗只是成果的一小部分,關于TFT_LCD以及LCD1602的驅動控制,以及Verilog語法規范與設計思路所讀的40多篇文獻,與兩本課本,調試的17組程序,雖然來不及在課堂上展示,但是在我自己購置的手冊齊全的DJ51單片機與我的TMS320F28335的DSP開發板上,均實現了非常令人喜悅的顯示效果。而且實際上我所缺的,不能很方便找到的資源,其實就是那本完整的硬件說明書,但是至于其他,收獲驚喜的比想象多了不少。對于硬件控制設計的理解也從大二的“僅僅是單片機”“不就是驅動個電機嗎”,有了更多的深入的思考。
畢竟,“高山仰止,景行行止,雖不能至,心向往之”。
各種編程語言與平臺,最終都是用不同的方式敘述同一種邏輯。編程的使用,只是讓構思的邏輯與想法最快生成可以感受到的成果的途徑,是表達的工具,也是最基礎的鏈接理論到實物的媒介,但是其中最不可替代的只是一直存在的想法而已。
`