基于FPGA的搶答器設(shè)計(jì)與實(shí)現(xiàn)
圖7.程序流程圖
圖注: 顯示“FF+成績”中FF 表示無效狀態(tài),成績表示上一次搶答的那個小組的成績;顯示“FX+成績”表示搶答小組答題完并進(jìn)行評分操作后的組號和成績;顯示“XF+成績”表示違規(guī)搶答的那個小組組號及減1分后的成績信息(X 表示1,2,3)。這里“+”是為了區(qū)分組號和成績信息,數(shù)碼管并不顯示加號,下同。
用Verilog HDL 分別編寫各個模塊,然后在ISE 環(huán)境下運(yùn)行程序,調(diào)試成功。最后生成的頂層模塊的方塊圖如圖8 所示。
圖8.頂層模塊圖
圖注:Line(2:0)和row(2:0)分別表示參賽小組按鍵的輸入陣列信號和輸出掃描陣列信號;start_key,add_key, sub_key,分別代表搶答開始命令,對各組成績的加、減操作命令;dp,error,push_key 分別表示開始鍵按下后的信號,違規(guī)搶答信號以及參賽組有人按鍵的響應(yīng)信號;hc_cp,hc_si 表示顯示譯碼芯片74HC164 的串行時鐘和數(shù)據(jù)信號。
問題與解決
1、狀態(tài)機(jī)問題
在整體調(diào)試的時候,當(dāng)主持人按開始按鈕后,程序就死在那里,不能接收搶答信息,由于搶答鍵盤已單獨(dú)調(diào)試成功,因此懷疑是控制搶答過程的狀態(tài)機(jī)除了問題,指示進(jìn)入開始狀態(tài)的紅色LED燈一直亮著,說明程序的確死在開始狀態(tài)。再次綜合的過程中發(fā)現(xiàn)警告提示:狀態(tài)機(jī)的狀態(tài)量的賦值錯誤,把二進(jìn)制標(biāo)識“b”誤寫為“h”,這樣由于狀態(tài)機(jī)數(shù)據(jù)寬度小于時間數(shù)據(jù)數(shù)據(jù)長度,自動取較小位數(shù)據(jù);如state_start = 4‘b0010誤寫為state_start = 4’h0010,實(shí)際就是state_start = 4’b0000,這肯定與前面狀態(tài)沖突;同時調(diào)試過程中也遇到過復(fù)位時沒有把狀態(tài)機(jī)復(fù)位到初始狀態(tài)的情況。經(jīng)過此次設(shè)計(jì),體會認(rèn)識到狀態(tài)機(jī)在實(shí)際控制中的重要性,以后設(shè)計(jì)中要學(xué)會看綜合布線過程中警告信息。
2、信號同步的問題
在搶答器按下開始鍵后有一個等待搶答30s 的延遲時間,當(dāng)30s 完成后如果三個小組都沒有人按搶答鍵,那么此次比賽搶答無效,系統(tǒng)自動回到主持人按開始前的系統(tǒng)等待狀態(tài);當(dāng)計(jì)時完成30s 后生成一個高電平的脈沖信號(pulse),由于此脈沖信號高電平持續(xù)時間是整個系統(tǒng)的系統(tǒng)時鐘(clk),這個時鐘周期小于狀態(tài)機(jī)的時鐘周期(clk_4),直接用狀態(tài)機(jī)的時鐘是檢測不到此脈沖信號,需要把此脈沖信號同步到與狀態(tài)機(jī)時鐘同步。
采用的方法是:首先用一個鎖存器(pulse_reg)鎖存此脈沖信號(鎖存器時鐘也為系統(tǒng)時鐘),通過鎖存器的輸出值和原脈沖信號寄存器值就可以檢測到脈沖由低電平0 到高電平1 的跳變沿,同樣用一個與系統(tǒng)時鐘同步的鎖存器(flag)鎖存這個跳變沿,當(dāng)出現(xiàn)這個跳變沿時flag=1;而為了讓狀態(tài)機(jī)時鐘(clk_4)檢測到flag 信號,同時要在狀態(tài)機(jī)時鐘檢測到后要把flag 清零,為下一次檢測作準(zhǔn)備,這時可以當(dāng)狀態(tài)機(jī)時鐘(clk_4)檢測到flag=1’b1 后,同時生成一個flag的清零信號(flag_rst)flag_rst=1’b1;當(dāng)flag_rst 為1 時把flag 清零。
調(diào)試信號同步的部分程序如下:
reg flag_rst; //生成flag_rst 信號
always @ (posedge clk_4 or negedge rst_n)
begin
if(!rst_n)
begin
flag_rst = 1‘b0;
end
else
begin
if(flag == 1’b0)
flag_rst = 1‘b0;
else
begin
flag_rst = 1’b1;
end
end
end
always @ (posedge clk)
begin
pulse_reg = pulse;
end
reg flag; //flag 用來檢測pulse 上升沿
always @ (posedge clk)
begin
if(!rst_n)
flag = 1’b0;
else
begin
if((pulse_reg == 1‘b0)(pulse == 1’b1))
flag = 1‘b1;
else if(flag_rst == 1’b1)
flag = 1‘b0;
end
end
reg flag_reg; //生成與clk_4 同步的用于檢測脈沖上升沿信號的flag 信號
always @ (posedge clk_4)
begin
flag_reg = flag;
end
用modesim6.0 仿真波形如下:
圖9.信號的同步的仿真波形
從仿真波形中可以看出當(dāng)pulse 高電平時的下一個時鐘flag = 1’b1;為了讓時鐘clk_4 能夠檢測到flag = 1’b1,就讓flag 一直保存到clk_4 上升沿出現(xiàn),然后在clk_4 上升沿把flag 的復(fù)位信號flag_rst 置1;然后flag, flag_rst都清零。改變pulse 脈沖出現(xiàn)的時間或者clk_4 的頻率都能檢測到pulse 的高電平。經(jīng)過信號同步后,狀態(tài)機(jī)能夠檢測搶答計(jì)時完30s 后生成的一個脈沖信號然后回到初狀態(tài)。
時序設(shè)計(jì)是數(shù)字電路電路的主要工作,在設(shè)計(jì)中一定要明白信號如何傳遞,在何時賦值,何時信號值需要改變等,這樣才能更好的設(shè)計(jì)。在需要改變寄存器值的時刻沒有對寄存器進(jìn)行操作,會造成結(jié)果的錯誤。
設(shè)計(jì)結(jié)果
根據(jù)搶答器功能要求,規(guī)劃程序包括的子模塊,并編寫Verilog 代碼,在硬件電路上調(diào)試運(yùn)行成功。
操作過程:開始時對,整個系統(tǒng)復(fù)位(默認(rèn)每組成績?yōu)?0 分),數(shù)碼管顯示“FF+10”。在主持人發(fā)出開始搶答的Start 之后,參賽隊(duì)員就可以按自己前面的搶答按鈕,同時用數(shù)碼管左邊兩位計(jì)時搶答時間30s,如果在30s 內(nèi)各組都無人搶答,則此次搶答無效,系統(tǒng)自動回到開始前的初狀態(tài)(數(shù)碼管顯示“FF+成績”),等待下一次操作;主持人可根據(jù)回答爭取與否,以及是否違規(guī)搶答,決定加減分(Add 為加分控制,Sub 為減分控制),加減操作后系統(tǒng)又回到開始前的等待狀態(tài)。設(shè)計(jì)中,哪個組搶答,就顯示哪個組的信息。如果搶答沒有違規(guī)(按開始后搶答)則顯示器左邊兩位顯示“FX”;反之,則顯示“XF”,X 代表組號1,2,3。按照操作方法,以第1 組搶答為例在VX_SP306 開發(fā)平臺上運(yùn)行看看數(shù)碼管顯示及整個過程:
1、在系統(tǒng)復(fù)位后顯示“FF+10”;
2、等待主持人按開始狀態(tài);
3、主持人按開始按鈕前第1 組搶答,顯示“1F+10”,減1 分操作后顯示“1F+09”;回到步驟2;
4、主持人按開始按鈕后,顯示“30+10”;30 每秒鐘減1 直到00;
5、在30s 內(nèi)第1 組搶答,顯示“F1+10”,主持人根據(jù)回答情況進(jìn)行加、減分操作,顯示“F1+分?jǐn)?shù)”;然后回到步驟2;
6、如果在30s 內(nèi)沒有人搶答,顯示“FF+10”,回到步驟2。
fpga相關(guān)文章:fpga是什么
蜂鳴器相關(guān)文章:蜂鳴器原理
評論