版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第十五章PicoBlaze接口開發(fā)15.1輸出端口15.2輸入端口15.3求平方和電路接口開發(fā)本章小結(jié)15.1輸出端口15.1.1輸出指令和時(shí)序輸出指令output寫數(shù)據(jù)到輸出端口。它有兩種格式:
outputsX,(sY) outputsX,端口名稱
第一種格式,端口的id存儲(chǔ)在sY寄存器中;第二種格式,端口名稱特指端口的id號(hào),它可以是兩位的十六進(jìn)制數(shù)或者預(yù)定義的符號(hào)常量。輸出數(shù)據(jù)通常存儲(chǔ)在sX寄存器中。如圖15-1所示是輸出指令為“outputs0,02”的時(shí)序圖。PicoBlaze指令執(zhí)行時(shí)間為兩個(gè)時(shí)鐘周期,指令執(zhí)行時(shí),s0內(nèi)容輸出到輸出端口以及02輸出到端口id,一共需要兩個(gè)時(shí)鐘周期。write_strobe信號(hào)在第二個(gè)時(shí)鐘周期有效,它可以作為存儲(chǔ)輸出寄存器的使能信號(hào)或者用來初始化指定接口操作。圖15-1輸出指令時(shí)序圖15.1.2輸出接口
PicoBlaze與輸出外設(shè)之間的接口通常由譯碼電路和輸出緩沖器組成。譯碼電路針對(duì)端口id號(hào)譯碼并產(chǎn)生相對(duì)應(yīng)的使能信號(hào)。在output指令執(zhí)行后,數(shù)據(jù)存儲(chǔ)到相應(yīng)的緩沖器當(dāng)中。為了理解輸出接口的電路結(jié)構(gòu),假設(shè)PicoBlaze接口包含四個(gè)輸出緩沖器,輸出端口id號(hào)分別定義為0016、0116、0216、0316。注意:端口地址的高六位都是一樣的,只是通過低兩位來區(qū)別不同的端口。電路的結(jié)構(gòu)框圖如圖15-2所示。電路的關(guān)鍵部分是譯碼電路,其真值表如表15-1所示。譯碼電路為一個(gè)2-4譯碼器,在輸出指令的第二個(gè)時(shí)鐘周期,write_strobe信號(hào)有效,并且四位en_d信號(hào)中有一位有效。僅僅一個(gè)時(shí)鐘周期的使能信號(hào)能激活對(duì)應(yīng)輸出寄存器從輸出端口接收數(shù)據(jù)。輸出指令為“outputs0,02”的譯碼指令時(shí)序如圖15-1所示,在輸出指令執(zhí)行的第二個(gè)時(shí)鐘周期,en_d[2]信號(hào)有效,輸出端口數(shù)據(jù)在下一個(gè)時(shí)鐘上升沿存儲(chǔ)到對(duì)應(yīng)的數(shù)據(jù)緩沖器中。圖15-2電路的結(jié)構(gòu)框圖一旦理解了基本的操作,便可以設(shè)計(jì),HDL代碼如下:
always@*
if(write_strobe)
case(port_id[1:0])
2'b00:en_d=4'b0001;
2'b01:en_d=4'b0010;
2'b10:en_d=4'b0100;
2'b11:en_d=4'b1000;
endcase
else
en_d=4'b0000;
以上解決方法可以應(yīng)用在任何輸出端口。有時(shí)要求編口地址可改變??梢栽谇懊娴睦又惺褂枚M(jìn)制編碼。如果輸出端口地址小于8,則可以用一位熱碼簡(jiǎn)化譯碼電路。比如,可以定義4個(gè)端口id為:0116(000000012)、0216(000000102)、0416(000001002)和0816(000010002),這時(shí)譯碼邏輯被簡(jiǎn)化為
always@*
if(write_strobe)
en_d=port_id[3:0];
else
en_d=4'b0000;需要注意的是,如果只有一個(gè)輸出端口,那么無需譯碼邏輯。write_strobe信號(hào)可以直接連接在寄存器使能信號(hào)上。
采用偽代碼表示I/O口在代碼中對(duì)應(yīng)的復(fù)雜設(shè)計(jì)非常有用。在文件開頭聲明二進(jìn)制地址,例如,初始化輸出地址可以聲明如下:
;-----------------------------輸出端口定義----------------------------
constantout_port_a,00
constantout_port_b,01
constantout_port_c,02
constantout_port_d,03
如果賦值改變,則僅需要修改文件頭。清晰的文件頭往往在開發(fā)HDL代碼時(shí)用于端口id號(hào)分辨。 15.2輸入端口
15.2.1輸入指令和時(shí)序
輸入指令input從輸入端口讀回?cái)?shù)據(jù)。與輸出指令相似,輸入指令也有兩種格式:
inputsX,(sY);
和
inputsX,端口名稱
其中,sY寄存器或者端口名稱表示端口id號(hào)。接收回來的數(shù)據(jù)保存在sX寄存器中。輸入指令為“inputs0,02”的時(shí)序圖如圖15-3所示。當(dāng)指令執(zhí)行時(shí),02輸出到端口id,兩個(gè)時(shí)鐘周期后,輸入端口數(shù)據(jù)在時(shí)鐘上升沿時(shí)被采樣并存儲(chǔ)到s0寄存器,外部電路必須確保在采樣期間輸入數(shù)據(jù)穩(wěn)定,以防數(shù)據(jù)采集錯(cuò)誤。
與輸出指令相同,read_strobe信號(hào)在第二個(gè)時(shí)鐘周期有效。read_strobe信號(hào)的功能與write_strobe的相似,在15.3節(jié)將詳細(xì)介紹。圖15-3輸入指令接口時(shí)序15.2.2輸入接口
PicoBlaze與輸入外設(shè)之間的接口通常需要一個(gè)多路選擇電路,根據(jù)port_id選擇相應(yīng)的值送往in_port。有時(shí)還需要類似于輸出接口的譯碼電路,它在輸入接口中用于數(shù)據(jù)獲取。
在輸入接口電路中,輸入端口經(jīng)常被分成連續(xù)存取端口和單次存取端口兩種。對(duì)于連續(xù)存取端口,數(shù)據(jù)不斷產(chǎn)生,如14.3.2節(jié)的撥碼開關(guān)輸入;對(duì)于單次存取端口,輸入端口輸入數(shù)據(jù)操作由單個(gè)不連續(xù)事件觸發(fā)。比如,從UART數(shù)據(jù)緩沖器讀取一個(gè)字符,當(dāng)獲取數(shù)據(jù)時(shí),必須將其從緩沖區(qū)移除,以免該數(shù)據(jù)被重新處理。通常采用一個(gè)時(shí)鐘周期的脈沖來清除寄存器標(biāo)志或者從FIFO緩沖器移除一個(gè)數(shù)據(jù)單元。連續(xù)讀取端口的接口電路僅包含一個(gè)多路選擇電路。如圖15-4所示為包含四個(gè)端口的連續(xù)讀取端口電路。
單次讀取端口電路接口在input指令執(zhí)行結(jié)束時(shí),需要一個(gè)從緩沖區(qū)“移除”接收數(shù)據(jù)的機(jī)制。這時(shí)可以采用譯碼電路,根據(jù)端口id號(hào)與read_strobe信號(hào)進(jìn)行譯碼。與輸出接口的譯碼電路結(jié)構(gòu)一樣,僅僅是將write_strobe信號(hào)替換成了read_strobe信號(hào)。譯碼輸出信號(hào)可以認(rèn)為是“移除”信號(hào),在一個(gè)有效時(shí)鐘周期內(nèi)“移除”讀取的數(shù)據(jù)。如圖15-5所示為接口帶有FIFO的譯碼和多路選擇電路。圖15-4四路持續(xù)讀取端口框圖圖15-5四輸入單次讀取端口框圖
rv信號(hào)為譯碼移除信號(hào),在input指令執(zhí)行結(jié)束時(shí),四位信號(hào)中選擇一位并使對(duì)應(yīng)的FIFO執(zhí)行一次讀操作,從緩沖區(qū)“移除”一個(gè)數(shù)據(jù)單元。如果定義0016、0116、0216、0316作為端口id,則接口代碼如下:
//多路選擇電路
always@*
case(port_id[1:0])
2'b00:data=in_data0;
2'b01:data=in_data1;
2'b10:data=in_data2;
2'b11:data=in_data3;
endcase
//譯碼電路
always@*
if(read_strobe)
case(port_id[1:0])
2'b00:rv=4'b0001;
2'b01:rv=4'b0010;
2'b10:rv=4'b0100;
2'b11:rv=4'b1000;
endcase
else
rv=4'b0000;
15.3求平方和電路接口開發(fā)
15.3.1輸出接口
在驗(yàn)證板上4個(gè)七段數(shù)碼管數(shù)據(jù)顯示端口共享同樣的輸入管腳,所以需要一個(gè)動(dòng)態(tài)掃描電路來完成數(shù)碼管的動(dòng)態(tài)顯示。對(duì)于基于PicoBlaze的設(shè)計(jì)來說,設(shè)計(jì)動(dòng)態(tài)掃描電路可以通過軟件來實(shí)現(xiàn),也可以在微處理器外設(shè)接口電路中實(shí)現(xiàn)。選用外設(shè)接口電路的方法來實(shí)現(xiàn),相對(duì)于匯編語言開發(fā)要簡(jiǎn)單一些,而且前面設(shè)計(jì)的動(dòng)態(tài)掃描電路也可以直接搬用。若電路不考慮所有時(shí)序信息,那么對(duì)于外部系統(tǒng)來說,就是四個(gè)獨(dú)立的七段數(shù)碼管。PicoBlaze輸出接口的框圖如圖15-6所示,接口包含4個(gè)八位的輸出端口,每個(gè)端口代表一個(gè)七段數(shù)碼管。圖15-6求平方和電路輸出接口
在匯編代碼中,4個(gè)LED數(shù)據(jù)存儲(chǔ)在PicoBlaze中并以地址偽代碼命名為led0、led1、led2和led3的數(shù)據(jù)RAM中,對(duì)應(yīng)的代碼為
…
;數(shù)據(jù)RAM地址偽代碼
constantled0,10
constantled1,11
constantled2,12
constantled3,13
…
;輸出端口定義
constantsseg0_port,00 ;七段數(shù)碼管led0
constantsseg1_port,01 ;七段數(shù)碼管led1
constantsseg2_port,02 ;七段數(shù)碼管led2
constantsseg3_port,03 ;七段數(shù)碼管led3
…
disp_led:
fetchdata,led0
outputdata,sseg0_port
fetchdata,led1
outputdata,sseg1_port
fetchdata,led2
outputdata,sseg2_port
fetchdata,led3
outputdata,sseg3_port
return
15.3.2輸入接口
輸入接口包含一個(gè)8位的撥碼開關(guān)和兩個(gè)1位的按鍵。前者由于其輸入值一直存在,所以為連續(xù)讀入端口;后者由于每次按鍵僅觸發(fā)一次單獨(dú)操作,所以為單次存儲(chǔ)電路。由于機(jī)械按鍵存在抖動(dòng),所以按鍵信號(hào)需要經(jīng)過按鍵防抖動(dòng)電路,變成一個(gè)干凈的單時(shí)鐘脈沖信號(hào)。由于PicoBlaze端口為8位數(shù)據(jù),所以輸入的兩位按鍵信號(hào)可以打包成一個(gè)輸入端口輸入。輸入接口的框圖如圖15-7所示。圖15-7求平方電路輸入接口框圖
接口包括兩個(gè)防抖動(dòng)電路、一個(gè)2選1選擇器、一個(gè)譯碼電路和兩個(gè)觸發(fā)器。兩個(gè)觸發(fā)器提供了設(shè)置和清零按鍵功能,當(dāng)按鈕按下時(shí),防抖動(dòng)電路輸出標(biāo)志設(shè)置有效,一直等到input指令執(zhí)行。設(shè)置選擇器的選擇信號(hào)使得數(shù)據(jù)到達(dá)PicoBlaze的輸入端口,并觸發(fā)清零信號(hào)。為了描述清楚,定義按鍵1為s按鍵,用來設(shè)置值;而按鍵0定義為c按鍵,用來對(duì)數(shù)據(jù)RAM清零。其處理過程可以用下面的偽代碼描述:
;輸入按鍵標(biāo)志
ifc=1then
;調(diào)用數(shù)據(jù)RAM清零電路
ifs=1then
;輸入撥碼開關(guān)值
;存儲(chǔ)到數(shù)據(jù)RAM當(dāng)中由于s按鍵輸入值a和b可選,因而采用一個(gè)全局寄存器switch_a_b追蹤當(dāng)前讀入值為a還是b。這個(gè)寄存器還作為數(shù)據(jù)RAM地址的偏移地址,其值可以為0或者2。當(dāng)s按鍵按下時(shí)鎖存該值。對(duì)應(yīng)的匯編代碼子程序?yàn)?/p>
;------------輸入端口定義---------------------
constantrd_flag_port,00 ;?2位標(biāo)志位(xxxxxxsc)
constantsw_port,01 ;?8位輸入撥碼開關(guān)
...
proc_btn:
inputs3,rd_flag_port ;獲取標(biāo)志
;檢查和處理按鍵c
tests3,01 ;檢查按鍵c標(biāo)志位
jumpz,chk_btns ;標(biāo)志未設(shè)置
callinit ;標(biāo)志已設(shè)置,執(zhí)行初始化程序
jumpproc_btn_done
chk_btns:
;檢查和處理按鍵s
tests3,02 ;檢查按鍵s標(biāo)志位
jump
z,proc_btn_done ;標(biāo)志位未設(shè)置
inputdata,sw_port ;獲取撥碼開關(guān)值
loadaddr,a_lsb ;獲取地址a
addaddr,switch_a_b ;?a地址與偏移地址相加
storedata,(addr) ;寫數(shù)據(jù)到RAM當(dāng)中
;更新當(dāng)前顯示位置
xorswitch_a_b,02 ;?switch_a_b在00和02之間變化
proc_btn_done:
return
15.3.3匯編程序設(shè)計(jì)
設(shè)計(jì)好I/O接口之后,可以開始設(shè)計(jì)匯編程序。按照第十四章介紹的逐個(gè)攻克法將主程序劃分成若干個(gè)子程序。主程序如下:
callinit ;初始化程序
forever:
;mainloopbody
callproc_btn ;檢查和處理按鍵
callsquare ;計(jì)算平方值
callload_led_pttn ;存儲(chǔ)LED顯示模式值到RAM中
calldisp_led ;輸出LED顯示模式值
jumpforever求平方和子程序來自于第十四章我們?cè)瓉淼脑O(shè)計(jì)。proc_btn和disp_led子程序在前面的章節(jié)中討論過。init子程序執(zhí)行系統(tǒng)初始化,其作用是用循環(huán)寫0的方式清零RAM并且設(shè)置switch_a_b寄存器為0(讀a)。load_led_pttn子程序讀切換輸入,首先從數(shù)據(jù)RAM獲取需要的值并轉(zhuǎn)換成七段數(shù)碼管可識(shí)別的格式,然后存儲(chǔ)到對(duì)應(yīng)的數(shù)據(jù)RAM中。disp_led子程序?qū)@示值寫到輸出端口上。load_led_pttn子程序包含get_upper_nibble和get_lower_nibble兩個(gè)子程序,用來提取2個(gè)四位十六進(jìn)制數(shù),hex_to_led子程序?qū)⑹M(jìn)制數(shù)轉(zhuǎn)換成七段數(shù)碼管顯示格式。
程序中所用到的寄存器比較多。除了平方和子程序需要數(shù)據(jù)存儲(chǔ)器之外,還有一個(gè)全局寄存器switch_a_b追蹤讀取a還是b的值。另外,還有4B的RAM用來存儲(chǔ)4個(gè)七段數(shù)碼管的顯示值,分別用led0、led1、led2和led3表示。
【程序15-1】求平方和子程序。
;===============================================
;帶七段數(shù)碼管接口的平方和電路
;===============================================
;程序功能:
;從撥碼開關(guān)讀取a和b的值
;計(jì)算a?×?a+b?×?b的結(jié)果
;顯示結(jié)果在七段數(shù)碼管上
;===============================================
;數(shù)據(jù)RAM地址定義
;===============================================
constanta_lsb,00
constantb_lsb,02
constantaa_lsb,04
constantaa_msb,05
constantbb_lsb,06
constantbb_msb,07
constantaabb_lsb,08
constantaabb_msb,09
constantaabb_cout,0A
constantled0,10
constantled1,11
constantled2,12
constantled3,13
;=============================================
;定義寄存器
;=============================================
;通用邏輯變量
nameregs0,data ;臨時(shí)數(shù)據(jù)寄存器
nameregs1,addr ;臨時(shí)存儲(chǔ)器或者I/O端口地址
nameregs2,i ;循環(huán)變量索引
;全局變量
nameregsf,switch_a_b;當(dāng)前開關(guān)輸入選擇以及RAM偏移地址
;==================================================
;端口變量定義
;==================================================
;------------輸入端口定義---------------------
constantrd_flag_port,00 ;?2位標(biāo)志位
constantsw_port,01 ;?8位撥碼開關(guān)
;------------輸出端口定義---------------------
constantsseg0_port,00 ;?led0
constantsseg1_port,01 ;?led1
constantsseg2_port,02 ;?led2
constantsseg3_port,03 ;?led3
;==============================================
;主程序
;==============================================
callinit ;程序初始化
forever:
;主程序循環(huán)體
callproc_btn ;檢查和處理按鍵
callsquare ;計(jì)算平方和
callload_led_pttn ;存儲(chǔ)顯示值到RAM中
calldisp_led ;顯示LED顯示值
jumpforever
;==============================================
;子程序名:init
;程序功能:執(zhí)行初始化并清零寄存器和RAM,并對(duì)switch_a_b清零
;臨時(shí)寄存器:data,i
;==================================================
init:
;清零寄存器
loadi,40 ;循環(huán)索引值為64
loaddata,00
clr_mem_loop:
storedata,(i)
subi,01 ;循環(huán)減1
jump
nz,clr_mem_loop ;重復(fù),直到i=0
;清零寄存器
loadswitch_a_b,00
return
;================================================
;子程序名:proc_btn
;程序功能:檢查兩個(gè)按鍵并處理顯示
;輸入寄存器:switch_a_b:ram地址偏移(a為0,b為2)
;輸出寄存器:s3:存儲(chǔ)輸入端口id
;臨時(shí)寄存器:data,addr
;================================================
proc_btn:
inputs3,rd_flag_port`` ;獲取標(biāo)志
;檢查和處理按鍵c
tests3,01 ;檢查按鍵c標(biāo)志位
jumpz,chk_btns ;標(biāo)志未設(shè)置
callinit ;標(biāo)志已設(shè)置,執(zhí)行初始化程序
jumpproc_btn_done
chk_btns:
;檢查和處理按鍵s
tests3,02 ;檢查按鍵s標(biāo)志位
jump
z,proc_btn_done ;標(biāo)志位未設(shè)置
inputdata,sw_port ;獲取撥碼開關(guān)值
loadaddr,a_lsb ;獲取地址a
addaddr,switch_a_b ;?a地址與偏移地址相加
storedata,(addr) ;寫數(shù)據(jù)到RAM中
;更新當(dāng)前顯示位置
xorswitch_a_b,02 ;?switch_a_b在00和02之間變化
proc_btn_done:
return
;================================================
;子程序名:load_led_pttn
;程序功能:讀取撥碼開關(guān)低三位輸入并將對(duì)應(yīng)顯示值轉(zhuǎn)換成數(shù)碼管顯示形式,裝
載到RAM中
;撥碼開關(guān)輸入譯碼值:000:a;001:b;010:a^2;011:b^2;其他a^2+b^2
;臨時(shí)寄存器:data,addr
;s6:從sw輸入數(shù)據(jù)
;================================================
load_led_pttn:
inputs6,sw_port ;獲取撥碼開關(guān)輸入
sl0s6 ;?s6內(nèi)容右移一位,獲取地址偏移值
compares6,08 ;判斷sw是否大于100
jumpc,sw_ok ;否
loads6,08 ;是,sw出錯(cuò),按默認(rèn)執(zhí)行sw_ok:
;處理字0節(jié)低四位
loadaddr,a_lsb
addaddr,s6 ;獲取低地址
fetchdata,(s6) ;獲取低字節(jié)
callget_lower_nibble ;獲取低4位
callhex_to_led ;轉(zhuǎn)換成led顯示模式
storedata,led0
;處理0字節(jié)高四位
fetchdata,(addr)
callget_upper_nibble
callhex_to_led
storedata,led1
;處理1字節(jié)低四位
addaddr,01 ;獲取高地址
fetchdata,(addr)
callget_lower_nibble
callhex_to_led
storedata,led2
;處理1字節(jié)高四位
fetchdata,(addr)
callget_upper_nibble
callhex_to_led
;檢查sw是否等于100來處理led小數(shù)點(diǎn)的進(jìn)位
compares6,08 ;是否顯示最終結(jié)果
jump
nz,led_done ;否
addaddr,01 ;獲取進(jìn)位地址
fetchs6,(addr) ;寄存器存儲(chǔ)進(jìn)位
tests6,01 ;測(cè)試進(jìn)位寄存器是否為1
jump
z,led_done ;否
anddata,7F ;是,賦值最高位(dp)為0
led_done:
storedata,led3
return
;=================================================
;子程序:disp_led
;功能:輸出四位led顯示值
;臨時(shí)寄存器:data
;==============================================
disp_led:
fetchdata,led0
outputdata,sseg0_port
fetchdata,led1
outputdata,sseg1_port
fetchdata,led2
outputdata,sseg2_port
fetchdata,led3
outputdata,sseg3_port
return
;===============================================
;子程序:hex_to_led
;功能:轉(zhuǎn)換十六進(jìn)制數(shù)為七段數(shù)碼顯示模式
;輸入寄存器:data
;輸出寄存器:data
;================================================
hex_to_led:
comparedata,00
jumpnz,comp_hex_1
loaddata,81 ;顯示0
jumphex_done
comp_hex_1:
comparedata,01
jumpnz,comp_hex_2
loaddata,CF ;顯示1
jumphex_done
comp_hex_2:
comparedata,02
jumpnz,comp_hex_3
loaddata,92 ;顯示2
jumphex_done
comp_hex_3:
comparedata,03
jump
nz,comp_hex_4
loaddata,86 ;顯示3
jumphex_done
comp_hex_4:
comparedata,04
jump
nz,comp_hex_5
loaddata,CC ;顯示4
jumphex_done
comp_hex_5:
comparedata,05
jump
nz,comp_hex_6
loaddata,A4 ;顯示5
jumphex_done
comp_hex_6:
comparedata,06
jump
nz,comp_hex_7
loaddata,A0 ;顯示6
jumphex_done
comp_hex_7:
comparedata,07
jump
nz,comp_hex_8
loaddata,8F ;顯示7
jumphex_done
comp_hex_8:
comparedata,08
jump
nz,comp_hex_9
loaddata,80 ;顯示8
jumphex_done
comp_hex_9:
comparedata,09
jump
nz,comp_hex_a
loaddata,84 ;顯示9
jumphex_done
comp_hex_a:
comparedata,0A
jump
nz,comp_hex_b
loaddata,88 ;顯示A
jumphex_done
comp_hex_b:
comparedata,0B
jump
nz,comp_hex_c
loaddata,E0 ;顯示B
jumphex_done
comp_hex_c:
comparedata,0C
jump
nz,comp_hex_d
loaddata,B1 ;顯示C
jumphex_done
comp_hex_d:
comparedata,0D
jump
nz,comp_hex_e
loaddata,C2 ;顯示D
jumphex_done
comp_hex_e:
comparedata,0E
jump
nz,comp_hex_f
loaddata,B0 ;顯示E
jumphex_done
comp_hex_f:
loaddata,B8 ;顯示F
hex_done:
return
;====================================
;子程序:get_lower_nibble
;功能:獲取數(shù)據(jù)低4位
;輸入寄存器:data
;輸出寄存器:data
;===============================================
get_lower_nibble:
anddata,0F ;清零高4位
return
;================================================
;子程序:get_upper_nible
;子程序功能:獲取輸入數(shù)據(jù)in_data的高4位
;輸入寄存器::data
;輸出寄存器:data
;=============================================
get_upper_nibble:
sr0data ;右移四次
sr0data
sr0data
sr0data
return
;==============================================
;子程序:square
;子程序功能:計(jì)算a?×?a+b?×?b
;數(shù)據(jù)結(jié)果存儲(chǔ)的RAM開始地址為SQ_BASE_ADDR
;臨時(shí)變量:s3,s4,s5,s6,data
;=============================================
square:
;計(jì)算a?×?a
fetchs3,a_lsb ;裝載a值
fetchs4,a_lsb ;裝載a值
callmult_soft ;計(jì)算a?×?a
stores6,aa_lsb ;存儲(chǔ)a?×?a結(jié)果的低字節(jié)
stores5,aa_msb ;存儲(chǔ)a?×?a結(jié)果的高字節(jié)
;計(jì)算b?×?b
fetchs3,b_lsb ;裝載b值
fetchs4,b_lsb ;裝載b值
callmult_soft ;計(jì)算b?×?b
stores6,bb_lsb ;存儲(chǔ)b?×?b結(jié)果的低字節(jié)
stores5,bb_msb ;存儲(chǔ)b?×?b結(jié)果的高字節(jié)
;計(jì)算a?×?a+b?×?b
fetchdata,aa_lsb ;獲取a?×?a的低字節(jié)
adddata,s6 ;計(jì)算a?×?a?+?b?×?b的低字節(jié)之和
storedata,aabb_lsb ;存儲(chǔ)a?×?a?+?b?×?b的低字節(jié)
fetchdata,aa_msb ;獲取a?×?a的高字節(jié)
addcydata,s5 ;計(jì)算a?×?a?+?b?×?b的高字節(jié)之和
storedata,aabb_msb ;存儲(chǔ)a?×?a?+?b?×?b的高字節(jié)
loaddata,00 ;清零數(shù)據(jù),但是保持進(jìn)位
addcydata,00 ;獲取前一次加法的進(jìn)位值
storedata,aabb_cout ;存儲(chǔ)a?×?a?+?b?×?b的進(jìn)位值
return
;================================================
;子程序:mult_soft
;程序功能:使用移位和與操作的8位無符號(hào)乘法器
;輸入寄存器:s3—被乘數(shù);s4—乘數(shù)
;輸出寄存器:s5—乘積高字節(jié);s6—乘積低字節(jié)
;臨時(shí)寄存器:i
;================================================
mult_soft:
loads5,00 ;清零s5寄存器
loadi,08 ;初始化循環(huán)變量i
mult_loop:
sr0s4 ;移位最低位到進(jìn)位寄存器
jump
nc,shift_prod;最低位是0
adds5,s3 ;最低位是1
shift_prod:
sras5 ;右移高字節(jié),進(jìn)位寄存器移位到最高位
;最低位移位到進(jìn)位寄存器
sras6 ;右移低字節(jié)
;?s5的低位移位到s6的高位
subi,01 ;循環(huán)減
jump
nz,mult_loop;重復(fù),直到i=0
return
15.3.4HDL程序開發(fā)
完整的HDL程序包括PicoBlaze、指令ROM、輸入接口,如圖15-7所示的外設(shè)、輸出接口,以及圖15-6所示的外設(shè)等。完整的程序如程序15-2所示。
【程序15-2】接口HDL程序。
modulepico_btn
(
input
wireclk,reset,
input
wire[7:0]sw,
input
wire[1:0]btn,
output
wire[3:0]an,
output
wire[7:0]sseg
);
//信號(hào)聲明
//KCPSM3以及ROM信號(hào)
wire[9:0]address;
wire[17:0]instruction;
wire[7:0]port_id,out_port;
reg[7:0]in_port;
wirewrite_strobe,read_strobe;
//I/O端口信號(hào)
//輸出使能
reg[3:0]en_d;
//4位七段數(shù)碼管顯示
reg[7:0]ds3_reg,ds2_reg,ds1_reg,ds0_reg;
//兩個(gè)按鈕
regbtnc_flag_reg,btns_flag_reg;
wirebtnc_flag_next,btns_flag_next;
wireset_btnc_flag,set_btns_flag,clr_btn_flag;
//主體
//===========================================
//I/O模塊
//==================================================
disp_muxdisp_unit
(.clk(clk),.reset(reset),
.in3(ds3_reg),.in2(ds2_reg),.in1(ds1_reg),
.in0(ds0_reg),.an(an),.sseg(sseg));
debouncebtnc_unit
(.clk(clk),.reset(reset),.sw(btn[0]),
.db_level(),.db_tick(set_btnc_flag));
debouncebtns_unit
(.clk(clk),.reset(reset),.sw(btn[1]),
.db_level(),.db_tick(set_btns_flag));
//===========================================
//例化KCPSM和ROM模塊
//===========================================
kcpsm3proc_unit
(.clk(clk),.reset(1'b0),.address(address),
.instruction(instruction),.port_id(port_id),
.write_strobe(write_strobe),.out_port(out_port),
.read_strobe(read_strobe),.in_port(in_port),
.interrupt(1'b0),.interrupt_ack());
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 深度解析(2026)GBT 19212.11-2020變壓器、電抗器、電源裝置及其組合的安全 第11部分:高絕緣水平分離變壓器和輸出電壓超過1000V的分離變壓器的特殊要求和試驗(yàn)
- 財(cái)務(wù)面試寶典財(cái)務(wù)知識(shí)面試題及答案
- 光纖融接設(shè)備項(xiàng)目可行性分析報(bào)告范文
- 實(shí)戰(zhàn)面試題員工自助崗運(yùn)營(yíng)專員崗位解析與參考答案
- 物流主管面試題庫與參考答案
- 系統(tǒng)集成項(xiàng)目經(jīng)理的職位全解及答案
- 特殊人群毒理數(shù)據(jù)亞組展示策略
- 深度解析(2026)《GBT 18481-2001電能質(zhì)量 暫時(shí)過電壓和瞬態(tài)過電壓》
- 電信行業(yè)網(wǎng)絡(luò)運(yùn)營(yíng)總監(jiān)面試題網(wǎng)絡(luò)優(yōu)化與安全保障
- 工程項(xiàng)目經(jīng)理職位的招聘面準(zhǔn)備題集
- 醫(yī)藥KA經(jīng)理工作總結(jié)
- 南京市煙草公司2025秋招市場(chǎng)分析崗位面試模擬題及答案
- 冠脈痙攣診療新進(jìn)展
- 舞蹈培訓(xùn)機(jī)構(gòu)薪酬制度設(shè)計(jì)方案
- 乙肝抗病毒治療禁忌癥
- 中職電動(dòng)機(jī)正反轉(zhuǎn)教學(xué)教案示范
- 2025年煤礦礦長(zhǎng)招聘考試題庫
- DB1331∕T 034-2022 建筑與市政工程無障礙設(shè)計(jì)圖集
- 《ISO 37001-2025 反賄賂管理體系要求及使用指南》專業(yè)深度解讀和應(yīng)用培訓(xùn)指導(dǎo)材料之4:6策劃(雷澤佳編制-2025A1)
- 委托加工項(xiàng)目管理制度
- 房屋結(jié)構(gòu)安全培訓(xùn)
評(píng)論
0/150
提交評(píng)論