日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--蜂鸣器封装(十七)

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【连载】【FPGA黑金开发板】Verilog HDL那些事儿--蜂鸣器封装(十七) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

聲明:本文轉載于http://www.cnblogs.com/kingst,版權歸akuei2及黑金動力社區(http://www.heijin.org)共同所有。

5.3?實驗十六:蜂鳴器封裝

當讀者看到這章,不要笑出來,筆者連蜂鳴器也不放過,蜂鳴器也逃不過封裝的命運。

在前面(5.15.2)的試驗中,無論是獨立鍵盤,還是數碼管,它們都有自己的考慮,如:獨立按鍵必須消抖,數碼管有掃描的規則?...

?

?

?

那么蜂鳴器要干什么!它這家伙那么單調,只要拉低電平,這家伙就會被驅動了。既然蜂鳴器那么單調,我們就要它不單調,那怎么不單調法呢?很簡單,就是在蜂鳴器的封裝中,為它加入“功能”。蜂鳴器應該加入什么功能?就加入產生S摩斯碼和O模式碼的功能吧。

?

?

?

我們利用4.3章的“命令式仿順序操作”的方法來建立它的功能模塊。(請稍微復習一下)

?

?

?

?

?

?

?

?

?

?

?

?

如上圖。等等!這就不是一個模塊嗎!?封裝?等于?建立模塊!?那么問題來了“模塊”和“接口”本質上到底有什么的不同呢?在這里我們需要重新為“接口”加入一個“新的定義”。?

?

?

?

5.15.2章中,我們定義了“接口”是“最后的工程”,不錯“封裝”卻是針對某個資源的最后建模工程。但是讀者有沒有發現,起始在5.1??5.2?章還包含著一個信息?

那就是“接口都是獨立性”這一個事實。

?

?

?

如果從另一個角度去理解“接口”,你可以把它看成是一個“部門”這樣的存在。在現實中我們知道“部門和部門之間”都市獨立性,而且每一個部門都是有內部的操作。那么如果要把這個觀點放入“蜂鳴器的封裝”里邊,又應該如何實現呢?

?

?

?

?

?

?

在這里我們就需要用到“FIFO”。顧名思義?FIFO?就是“先入先讀”的意思。但是在宏觀來看FIFO是雙向口的RAMFIFO可分為兩方,“左方是寫”和“右方是讀”。然后經過一些內部加工,讀和寫可以在同時發生。?

?

?

?

FIFO的被需要時絕對有目的的。我們重新復習一下仿順序操作的概念。當某一個下層被使能時(Start_Sig?等于1),上一層模塊就必須等待下層模塊直到完成工作,才能執行下一個操作。為了避免上述的內容,我們必須借用FIFO的力量。

我們可以嘗試這樣想“如果我把操作信息全部緩沖到FIFO里的話?...”,那么上一層的模塊可以將全部操作信息緩沖到?FIFO里面,就可以擺脫“反饋信息”的“束縛”。這話怎么講呢?每當下一層模塊完成工作以后,可以直接從FIFO里面讀取操作信息,而不必依賴上一層模塊所下達的操作指令。

?

?

?

?

?

?

如果以“圖形”來表示,那么結果會是如圖上。上圖大致的操作如下:

?

?

?

(一)首先上一層模塊可以往FIFO里邊寫入大量的操作信息。然后上一層模塊可以執行其他的操作,而不必在乎“反饋信息”。

(二)FIFO里面存在信息,控制模塊會從FIFO里面讀取信息。信息被過濾以后,轉換為執行命令,故啟動功能模塊。

(三)功能模很快便開始工作,直到工作結束,并且反饋完成信息給控制模塊。

(四)當控制模塊接收到從功能模塊反饋回來的完成信息,會再度從FIFO讀取信息,重復上述一樣的動作,直到FIFO里面的信息全部讀取完畢。

?

?

?

估計筆者們都對FIFO不怎么熟悉吧(筆者也是),那么我們就稍微的來理解一下FIFO的時序和操作:

?

?

?

(時間上升沿有效)

?

?

?

上圖是8個深度的FIFO。在FIFO初始化的時候?wr_en_a_0拉高,然而Wr_data_a_0??wr_level_0?都呈現?“32”?的信息?。但是在第二個時鐘的時候,?信息1就被存入深度1。第三個時鐘信息2存入深度2。直到第七個時鐘,當寫入信息6到深度6的時候,FIFO的狀態反應出“忙”,故此拉高?wr_full_0?信號,在同一個時間?we_en_a_0?被拉低。在第九個時鐘?wr_en_a0?拉高,信息8被寫入深度7。由于FIFO出現飽和狀態,所以拉高?wr_full_0信號。

?

?

在上述的內容中,我們發現在初始化的時候FIFO的深度0是用來預備初始化信息。然而在第九個時鐘的時候,基本上?FIFO已經飽和了。因此FIFO沒有理由再往里面寫入信息了,多以拉高?wr_en_a0?也沒有任何意義。

?

?

?

// wr_en?寫使能,?wr_data?寫數據,?wr_full?寫飽和。

?

?

?

?

下圖是FIFO讀數據的時序圖:

?

?

?

?

(時間上升沿有效)

?

?

在初始化的時候?rd_data_b_0?呈現初始化信息“32”。在第二個時間中,從FIFO的深度7讀出信息1。在第三個時間中,從深度6讀出信息2。直到第八個時間從深度1讀出信息8以后,FIFO反應出“FIFO沒有信息了”,所以就拉高?rd_empty_0?信號。

?

?

?

?

// rd_en?讀使能,?rd_data?讀數據,?rd_empty?讀空置。

?

?

?

?

上述FIFO讀寫內容的大致“圖形”如下:

?

?

?

?

?

?

在時序圖上分析FIFO看似很輕松,實際上FIFO的調用也挺別扭的。信息會發生“被卡現象”。?

?

?

?

?

?

?

?

上圖?beep_interface.v?組合模塊中:

?

?

?

(一)FIFO擁有16個深度。

?

?

?

(二)蜂鳴器控制模塊的主要功能是從FIFO讀入一個信息經FIFO_Read_Data,?蜂鳴器控制模塊,根據從FIFO讀取的信息來使能“蜂鳴器功能模塊”;

?

?

在這一章的實驗中“蜂鳴器功能模塊”只包含兩個功能:就是產生S摩斯碼和O摩斯碼。

?

所以?Command_Sig?或者?Function_Start_Sig?都是2個位寬。

?

?

?

Function_Start_Sig = 2'b10

產生S摩斯碼

Function_Start_Sig = 2'b01

產生O模式嗎

?

?

?

整個?beep_interface.v?說穿了就是“如何調用FIFO”而已,??FIFO?的信號有?:

?

?

?

(一)Write_Req_Sig?等價于?write_en ;

(二)Read_Req_Sig?等價于?read_en ;

(三)Full_Sig?等價于?write_full ;

(四)Empty_SIg?等價于?read_empty ;

(五)FIFO_Write_Data?等價于?write_data ;

(六)FIFO_Read_Data?等價于?read_data ;

?

?

?

那么這個?beep_interface.v?具體是如何運作還是直接看代碼好。

?

beep_function_module.v

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

5行中的[1:0]Start_Sig?表示了該功能模塊包含了兩個功能。11~40行是1ms定時器到1秒計數器。57~74行是S摩斯碼的產生,反之75~92行是O摩斯碼的產生。在97行,由于在實際資源,蜂鳴器的控制只掛著PNP三極管,rPin_Out的輸出必須取反。

?

?

beep_control_module.v

?

?

?

?

?

?

?

?

?

?

?

?

17~31行是“加碼操作”的部分,23行會判斷經FIFO_Read_Data?讀來的信息,將它加碼為特定的命令。如通碼S1B”加碼為命令“2'b10”(25行),通碼O44”加碼為命令“2'b01”(26行)。然后將轉換后的命令,暫存在rCmd寄存器。但是前提必須在步驟i等于1的時候才能執行(22行),和步驟i等于5的時候清零rCmd寄存器。為什么呢?

?

?

?

35~70行是該控制模塊的核心部分。在50行,步驟0先判斷FIFO是否為空,如果FIFO不是為空?Empty_Sig?信號就被拉低。如果FIFO不為空?if?條件成立,i遞增以示下一步步驟。

?

?

?

52~56行是讀FIFO的操作,在這里我先簡單的介紹一下。在前面的?FIFO?時序圖中,當FIFO為讀狀態,如果??Read_Reg_Sig ( read_en )?不拉高,就無法把數據讀出來。FIFO讀數據是根據每一個時鐘的上升沿,如果?Read_Reg_Sig?read_en?)拉高,那么在這一個上升沿中,數據就會被讀出來。換句話說,我們可以利用?Read_Reg_Sig?來充當讀取數據的“鎖匙”。?

?

?

?

1begin isRead <= 1'b1; i <= i + 1'b1; end

2begin isRead <= 1'b0; i <= i + 1'b1; end

?

?

?

如上的步驟12表示從FIFO讀取“一個深度的數據”。

?

?

?

52~56行正是如上的操作。在53行將?isRead?拉高,從FIFO讀取數據。在讀入FIFO數據的一瞬間,“加碼操作”發生了(22行),“加碼成功的數據”會暫存在rCmd寄存器里。然后在56行將?isRead?拉低,為此我們已經完成“從FIFO讀取數據,然后加碼成功”。

?

?

?

在步驟358行先判斷?rCmd的值是否為8'h00,如果?rCmd的我值為?8'h00表示這不是我們要的命令,然后步驟i清理,返回開始。如果?rCmd的值不是?8'h00?的話,i遞增以示下一步步驟。

?

?

?

在步驟464行是使能?beep_function_module.v?的工作。isStart是作為?Function_Start_Sig?的驅動(75行)。加入我從FIFO讀取的信息是?8'h1B,那么它會被加碼為?2'b10?,亦即執行“S摩斯碼產生”的命令。接下來的工作就和“仿順序操作一樣”,直到下一層模塊反饋完成信號,isStart會被清理?(63)i遞增以示下一個步驟。

?

?

?

步驟566~67行)多出來是用來清零rCmd寄存器的(30行)。如果不清零?rCmd寄存器后果會很麻煩。最后i清零,以示返回開始。

?

?

?

beep_interface.v

?

?

?

?

?

?

?

?

?

?

?

?

beep_interface.v?組合模塊的結果和“圖形”一樣。自己看著辦吧。

?

?

?

實驗十六說明:

實驗十六的重點,就是“如何對FIFO讀取”而已。其余的建模部分都是以往實驗的復習。

?

?

?

完成擴展圖:

?

?

?

?

?

?

實驗十六結論:

在某種程度來說,實驗十六的蜂鳴器接口,標準操作信息是“鍵盤通碼”。

實驗十六演示:

?

?

?

在上圖的組合模塊中,控制模塊對蜂鳴器接口寫入“8'h1B, 8'h44, 8'h1B”這三個信息,然后就停止操作。接著,蜂鳴器接口卻會發出“SOS信號”實際上對蜂鳴器接口的調用就是“如何對FIFO寫入信息”這一回事。

?

?

?

beep_interface_demo.v

?

?

?

?

?

?

?

?

?

這份源碼有分為兩種對FIFO寫入的辦法。

?

?

?

辦法一:

?

?

?

在拉高?isWrite?的三個時間內,同時寫入3份信息。然后再追加寫入一份?8'h00以使得達到強制擠出的效果。寫完后拉低isWrite,以示一次性的寫入操作已經結束(29~41行)。

?

?

?

辦法二:

?

?

?

辦法比較傻瓜,但是解讀性卻很好。把?isWrite?當著寫入數據的鑰匙。在拉高?isWrite?的同時寫入數據,然后在下一個步驟拉低?isWrite?以示一次性的寫數據操作已經完成。(44~60行)。

?

?

?

如果給筆者選擇,筆者會選擇辦法二。原因是辦法二比較“和藹可親”。還有一點,就是Full_Sig?這個信號是從?beep_interface.v?反饋出有關FIFO的空間狀態。如果Full_Sig?被拉高,亦即?beep_interface.v?中的?FIFO?全部?16個深度?空間已經被寫滿了。所以每一次要向?beep_interface.v?寫入信息的時候,必須判斷?Full_Sig?是否是被拉高的狀態(475359行)。第65行寫入8'h00追加信息,以使得達到強制擠出的效果。

實驗十六演示說明:

在這個演示中是“beep_interface.v?如何調用”等于“FIFO如何寫入”這一回事。

?

?

?

為什么在?beep_interface_demo.v?中,當寫入?3個信息至?FIFO以后,還將無相關的?8'h00?信息寫入呢?原因很簡單,8'h00信息用來擠出前3個信息中的最后一個。如果不把第三個信息擠出,它就會卡在FIFO里邊。

?

?

?

為什么在FIFO里邊的第3個信息,如果不把它擠出,就會發生被卡現象?這個筆者也說不清楚,只是實驗結果如此?......

?

?

?

實驗十六演示結論:

?

?

?

在這一章中我們明白到,“接口”的定義除了“最后的工程”以外還有“接口是獨立”這一個定義。實際上FIFO是用來緩沖兩個時間域不同的訪問,在某種程度上“數據緩沖”的作用有如“倉庫”。所以我們可以利用這個“倉庫”作為“接口的輸入”,以致“接口”有獨立性的作用。

?

?

?

所以呀,當上一層模塊調用某個“接口”時,只要把“信息”寫入“倉庫”即可,上一層模塊用不著與該接口“互動”而被“束縛著”。該接口如果發現“倉庫”有信息,就處理信息,如果“倉庫”里沒有信息就作罷。


總結

以上是生活随笔為你收集整理的【连载】【FPGA黑金开发板】Verilog HDL那些事儿--蜂鸣器封装(十七)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。