(转载)FPGA基础知识------PS/2基础知识
本篇博客轉(zhuǎn)載來源于http://www.cnblogs.com/kingst/,僅供學(xué)習(xí)。
3.2 實驗八:PS2解碼
PS2的簡單認(rèn)識
在以前使用單片機對PS2進(jìn)行解碼的時候,一句話就是苦。 如果是CPLD 或者 FPGA 的前提下,PS2的解碼才有意義。
PS2的接口如上圖,除了Pin 5 和 Pin 1 其他的引腳對解碼沒有什么意義。而下圖是PS2協(xié)議的時序圖。PS2協(xié)議對數(shù)據(jù)的移位是“Clock 的下降沿”有效。PS2時鐘的頻率比較慢,大約是10Khz左右。
第N位
屬性
0
開始位
1~8
數(shù)據(jù)位
9
校驗位
10
結(jié)束位
PS2的一幀是11位。對PS2進(jìn)行解碼時,除了第1~8位數(shù)據(jù)位以外,其余的位都可以無視。
對編碼鍵盤“鍵盤碼”的簡單認(rèn)識
普通計算機采用的都是“編碼鍵盤”,但是“編碼鍵盤”的“編碼方式”有分為“第一套”“第二套”和“第三套”。“第二套”的編碼使用較為普遍,大致上的民用鍵盤都是采用“第二套”編碼方式。
鍵盤的編碼有“通碼”(Make)和“斷碼”(Break)之分。看得簡單一點就是,“通碼”是某按鍵的“按下事件”,“斷碼”是某按鍵的“釋放事件”。
假設(shè),我按下“W”鍵不放,每秒大約會輸出10個“0x1d”的“通碼”。然后我釋放“W”鍵,就會輸出 “0xF0 0x1d” 的“斷碼”。 編碼鍵盤還有一個老規(guī)則,就是一次只有一個輸出。
再假設(shè)我按下“W”鍵不放,然后我再按下“X”鍵不放,那么會輸出“0x1d”“0x22”“0x22”........ 的通碼。如果此時我放開“X”鍵,就會輸出“0xf0 0x22”的“斷碼”,此時“W”鍵的“通碼”已經(jīng)無效。但是當(dāng)我釋放“W”鍵的時候,依然會輸出“0xf0 0x1d”, “W”鍵的“斷碼”。
至于組合鍵 “ Shift + ?” ,“ Ctrl + ?”都是軟件的工作,我們就無視吧。
實驗八源碼:
實驗八的目的很簡單,實驗主要對PS2進(jìn)行解碼,然后對“通碼”進(jìn)行判斷,然而對 “斷碼”采取忽略的行為。
在組合模塊 ps2_module.v 中包含了兩個功能塊: “電平檢測模塊” detect_module.v 和 "ps2解碼模塊" ps2_decode_module 。detect_module.v 的添加時為了檢查 PS2 時鐘信號的“下降沿”,此外也是為了使模塊的建立更簡單。ps2_decode_module.v 如字面上的意思,對每幀(十一位一組數(shù)據(jù))的數(shù)據(jù)進(jìn)行解碼和過濾的行為,最后將一字節(jié)數(shù)據(jù)輸出 PS2_Data,然后 PS2_Done_Sig 產(chǎn)生一個高脈沖,表示完成一次性的操作。
3.2.1 detect_module.v
嗯!這個功能模塊的解釋可以參考實驗實驗三。
3.2.2 ps2_decode_module
ps2_decode_module.v 最主要的核心是在第31~55行。同樣這個模塊也是采用“仿順序操作”的寫法。步驟i一開始會停留在0(33行),當(dāng)檢查到 H2L_Sig 的變化,我們知道PS2一幀數(shù)據(jù)的第第0位是開始位,所以無視。在接下來的8個位都是數(shù)據(jù)位,PS2的數(shù)據(jù)位是從最低位開始,最高位結(jié)束。然后對 PS2_Data_Pin_In 引腳進(jìn)行讀值(第36~37行)。
PS2一幀數(shù)據(jù)的第9~10位是校驗位和結(jié)束位,執(zhí)行無視操作(39~40行)。在 i 等于 11的時候(42行),我們要進(jìn)行判斷,讀取的“數(shù)據(jù)是通碼還是斷碼?”,如果是“通碼”(44行),就進(jìn)入49行隨后產(chǎn)生一個高脈沖的完成信號(49~53行),最后返回33行,等待下一次的操作。
如果是“斷碼”(43行),進(jìn)入46行隨后對“斷碼”采取無視的操作(46~47行),最后產(chǎn)生一個高脈沖的完成信號,然后返回第33行(49~53行)。
3.2.3 ps2_module
實驗八說明 :
實驗八的PS2解碼僅對“通碼”執(zhí)行操作,相反卻對“斷碼”采取無視的行為。實驗八的重點主要是如何實現(xiàn)“PS2時鐘采樣”和“PS2數(shù)據(jù)采樣”操作?
從上圖中我們可以看到,黑金的時鐘頻率比起PS2的時鐘頻率,大約是2000倍。而 detect_module.v 就是利用這2000個時鐘信號去采集每個PS2時鐘的下降沿(小箭頭)。
當(dāng)detect_module.v 檢測到ps2時鐘產(chǎn)生下降沿,(detect_module.v 32行)由于布爾的表達(dá)式關(guān)系,就會產(chǎn)生一個高脈沖經(jīng)H2L_Sig 信號。PS2協(xié)議的一幀數(shù)據(jù)大約是11個數(shù)據(jù)位,換句話說就會產(chǎn)生11個下降沿,也就是說會產(chǎn)生11次高脈沖的H2L_Sig。
PS2時鐘在每一個下降沿的時候,PS2數(shù)據(jù)就會“設(shè)置”(移位)數(shù)據(jù),而 ps2_decode_module.v 中的 31~55行,就是對PS2數(shù)據(jù)的移位進(jìn)行“數(shù)據(jù)采樣”。假設(shè)PS2時鐘在第一次的下降沿,自然而然PS2數(shù)據(jù)會“設(shè)置”第0位數(shù)據(jù)( ps2_decode_module.v 34行 ),ps2_decode_module.v 采取無視的操作,接下來的八位數(shù)據(jù)位才是真正需要的數(shù)據(jù)位。
有一點比較值得注意的是在 ps2_decode_module.v 第42~44行。從上面我們知道,黑金的時鐘頻率對ps2的時鐘頻率有 2000倍的相差,從另一個角度去理解的話,距離每一次PS2時鐘信號的下降沿,黑金擁有2000個可以執(zhí)行的時間。然而在第42~44行只用了一個時間去判斷,余下還剩下1999個可空閑的時間。
也就是說,采樣和被采樣的頻率如果相差越大,采樣方可執(zhí)行的空余的時間就越多,在設(shè)計上就越輕松。
完成擴展圖:
實驗八結(jié)論 :
實驗八總歸也就是屬于PS2解碼的部分。然而筆者在設(shè)計上,對 ps2_detect_module.v 添加了 PS2_Done_Sig, 這個信號無疑是表示了 “一次性操作”已經(jīng)完成的次數(shù)。因為編碼的鍵盤,只要按著不放就會一直發(fā)送“通碼”,如果筆者針對“通碼”去設(shè)計的話,筆者永遠(yuǎn)“只能得到鍵盤的數(shù)據(jù)”,已不是“通碼”和“次數(shù)”這兩方。
實驗八演示:
實驗八演示中的“命令控制模塊”cmd_control_module.v 會對“W”,“X”和“Ctrl”鍵作出反應(yīng)。在 cmd_control_module.v 的輸出是4位的信號,初始值是4'b0001。當(dāng)“W”鍵按下,就會產(chǎn)生左移的效果,“X”鍵則是右移。至于“Ctrl”鍵會產(chǎn)生“互換”。
第16~35行是 cmd_control_module.v 的核心部分,當(dāng)PS2_Done_Sig 產(chǎn)生高脈沖(23行),該控制模塊就會對 PS2_Data 產(chǎn)生反應(yīng)。8'h1d 是“W”鍵的通碼,而 8'h22 是“X”鍵的通碼,至于 8'h14 是“Ctrl”鍵的通碼。
“W”鍵,產(chǎn)生左移效果(26~27行),
“X”鍵,產(chǎn)生右移效果(29~30行),
“Ctrl”鍵,產(chǎn)生互換效果(32~33行)。
exp08_demo.v 是 ps2_module 和 cmd_control_module.v 的組合模塊。ps2_module.v 的具體介紹請參考實驗七。
實驗八演示說明:
在 cmd_control_module.v 中的第23行,PS2_Done_Sig 很有效被利用來控制執(zhí)行的次數(shù)。而且cmd_control_module.v 僅對 “W”“X”“Ctrl”鍵的“通碼”產(chǎn)生反應(yīng)而已,換一句話說,cmd_control_module.v 只會在以上三個鍵在“按下”或者“按下不放”才會有所反應(yīng)。
完成擴展圖:
實驗八演示結(jié)論:
我以前接觸過很多有關(guān) PS2的解碼實驗,都非常執(zhí)著與“字符”有關(guān)。其實無論是什么輸出,只要有效的利用“通碼”就不成問題。最重要的是如何編輯這些“通碼”稱為有效的“命令”!?
還有另一點,編碼鍵盤雖然很方便,但是編碼鍵盤是無法取代獨立鍵盤。在實驗八演示中,在兩個鍵同時按下的時候,僅有按下最遲的一方才有輸出“通碼”的權(quán)利。相反獨立按鍵是完全“并行”執(zhí)行, 不會出現(xiàn)對輸出爭先恐后的事件。所以在許多方面編碼鍵盤還是不完美。
最后還有一點,就是所有擁有PS2接口的設(shè)備,一般上都是“低速”設(shè)備,這一點要好好的記住。
實驗八總結(jié):
實驗八主要是表達(dá)“低級建模”在“讀取”或者“采樣”上發(fā)揮的效果。在眾多同樣的試驗中,筆者常常可以看到所有模塊都是往一個 .v 文件里面寫,雖然在編輯上會很方便,但是在“理解的方式上”,“理解的形狀上”又是怎么一回事?
同樣的,實驗八和實驗七建模的數(shù)量都是不相上下,或者可以說這是“低級建模”的普遍缺點,但是讀者是不是會察覺到?當(dāng)你在組合模塊,將一個一個模塊實例化,思路無比是清晰,而且設(shè)計的工作也容易?
好吧,換另一個話題去討論實驗八的重點:
always @ ( posedge CLK )
......
always @ ( posedge CLK )
......
如上面的代碼,在同樣一個模塊中出現(xiàn)了兩個always 塊,在一般的情況下,我們都會“從上往下”讀,類似順序操作那樣看待。如果你的理解能力好,或者已經(jīng)習(xí)慣了,那么這事兒不成問題。但是在實際的操作中,所有 always塊都是“并行”執(zhí)行者,很多新手都會被自身的“假概念”誤導(dǎo)。如果將上述的問題反映在建模上,往往會使更多新手進(jìn)入瓶頸。
就像在第二章的實驗,筆記一直在強調(diào)“并行”的概念和重要性。“低級建模”的多模塊設(shè)計無疑是能很好的發(fā)揮“并行”的概念。如實驗八演示中,detect_module.v,ps2_decode_module.v,cmd_control_module.v ,它們在每一個時鐘的上升都是在獨立工作著。至于它們會不會被觸發(fā)或者協(xié)調(diào)執(zhí)行,完全是依賴自身早已被設(shè)定好的功能。
detect_module.v 在每一個時鐘源的上升沿(posedge CLK),如果檢測到 PS2時鐘發(fā)生下降沿,就會經(jīng) H2L_Sig 產(chǎn)生高脈沖,除此之外它的工作就結(jié)束了。
然而 ps2_decode_module.v 在每一個時鐘源的上升沿(posedge CLK),如果檢測到 H2L_Sig 的高脈沖,就會對 PS2數(shù)據(jù)一幀數(shù)據(jù)的執(zhí)行采集和過濾的動作,最后將完整的數(shù)據(jù)輸出至 PS2_Data, 然后 PS2_Done_Sig 產(chǎn)生一個時鐘的高脈沖,它就完工了。
cmd_control_module.v 在每一個時鐘源的上升沿(posedge CLK),如果被PS2_Done_Sig 觸發(fā),那么它就會依據(jù) PS2_Data 的數(shù)據(jù)作出相對的反應(yīng),否則它就一直保持沉默。
雖然整體的主觀上,它們會如同連線關(guān)系一方接著觸發(fā)著一方。但是實際上,每一個模塊都保持者獨立關(guān)系,只有在“觸發(fā)”的時候才工作。當(dāng)然“低級建模”所強調(diào)的準(zhǔn)則不僅是重視在“并行”的理解上,還有好多好多的故事會發(fā)生在這本筆記的后面。
轉(zhuǎn)載于:https://www.cnblogs.com/yingfang18/archive/2010/12/05/1897071.html
總結(jié)
以上是生活随笔為你收集整理的(转载)FPGA基础知识------PS/2基础知识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何开展灰盒测试[1]:灰盒测试优缺点分
- 下一篇: 智能卡中的数据结构