版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章“計算機組成原理”課程練習7.1一個簡單的計算機系統(tǒng)7.2程序控制輸入/輸出7.3子程序與堆棧7.4輪詢與中斷7.5總線通信7.1一個簡單的計算機系統(tǒng)7.1.1建立一個簡單的計算機系統(tǒng)在本練習中,我們使用SOPCBuilder建立一個如圖7.1所示的系統(tǒng),這個系統(tǒng)由一個NiosⅡ/e處理器和一個片上存儲器塊組成,NiosⅡ/e處理器用來處理數(shù)據(jù),存儲器塊用來保存指令和數(shù)據(jù)。請按照以下步驟實現(xiàn)如圖7.1所示的NiosⅡ系統(tǒng):
(1)新建一個QuartusⅡ工程,選擇CycloneⅡEP2C35F672C6作為目標器件,這個器件是AlteraDE2平臺上采用的器件。
(2)使用SOPCBuilder建立一個名為nios_system的系統(tǒng),系統(tǒng)中包括以下部件:①帶JTAGDebugModuleLevel1的NiosⅡ/e處理器。②RAM模式、32位寬、32K字節(jié)深度的On-ChipMemory。
(3)從System菜單中選擇Auto-AssignBaseAddresses,自動分配系統(tǒng)中部件的基地址,得到如圖7.1所示的系統(tǒng)。
(4)生成系統(tǒng)后退出SOPCBuidler并返回QuartusⅡ軟件。
(5)在Verilog/VHDL模塊中例化生成的NiosⅡ系統(tǒng)。
(6)分配引腳如下:①clk-PIN_N2(50MHz時鐘輸入)。②reset_n-PIN_G26(AlteraDE2平臺上的按鍵KEY0)。
(7)編譯QuartusⅡ工程。
(8)下載并配置DE2上的CycloneⅡ系列FPGA以實現(xiàn)生成的系統(tǒng)。使用這個系統(tǒng)前,還必須為處理器提供可供執(zhí)行的程序,圖7.1SOPCBuilder中的NiosII系統(tǒng)7.1.2對序列中出現(xiàn)的連續(xù)的1計數(shù)在數(shù)字計算機中,所有的數(shù)據(jù)都是按0和1的序列出現(xiàn)的。代碼7.1所列的NiosⅡ匯編語言代碼用以測試一串二進制數(shù)據(jù)中連續(xù)出現(xiàn)的1的最大長度。例如0x937a(1001001101111010)中最多有4個1連續(xù)出現(xiàn)(粗體部分)。代碼7.1用于計算數(shù)據(jù)0x90abcdef中連續(xù)出現(xiàn)1的最大長度。代碼7.1計算數(shù)據(jù)0x90abcdef中連續(xù)出現(xiàn)1的最大長度。.include"nios_macros.s".text.equTEST_NUM,0x90abcdef /*接受測試的數(shù)據(jù)*/.global_start_start:movia r7,TEST_NUM /*用r7初始化被測試的數(shù)據(jù)*/ mov r4,r7 /*將數(shù)據(jù)復制到r4*/STRING_COUNTER: mov r2,r0 /*初始化計數(shù)器*/STRING_COUNTER_LOOP: /*循環(huán)直至r4中沒有1*/ beq r4,r0,END_STRING_COUNTER srli r5,r4,0x01 /*通過移位并將移位結(jié)果與自身相與來計算1的數(shù)量*/ and r4,r4,r5 addi r2,r2,0x0001 /*計數(shù)器加1*/ br STRING_COUNTER_LOOPEND_STRING_COUNTER: mov r16,r2 /*將結(jié)果保存在r16中*/END: br END /*程序結(jié)束*/.end請參照以下步驟編譯并執(zhí)行代碼7.1:
(1)打開AlteraDebugClient,并用7.1.1小節(jié)中生成的系統(tǒng)及代碼7.1所示的應用程序配置AlteraDebugClient。
(2)編譯并裝載該程序。
(3)單步執(zhí)行完該程序,觀察指令是如何改變處理器的寄存器值的,當程序執(zhí)行結(jié)束之后,寄存器r16的值應該為4。
(4)將程序計數(shù)器(ProgramCounter)設(shè)為0x00000008,以此來跳過剛開始的兩條指令重新執(zhí)行程序。
(5)在地址0x28設(shè)置一個斷點,這樣程序執(zhí)行完后會自動停止。
(6)將r7設(shè)為0xabcdef90,按F3(繼續(xù)運行)重新運行程序,檢驗運行結(jié)果是否正確。7.1.3指令的組成與數(shù)據(jù)一樣,指令也是由1和0組成的二進制序列。本練習主要考查指令是如何組成的。請參照以下步驟完成練習:
(1)在AlteraDebugClient中選擇Actions>Load,重新裝載程序,以清除7.1.2小節(jié)中對存儲器內(nèi)容的修改,重新執(zhí)行一遍程序,結(jié)束后停下來。
(2)從Altera的網(wǎng)站上下載NiosⅡProcessorReferenceHandbook,光盤的Documents目錄下也包含了這個手冊,用該手冊確定andr3,?r7,?r6和srar7,?r7,?r3兩句代碼的機器指令表示。
(3)使用AlteraDebugClient的memory-fill功能將這兩個指令放在0和4的位置,我們會注意到在DebugClient的反匯編視圖中看不到這些更新后的值。
(4)將程序計數(shù)器設(shè)為0x00000000,這個時候會發(fā)生什么呢?先想一想,然后再驗證答案,先單步執(zhí)行放在地址0和地址4的指令(查看是否已經(jīng)生效),然后執(zhí)行其他代碼。
(5)使用memory-fill功能修改最后一個分支指令,使之指向程序的開始而不是本身,這樣就不需要手工修改程序計數(shù)器了。
(6)返回程序,直至1的數(shù)量及被測試的數(shù)據(jù)變?yōu)槌?shù)。
(7)用指令srl47,?r7,?r3替代srar7,?r7,?r3,重復步驟(1)~(6),看看有什么區(qū)別。7.1.4子程序在大多數(shù)應用程序中,部分代碼可能需要在一個程序中的不同位置被多次執(zhí)行,這部分代碼可以用子程序的形式實現(xiàn)。在程序的任何位置都可以通過call指令調(diào)用子程序,如果子程序以ret指令結(jié)尾,則在執(zhí)行完畢后返回調(diào)用該子程序的位置。本練習建立一個子程序?qū)B續(xù)的1計數(shù),再調(diào)用這個子程序?qū)σ粋€給定數(shù)據(jù)中的1和0計數(shù)。請在7.1.2小節(jié)中代碼的基礎(chǔ)上進行如下修改:
(1)將對連續(xù)的1計數(shù)的程序作為一個子程序,在該子程序中用寄存器r4作為輸入寄存器的接收輸入,用寄存器r2保存計數(shù)結(jié)果作為子程序的輸出。
(2)調(diào)用兩次新建立的子程序,一次用來計算連續(xù)出現(xiàn)的1;另一次用來計算連續(xù)出現(xiàn)的0,計算連續(xù)的0時,先將輸入數(shù)據(jù)取反,然后調(diào)用子程序進行計算。
(3)將連續(xù)出現(xiàn)的1的數(shù)量寫入寄存器r16,而將連續(xù)出現(xiàn)的0的數(shù)量寫入寄存器r17。7.1.5對交替出現(xiàn)的1和0計數(shù)我們有時需要計算一個序列中交替出現(xiàn)的1和0最多的字符串長度,例如二進制序列101101010001中有一個長度為6的交替出現(xiàn)1和0的字符串(粗體部分)。本練習使用7.1.4小節(jié)中建立的子程序來對交替出現(xiàn)的1和0計數(shù),將計數(shù)結(jié)果保存在寄存器r18中,假設(shè)最后兩位可以看做最長字節(jié)的一部分,例如1010有4個連續(xù)位交替出現(xiàn)的1和0。(提示:將數(shù)字左移一位或右移一位并與原始數(shù)據(jù)進行異或運算,看看會得到什么結(jié)果。)7.1.6C語言與匯編語言的比較使用C語言完成7.1.5小節(jié)中的練習。建立一個名為count_ones的函數(shù)用以對連續(xù)出現(xiàn)的1計數(shù)。從反匯編之后的代碼中找到main函數(shù)及count_ones子程序,對照是否采用了同樣的方式來編寫匯編代碼。分析編譯器使用了哪些寄存器以及使用原因。7.2程序控制輸入/輸出本練習探討為處理器提供輸入/輸出功能以及能夠被軟件控制的外設(shè),將從軟件和硬件兩個角度來驗證程序控制輸入/輸出操作,在AlteraDE2平臺上使用PIO部件實現(xiàn)程序控制并行接口。本練習的背景知識可以參照本書部分相關(guān)內(nèi)容,也可以從Altera網(wǎng)站上的IntroductiontotheAlteraNiosⅡ?SoftProcessor及IntroductiontotheAlteraSOPCBuilder文檔中獲得,光盤的目錄Documents中也提供了這些文檔。其中IntroductiontotheAlteraSOPCBuidler有兩個版本,一個是針對VHDL設(shè)計的,另一個是針對Verilog設(shè)計的。本練習中使用的PIO接口,是一個可以由SOPCBuilder生成的部件,用以提供輸入/輸出或雙向數(shù)據(jù)傳輸。PIO提供的數(shù)據(jù)傳輸是1~32位的并行傳輸,傳輸數(shù)據(jù)位寬n及傳輸方向可以由使用者在SOPCBuilder中設(shè)定,PIO接口可以包含如表7.1所示的4個寄存器。每一個寄存器都是n位長,各寄存器的用途如下:
(1)?Data(數(shù)據(jù)寄存器):用以保存PIO接口與NiosⅡ處理器之間傳輸?shù)臄?shù)據(jù),SOPCBuilder可以根據(jù)要求用輸入寄存器、輸出寄存器或雙向寄存器實現(xiàn)數(shù)據(jù)寄存器。
(2)?Direction(方向寄存器):用以定義SOPCBuilder生成的雙向寄存器的傳輸方向。
(3)?Interrupt-mask(中斷控制寄存器):用以控制連接在PIO接口上的輸入口的中斷使能。
(4)?Edge-capture(邊沿捕捉寄存器):?用以表明連接在PIO接口上的輸入口何時發(fā)生邏輯電平的變化。并不是所有的寄存器都在每一個PIO接口模塊中出現(xiàn)。如果不使用雙向接口,則SOPCBuilder就不會生成方向寄存器;如果不使用輸入接口,則不會生成中斷控制寄存器和邊沿捕捉寄存器。
PIO寄存器可以像處理器的存儲器一樣進行訪問。可以將NiosⅡ處理器的任意一個低4位為0的地址分配給PIO接口(地址分配一般由SOPCBuilder自動完成),這個地址是數(shù)據(jù)寄存器Data的地址,其他3個寄存器的地址相對于數(shù)據(jù)寄存器Data分別有4、8和12個字節(jié)(1、2和3個雙字)的偏移。關(guān)于PIO外設(shè)的更多信息請參考文檔QuartusⅡ?Version6.0HandbookVolume5:AlteraEmbeddedPeripherals(可從Altera網(wǎng)站或光盤的Doucuments目錄中獲得)中的相關(guān)內(nèi)容。本練習的任務是用AlteraDE2平臺上的波段開關(guān)輸入一組帶符號的8位數(shù)字,將這些數(shù)字相加并在LED和七段數(shù)碼管上顯示結(jié)果。7.2.1建立包含三個PIO接口部件的系統(tǒng)本練習使用8個波段開關(guān)SW7~SW0輸入數(shù)字,使用綠色LED燈LEDG7~LEDG0顯示由波段開關(guān)所定義的數(shù)字,使用16個紅色LED燈LEDR15~LEDR0顯示累加和。我們使用一個包含三個PIO接口的NiosⅡ系統(tǒng)完成該練習,其中一個PIO接口連接波段開關(guān),為處理器提供數(shù)據(jù);另外兩個PIO接口分別連接到綠色和紅色LED燈,作為輸出接口,分別用來顯示輸入的數(shù)字以及累加和。請參照以下步驟在DE2平臺上建立一個NiosⅡ系統(tǒng)并實現(xiàn)練習所需的硬件:
(1)新建一個NiosⅡ工程,選擇DE2平臺上的CycloneⅡEP2C35F672C6作為目標器件。
(2)使用SOPCBuilder生成所需的電路,系統(tǒng)名稱為nios_system,這個系統(tǒng)由以下部件組成:①帶JTAGDebugModuleLevel1的NiosII/s處理器,使用以下選項?!?HardwareMultiply下拉菜單中的EmbeddedMultiplier(用硬件乘法器實現(xiàn)乘法)?!襁x中HardwareDivide(硬件除法器)。②RAM模式32K字節(jié)深度的片上存儲器。③8位PIO輸入接口電路。④8位PIO輸出接口電路。⑤16位PIO輸出接口電路。SOPCBuilder自動為三個PIO接口命名為pio_0、pio_1和pio_2,也可以根據(jù)PIO所做的具體工作修改名稱,例如,可分別命名為new_number、green_LEDs和red_LEDs。
(3)使用System>Auto-AssignBaseAddresses菜單,自動為系統(tǒng)中的所有部件分配地址,結(jié)果為如圖7.2所示的系統(tǒng),看看各PIO模塊的地址是如何分配的。
(4)在Verilog/VHDL文件中例化nios_system,并在Verilog/VHDL設(shè)計中對所需要的與DE2平臺上開關(guān)和LED燈的連接進行定義。
(5)導入DE2_pin_assignment.csv中的引腳配置(可參考3.5.2小節(jié)),為設(shè)計分配引腳。
(6)編譯QuartusⅡ工程。
(7)下載并配置DE2平臺上的CycloneⅡ系列FPGA以實現(xiàn)所生成的系統(tǒng)。圖7.2包含了三個PIO模塊的NiosⅡ系統(tǒng)7.2.2用NiosⅡ匯編語言實現(xiàn)數(shù)據(jù)輸入、累加及輸出本練習用NiosⅡ匯編語言實現(xiàn)數(shù)據(jù)的輸入、累加及輸出,請參照以下步驟完成練習:
(1)用匯編語言編寫一段程序,讀取波段開關(guān)的內(nèi)容,將相應的值在綠色LED上顯示出來,將這個數(shù)字加到一個累加和上,并用紅色LED顯示累加結(jié)果。
(2)使用AlteraDebugClient軟件編譯并下載程序。
(3)單步執(zhí)行程序并通過輸入不同的數(shù)據(jù)來驗證設(shè)計的正確性。注意,單步執(zhí)行程序允許改變輸入數(shù)據(jù)而不用擔心程序會多次重復讀取相同的數(shù)據(jù)。7.2.3用按鍵控制數(shù)據(jù)讀取在本練習中,我們要為應用程序增加連續(xù)讀取數(shù)據(jù)的功能,并通過一個按鍵啟動數(shù)據(jù)讀取。當在波段開關(guān)上輸入新的數(shù)據(jù)后,通過按鍵通知處理器讀取數(shù)據(jù)。本練習還需要監(jiān)測控制電路的狀態(tài)。通常使用一個狀態(tài)標志(StatusFlag),首先將這個標志位清零,當I/O設(shè)備接口做好下一次數(shù)據(jù)傳輸?shù)臏蕚鋾r,將狀態(tài)標志位置1,傳輸結(jié)束后,重新把該標志位清零,這樣,處理器可以通過輪詢狀態(tài)標志決定何時可以傳輸數(shù)據(jù)。在本練習中,I/O設(shè)備是波段開關(guān),I/O接口是由SOPCBuilder生成的PIO電路,為了提供一個狀態(tài)標志,我們可以生成一個特殊的帶邊沿捕捉功能的一位PIO電路。這個PIO與普通的PIO非常相似,寄存器分配與表7.1也一致。在目錄altera_up_avalon_DE2_pio中定義了這個PIO,必須將這個定義導入到工程中來。該目錄包含在光盤的目錄\DE2_Computer_Organization\University_Program_IP_Cores中,也可以從Altera大學計劃網(wǎng)站/up/pub/University_Program_IP_Cores/DE2_pio.zip上獲得。請參照以下步驟完成練習:
(1)新建一個工程并實現(xiàn)一個與7.2.1小節(jié)中相同的系統(tǒng)。
(2)將altera_up_avalon_DE2_pio目錄復制到工程目錄中。打開SOPCBuidler,其中已經(jīng)列出了已有的NiosⅡ子系統(tǒng)。為了能在SOPCBuilder中看到altera_up_avalon_DE2_pio,使用File>RefreshComponentList菜單刷新部件列表,此時在AvalonComponents>UniversityProgramDE2Board中將出現(xiàn)部件DE2_PIO。
(3)使用DE2_PIO生成一個狀態(tài)標志部件,將這個部件配置成1位寬的輸入口,在InputOptions中選擇下降沿觸發(fā)的SynchronouslyCapture。
(4)生成NiosⅡ子系統(tǒng)。
(5)針對完成的NiosⅡ系統(tǒng)修改Verilog/VHDL設(shè)計,使用按鍵KEY0作為狀態(tài)標志PIO的輸入(按鍵是低電平有效的)。
(6)分配引腳并編譯工程。
(7)修改應用程序,當按鍵按下后接收一個新數(shù)據(jù),并將Edge-capture寄存器的StatusFlag位置1,輸入的數(shù)據(jù)累加之后,應用程序通過向Edge-capture寄存器中寫入0來清除狀態(tài)標志位。
(8)下載并運行編寫的程序以驗證其正確性,程序應該連續(xù)運行,且每次按下按鍵后加一個新的數(shù)字。7.2.4用七段數(shù)碼管顯示十六進制累加結(jié)果在前面的練習中用紅色LED顯示累加結(jié)果,本練習將對設(shè)計加以修改,除在紅色LED上顯示累加結(jié)果之外,同時在七段數(shù)碼管HEX3~HEX0上用十六進制數(shù)顯示累加結(jié)果。7.2.5將累加結(jié)果轉(zhuǎn)換成十進制顯示本練習在前面練習的基礎(chǔ)上,用十進制數(shù)在七段數(shù)碼管上顯示累加結(jié)果,應用程序應能夠完成所需的數(shù)制轉(zhuǎn)換。注意:只有在7.2.1小節(jié)中選中HardwareDivide選項,才能使用div指令。7.3子程序與堆棧7.3.1建立一個NiosⅡ系統(tǒng)本練習中,我們將用到一個包含片上存儲器塊及JTAGUART模塊的NiosⅡ系統(tǒng),其中JTAGUART模塊用以實現(xiàn)NiosⅡ處理器與主機之間的通信。請參照以下步驟實現(xiàn)這個系統(tǒng):
(1)新建一個QuartusⅡ工程,選擇CycloneⅡ?EP2C35F673C6作為目標器件。
(2)使用SOPCBuilder建立一個名為nios_system的系統(tǒng),該系統(tǒng)包含以下部件:①帶JTAGDebugModuleLevel1的NiosⅡ/s處理器。②RAM模式32K字節(jié)深度的片上存儲器模塊。
(3)用System>Auto-AssignBaseAddresses菜單自動分配基地址,實現(xiàn)如圖7.3所示的系統(tǒng)。圖7.3用SOPCBuilder實現(xiàn)帶jtag_debug_module的系統(tǒng)
(4)生成系統(tǒng)后,退出SOPCBuilder并返回QuartusⅡ軟件。
(5)在Verilog/VHDL模塊中例化所生成的NiosⅡ系統(tǒng)。
(6)分配引腳如下:①clk-PIN_N2作為50?MHz時鐘輸入。②reset_n-PIN_N25作為AlteraDE2平臺上的按鍵SW0。
(7)編譯QuartusⅡ工程。
(8)下載并配置DE2上的CycloneⅡ系列FPGA以實現(xiàn)生成的系統(tǒng)。7.3.2對32位正整數(shù)排序本練習的目標是對一系列32位正整數(shù)按降序排序。這些數(shù)據(jù)用文件的形式提供,文件的第一個32位數(shù)據(jù)表示數(shù)據(jù)列表的長度,其余為被排序的數(shù)據(jù)。請參照以下步驟用NiosⅡ匯編語言完成練習:
(1)編寫一段匯編程序,對存儲器中從LIST_FILE開始的數(shù)據(jù)文件中的數(shù)據(jù)進行排序。假設(shè)這個數(shù)據(jù)文件很大,沒有足夠的空間為排序后的數(shù)據(jù)提供單獨的存儲空間,因此排序過程要采用原位排序,即排序之后的數(shù)據(jù)列表和原始數(shù)據(jù)列表使用相同的存儲空間。
(2)編譯并用AlteraDebugClient下載程序。
(3)在存儲器中手工建立一個數(shù)據(jù)列表,裝載到內(nèi)存中并運行程序。提示:包含數(shù)據(jù)列表的文件可以通過AlteraDebugClient裝載到存儲器中。7.3.3用子程序?qū)崿F(xiàn)排序任務本練習中,我們使用子程序?qū)崿F(xiàn)排序任務。為了使子程序更為通用,在進入子程序之前先將子程序使用的寄存器的內(nèi)容保存到堆棧中,離開子程序之前再將這些內(nèi)容寫回寄存器。注意必須通過初始化堆棧指針sp(寄存器r27)建立堆棧,堆棧一般從高地址存儲器位置開始向低地址方向增長。當有新的項目壓入堆?;蚨褩V械膬?nèi)容彈出之后要動態(tài)地調(diào)整堆棧指針。為了保證堆棧由高地址向低地址增長,在新項目壓入堆棧之前,堆棧指針先減4,項目從堆棧中彈出后,必須將堆棧指針再加4。請參照以下步驟修改7.3.2小節(jié)中的程序,完成練習:
(1)編寫一個名為SORT的子程序,能夠?qū)Υ鎯ζ髦腥我馕恢萌我鈹?shù)量的數(shù)據(jù)進行排序,假設(shè)數(shù)據(jù)列表的地址和數(shù)量通過如下寄存器傳遞給子程序:①參數(shù)size(排序數(shù)據(jù)的數(shù)量)由NiosⅡ寄存器r2給定。②列表中第一個項目的地址由寄存器r3的內(nèi)容給定。
(2)編寫一個主程序,初始化堆棧指針,將所需要的參數(shù)寫入寄存器r2和r3,然后調(diào)用子程序SORT進行排序。同時將數(shù)據(jù)列表裝載到存儲器中的LIST_FILE處。
(3)編譯并下載程序。
(4)建立一個示例數(shù)據(jù)列表,裝載到存儲器中并運行程序。7.3.4用堆棧向子程序傳遞參數(shù)修改7.3.3小節(jié)中的程序,用堆棧從主程序向子程序傳遞參數(shù)。編譯、下載并運行程序。7.3.5用遞歸算法計算階乘所有的NiosⅡ處理器都使用ra寄存器(r31)來保存子程序調(diào)用時的返回地址,在子程序中又會調(diào)用另外一個嵌套子程序,此時必須確保第一次子程序調(diào)用的返回地址不會被新寫入ra的返回地址所覆蓋。解決這個問題常用的辦法是,先將第一次子程序調(diào)用的返回地址壓入堆棧,第二個子程序返回時再將第一個子程序的返回地址重新寫回ra。我們通過計算一個給定整數(shù)n的階乘來探討嵌套調(diào)用子程序的概念。整數(shù)n的階乘由下式表示:n!=n(n-1)(n-2)×…×2×1也可以用下式遞歸計算:n!=n(n-1)!請注意:0!=1。請編寫一個用遞歸算法計算n的階乘的程序。程序中包括一個子程序FACTOR,該子程序重復調(diào)用自己,直至完成階乘的計算。主程序通過堆棧將參數(shù)n傳遞給子程序。提示:由于子程序中要使用乘法指令mul,因此7.3.1小節(jié)中的系統(tǒng)一定要選擇NiosII/s處理器,經(jīng)濟版NiosⅡ處理器NiosⅡ/e不能實現(xiàn)mul指令。編譯、下載并運行程序,用不同的n驗證其正確性。7.4輪?詢?與?中?斷本練習的目標是學習如何通過I/O設(shè)備發(fā)送和接收數(shù)據(jù)??梢杂脙煞N方法來獲得I/O設(shè)備的狀態(tài):第一種方法稱做輪詢,處理器不斷地查詢I/O設(shè)備來確定是否可以發(fā)送數(shù)據(jù)或接收數(shù)據(jù);第二種方法稱做中斷,由I/O設(shè)備主動向處理器表明已經(jīng)提供了有效數(shù)據(jù)或可以接收處理器發(fā)送的數(shù)據(jù)。一個簡單而且通用的處理器與I/O設(shè)備之間傳輸數(shù)據(jù)的方案是UART接口電路。UART接口電路置于處理器與外部I/O設(shè)備之間,每次處理一個8位字符。UART接口電路與處理器之間的數(shù)據(jù)傳輸是并行的,即使用一組連線一次完成一個字符的傳輸;而UART與I/O設(shè)備之間的數(shù)據(jù)傳輸采用串行傳輸,即每一次只傳輸一位字符。
SOPCBuilder可以為NiosⅡ系統(tǒng)提供一個名為JTAGUART的UART類型的接口電路。這個電路可以用來在DE2平臺上的NiosⅡ處理器與計算機主機之間建立連接。圖7.4是JTAGUART的原理框圖,JTAGUART的一端連接到Avalon交換架構(gòu),另一端通過USB-Blaster連接到主機。JTAGUART中包括Data和Control等兩個寄存器,NiosⅡ處理器可以按存儲器地址的方式訪問這兩個寄存器,Control寄存器的地址比Data寄存器的地址高4個字節(jié)。JTAGUART中還包括兩個FIFO作為存儲緩沖,一個用來存儲排隊等候發(fā)送的數(shù)據(jù),一個用來存儲從主機傳來的排隊等候接收的數(shù)據(jù)。圖7.5給出了寄存器的格式。圖7.4JTAGUART原理框圖圖7.5JTAGUART的寄存器(a)數(shù)據(jù)寄存器(Data);(b)控制寄存器(Control)
Data寄存器中各字段的定義如下:
(1)?b7~b0(DATA):8位字符型數(shù)據(jù),處理器用Store操作可以將這個數(shù)據(jù)寫入發(fā)送FIFO,用Load操作則將接收FIFO中的第一個數(shù)據(jù)寫入Data寄存器。
(2)?b15(RV,RVALID):表明DATA中是否包含能夠被處理器讀取的有效數(shù)據(jù),如果DATA字段有效,則RV置1,否則RV置0。
(3)?b31~b16(RAVAIL):表明此次讀取之后,接收FIFO中還有多少有效數(shù)據(jù)等待讀取。
Control寄存器中各字段的定義如下:
(1)?b0(RE):如果置1則允許讀中斷。
(2)?b1(WE):如果置1則允許寫中斷。
(3)?b8(RI):如果置1則表明有未決的讀中斷,讀取DATA中的數(shù)據(jù)可自動將RI清零。
(4)?b9(WI):如果置1則表明有未決的寫中斷。
(5)?b10(AC):如果置1則表明自從上次清零之后發(fā)生過JTAG活動(比如主機通過輪詢來驗證JTAG連接是否存在等),向AC寫入1可以將AC清零。
(6)?b31~b16(WSPACE):表明發(fā)送FIFO中剩余空間的數(shù)量。關(guān)于JTAGUART的更多信息請參考QuartusⅡVersion6.0HandbookVolume5:AlteraEmbeddedPeripherals的第5章。7.4.1建立一個包含計時器及JTAGUART的NiosⅡ系統(tǒng)用SOPCBuilder建立一個如圖7.6所示的系統(tǒng),該系統(tǒng)包含一個NiosⅡ/s處理器、一個JTAGUART、一個存儲器塊及一個計時器(IntervalTimer)。圖7.6包含計時器及JTAGUART的系統(tǒng)請參照以下步驟實現(xiàn)該系統(tǒng):
(1)新建一個QuartusⅡ工程,選擇DE2平臺上的CycloneⅡEP2C35F672C6作為目標器件。
(2)使用SOPCBuilder建立一個名為nios_system的系統(tǒng),該系統(tǒng)包括以下部件:①帶JTAGDebugModuleLevel1的NiosⅡ/s處理器。②RAM模式32K字節(jié)深度的片上存儲器。③使用缺省設(shè)置的JTAGUART。④計時器(Other組中的IntervalTimer),如圖7.7所示,定時器硬件選項中的PresetConfigurations選擇Simpleperiadicinterrupt,TimeoutPeriod選擇固定500?ms。圖7.7計時器設(shè)置
(3)用System>Auto-AssignBaseAddresses菜單為NiosⅡ系統(tǒng)自動分配地址,得到如圖7.8所示的系統(tǒng)。
(4)生成該系統(tǒng)后,退出SOPCBuidler并返回QuartusⅡ軟件。
(5)在Verilog/VHDL頂層設(shè)計中例化生成的NiosⅡ系統(tǒng)。
(6)分配引腳如下:①clk-PIN_N2作為50?MHz時鐘輸入。②reset_n-PIN_G26作為AlteraDE2平臺上的按鍵KEY0。
(7)編譯QuartusⅡ工程。
(8)下載并配置DE2上的CycloneⅡ系列FPGA以實現(xiàn)生成的系統(tǒng)。圖7.8用SOPCBuilder實現(xiàn)包含計時器及JTAGUART的系統(tǒng)7.4.2通過JTAGUART向主機發(fā)送字符
JTAGUART可以向AlteraDebugClient傳送ASCII字符,AlteraDebugClient將接收到的ASCII字符顯示在終端窗口中,當JTAGUART控制寄存器中的WSPACE字段為非零值時,JTAGUART可以接收處理器發(fā)送到AlteraDebugClient的字符。當處理器向AlteraDebugClient發(fā)送字符時,將輪詢(連續(xù)讀取)控制寄存器直至發(fā)送FIFO中有剩余的空間出現(xiàn),一旦發(fā)送FIFO中有剩余的空間,處理器就可以將要發(fā)送的字符數(shù)據(jù)寫入JTAGUART的Data寄存器中。編寫一個NiosⅡ匯編語言程序,每隔500?ms在AlteraDebugClient的終端窗口中顯示字符“Z”,請參照以下步驟建立并執(zhí)行該程序:
(1)使用NiosⅡ匯編語言編寫程序,循環(huán)讀取JTAGUART的Control寄存器直至發(fā)送FIFO中有多余的空間出現(xiàn)。
(2)向Data寄存器中寫入Z。
(3)使用AlteraDebugClient,編譯并下載該匯編語言程序。
(4)單步執(zhí)行這個程序,如果連續(xù)運行該程序,發(fā)送到AlteraDebugClient的字符會太多而導致終端窗口來不及處理接收到的字符。
(5)在匯編語言代碼中,增加一個延遲循環(huán),使處理器約每0.5?s向AlteraDebugClient發(fā)送一個字符。
(6)重新編譯、裝載并運行該程序。7.4.3用JTAGUART實現(xiàn)打字機功能
JTAGUART不僅可以向終端窗口寫字符,還可以從終端窗口中接收ASCII字符,JTAGUART的Data寄存器的RVALID位(b15)表明DATA字段中是否包含接收到的有效數(shù)據(jù),如果接收FIFO中還有更多的數(shù)據(jù)等待讀取,則RAVAIL字段是一個非零值。編寫一段程序?qū)崿F(xiàn)一個類似打字機的任務,處理器讀取JTAGUART從主機接收到的字符后,將這個字符在AlteraDebugClient的終端窗口上顯示出來。使用輪詢的方式判斷JTAGUART是否接收到了有效數(shù)據(jù)。注意:必須將光標置于終端窗口中才能通過鍵盤向JTAGUART的接收端口寫數(shù)據(jù)。7.4.4使用中斷方式實現(xiàn)打字機功能使用輪詢方式處理UART的數(shù)據(jù)接收時,要通過讀取寄存器的值來確定UART的狀態(tài),這會產(chǎn)生額外的開銷,因此效率較低,并顯著地降低了程序的性能。如果使用中斷方式,則讓處理器在等待I/O設(shè)備傳輸數(shù)據(jù)時進行其他工作,可大大提高程序的性能。建立一個中斷服務程序以讀取JTAGUART從主機接收到的字符,將中斷服務程序放在十六進制地址0x20處,這個地址是SOPCBuilder確定的異常處理程序(ExceptionHandler)缺省地址。將寄存器ea中的異常返回地址減4可以得到外部中斷地址。代碼7.2是用NiosⅡ匯編語言編寫的終端服務程序的框架。代碼7.2中斷服務程序框架。.include“nios_macros.s”.text.org0x20 /*將中斷服務程序放在相應地址*/ISR:rdctlet,ctl4 /*檢查是否有外部中斷發(fā)生*/beqet,r0,SKIP_EA_DECsubiea,ea,4 /*如果有外部中斷發(fā)生,將ea減4以執(zhí)行中斷指令*/SKIP_EA_DEC: ...中斷服務程序END_ISR:eret /*從異常處理程序中返回*/.global_start_start: /*程序起始位置*/ ...中斷使能代碼
...主程序代碼LOOP: brLOOP /*無限循環(huán)*/.end可以用NiosⅡ控制寄存器ctl3(或叫做ienable寄存器)來單獨打開中斷。注意在7.4.1小節(jié)建立的系統(tǒng)中JTAGUART的中斷被設(shè)為level0,這表明必須將ctl3的bit0置1才能打開JTAGUART的中斷。請參照以下步驟完成練習:
(1)建立一個從JTAGUART讀取字符的中斷服務程序,注意中斷服務程序必須放在存儲器中0x20的位置,只有將相應的值寫入JTAGUART的Control寄存器、NiosⅡ控制寄存器ctl0及ctl3,才能打開中斷。
(2)在中斷服務程序中使用輪詢的方法將接收到的字符顯示到主機上運行的AlteraDebugClient終端窗口中。
(3)編譯、裝載并運行程序。如果程序不能正常運行,則必須對程序進行調(diào)試以修正錯誤。AlteraDebugClient的單步調(diào)試特性允許使用者在每一條指令執(zhí)行之后觀察執(zhí)行的程序流以及NiosⅡ的寄存器內(nèi)容,這是一個很有效的調(diào)試工具。但單步執(zhí)行會自動禁止中斷,因此這種方法無法調(diào)試中斷服務程序,對于含有中斷的應用,可以通過設(shè)置斷點來調(diào)試程序。另外還需要注意,執(zhí)行中斷服務程序時會自動禁止中斷,中斷服務程序結(jié)束后才能重新打開中斷,因此,當有些應用需要使用嵌套中斷時,必須在進入中斷服務程序后重新打開中斷。7.4.5計時器中斷的使用本練習中,我們用中斷方式讀取JTAGUART從主機接收到的字符,并以500?ms的時間間隔將最后接收到的字符重復顯示在AlteraDebugClient的終端窗口中。在7.4.2小節(jié)中我們用延時循環(huán)近似實現(xiàn)了這個時間間隔,現(xiàn)在改用計時器電路來實現(xiàn)500?ms的時間間隔。計時器每500?ms向處理器發(fā)送一次中斷,處理器接收到這個中斷后,通過JTAGUART向DebugClient終端窗口發(fā)送一個字符。計時器內(nèi)部有一個計數(shù)器,將這個計數(shù)器設(shè)定為一個特定的初值,在每一個時鐘周期內(nèi),計數(shù)器的值減1,當計數(shù)器的值為0時,會產(chǎn)生一個超時(Timeout)事件,計時器相應地產(chǎn)生一個中斷而計數(shù)器的值被重新置于原來設(shè)定的值。與JTAGUART一樣,計時器也有一組可以按存儲器地址訪問的16位寄存器,圖7.9所示為Status寄存器(狀態(tài)寄存器)和Control寄存器(控制寄存器)。狀態(tài)寄存器(Status)的地址為計時器的基地址,控制寄存器(Control)的地址比Status寄存器的地址高4個字節(jié)。圖7.9計時器的寄存器(a)狀態(tài)寄存器(Status);(b)控制寄存器(Control)狀態(tài)寄存器中各位的定義如下:
(1)?b0(TO):超時位,當計時器中計數(shù)器的值為0時,該位自動置1,只有處理器向該位寫入0才可以將該位清零。
(2)?b1(RUN):當內(nèi)部計數(shù)器運行時該位為1,否則該位為0,狀態(tài)寄存器的寫操作對此位無效。控制寄存器中各位的定義如下:
(1)?b0(ITO):置為1時允許計時器中斷。
(2)?b1(CONT):用以確定計數(shù)器內(nèi)部的寄存器到0后如何處理,如果CONT=1,計數(shù)器將自動重新裝載,否則計數(shù)值到0后計數(shù)器將停止工作。
(3)?b2(START):通過向這個寄存器寫入1來啟動計數(shù)器。
(4)?b2(STOP):通過向這個寄存器寫入1使計數(shù)器停止計數(shù)。關(guān)于計時器的更多信息請參考QuartusⅡ?Version6.0HandbookVolume5:AlteraEmbeddedPeripherals的第12章。如圖7.8所示,JTAGUART的中斷連接在NiosⅡ處理器的中斷線0上,而計時器連接在處理器的中斷線1上,因此同時打開JTAGUART中斷和計時器中斷,需要將控制寄存器ctl3的b0和b1位都置1。控制寄存器ctl4(也叫做ipending寄存器)可以用來確定發(fā)生何種中斷。如果一個外設(shè)的中斷被寄存器ctl3所禁止,即使這個外設(shè)將其中斷請求線置1也不能啟動中斷服務程序,且不會影響寄存器ctl4的值。請參照以下步驟完成練習:
(1)修改7.4.4中的程序,在主程序中打開JTAGUART和計時器中斷,然后進入無限循環(huán)。
(2)修改中斷服務程序來處理JTAGUART中斷和計時器中斷。
(3)為了啟動這些中斷,必須向JTAGUART的Control寄存器、計時器的Control寄存器和NiosⅡ的控制寄存器ctl0和ctl3寫入相應的值。
(4)編譯、下載并運行程序。7.5總線通信本練習學習如何使用總線進行通信。由SOPCBuilder生成的NiosⅡ系統(tǒng)設(shè)計中,NiosⅡ處理器通過Avalon交換架構(gòu)與外設(shè)相連,外設(shè)需要通過SOPCBuilder的部件(Component)連接到Avalon交換架構(gòu)上。為了研究總線通信,本練習不需要建立專用的SOPCBuilder部件,而是通過SOPC的部件Avalon至外部總線橋(AvalontoExternalBusBridge)與外部總線通信,設(shè)計者可以使用這個總線橋在QuartusⅡ軟件中建立一個外設(shè)并連接到NiosⅡ系統(tǒng)。AvalontoExternalBusBridge建立了一個可以連接多個“從”設(shè)備的類似于總線的接口。圖7.10為外部總線的信號及時序,所需要的信號如下:
(1)?Address:k位地址信號(最多32位)。所要傳輸數(shù)據(jù)的地址按字節(jié)計算,自動與數(shù)據(jù)的尺寸對齊,對于32位數(shù)據(jù),地址的低兩位等于0,使用ByteEnable信號可以傳輸少于4字節(jié)的數(shù)據(jù)。
(2)?BusEnable:1位總線使能信號。
(3)?R/W:1位讀寫信號,1表示讀傳輸,0表示寫傳輸。
(4)?ByteEnable:16、8、4、2或者1位字節(jié)使能信號,每一位表示能否對相應的字節(jié)進行讀寫,ByteEnable高電平有效。
(5)?WriteData:128、64、32、16或8位寫數(shù)據(jù),在寫傳輸中向外設(shè)傳輸?shù)臄?shù)據(jù)。
(6)?Acknowledge:1位應答信號,外設(shè)通過應答信號表明數(shù)據(jù)傳輸結(jié)束。
(7)?ReadData:128、64、32、16或8位讀數(shù)據(jù),在讀傳輸中從外設(shè)讀取的數(shù)據(jù)。
(8)?IRQ:1位中斷信號,外設(shè)用來中斷NiosⅡ處理器的信號,中斷信號是可選信號,沒有在圖中出現(xiàn)。圖7.10Avalon至外部總線橋的信號(a)外部總線信號;(b)外部總線時序這個總線是一個同步總線,所有向外設(shè)傳輸?shù)男盘柋仨氃跁r鐘的上升沿被讀取。將Address、R/W、ByteEnable以及可能的WriteData信號設(shè)置為合適的值,然后將BusEnable信號設(shè)置為1,可以發(fā)起一次傳輸。如果R/W信號為1,則表明傳輸是一個讀操作,外設(shè)必須將ReadData設(shè)置為合適的值,并將Acknowledge信號置1。Acknowledge信號必須且只能保持一個時鐘周期,ReadData信號在Acknowledge信號有效期間,必須保持不變。如果Acknowledge信號保持兩個或兩個以上的時鐘周期,Avalon交換架構(gòu)可能會認為這是另一次總線傳輸,因此Acknowledge信號只能保持一個時鐘周期。如果R/W信號為0,則表明該傳輸是一個寫操作,外設(shè)應該將WriteData線上的數(shù)據(jù)寫入適當?shù)奈恢?。一旦外設(shè)完成了寫傳輸,則必須將應答信號置1并保持一個時鐘周期。7.5.1實現(xiàn)外部總線橋及七段數(shù)碼管控制器圖7.11為本練習中實現(xiàn)的系統(tǒng),它可以由SOPCBuilder生成。該系統(tǒng)包括一個NiosⅡ/s處理器、一個JTAGUART、一個片上存儲器塊以及一個Avalon至外部總線橋。生成的系統(tǒng)如圖7.12所示,從外設(shè)是一個由用戶編寫的Verilog/VHDL模塊。Avalon至外部總線橋?qū)iosⅡ系統(tǒng)的Avalon交換架構(gòu)與前文所述的外部總線連接起來,Avalon交換架構(gòu)是SOPCBuilder所生成的系統(tǒng)中外設(shè)的主要互聯(lián)網(wǎng)絡。圖7.11包含了外部總線接口的NiosⅡ系統(tǒng)原理圖7.12包含了外部總線接口的NiosⅡ系統(tǒng)從外設(shè)包含四個16位寄存器以及用DE2平臺上的七段數(shù)碼管顯示寄存器值的電路。這些寄存器可以按存儲器地址來訪問,因此NiosⅡ處理器可以直接將數(shù)據(jù)寫入這些寄存器。為了幫助實現(xiàn)上述從外設(shè),提供了三個Verilog/VHDL模塊,其中的一個模塊提供了完整的代碼,另外兩個模塊只給出了代碼的架構(gòu),本練習的一部分就是完成這兩個模塊的代碼,這些模塊分別如下:
(1)?Lab5_Part1(提供了完整的代碼)。
(2)?Peripheral_on_External_Bus(提供了代碼架構(gòu))。
(3)?Seve_Segment_Display(提供了代碼架構(gòu))。光盤的DE2_Computer_Organization目錄中,壓縮文件comporg_lab5_design_files.zip包含了以上文件,也可以從Altera的網(wǎng)站/up/pub/Laboratory_Exercises/Comp_Org/comporg_lab5_designfiles.zip上獲得。生成如圖7.12所示的系統(tǒng)之后,修改Verilog/VHDL模塊Peripheral_on_External_Bus,將它連接到Avalon至外部總線橋的信號上,另外修改這個模塊使之包含四個寄存器,將每一個寄存器映射為SOPCBuilder分配給地址的1/4,并使用七段數(shù)碼管HEX3~HEX0顯示這些寄存器的內(nèi)容。由于每次只能在數(shù)碼管上顯示一個寄存器的內(nèi)容,因此使用波段開關(guān)SW1和SW0來選擇所要顯示的寄存器。以上設(shè)置再加上SOPCBuilder生成的系統(tǒng)即可實現(xiàn)如圖7.11所示的系統(tǒng)。為了使用外部總線橋,必須在啟動SOPCBuilder軟件之前,將目錄altera_up_avalon_to_external_bus_bridge復制到工程目錄中,這個目錄可以從Altera大學計劃/up/pub/university_Program_IP_Cores/avalon_to_external_bus_bridge.zip上獲得。光盤的\DE2_Computer_Organization\University_Program_IP_Cores目錄下也可以找到這個壓縮文件。請按以下步驟實現(xiàn)所要求的系統(tǒng):
(1)新建一個名為Lab5_Part1的QuartusⅡ工程,選擇DE2平臺上的CycloneⅡEP2C35F672C6作為目標器件。
(2)使用SOPCBuilder建立一個名為nios_system的系統(tǒng),該系統(tǒng)包含以下部件:①帶JTAGDebugModuleLevel1的NiosⅡ/s處理器。②RAM模式32?K字節(jié)深度的片上存儲器。③采用缺省設(shè)置的JTAGUART。④Avalon至外部總線橋,選擇數(shù)據(jù)寬度為16位,地址范圍為512?K字節(jié)。選擇這個參數(shù)是為了在7.5.2小節(jié)的練習中能方便地與SRAM連接。在SOPCBuilder窗口中,外部總線橋組件的位置為AvalonComponents>UniversityProgramDE2Board>AvalontoExternalBusBridge。注意:選擇512?K字節(jié)的地址范圍意味著實現(xiàn)的總線上共有k=19根地址線。
(3)將Avalon至外部總線橋連接到NiosⅡ的data_master端口而不是instruction_master端口,可以通過單擊SOPCBuilder窗口中的連接路徑來移除總線橋與instruction_master端口之間的連接。
(4)用System>Auto-AssignBaseAddress菜單自動分配地址空間,可以得到如圖7.12所示的系統(tǒng)。
(5)生成系統(tǒng)后,退出SOPCBuilder并返回QuartusⅡ軟件。
(6)將上面提到的四個Verilog/VHDL模塊加入到QuartusⅡ工程中。
(7)檢查給定的Verilog/VHDL模塊Lab5_Part1是否正確地例化了生成的NiosⅡ系統(tǒng)。
(8)修改Verilog/VHDL模塊Peri
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026山東事業(yè)單位統(tǒng)考臨沂市郯城縣招聘綜合類崗位29人備考題庫及答案詳解(考點梳理)
- 2026云南昭通市水富市文化館城鎮(zhèn)公益性崗位人員招聘1人備考題庫(含答案詳解)
- 2026北京北化化學科技有限公司招聘15人備考題庫及一套完整答案詳解
- 2026北京航空航天大學計算機學院聘用編高級研發(fā)工程師F崗招聘1人備考題庫及答案詳解(奪冠系列)
- 2026安徽亳州市蒙城縣縣直幼兒園面向農(nóng)村學校選調(diào)教師55人備考題庫及答案詳解參考
- 2026安徽合肥國家實驗室技術(shù)支撐崗位招聘2人備考題庫及答案詳解(奪冠系列)
- 2025河南商丘市梁園區(qū)消防救援大隊政府專職消防員招錄10人備考題庫及答案詳解一套
- 淄博2025年山東淄博周村區(qū)事業(yè)單位招聘教師9人筆試歷年參考題庫附帶答案詳解
- 2026山東事業(yè)單位統(tǒng)考濟南鋼城區(qū)招聘初級綜合類崗位45人備考題庫及答案詳解(考點梳理)
- 河南河南省疾病預防控制中心河南省預防醫(yī)學科學院2025年招聘11人筆試歷年參考題庫附帶答案詳解
- 交通運輸安全檢查與處理規(guī)范(標準版)
- UCL介紹教學課件
- 扁鵲凹凸脈法課件
- 2026年開封大學單招職業(yè)適應性測試題庫及完整答案詳解1套
- 北京市2025北京市體育設(shè)施管理中心應屆畢業(yè)生招聘2人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)2套試卷
- 建筑施工現(xiàn)場材料采購流程
- DB31∕T 1234-2020 城市森林碳匯計量監(jiān)測技術(shù)規(guī)程
- 園林綠化施工工藝及注意事項
- 2025年高中語文必修上冊《登泰山記》文言文對比閱讀訓練(含答案)
- 2025年金蝶AI蒼穹平臺新一代企業(yè)級AI平臺報告-
- 2026屆山東菏澤一中高三化學第一學期期末達標測試試題含解析
評論
0/150
提交評論