《EDA 技術及應用》實驗報告
實驗一
點亮 LED 設計 一、實驗目的
通過此實驗讓用戶逐步了解、熟悉和掌握 FPGA 開發軟件 QuartusII 的使用方法及 Verilog HDL 的編程方法。
本實驗力求以詳細的步驟和講解讓讀者以最快的方式了解 EDA 技術開發以及軟件的使用,從而快速入門并激起讀者對 EDA 技術的興趣。
二、實驗容
SmartSOPC 實驗箱上有 8 個發光二極管 LED1~8,并分別與 FPGA 的 50、53~55、176 和 47~49 引腳相連。本實驗的容是建立可用于控制 LED 亮/滅的簡單硬件電路,要求點亮 SmartSOPC 實驗箱上的 4 個發光二極管(LED1、LED3、LED5 和 LED7)。
三、實驗原理
FPGA 器件同單片機一樣,為用戶提供了許多靈活獨立的輸入/輸出 I/O 口(單元)。FPGA 每個 I/O 口可以配置為輸入、輸出、雙向 I/O、集電極開路和三態門等各種組態。作為輸出口時,FPGA 的 I/O 口可以吸收最大為 24mA 的電流,可以直接驅動發光二極管 LED 等器件。所以只要正確分配并鎖定引腳后,在相應的引腳上輸出低電平“0”,就可以實現點亮該發光二級管的功能。
四、實驗步驟
1、啟動 Quarters II 建立一個空白工程,命名為 led_test.qpf。然后分別建立圖形設計文件,命名為 led_test.bdf,以及文本編輯文件 led1.v,將他們都添加進工程中。
2、對工程進行設計。在 led1.v 中輸入程序代碼,并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。從設計文件中創建模塊,由 led1.v 生成名為 led1.bsf 的模塊符號文件。在 led_test.bdf 中任意空白處雙擊鼠標左鍵,將 symbol 對話框中 libraries:project 下的 led1 模塊添加到圖形文件led_test.bdf 中,加入輸入、輸出引腳,雙擊各管腳符號,進行管腳命名。完整的頂層模塊原理圖如下圖所示。選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
led[7..0]OUTPUTled[7..0]led1inst 3、設置編譯選項并編譯硬件系統。將 led_test.bdf 設置為頂層實體。對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
4、下載硬件設計到目標 FPGA。將產生的 led_test.sof 輸出對 FPGA 進行配置。
5、觀察 LED 的狀態。
五、實驗程序 //利用連續賦值 assign 語句實現 module led1(led);
//模塊名 led1 output[7:0] led;
//定義輸出端口、 assign led =8"b10101010;
//輸出 0xAA endmodule //利用過程賦值語句實現(暫時已屏蔽)
/* module led1(led);
//模塊名 led1 output[7:0] led;
//定義輸出端口 reg[7:0] led;
//定義寄存器 always
//過程 1,無敏感變量 begin
led = 8"b10101010;
//輸出 0xAA end endmudule*/
六、思考題
寫出使用 QuartusII 軟件開發工程的完整的流程。
實驗二 流水燈實驗
一、實驗目的 通過此實驗讓用戶進一步了解、熟悉和掌握 CPLD/FPGA 開發軟件的使用方法及 Verilog HDL 的編程方法。學習簡單時序電路的設計和硬件測試。
二、實驗容 本實驗的容是建立可用于控制 LED 流水燈的簡單硬件電路,要求在SmartSOPC 實驗箱上實現 LED1~LED8 發光二極管流水燈顯示。
三、實驗原理 1、在 LED1~LED8 引腳上周期性的輸出流水數據,如原來輸出的數據是 11111100則表示點亮 LED1、LED2,流水一次后,輸出的數據應該為 11111000,而此時則應點亮 LED1~LED3 三個 LED 發光二極管,就可以實現 LED 流水燈。為了觀察方便,流水速率最好在 2Hz 左右。在 QuickSOPC 核心板上有一個 48MHz 的標準時鐘源,該時鐘脈沖 Clock 與芯片的 28 管腳相連。為了產生 2Hz 的時鐘脈沖,在此調用了一個分頻模塊(int_div 模塊,位于光盤中 EDA_Component 目錄下),通過修改分頻系數來改變輸出頻,當分頻系數為 24x10^6 時,輸出即為 2Hz 的頻率信號。
2、Int_div 分頻模塊說明:int_div 模塊是一個占空比為 50%的任意整數分頻器。輸入時鐘為 clock,輸出時鐘為 clk_out。其中 F_DIV 為分頻系數,分頻系數圍為1~2^n (n=F_DIV_WIDTH),若要改變分頻系數,改變參數F_DIV 和F_DIV_WIDTH到相應圍即可。在本例中輸入時鐘為 48MHz,要得到 2Hz 的信號,所以分頻系數為 48x10^6/2=24x10^6;對于分頻系數為 24x10^6 的數需要一個 25 位寬的計數器即可。
四、實驗步驟
1、啟動 Quarters II 建立一個空白工程,命名為 led_water.qpf。
2、新建 Verilog HDL 源程序文件 ledwater.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
3、從設計文件中創建模塊,由 ledwater.v 生成名為 ledwater.bsf 的模塊符號文件。
4、將光盤中 EDA_Component 目錄下的 int_div.bsf 和 int_div.v 拷貝到工程目錄。
5、新建圖形設計文件命名為 led_water.bdf 并保存。在空白處雙擊鼠標左鍵,分別將 symbol 對話框中 libraries:project 下的 ledwater 和 int_div 模塊放在圖形文
件 led_water.bdf 中,加入輸入、輸出引腳,雙擊各管腳符號,進行管腳命名。雙擊 int_div 的參數框,并修改參數,將 F_DIV 的值改為 24000000,F_DIV_WIDTH的值改為 25. 完整的頂層模塊原理圖如下圖所示。
VCCclockINPUTled[7..0]OUTPUTclk led[7..0]ledwaterinst1F_DIV 24000000F_DIV_WIDTH 25Parameter Valueclock clk_outint_divinst 6、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
7、將 led_water.bdf 設置為頂層實體。對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
8、將產生的 led_water.sof 輸出對 FPGA 進行配置。
9、更改分頻模塊(int_div)的分頻系數,并重新編譯下載,觀察流水燈的變化。
五、實驗程序 module ledwater (led,clk);
//模塊名 ledwater output[7:0] led;
//定義 LED 輸出口 input
clk;
//定義時鐘輸入口 reg[8:0]
led_r;
//定義輸出寄存器 assign led = led_r[7:0];
//寄存器輸出 always (posedge clk)
//在時鐘上升沿觸發進程 begin
led_r <= led_r << 1;
//是,則輸出左移一位
if(led_r == 9"d0)
//循環完畢嗎?
led_r <= 9"b111111111;
//是,則重新賦初值 end endmodule
六、思考題
本實驗頂層采用了圖形輸入的方式,若采用文本輸入方式,如何編寫頂層文件?寫出相應程序。
實驗三
鍵盤、 LED 發光實驗 一、實驗目的
通過此實驗讓用戶進一步了解、熟悉和掌握 CPLD/FPGA 開發軟件的使用方法及 Verilog HDL 的編程方法,熟悉以 Verilog HDL 文件為頂層模塊的設計。學習和體會分支條件語句 case 的使用方法及 FPGA I/O 口的輸出控制。
二、實驗容
SmartSOPC 實驗箱上有 8 個發光二極管 LED1~8 和 8 個按鍵 KEY1~KEY8。
本實驗的容要求在SmartSOPC實驗箱上完成對8個按鍵KEY1~KEY8進行監控,
一旦有按鍵輸入判斷其鍵值,并點亮相應的發光二極管,如若 KEY3 按下,則點亮 LED1~LED3 發光二極管。
三、實驗原理 FPGA 的所有 I/O 控制塊允許每個 I/O 口引腳單獨配置為輸出口,不過這種配置是系統自動完成的,一旦該 I/O 口被設置為輸入口使用時(如定義 key0 為輸入引腳:input key0;)該 I/O 控制模塊將直接使三態緩沖區的控制端接地,使得該I/O 口引腳對外呈高阻態,這樣該 I/O 口引腳即可用作專用輸入引腳。只要正確分配并鎖定引腳后,一旦在 KEY1~KEY8 中有按鍵輸入,在檢測到鍵盤輸入的情況下,繼續判斷其鍵值并做出相應的處理。
四、實驗步驟 1、啟動 Quarters II 建立一個空白工程,命名為 keyled.qpf。
2、新建 Verilog HDL 源程序文件 keyled.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
3、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
4、對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
5、將產生的 keyled.sof 輸出對 FPGA 進行配置。按下不同按鍵觀察 LED 發光管的狀態。
五、實驗程序
module keyled(key,led);
//模塊名 keyled input[7:0]
key;
//定義鍵盤輸入口 output[7:0] led;
//定義發光管輸出口 reg[7:0] led_r;
//定義寄存器 reg[7:0] buffer_r;
assign led = led_r;
//輸出鍵值
always(key)
//過程 1 begin
buffer_r = key;
//讀取鍵值
case(buffer_r)
8"b11111110:led_r = 8"b11111110; //是鍵 KEY1,則給寄存器賦值 0xfe
8"b11111101:led_r = 8"b11111100; //是鍵 KEY2,則給寄存器賦值 0xfc
8"b11111011:led_r = 8"b11111000; //是鍵 KEY3,則給寄存器賦值 0xf8
8"b11110111:led_r = 8"b11110000; //是鍵 KEY4,則給寄存器賦值 0xf0
8"b11101111:led_r = 8"b11100000; //是鍵 KEY5,則給寄存器賦值 0xe0
8"b11011111:led_r = 8"b11000000; //是鍵 KEY6,則給寄存器賦值 0xc0
8"b10111111:led_r = 8"b10000000; //是鍵 KEY7,則給寄存器賦值 0x80
8"b01111111:led_r = 8"b00000000; //是鍵 KEY8,則給寄存器賦值 0x00
default: led_r = 8"b11111111; //否則給寄存器賦值 0xff
endcase end endmodule 六、思考題 能否用 if 語句改寫本實驗程序?如果能,寫出相應程序。
實驗四
靜態數碼管顯示實驗 一、實驗目的
學習 7 段數碼管顯示譯碼器的設計,進一步了解、熟悉和掌握 FPGA 開發軟件 Quartus II 的使用方法及 Verilog HDL 的編程方法,學習 LPM 兆功能模塊的調用。
二、實驗容 SmartSOPC 實驗箱上有 2 個 4 位動態共陽極數碼管 LED12 和 LED13。其中8 個位碼 DIG0~DIG7 和 8 位段碼 SEG0~SEG7 分別與 FPGA 相應的引腳相連。這樣,只要 DIG0~DIG7 上一直輸出低電平“0”,則 8 個數碼管將顯示相同的數碼(因為 8 個 LED 數碼管的段碼線分別接到了同一引腳上),這樣 8 位動態的 LED數碼管就變成了靜態的 LED。
本實驗的容是建立 7 段譯碼顯示模塊,用于控制 LED 數碼管的靜態顯示。要求在 SmartSOPC 實驗箱上的數碼管依次顯示 0~9 和 A~F16 個字符。
三、實驗原理 數碼管 LED 顯示是工程項目中使用較廣的一種輸出顯示器件。常見的數碼管有共陰和共陽 2 種。共陰數碼管是將 8 個發光二極管的陰極連接在一起作為公共端,而共陽數碼管是將 8 個發光二極管的陽極連接在一起作為公共端。公共端常被稱作位碼,而將其他的 8 位稱作段碼。數碼管有 8 個段分別為:h、g、f、e、d、c、b 和 a(h 為小數點),只要公共端為高電平“1”,某個段輸出低電平“0”則相應的段就亮。
本實驗通過分頻模塊 int_div 分頻得到 1Hz 的頻率信號,加載于 4 位計數器的時鐘輸入端,計數循環輸出 0~9、A~F16 個數。最后通過七段譯碼模塊譯碼后在數碼管上顯示出來。
四、實驗步驟
1、啟動 Quarters II 建立一個空白工程,命名為 sled.qpf。
2、新建 Verilog HDL 源程序文件 decl7s.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
3、從設計文件中創建模塊,由 decl7s.v 生成名為 decl7s.bsf 的模塊符號文件。
4、將光盤中 EDA_Component 目錄下的 int_div.bsf 和 int_div.v 拷貝到工程目錄。
5、添加 4 位計數器兆功能模塊。
6、新建圖形設計文件命名為 sled.bdf 并保存。在空白處雙擊鼠標左鍵,分別將symbol 對話框中 libraries:project 下的 counter、decl7s 和 int_div 模塊放在圖形文件 sled.bdf 中,在 symbol 對話框中 Name:輸入 gnd,添加 gnd 符號。加入輸入、輸出引腳,雙擊各管腳符號,進行管腳命名。雙擊 int_div 的參數框,并修改參數,將 F_DIV 的值改為 48000000,F_DIV_WIDTH 的值改為 26。完整的頂層模塊原理圖如下圖所示。
VCCclockINPUTseg[7..0]OUTPUTdig[7..0]OUTPUTup counterclockq[3..0]counterinstd[3..0] seg[7..0]decl7sinst1GNDF_DIV 48000000F_DIV_WIDTH 26Parameter Valueclock clk_outint_divinst2數碼管位碼輸出數碼管段碼輸出 7、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
8、將 sled.bdf 設置為頂層實體。對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
9、將產生的 sled.sof 輸出對 FPGA 進行配置。觀察 LED 顯示狀態。
五、實驗程序 module decl7s(d,seg);
//模塊名 decl7s input[3:0] d;
//輸入 4 位二進制碼 output[7:0] seg;
//七段譯碼輸出 reg[7:0] seg_r;
//定義數碼管輸出寄存器
assign seg = seg_r;
//輸出數碼管譯碼結果
always (d) begin
case(d)
//七段譯碼
4"h0:seg_r = 8"hc0;
//顯示 0
4"h1:seg_r = 8"hf9;
//顯示 1
4"h2:seg_r = 8"ha4;
//顯示 2
4"h3:seg_r = 8"hb0;
//顯示 3
4"h4:seg_r = 8"h99;
//顯示 4
4"h5:seg_r = 8"h92;
//顯示 5
4"h6:seg_r = 8"h82;
//顯示 6
4"h7:seg_r = 8"hf8;
//顯示 7
4"h8:seg_r = 8"h80;
//顯示 8
4"h9:seg_r = 8"h90;
//顯示 9
4"ha:seg_r = 8"h88;
//顯示 a
4"hb:seg_r = 8"h83;
//顯示 b
4"hc:seg_r = 8"hc6;
//顯示 c
4"hd:seg_r = 8"ha1;
//顯示 d
4"he:seg_r = 8"h86;
//顯示 e
4"hf:seg_r = 8"h8e;
//顯示 f
endcase end endmodule 六、思考題 1.本實驗采用的是共陽極數碼管,若采用共陰極數碼管,有什么不同?
2.如何顯示 HHHHHHHH 和 PPPPPPPP?
實驗五
動態數碼管顯示實驗 一、實驗目的
學習動態掃描顯示的原理及電路的設計。
二、實驗容
本實驗的容是建立數碼管動態掃描顯示模塊,具體容如下:
1、在 SmartSOPC 實驗箱上完成 LED 數碼管的動態顯示“1~8”8 個數字; 2、放慢掃描速度演示動態顯示的原理過程。
三、實驗原理
一個 FPGA 的片子如果帶動多個(比如說 8 個)數碼管,選用靜態顯示的話,管腳很容易不夠用,于是大多采用動態顯示的方式。本次采用共陽極的數碼管,其中每個數碼管的 8 個段:h、g、f、e、d、c、b 和 a(h 為小數點)都分別連接到 SEG0~SEG7,8 個數碼管分別由 8 個選通信號 DIG0~DIG7 來選擇。被選通的數碼管顯示數據,其余關閉。如果在某一時刻 DIG2 為低電平“0” ,其余選通信號為高電平“1” ,這時僅 DIG2 對應的數碼管顯示來自段碼信號端的數據,其余 7 個數碼管呈現關閉狀態。根據這種電路狀態,如果希望 8 個數碼管顯示希望的數據,就必須使得 8 個選通信號 DIG0~DIG7 分別被單獨選通,并在此同時,在段信號輸入口加上希望在該對應數碼管上顯示的數據,于是隨著選通信號的掃描就能實現掃描顯示的目的。雖然每次只有一個 LED 顯示,但只要掃描顯示速率足夠快,由于人的視覺余輝效應,使我們仍會感覺所有的數碼管都在同時顯示。
四、實驗步驟
1、啟動 Quarters II 建立一個空白工程,命名為 dled.qpf。
2、新建 Verilog HDL 源程序文件 scan_led.v,輸入程序代碼并保存,進行綜合編
譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
3、從設計文件中創建模塊,由 scan_led.v 生成名為 scan_led.bsf 的模塊符號文件。
4、將光盤中 EDA_Component 目錄下的 int_div.bsf 和 int_div.v 拷貝到工程目錄。
5、添加常量兆功能模塊。
6、新建圖形設計文件命名為 dled.bdf 并保存。在空白處雙擊鼠標左鍵,分別將symbol 對話框中 libraries:project 下的 constant、scan_led 和 int_div 模塊放在圖形文件 dled.bdf 中,加入輸入、輸出引腳,雙擊各管腳符號,進行管腳命名。雙擊 int_div 的參數框,并修改參數,將 F_DIV 的值改為 48000,F_DIV_WIDTH的值改為 16。完整的頂層模塊原理圖如下圖所示。
VCCclockINPUTdig[7..0]OUTPUTseg[7..0]OUTPUT30541989632constantinst1clk_1kd[31..0]dig[7..0]seg[7..0]scan_ledinst2F_DIV 48000F_DIV_WIDTH 16Parameter Valueclock clk_outint_divinst 7、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
8、將 dled.bdf 設置為頂層實體。對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
9、將產生的 sled.sof 輸出對 FPGA 進行配置。觀察 LED 數碼管上的數字是否為“12345678” ,然后把分頻模塊的參數改為 F_DIV:24000000,F_DIV_WIDTH:25,再重新編譯下載,觀察這次 LED 數碼管上的顯示數據,可以看到數據“12345678”動起來了,這正是動態掃描的方法和過程。
五、實驗程序
module scan_led(clk_1k,d,dig,seg);
//模塊名 scan_led input clk_1k;
//輸入時鐘 input[31:0] d;
//輸入要顯示的數據 output[7:0] dig;
//數碼管選擇輸出引腳 output[7:0] seg;
//數碼管段輸出引腳
reg[7:0] seg_r;
//定義數碼管輸出寄存器 reg[7:0] dig_r;
//定義數碼管選擇輸出寄存器
reg[3:0] disp_dat;
//定義顯示數據寄存器 reg[2:0]count;
//定義計數寄存器
assign dig = dig_r;
//輸出數碼管選擇 assign seg = seg_r;
//輸出數碼管譯碼結果
always (posedge clk_1k)
//定義上升沿觸發進程 begin
count <= count + 1"b1; end
always (posedge clk_1k)
begin
case(count)
//選擇掃描顯示數據
3"d0:disp_dat = d[31:28];
//第一個數碼管
3"d1:disp_dat = d[27:24];
//第二個數碼管
3"d2:disp_dat = d[23:20];
//第三個數碼管
3"d3:disp_dat = d[19:16];
//第四個數碼管
3"d4:disp_dat = d[15:12];
//第五個數碼管
3"d5:disp_dat = d[11:8];
//第六個數碼管
3"d6:disp_dat = d[7:4];
//第七個數碼管
3"d7:disp_dat = d[3:0];
//第八個數碼管
endcase
case(count)
//選擇數碼管顯示位
3"d0:dig_r = 8"b01111111;
//選擇第一個數碼管顯示
3"d1:dig_r = 8"b10111111;
//選擇第二個數碼管顯示
3"d2:dig_r = 8"b11011111;
//選擇第三個數碼管顯示
3"d3:dig_r = 8"b11101111;
//選擇第四個數碼管顯示
3"d4:dig_r = 8"b11110111;
//選擇第五個數碼管顯示
3"d5:dig_r = 8"b11111011;
//選擇第六個數碼管顯示
3"d6:dig_r = 8"b11111101;
//選擇第七個數碼管顯示
3"d7:dig_r = 8"b11111110;
//選擇第八個數碼管顯示
endcase
end
always (disp_dat) begin
case(disp_dat)
//七段譯碼
4"h0:seg_r = 8"hc0;
//顯示 0
4"h1:seg_r = 8"hf9;
//顯示 1
4"h2:seg_r = 8"ha4;
//顯示 2
4"h3:seg_r = 8"hb0;
//顯示 3
4"h4:seg_r = 8"h99;
//顯示 4
4"h5:seg_r = 8"h92;
//顯示 5
4"h6:seg_r = 8"h82;
//顯示 6
4"h7:seg_r = 8"hf8;
//顯示 7
4"h8:seg_r = 8"h80;
//顯示 8
4"h9:seg_r = 8"h90;
//顯示 9
4"ha:seg_r = 8"h88;
//顯示 a
4"hb:seg_r = 8"h83;
//顯示 b
4"hc:seg_r = 8"hc6;
//顯示 c
4"hd:seg_r = 8"ha1;
//顯示 d
4"he:seg_r = 8"h86;
//顯示 e
4"hf:seg_r = 8"h8e;
//顯示 f
endcase end endmodule 六、思考題
說出數碼管動態顯示的原理。
實驗六
按鍵去抖動實驗 一、實驗目的
學習按鍵去抖動電路的硬件設計。
二、實驗容 本實驗的容是建立按鍵消抖模塊。通過 SmartSOPC 實驗箱上的按鍵 KEY1(經過消抖)或 KEY2(沒有消抖)控制數碼管顯示數字。對比有加消抖和沒有加消抖模塊電路的區別。
三、實驗原理 作為機械開關的鍵盤,在按鍵操作時,由于機械觸點的彈性及電壓突跳等原因,在觸點閉合或開啟的瞬間會出現電壓抖動,實際應用中如果不進行處理將會造成誤觸發。
由于這里是低電平表示按鍵按下,所以按鍵去抖動的關鍵在于提取穩定的低電平狀態,慮除前沿、后沿抖動毛刺。對于一個按鍵信號,可以用一個脈沖對他進行取樣,如果連續三次取樣為低電平,可以認為信號已經處于鍵穩定狀態,這時輸出一個低電平按鍵信號。繼續取樣的過程中如果不能滿足連續三次取樣為低,則認為鍵穩定狀態結束,這時輸出變為高電平。一通道的消抖電路原理圖如下:
CLRNDPRNQDFFinstCLRNDPRNQDFFinst1CLRNDPRNQDFFinst2VCCkey_inINPUTVCCclockINPUTkey_outOUTPUTOR3inst3
四、實驗步驟 1、啟動 Quarters II 建立一個空白工程,命名為 key_debounce.qpf。
2、將上圖所示消抖電路用 Verilog HDL 語言描述出來,并拓展多個通道。新建Verilog HDL 源程序文件 debounce.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
3、從設計文件中創建模塊,由 debounce.v 生成名為 debounce.bsf 的模塊符號文件。
4、將光盤中 EDA_Component 目錄下的 int_div.bsf 和 int_div.v 拷貝到工程目錄。
5、添加 4 位計數器兆功能模塊。
6、新建圖形設計文件命名為 key_debounce.bdf 并保存。在空白處雙擊鼠標左鍵,分別將 symbol 對話框中 libraries:project 下的 counter、debounce、decl7s 和int_div模塊放在圖形文件 debounce.bsf 中,在symbol對話框中 Name:輸入gnd,添加 gnd 符號,輸入 and2,添加與門。加入輸入、輸出引腳,雙擊各管腳符號,進行管腳命名。雙擊 int_div 的參數框,并修改參數,將 F_DIV 的值改為 240000,F_DIV_WIDTH 的值改為 18。完整的頂層模塊原理圖如下圖所示。
VCCclockINPUTVCCkey1INPUTVCCkey2INPUTseg[7..0]OUTPUTdig[7..0]OUTPUTF_DIV 240000F_DIV_WIDTH 18Parameter Valueclock clk_outint_divinstKEY_WIDTH 1Parameter Valueclkkey_in[KEY_WIDTH-1..0]key_out[KEY_WIDTH-1..0]debounceinst1AND2inst2up counterclockq[3..0]counterinst3d[3..0] seg[7..0]decl7sinst4GND數碼管位碼輸出數碼管段碼輸出i 消抖后的信號輸出 7、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
8、將 key_debounce.bdf 設置為頂層實體。對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
9、將產生的 key_debounce.sof 輸出對 FPGA 進行配置。分別連續按 KEY1 或KEY2 觀察數碼管顯示狀態,看數值是否連續遞增,比較前后兩次操作有何不同。
五、實驗程序 module debounce(clk,key_in,key_out);
//按鍵消抖模塊 input clk;
//系統時鐘輸入 input[KEY_WIDTH-1:0] key_in;
//外部按鍵輸入 output[KEY_WIDTH-1:0]key_out;
//按鍵消抖輸出 reg[KEY_WIDTH-1:0]dout1,dout2,dout3; //寄存器
parameter KEY_WIDTH = 8;
//參數
assign key_out = (dout1 | dout2 | dout3); //按鍵消抖輸出
always (posedge clk) begin
dout1 <= key_in;
dout2 <= dout1;
dout3 <= dout2;
end endmodule
六、思考題 比較下面兩段程序的異同,并畫出電路結構圖。
always ( posedge clk) begin
dout1<=key_in;
//非阻塞賦值
dout2<=dout1;
dout3<=dout2; end
always ( posedge clk) begin
dout1<=key_in;
//阻塞賦值
dout2<=dout1;
dout3<=dout2; end
實驗七
硬件電子琴實驗 一、實驗目的 學習利用蜂鳴器和按鍵設計硬件電子琴。
二、實驗容 在 SmartSOPC 實驗箱上實現一個簡易電子琴。按下 KEY1~KEY7 分別表示中音 DO、RE、MI、FA、SOL、LA、SI;按住 KEY8 再按 KEY1~KEY7 分別表示高音的 DO、RE、MI、FA、SOL、LA、SI。
三、實驗原理 樂曲演奏的原理是:由于組成樂曲的每個音符的頻率值(音調)及其持續時間(音長)是樂曲演奏的 2 個基本數據,因此需要控制輸出到揚聲器的激勵信號的頻率高低和該頻率信號持續的時間。頻率的高低決定了音調的高低,而樂曲的簡譜與各音名的頻率之間也有固定的對應關系。所有不同頻率的信號都是從同一基準頻率分頻而得來的,由于音階頻率多為非整數,而分頻系數又不能為小數,故必須將計算的到的分頻數進行四舍五入取整,基準頻率和分頻系數應綜合考慮加以選擇,從而保證音樂不會走調。如在 48MHz 時鐘下,中音 1(對應的頻率值為 523.3Hz)的分頻系數應該為:48000000/(2*523.3)=0xb327,這樣只需對系統時鐘進行 45863 次分頻即可得到所要的中音 1。至于其他音符,同樣可求出對應的分頻系數,這樣利用程序可以很輕松地得到對應的樂聲。
四、實驗步驟 1、在 Quarters II 中建立一個工程項目文件 beep1.qpf。并在該項目下新建 Verilog HDL 源程序文件 beep1.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
2、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
3、對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
4、將產生的 beep1.sof 輸出對 FPGA 進行配置。按下按鍵 KEY1~KEY8 就可以開始使用電子琴來演奏音樂了。
五、實驗程序 module beep1(clk,key,beep,led);
//模塊名稱 beep1
input clk;
//系統時鐘 48MHz
input[7:0]key;
//按鍵輸入 output beep;
//蜂鳴器輸出端
output[7:0]led;
//LED 輸出
reg beep_r;
//寄存器 reg[15:0]count,count_end; reg[7:0]key_r;
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
key_r = key;
//取鍵值
case(key_r)
8"b11111110:count_end = 16"hb327;
//中音 1 的分頻系數值
8"b11111101:count_end = 16"h9fa0;
//中音 2 的分頻系數值
8"b11111011:count_end = 16"h8e32;
//中音 3 的分頻系數值
8"b11110111:count_end = 16"h8637;
//中音 4 的分頻系數值
8"b11101111:count_end = 16"h7794;
//中音 5 的分頻系數值
8"b11011111:count_end = 16"h6a88;
//中音 6 的分頻系數值
8"b10111111:count_end = 16"h5ee8;
//中音 7 的分頻系數值
8"b01111110:count_end = 16"h59ab;
//高音 1 的分頻系數值
8"b01111101:count_end = 16"h4fce;
//高音 2 的分頻系數值
8"b01111011:count_end = 16"h471a;
//高音 3 的分頻系數值
8"b01110111:count_end = 16"h431c;
//高音 4 的分頻系數值
8"b01101111:count_end = 16"h3bca;
//高音 5 的分頻系數值
8"b01011111:count_end = 16"h3544;
//高音 6 的分頻系數值
8"b00111111:count_end = 16"h2f74;
//高音 7 的分頻系數值
default:count_end = 16"hffff;
endcase end
assign beep =beep_r;
//輸出音樂 assign led =key_r;
//輸出按鍵狀態 endmodule 六、思考題 舉例說明產生不同音符的原理。
實驗八
數字時鐘設計 一、實驗目的 學習數字時鐘的硬件設計。
二、實驗容 在 SmartSOPC 實驗箱上完成一個可以計時的數字時鐘,其顯示時間圍是00:00:00~23:59:59,,且該時鐘具有暫停計時和清零等功能。
三、實驗原理 一個完整的時鐘應由 3 部分組成:秒脈沖發生電路、計數顯示部分和時鐘調整部分。一個時鐘的準確與否主要取決于秒脈沖的精確度。為了保證時鐘計時準確我們對系統時鐘 48MHz 進行了 48000000 分頻,從而得到 1Hz 的秒脈沖。至于顯示部分與 LED 數碼管原理相同,而校時電路用戶可以自由發揮,如定義 3 個按鍵 keystart、keymon 和 keyadd,分別用于控制時鐘的計時開始、調整功能選擇和加 1 處理,從而完成對現在時間的調整。本實驗的校時電路在此僅僅完成了
暫停、清零等基本功能。
四、實驗步驟 1、在 Quarters II 中建立一個工程項目文件 clock.qpf。并在該項目下新建 Verilog HDL 源程序文件 clock.v,輸入程序代碼并保存,進行綜合編譯,若在編譯中發現錯誤,則找出并更正錯誤,直至編譯成功為止。
2、選擇目標器件并進行引腳鎖定。將未使用的管腳設置為三態輸入。
3、對該工程文件進行全程編譯處理。若在編譯過程中發現錯誤,則找出并更正錯誤,直到編譯成功為止。
4、將產生的 clock.sof 輸出對 FPGA 進行配置。觀察數碼管的顯示狀態。按下按鍵 KEY1、KEY2 觀察數字鐘上的時間有什么變化。
五、實驗程序 module clock(clk,key,dig,seg);
//模塊名 clock input clk;
//輸入時鐘 input[1:0] key;
//輸入按鍵 output[7:0] dig;
//數碼管選擇輸出引腳 output[7:0] seg;
//數碼管段輸出引腳
reg[7:0] seg_r;
//定義數碼管輸出寄存器 reg[7:0] dig_r;
//定義數碼管選擇輸出寄存器 reg[3:0] disp_dat;
//定義顯示數據寄存器 reg[24:0]count;
//定義計數寄存器 reg[23:0]hour;
//定義現在時刻寄存器 reg sec,keyen;
//定義標志位 reg[1:0]dout1,dout2,dout3;
//寄存器 wire[1:0]key_done;
//按鍵消抖輸出
assign dig = dig_r;
//輸出數碼管選擇 assign seg = seg_r;
//輸出數碼管譯碼結果
//秒信號產生部分 always (posedge clk)
//定義 clock 上升沿觸發 begin
count = count + 1"b1;
if(count == 25"d24000000)
//0.5S 到了嗎?
begin
count = 25"d0;
//計數器清零
sec = ~sec;
//置位秒標志
end end
//按鍵消抖處理部分 assign key_done = (dout1 | dout2 | dout3); //按鍵消抖輸出
always (posedge count[17]) begin
dout1 <= key;
dout2 <= dout1;
dout3 <= dout2;
end
always (negedge key_done[0]) begin
keyen = ~keyen;
//將琴鍵開關轉換為乒乓開關 end
//數碼管動態掃描顯示部分 always (posedge clk)
//count[17:15]大約 1ms 改變一次 begin
case(count[17:15])
//選擇掃描顯示數據
3"d0:disp_dat = hour[3:0];
//秒個位
3"d1:disp_dat = hour[7:4];
//秒十位
3"d2:disp_dat = 4"ha;
//顯示"-"
3"d3:disp_dat = hour[11:8];
//分個位
3"d4:disp_dat = hour[15:12];
//分十位
3"d5:disp_dat = 4"ha;
//顯示"-"
3"d6:disp_dat = hour[19:16];
//時個位
3"d7:disp_dat = hour[23:20];
//時十位
endcase
case(count[17:15])
//選擇數碼管顯示位
3"d0:dig_r = 8"b11111110;
//選擇第一個數碼管顯示
3"d1:dig_r = 8"b11111101;
//選擇第二個數碼管顯示
3"d2:dig_r = 8"b11111011;
//選擇第三個數碼管顯示
3"d3:dig_r = 8"b11110111;
//選擇第四個數碼管顯示
3"d4:dig_r = 8"b11101111;
//選擇第五個數碼管顯示
3"d5:dig_r = 8"b11011111;
//選擇第六個數碼管顯示
3"d6:dig_r = 8"b10111111;
//選擇第七個數碼管顯示
3"d7:dig_r = 8"b01111111;
//選擇第八個數碼管顯示
endcase
end
always (posedge clk) begin
case(disp_dat)
4"h0:seg_r = 8"hc0;
//顯示 0
4"h1:seg_r = 8"hf9;
//顯示 1
4"h2:seg_r = 8"ha4;
//顯示 2
4"h3:seg_r = 8"hb0;
//顯示 3
4"h4:seg_r = 8"h99;
//顯示 4
4"h5:seg_r = 8"h92;
//顯示 5
4"h6:seg_r = 8"h82;
//顯示 6
4"h7:seg_r = 8"hf8;
//顯示 7
4"h8:seg_r = 8"h80;
//顯示 8
4"h9:seg_r = 8"h90;
//顯示 9
4"ha:seg_r = 8"hbf;
//顯示-
default:seg_r = 8"hff;
//不顯示
endcase
if((count[17:15]== 3"d2)&sec)
seg_r = 8"hff; end
//計時處理部分 always (negedge sec or negedge key_done[1])//計時處理 begin
if(!key_done[1])
//是清零鍵嗎?
begin
hour = 24"h0;
//是,則清零
end
else if(!keyen)
begin
hour[3:0] = hour[3:0] + 1"b1;
//秒加 1
if(hour[3:0] == 4"ha)
begin
hour[3:0] = 4"h0;
hour[7:4] = hour[7:4] + 1"b1; //秒的十位加一
if(hour[7:4] == 4"h6)
begin
hour[7:4] = 4"h0;
hour[11:8] = hour[11:8] + 1"b1;//分個位加一
if(hour[11:8] == 4"ha)
begin
hour[11:8] = 4"h0;
hour[15:12] = hour[15:12] + 1"b1;//分十位加一
if(hour[15:12] == 4"h6)
begin
hour[15:12] = 4"h0;
hour[19:16] = hour[19:16] + 1"b1;//時個位加一
if(hour[19:16] == 4"ha)
begin
hour[19:16] = 4"h0;
hour[23:20] = hour[23:20] + 1"b1;//時十位加一
end
if(hour[23:16] == 8"h24)
hour[23:16] = 8"h0;
end
end
end
end
end end endmodule 六、思考題 1. 自己動手添加校時程序,寫出相應程序。
推薦訪問: 實驗 報告 技術上一篇:教學質量自查報告
同志們:今天這個大會,是市委全面落實黨要管黨、從嚴治黨要求的一項重大舉措,也是對縣市區委書記履行基層黨建工作第一責任人情況的一次集中檢閱,同時是對全市基層黨建工作的一次再部署、再落實的會議。前面,**
***年,我認真履行領班子、帶隊伍、抓黨員、保穩定的基層黨建工作思路,以學習貫徹習近平新時代中國特色社會主義思想和黨的十九大歷次全會精神為主線,以市局基層黨建工作考核細則為落腳點,落實全面從嚴治黨主體
根據會議安排,現將2022年履行抓基層黨建工作職責情況報告如下:一、履職工作特色和亮點1 突出政治建設,著力在思想認識上提高。牢固樹立抓黨建就是抓政績的理念,以“黨建工作抓引領、社區治理求突破,為民服
2022年以來,在**黨委的正確領導下,堅持以習近平新時代中國特色社會主義思想為指導,深入學習宣傳貫徹黨的二十大精神,以黨建工作為統領,扎實開展夯實“三個基本”活動,以“四化四力”行動為抓手,聚力創建
各位領導,同志們:根據會議安排,現就2022年度抓基層黨建工作情況匯報如下:一、主要做法及成效(一)強化政治引領。一是不斷強化理論武裝。堅持通過黨組會、中心組學習會和“三會一課”,第一時間、第一議題學
2022年度抓基層黨建工作述職報告按照黨委工作部署,現將本人2022年度抓基層黨建工作情況報告如下:一、2022年度抓基層黨建工作情況(一)旗幟鮮明講政治將旗幟鮮明講政治放在全局發展首要位置,積極開展
2022年,是我在數計系黨總支書記這個新崗位上度過的第一個完整的工作年度。回首一年來在校黨委的正確領導下,與數計系領導班子和全體師生共同走過的日子,艱辛歷歷在目,收獲溫潤心田。作為黨總支書記,我始終牢
按照考核要求,現將本人一年來,作為統戰部長履行職責、廉潔自律等方面情況報告如下:一、著眼增強政治素質,不斷深化理論學習堅持把旗幟鮮明講政治作為履職從政的第一位要求,帶領統戰系統干部堅決擁護“兩個確立”
**年,緊緊圍繞黨工委、管委會的決策部署,全體人員團結協作、凝心聚力,緊扣黨工委“**”基本工作思路,全力開拓進取,認真履職盡責,圓滿完成各項工作任務。一、個人思想政治狀況檸檬文苑www bgzjy
按照縣委關于開展抓基層黨建述職評議會議的有關要求,經請示縣委組織部同意,今天,我們在此召開2022年度基層黨組織書記抓基層黨建述職評議會議。1 首先,請**黨委書記,**同志述職。**黨委能夠主動研究