5-1 繪電路頻率響應分析
以繪圖方式如圖5-1所示除16二進位同步除頻器之電路動作原理已於前幾章討論過,經組譯後其CPLD各LEs元件配置使用情形如圖5-1所示。
圖5-1 同步4位元計數器電路
圖5-2 同步4位元計數器之LE配置圖
請與我們聯絡
將圖5-1電路予以設定並組譯後經時間延遲測試後顯示如圖5-3,其延遲最差情況下為14.3ns故其時脈衝最高輸入頻率達69.93MHz。
圖5-3 同步4位元計數器之頻率及延遲速度測試
圖5-4 為各路徑執行之延遲時間表,其中最長是由D型正反器54輸入端到正反器67之輸出端為12.5ns,再加上
輸入同步時鐘波經各正反器反應將其輸入D之資料輸入組合反應到輸出端Q時之正反器執行時間1.8ns總共為14.3ns也就是說由最遠的正反器54號之D資料輸入端傳達到最後一級正反器67號之資料輸入控制D67=(Q54&Q57&Q63)$Q67
(EN=Vcc)等運算延遲12.5ns再加上時脈CLOCK上升穩定時間和正反器將D輸入資料反應輸出到Q67端之執行時間1.8ns
故總共需14.3ns為整個電路之最大延時路徑,若輸入時脈CLOCK短於14.3ns即頻率高於69.93MHz時此除頻電路將無法正確地對應輸入時脈作反應便產生錯誤之計數或除頻等工作,各級之輸入對應輸出延時可由圖5-4表格中分析如下:(注意!54到54之延時意指輸出Q回授到本級之D輸入端)
圖5-4 為圖5-1電路各元件執行之延遲路徑表(LIST
PATH)
1. 各級正反器對應D輸入到輸出之延時都為3.2ns再加上正反器延時1.8ns故各級輸入經時脈CLOCK
控制傳出Q端之總延時為5.0ns但第一級54號正反器輸入組合邏輯少一個串接故僅2.3ns+1.8ns=4.1ns。
2. 由54輸出端到57號輸入端之延時為5.1ns,54到63為8.8ns而54到67則為12.5ns另外57到63為7.7ns且63到67也是7.7ns,若要對應時脈輸入則需加上1.8ns才對。
3. 注意!在前幾章中所介紹的CPLD架構中LEs之組合邏輯是由LUT組成,因此其本級之執行延時都是相等且極快速的,唯一的延時是發生在後級之資料需由前級輸出訊號組合後再予輸入控制,因此大大降低了其執行速度。
提高頻率響應及執行速度有四種方法:
1. 化簡整個電路之結構使得到最佳化之架構。
2. CPLD之LEs元件配置及對應輸出入接腳之設定以為最簡短。
3. 各級如加法器(ADDER)計數器(COUNTER)等之串接盡量以使用最短接線且快速僅0.6ns之進位鏈(CARRY)或其它運算用之串接(CASCADE)鏈,在多位元運算中使用專用之串級方式速度可相當的提高。
4. 計數器需盡量使用同步式故輸入脈衝波可使用全區式專用輸入線(Ded
Input),且在多級同步資料輸入控制中予以截斷而以管線(Pipline)正反器將資料先栓鎖穩定後延遲一個時脈再予同步推出,這樣資料傳輸之穩定時間被切一半故時脈約可增加一倍,此技巧稱為管線控制(Pipline)。
電路之化簡在ALTERA組譯器中會自動予以簡化架構成各種CPLD之LEs格式,而接腳設定可以在組譯前由ASSIGN功能設定為AUTO自動選擇設定及快速(FAST)
之執行指定等由組譯器予以自動轉移選擇控制即可,另外的使用進位鏈(CARRY)在計數器上是十分有效率的。
5-1-1 使用進位鏈之四位元計數除頻器之頻率響應分析
圖5-5即在每一級使用其LE之進位鏈(CARRY)將各級Q輸出串接到下一級之輸入LUT組合邏輯控制端,要使用進位鏈時需由PRIM檔案中取得進位(CARRY)符號加以串接即可,將圖5-5予以設定並組譯後測試其延時及頻率響應如圖5-6所示,可見頻率提高到185.18MHz而延時就縮短到僅5.4ns這麼短了,可見善於利用進位鏈串接使頻率響應提高是非常重要的。
圖5-5 使用進位鏈串接之同步4位元計數器電路
圖5-7為各級之延時表,各正反器D輸入到Q輸出之穩定及執行時間仍為1.8ns但各級輸出傳到下幾級之輸入延時卻短少相當多了,此即使用進位(CARRY)鏈之好處,但進位鏈使用時需對照LE邏輯架構組合下應特別注意如下!
圖5-6 使用進位鏈串接之同步4位元計數器之延時及頻率響應測試
圖5-7 使用進位鏈串接之同步4位元計數器之各路徑延時表
1. 本級CI輸入端可驅動一個或二個的邏輯輸入點,除了一般態模式外其它如算術,上下計數,可清除之計數器等模式若驅動二個邏輯運算輸入時必需在同一個LE內且其中一個必需是為進位鏈輸出CO。
2. 使用進位鏈輸入CI時(也就是說上一級之CO)能跟此輸入端一起對外作運算之輸入最多也僅可二個輸入端且必需是相同之輸入訊號,若有第三個時其就僅為此進位鏈CI輸入了。
3. 一個進位鏈輸出CO驅動另一個LE之邏輯輸入點後此進位鏈輸出就可驅動二個輸入端若有第三個時其必需為進位鏈輸入才可以。
4. 進位鏈處於LE元件之LUT前導輸入端,故不可作為外部輸入端或輸出端使用。
5. 二個進位鏈是不可以驅動同一個邏輯閘的。
5-1-2 使用管線結點16位元計數除頻器之頻率響應分析
同步並列計數器利用各級輸出狀態予以組合串接控制其D型正反器之D輸入控制端,因此若使用多位元控制時將因串接組合多級而造成多層之延時而使得頻率響應大大降低,前述之採用進位鏈可減少延時時間,另一種方法就是在計數器或除頻器各位元與串接中間予以截斷再插入一時脈延時正反器將前級之輸出控制資料予以栓鎖住,等待其穩定後下一個時脈來臨時再作為下一級之控制資料,如圖5-8所示16位元計數除頻器在第8位元進位輸出CO端串接進位鏈進入一個D型正反器之D輸入端再由其Q輸出端串接進位鏈緩衝接入下一級第9級之致能(EN)控制輸入端予以控制,此時由第一級EN輸入控制到第8級之CO輸出總延時時間為DT1,接著將管線結輸出Q(延後一個時脈C之CO訊號)進入第9級之控制端,第9到第15級之總延時亦為DT1而非2DT1,可見此種管線結會將延時時間減半提高了計數或除頻之頻率響應,但有一個缺點就是!整個計數器值輸出將非對應正確,及第9到16級會延後一個時脈C對應計數,但對應第1到第8位元計數仍正常之計數,也就是說第1到8位計數到第255個脈衝時計數值為11111111時其CO輸出為1,而在下一個第256個時脈來臨時管線結正反器Q輸出才為1而第1-8計數值為00000000,但第9-16卻未進位仍為00000000直到下一個脈衝(第257)來臨時因Q=1而令9-16級輸出為00000001但此時第1-8級輸出已計數到00000001值,即將輸出為00000001
00000000之狀態(256顯示值)消失掉轉移入管線結正反器Q輸出端,但第257個脈衝值00000001
00000001卻正確輸出顯示了,故在256計數值會轉成0000 0000 0000 0000及Q=1之狀態直到第257時才正確顯示0000
0001 0000 0001值,但對整個除頻之第16級輸出CO時脈卻毫無影響,作計數器時解碼需將Q輸出加入運算處理即可。
圖5-8 使用管線結(Pipline)作16位元同步除頻電路圖(CNTLNG.gdf)
圖5-9即將圖5-8電路予以組譯後所測出之延時及頻率響應,圖5-10為各級段之延時區段表,其中第16單元到第11單元之前8位元除頻最長延時僅為5.5ns加上正反器之穩定執行時間1.8ns故對應時脈反應為7.3ns而第11到輸出第15端之延時為6.1ns加上1.8ns等於7.9ns,此因Q正反器多了個進位鏈0.6ns,但整個除頻電路已被分割成獨立單元因此整個除頻電路之最大延時則為第11到第15輸出之7.9ns頻率響應達126.58MHz了。
圖5-9 使用管線結(Pipline)作16位元同步除頻之延時及頻率響應
圖5-10 使用管線結(Pipline)作16位元同步除頻之各級段之延時表
圖5-11 未使用管線結(Pipline)作16位元同步除頻電路圖(CNTLNGN.gdf)
另外若不使用管線結作除頻緩衝予以提升其除頻速度時如圖5-11電路,其延時及頻率響應如圖5-12所示降低到80.0MHz之頻率響應延時達12.5ns,圖5-13為各級延時表由第11級Q0輸出到最後一級第12之Q3輸出端延時增為10.7ns再加上正反器之穩定及傳輸轉換延時時間1.8ns總計由最前級輸入到最後一級Q3輸出延時為12.5ns即80.0MHz頻率響應。
圖5-12 未使用管線結(Pipline)作16位元同步除頻之延時及頻率響應
圖5-13 未使用管線結(Pipline)作16位元同步除頻之各級段之延時表
5-2 24小時時鐘計數之HDL描述控制
計時及模式設定僅有分及時分別為24及60之調整設定和正常計時等三種模式,因此stmode[1..0]僅二位元,但多了24小時之計時故需多了個cnte[3..0]及cntf[1..0]等二組計數器,時基除頻divcnt[24..0]及分計數cntc[3..0]及cntd[2..0]和秒計數cnta[3..0]及cntb[2..0]等時間計數控制,另外按鍵同步脈衝產生器共需二組即stka[1..0]及stkb[1..0],計時顯示及調整模式之移位暫存器stmode[1..0]和管線結速度提升正反器pulsa,pulsl及pulsh等三個D正反器以及使用於按鍵雜訊消除之延時取樣計時dbpuls[1..0]之D正反器共使用了56個暫存器,這些暫存器都是以sysclk輸入之20MHz頻率作同步計數及控制用。
輸入端有sysclk脈衝及調整設定按鍵btna及btnb等二只,而輸出則由七段LED顯示解碼之輸出端segout[6..0]等七段陣列驅動四位七段LED之共接陽極A-F段,其陰極則由4對1解碼掃描之selout[3。。0]
四位元分別驅動各對應陰極顯示端,並有dotout小數點對應計時及調整設定模式隨著掃描予以對應顯示,整個的HDL描述及部分對應說明如下:
SUBDESIGN
timerd2
( sysclk,btna,btnb
: INPUT;
segout[6..0],dotout,selout[3。。0]:OUTPUT;)
VARIABLE
cnta[3..0],cntb[2..0],cntc[3..0],cntd[2.0],cnte[3..0],cntf[1..0]:DFF;
divcnt[24..0],pulsa,pulsh,pulsl:DFF;
dbpuls[1..0],stka[1..0],stkb[1..0],stmode[1..0]:DFF;
cntout[3..0],sel[1..0],dotc,dotd,dote,dotf:NODE;
BEGIN
(divcnt[],cnta[],cntb[],cntc[],cntd[],cnte[],cntf[],pulsa,pulsl,pulsh,dbpuls[],stka[],stkb[],stmode[]).clk=sysclk;
IF(divcnt[]==19999999)
THEN
divcnt[]=0;
IF(stmode[]==B"00")
THEN pulsa=VCC; ELSE pulsa=GND; END IF;
ELSE
%pulsa為管線結正反器提升工作頻率降低延時時間%
divcnt[]=divcnt[]+1;
pulsa=GND;
END IF;
IF(pulsa)
THEN
IF(cnta[]==9)
THEN
cnta[]=0;
ELSE
cnta[]=cnta[]+1;
END IF;
ELSE
cnta[]=cnta[];
END IF;
IF(pulsa &
cnta[]==9) THEN
IF(cntb[]==5)
THEN
cntb[]=0;
ELSE
cntb[]=cntb[]+1;
END IF;
ELSE
cntb[]=cntb[];
END IF;
pulsl=pulsa
& cnta[]==9 & cntb[]==5;
%pulsl為管線結正反器提升工作頻率降低延時時間亦即"秒"之計數達59%
%值及一秒計時pulsa=1到時之條件狀態截割%
IF(pulsl
# stmode[]==B"01" & stkb[0]) THEN
IF(cntc[]==9)
THEN
cntc[]=0;
ELSE
cntc[]=cntc[]+1;
END IF;
ELSE
cntc[]=cntc[];
END IF;
IF((pulsl
# stmode[]==B"01" & stkb[0]) & cntc[]==9) THEN
IF(cntd[]==5)
THEN
cntd[]=0;
ELSE
cntd[]=cntd[]+1;
END IF;
ELSE
cntd[]=cntd[];
END IF;
%pulsh為管線結正反器提升工作頻率降低延時時間亦即為前述"分"%
%計數達59且"秒"=pulsl也為HI=1之計數達59時之條件狀態截割%
pulsh=pulsl
& cntc[]==9 & cntd[]==5;
%若上述條件成立或或調時按鍵於stmode[]=10模式且壓放調整脈衝已輸入時%
IF(pulsh
# stmode[]==B"10" & stkb[0]) THEN
%當"時"計數器十位數cntf[]=2及個位數cnte[]=3或者cnte[]=9則令cnte[]=0%
%即"時"計數到23小時或時之個位數已達9時,需在下一個脈衝來前令其歸零%
IF((cntf[]==2
& cnte[]==3) # cnte[]==9) THEN
cnte[]=0;
ELSE
%否則"時"之個位數可繼續依sysclk時序計數遞增%
cnte[]=cnte[]+1;
WHEN 2 =>
cntout[]=(B"0",cntd[]);
selout[]=B"0010";
dotout=dotd;
WHEN 3
=>
cntout[]=cntc[];
selout[]=B"0001";
dotout=dotc;
END CASE;
TABLE
cntout[]
=> segout[];
H"0"
=> B"1111110";
H"1"
=> B"0110000";
H"2"
=> B"1101101";
H"3"
=> B"1111001";
H"4"
=> B"0110011";
H"5"
=> B"1011011";
H"6"
=> B"1011111";
H"7"
=> B"1110000";
H"8"
=> B"1111111";
H"9"
=> B"1111011";
END TABLE;
%雜訊消除用之取樣控制時序dbpuls[0]由25位元除頻器之第19位元或%
%第18位元divcnt[19]約為40ms-20ms取樣延時輸出單一無雜訊脈衝控制%
%此電路描述類同於圖11-23但KEY輸入是由divcnt[19]輸入控制%
CASE dbpuls[]
IS %對應dbpuls[]暫存器之狀態碼作條件轉移控制%
WHEN B"00"
=> %當dbpuls[]=00時轉移條件時%
IF(divcnt[19])
THEN %若除頻divcnt[19]=1來臨輸出為HI=1時則%
dbpuls[]=B"01";
%令dbpuls[]轉成01值產生dbpuls[0]之HI態%
ELSE
%否則將其維持於dbpuls[]=00原值%
dbpuls[]=B"00";
END IF;
%結束IF之條件敘述%
WHEN B"01"
=> %當dbpuls[]=01態時下一個sysclk來臨轉成10態%
dbpuls[]=B"10";
%即令dbpuls[0]輸出一個sysclk之脈衝波%
WHEN B"10"
=> %當dbpuls[]=10態時%
IF(!divcnt[19])
THEN %若divcnt[19]=0時則令轉回dbpuls[]=00態%
dbpuls[]=B"00";
%即divcnt[19]=0態後才令dbpuls[]=00之起始態%
ELSE %否則將維持於dbpuls[]=10原值不能再由dbpuls[0]輸出脈衝%
dbpuls[]=B"10";
END IF;
%結束IF之條件敘述%
END CASE;
%狀態條件描述完畢%
%下述電路描述類同於圖11-23之按鍵電路但多加了dbpuls之雜訊消除控制%
CASE stka[]
IS
WHEN B"00"
=>
IF(btna
& dbpuls[0]) THEN %若btna按鍵壓下及dbpuls[0]=1狀態下則%
stka[]=B"01";
%可令stka[]在sysclk來臨轉態為01即在btna壓下%
ELSE
%後間隔dbpuls[0]=1之約為20-40ms延時雜訊消除控制下%
stka[]=B"00";
%否則令stka[]維持原00態%
END IF;
%條件判別對應執行完畢%
WHEN B"01"
=> %當stka[]=01時在下個sysclk可轉態為10%
stka[]=B"10";
%令stka[0]輸出一個sysclk脈衝%
WHEN B"10"
=> %當stka[]=10態時在btna放開及dbpuls[0]=1時即約隔%
IF(!btna
& dbpuls[0]) THEN %20ms-40ms才可對應將%
stka[]=B"00";
%stka[]轉回00初態而可重新由btna壓放產生脈衝%
ELSE
%否則將令stka[]維持原10態不能再產生脈衝%
stka[]=B"10";
END IF;
%結束按鍵放開及dbpuls[0]=1之雜訊延時消除控制描述%
WHEN B"11"
=> %若stka[]=11之不正常態則在下個sysclk來臨回到00態%
stka[]=B"00";
END CASE;
%結束stka[]按鍵雜訊消除及單一脈衝產生之描述態%
%stkb[]之設定控制與stka相同%
CASE stkb[]
IS
WHEN B"00"
=>
IF(btnb
& dbpuls[0]) THEN
stkb[]=B"01";
ELSE
stkb[]=B"00";
END IF;
WHEN B"01"
=>
stkb[]=B"10";
WHEN B"10"
=>
IF(!btnb
& dbpuls[0]) THEN
stkb[]=B"00";
ELSE
stkb[]=B"10";
END IF;
WHEN B"11"
=>
stkb[]=B"00";
END CASE;
%"時"與"分"之計時及調整僅有三種模式故以stmode[1..0]作狀態機%
CASE stmode[]
IS
WHEN B"00"
=>
(dotd,dote)=(divcnt[24],divcnt[24]);
%(dotc,dotf)=(!divcnt[24],!divcnt[24]);%
IF(stka[0]==1)
THEN
stmode[1]=VCC;
ELSE
stmode[1]=GND;
END IF;
WHEN B"1X"
=>
(dotf,dote)=(divcnt[24],divcnt[24]);
(dotd,dotc)=(GND,GND);
IF(stka[0]==1)
THEN
stmode[]=B"01";
ELSE
stmode[]=B"10";
END IF;
WHEN B"X1"
=>
(dotd,dotc)=(divcnt[24],divcnt[24]);
(dotf,dote)=(GND,GND);
IF(stka[0]==1)
THEN
stmode[0]=B"0";
ELSE
stmode[0]=B"1";
END IF;
END CASE;
END;
注意!對應設定及調整之按鍵開關可使用一般沒有雜訊消除之二點式ON/OFF開關即可以,接腳之配置因沒有將秒計時拉線輸出故可將P01-P08去掉原P81,P83之按鍵改接到P01,P02端即可,設定及取材或此電路之CPLD資料結構位元可以CPLD主動串列式由燒錄於SEEPROM
內讀取結構化或搭配單晶片892051或PIC或89C52等將其燒錄於其內部ROM或其它外部PROM或SROM透過單晶片讀取再令CPLD以被動串列式載入電路結構資料於CPLD內部SRAM內就可完成即時之時鐘控制和單晶片微控系統了。
5-3 精簡指令RISC架構單晶CPU之設計
一般RISC精簡指令都是十分簡易之運作,故執行速度都在幾個脈衝週期就可完成,因而可以管線結模式(PipeLine)造成相對應一個執行週期之速度,一般RISC架構執行都是4到5個週期之延後執行完成,但對每個週期都有對整個指令進行執行,故對應每個指令都是一個週期執行時間,本設計系統是採用4個執行循環週期,繪表5-1說明如下:
表5-1 4個執行週期之指令管線結(Instruction
PipeLine)執行序表
CLK1
CLK2
CLK3
CLK4
CLK5
CLK6
CLK7
CLK8
IST Ft/Dc
(PC)
IST Ft/Dc
(PC+1)
IST Ft/Dc
(PC+2)
IST Ft/Dc
(PC+3)
IST Ft/Dc
(PC+4)
IST Ft/Dc
(PC+5)
IST Ft/Dc
(PC+6)
IST Ft/Dc
(PC+7)
OP/RD
(PC-1)
OP/RD
(PC)
OP/RD
(PC+1)
OP/RD
(PC+2)
OP/RD
(PC+3)
OP/RD
(PC+4)
OP/RD
(PC+5)
OP/RD
(PC+6)
EXE
(PC-2)
EXE
(PC-1)
EXE
(PC)
EXE
(PC+1)
EXE
(PC+2)
EXE
(PC+3)
EXE
(PC+4)
EXE
(PC+5)
RG/WR
(PC-3)
RG/WR
(PC-2)
RG/WR
(PC-1)
RG/WR
(PC)
RG/WR
(PC+1)
RG/WR
(PC+2)
RG/WR
(PC+3)
RG/WR
(PC+4)
IST Ft/Dc
= 指令及資料抓取並予指令解碼控制週期
OP/RD = 運算元(Operand)之資料讀取動作週期
EXE = 對應指令將運算元執行運算控制週期
RG/WR = 運算結果需將其寫入運算元內之控制動作週期
從上面之指令管線結動作時序表中可見RISC指令精簡劃一,均為4個週期就可完成,故可予以管線結控制,也就是說每個週期都可同時作本程式計數器PC之指令及資料抓取並予指令解碼控制IST
Ft/Dc,對應上一個程式計數器(PC-1)之運算元(Operand)之資料讀取動作OP/RD,以及上上個程式計數器(PC-2)之指令對應運算及執行控制等EXE,並對應上上上個程式計數器(PC-3)之指令對應運算結果後所需之運算元之回寫入控制RG/WR,因此在每個週期都有EXE及RG/WR控制執行,故可以說是每個指令執行速度為一個CLOCK脈衝週期,只是會延後4個CLOCK脈衝時間才出現結果的,但對應整個執行速度是一個脈衝CLOCK週期,比起PIC單晶片之4個週期為一個指令執行速度要快多了,再比起8051族系之12個執行週期就更不用說了,由此可見以精簡RISC指令所設計之CPU是快速無比的.
5-3-1 CPU內部暫存器及I/O埠之設計
CPU內部共設計有16個8位元寬暫存器,分別編號為0-F共四位元定址,但其中C,D,E,F為I/O輸入輸出埠共4×8=32個,I/O之輸出入方向設定各分高低四位元8組個別由B暫存器內含予以設定1為輸出,0為高組抗三態輸入,即B暫存器內D7,D6設定控制C之I/O輸出入模態,而D5,D4設定D之I/O輸出入模態,D3,D2設定控制E之I/O輸出入模態,D1,D0設定控制F之I/O輸出入模態,其控制對應各I/O輸出入如表5-2所示。
表5-2 C,D,E,F共32個I/O埠分8組由B暫存器設定控制作輸出輸入
暫存器
各I/O埠之高四位元設定
各I/O埠之低四位元設定
備註
B
D7 D6 D5
D4 (1為輸出0為輸入)
D3 D2 D1
D0(1為輸出0為輸入)
控制
C
(I/OC7 -
I/OC4)由B之D7控制
(I/OC3 -
I/OC0)由B之D6控制
I/O
D
(I/OD7 -
I/OD4)由B之D5控制
(I/OD3 -
I/OD0)由B之D4控制
I/O
E
(I/OE7 -
I/OE4)由B之D3控制
(I/OE3 -
I/OE0)由B之D2控制
I/O
F
(I/OF7 -
I/OF4)由B之D1控制
(I/OF3 -
I/OF0)由B之D0控制
I/O
除了B,C,D,E,F五個暫存器作32個I/O埠控制及作輸出入用外,其餘0-A共11個為一般通用暫存器可用作各種運算處理等使用.
5-3-2 CPU內部暫存器及資料之運算控制
暫存器共有16個故需由ws[3..0]四個定址暫存器加以選擇,要加入運算器ALU之暫存器X及Y運算元由MUXA及MUXB二組16對1之8位元多工器加以選擇各由RESULT端輸出到暫存器RGA及RGB端暫存,此為IST
Ft/Dc第一個CLOCK步驟,接著在第二個CLOCK之OP/RD讀取暫存器內含時需各別由RGAB及RGBB暫存器緩衝讀取再加入ALU之Ain及Bin之二個輸入端,但在與資料運算之OP
TT,X,#DDH模式時是將上端RGAB與資料DDH運算而非與RGBB運算,故此需一個由ALDB控制之多工器選擇指令資料端之pdx[7..0]=#DDH予以輸入ALU之Bin端參與運算,如圖5-14所示,ALU之運算模式有ADD,SUB,AND,OR等四種功能由pdx[13..12]所截取存入alosel[1..0]暫存器內再加以輸出控制,ALU輸出alo[7..0]輸出必需在第三個CLOCK脈衝週期同步地存於rdi[7..0]暫存器內,ALU加減運算後第9位元即ALO[8]則為進位或借位輸出CF之訊號,當運算完成後在第四個CLOCK脈衝週期RG/WR同步地由weny控制寫入暫存器內(wen記存第一個時序時有write指令,wenx記存第二個時序,如此則完成一個指令之執行,圖中標示“e”即代表由脈衝波CLOCK予以同步控制的.
圖5-14 暫存器之資料運算控制結構方塊圖
5-3-3 程式計數器PC之運算控制
對應程式計數器PC之遞增加一或JMP指令之跳躍改到任意A11-A0位址或條件跳躍指令JP
CC,ADR當CC條件之JZ,JNZ,JC,JNC等成立時就需將程式計數器改到ADR相對位址端,也就是說將PC值與ADR位址相加產生程式分支功能,而對應CALL及RET指令則在CALL指令將PC存於堆疊STK內再進行跳躍到相對差值ADR位址,而當執行RET指令時需由STK之暫存器內取回原CALL時存入之PC位址值而跳回主程式,程式計數器PC運算控制方塊如圖5-15所示.
圖5-15方塊結構中可見當執行JMP,JP
CC,ADR等執令時,以pcadmxx暫存器作栓鎖狀態時序判別及確認PC要轉移位址,也就是說必需確認前面所有狀態pcadmxx處於非動作態pcadmxx=0且在條件解碼(本指令第2時序)條件CC都成立時tcnd=1,同時在此指令解碼時第一個時序確認非處於前時序之jmp指令環境下pcadmx=1,也就是說在此第2時序來臨時再確認前2指令非為jmp指令時才可令pcadmxx=1栓鎖作jmp相對位址ADR之運算跳躍,因此改變PC指令是在第3個時序便轉變了PC值出現,若是CALL指令時會令pushst堆疊旗號標誌著在pcadmxx=0態下為1,並以pushstx暫存器栓鎖記存,然後在第2時序將pcx[11..0]=ADR資料栓鎖入sp[i][11..0]內,將並令堆疊指標sp[i]減1(或加1都可以)以便下一個CALL指令再推入sp-1位址內,而當執行到RET指令時會將標誌pcmx在pcadmxx=0條件下令其栓鎖標記著1值,同時在第2個時序時轉記存入pcmxx暫存器內,同樣需pcadmxx=0即前指令不是jmp執行時才會令pcmxx=1,在pcmx=1及pcadmxx=0時令sp[i]+1以便設定前CALL指令時所推入sp[i]之內含值,故堆疊暫存器之多工muxstk.sel[i]=sp[i]加以選擇正確之堆疊暫存器內含由muxstk.dat[i][11..0]=
stk[i][11..0]輸入而由muxstk.result[i][11..0]輸出,再經pcmxx控制選擇muxstk.result[][]輸出到pc[]暫存器端由系統時脈sysclk加以栓鎖控制,若非RET執行時序時,pcmxx=0選擇經pcadd之PC加法器由JMP,JP
CC,ADR,CALL等指令所加入之pdy[]=ADR運算值或其它指令之PC遞增加1指令所得之pcadd.result回接入PC栓鎖暫存器內,第一個IST
Ft/Dc週期將PC程式計數器值記存入pcx[15..0]暫存器內.
圖5-15 程式計數器之運算控制結構方塊圖
在第一個時序脈衝c1=IST
Ft/Dc執行時,將PC程式計數器之程式pd[15..0]內含資料栓鎖入pdx[15..0]內,在第二個時序c2=OP/RD又將pdx[15..0]資料栓鎖入pdy[15..0]內,第三個時序c3=EXE執行週期,便可對應存於pdx[]及pdy[]內含個別依時序所需予以取出運算元或資料或指令等對應作所需之運算或判別等控制,如圖5-16所示程式計數器採用lpm模組之rom結構電路取FLEX
10k10之RAM記憶體EAB模組以prom宣告參變數取用之,定址為A7-A0=PC共256個16位元D15-D0等組成程式記憶體作程式內含執行控制,其資料D15-D0依時序C1存記入pdx[]內,C2在由pdx[]轉入pdy[]記存,故對應表14-2之執行對應週期取其所需之指令,條件CC及暫存器X,Y,Z和相對位址ADR或直接資料#DDH等作運算處理控制等.
圖5-16 程式內含資料之運算控制結構方塊圖
5-3-4 規劃CPU之HDL使用LPM模組
本系統使用到LPM模組之"LPM_MUX"以大小LPM_SIZE=SS設定其多工組數及LPM_WIDTH=WW多工位元寬和輸入選擇控制碼位元寬LPM_WIDTHS=SW等參變數設定,輸入為MUX.DATA[ ]輸出為MUX.RESULT[ ]及控制選擇輸入之MUX.SEL[ ]等三個輸出入矩陣端埠,多工器共有muxa,muxb及muxstk等三組,另外使用LPM模組之"LPM_ADD_SUB"作ALU之ADD及SUB等加減運算和PC定址,跳躍及遞增等運算控制,pcadd其參數是LPM_WIDTH=12位元運算寬及LPM_DIRECTION ="ADD"加算運算方向設定,輸入為pcadd.dataa[]及pcadd.datab[]二組12位元輸入,輸出為pcadd.result[]為運算結果,另外一個模組是FLEX 10KXX系列EAB模組僅有之"LPM_ROM"程式記憶體模組,以參數LPM_WIDTH=16設定其ROM位元寬是16位元,而位址寬則以LPM_WIDTHAD=8設定位址為A7-A0共8位元,其ROM之內含寫入由LPM_FILE="prog2.mif"予以設定寫入而得,另外需設定定址輸入控制模式是否需以暫存器予以栓鎖或不為暫存器模式之LPM_ADDRESS_CONTROL="UNREGISTERED",同樣對應輸出資料也需設定為暫存器式之"REGISTERED"或為非暫存器式LPM_OUTDATA="UNREGISTERED"模式,定址之輸入為prom.addr[7..0]=pc[7..0]作輸入設定,而輸出資料設定為pd[15..0]=prom.q[15..0],詳細之LPM模組之參數設定及輸出和輸入之編寫設定可參照ALTERA公司之HELP檔案內之Megafunction /LPM加以查閱說明.
5-3-5 HDL描述I/O設定及PROM規劃
暫存器CH-FH共4字元32個位元為雙向可設定為輸出或輸入端,但每字元之高低四位元分二組可被分別設定輸入或輸出用,故共分成2×4=8群分別由埠B之各D7,D6設定埠F之高低四位元群之輸出入方向,設定D7=1即令資料栓鎖於F暫存器之D7-D4予以輸出到CPLD外端P37-P34接腳,若D6=0則將CPLD輸入端之P33-P30值透過TRI三態閘控制寫入F暫存器之D3-D0位元,C,D,E等I/O埠暫存器之對應CPLD外部接腳端P00-P07,P10-P17,P20-P27等寫入及讀出方向則類推依次由方向控制埠B之D0-D5予以設定控制,因此在設定讀寫P00-P07,P10-P17,P20-P27及P30-P37作輸出入資料傳輸控制時,必需先對應暫存器B之各位元予以寫入設定各埠之四位元組之0為輸入,1為輸出等之設定控制,當然0為輸出1為輸入作設定也可以,只要改變HDL描述就可以,對應各埠之方向組作TRI輸入致能設定控制之HDL描述及其對應說明如下:
FOR j IN
3 TO 0 GENERATE %共有四組8位元雙向I/O 作輸出入設定控制%
FOR i IN
3 TO 0 GENERATE %每組I/O分高低四位元作輸出入方向設定%
iopt[j][i]=TRI(rgg[12+j][i],rgg[11][j*2]);
%j固定埠址對應C-F埠D3-D0作三態輸入致能由埠BH=11之D(j*2)對應控制%
iopt[j][i+4]=TRI(rgg[12+j][i+4],rgg[11][j*2+1]);
%j固定埠址對應C-F埠D7-D4作三態輸入致能由埠BH之D(j*2+1)對應控制%
END GENERATE;
%各埠之高低四位元由埠B對應各位元予以對應設定%
END GENERATE;
%共四個8位元埠共32個位元分別予以設定TRI狀態控制%
上列對應一個RISC精簡架構CPU之設計HDL硬體描述都已完成,所有程式內含由EPF
10K10內之EAB組成256×16作程式ROM規劃設計執行,EAB作ROM之資料讀取時由ALTERA公司提供之LPM_ROM模組規範作控制,而對應寫入程式則以另編檔案.MIF予以寫入就可以,當然若真正要用需為ROM或PROM,EPROM或FLASH
ROM都可以,在此為模擬此自行設計的單晶片CPU執行狀態而以編寫.MIF方式予以設計規劃,或另設計組合語言格式及組譯器將其組譯成本.MIF之機械碼就方便多了.
.應注意!下列為PROG5.MIF之PROM模組之ROM內含檔,在規劃設定LPM_ROM模組參數時就要將其設定載入,隨同主程式"RISCPU4.TDF"主譯時會一起將其設定寫入EAB模組內的,若要以不同檔名或內含時,LPM_ROM之參數檔名需同時更改並要重新組譯才可以,程式之編輯參考範例如下及其對應說明,讀者應詳加研讀.
5-3-6 CPLD規劃CPU指令分析
上列所設計出之CPU指令僅有16個,卻沒有搬移MOV指令,但可以先將暫存器AND RR,#00H,再執行OR RR,#KKH就可以,暫存器之互相搬移可使用一個內含為#00H值之暫存器再以OR A,Z,Y指令運算,其中Z內含#00H則會將A暫存器內含搬入Y暫存器內,也不會是很麻煩的,最重要是旗號ZF,CF在很多指令運作時都會受影響,故條件判斷必需在運算後立即執行條件判別工作,若有需要則應先將旗號立即置放於暫存器某位元內作標誌,對應一般8051族系或PIC等CPU之重要指令轉移說明如下:
1. MOV NN,#KK
> (a)AND N,#00H (b)OR N,#KK暫存器搬入資料
2. MOV NN,MM
> (a)AND 0H,#00H (b)OR MM,00,NN暫存器MM搬入NN
3. JC SSSS
> (a)AND FH,#FEH (b)ADD 01,02,02 (c)JNC NEXT (d)OR FH,#01H(上烈對應將ADD
01,02,02運算結果之CF旗號置於F暫存器之D0位元內) (e) AND FH,#01H (f)JZ
SSSS(將F暫存器內含與#01作AND運算後就可判別先前ADD運算之CF旗號)
雖然顯得很麻煩但仍然在寫程式的技巧上多花些功能就可以克服的,上面指令中NOP並沒有必要,但在鑼輯運算中卻少了一個重要的NOT或XOR指令,因此若將NOP指令改成XOR指令運算時,作NOT運算只要將暫存器與#FFH作XOR就可以了,NOP指令改成XOR指令只要修改指令解碼及指令運算之HDL描述就可以,多出之XOR運算模式為XOR
X,Y,Z等三個暫存器運算模式,故需在指令解碼中設定暫存器寫入致能wen之旗號就可以,因此在運算指令解碼中僅需使用3位元作運寫解碼,其它涵蓋入之指令碼因沒有令寫入致能旗號wen=1,雖然ALU同樣作運算也是沒用的,由此修改後指令格式如表5-3所示.
指令解碼多了0000指令之XOR運算而需令寫入暫存器致能旗號wen,故予修改如下:
(pcadmx,pcmx,pushst,wen,aldb).clk=sysclk;
%指令執行旗號暫存器由sysclk同步%
CASE pd[15..12]
IS
%由第一時序IST
Ft/Dc週期之pd[15..12]指令碼予解碼%
WHEN B"0000"
=> %若指令碼為0000時代表XOR指令故應令寫入wen旗號%
wen=!pcadmxx;
%wen.d=!pcadmxx.q確認非處於定址跳躍指令模式即可%
WHEN B"0001"
=> %若指令碼為0001時代表RET指令故應令pcmx旗號%
pcmx=!pcadmxx;
%pcmx.d=!pcadmxx.q確認現在非處於定址跳躍指令模式%
pcadmx=!pcadmxx;
%pcadmx.d=!pcadmxx.q非處於定址跳躍指令模式%
WHEN B"0010"
=> %若指令碼為0010時代表JMP指令故應令pcadmx旗號%
pcadmx=!pcadmxx;
%pcadmx.d=!pcadmxx.q確認非處於定址跳躍指令模式%
WHEN B"0011"
=> %若指令碼為0011時代表CALL指令故應令pcadmx旗號%
pcadmx=!pcadmxx;
%及pushst堆疊狀態旗號由!pcadmxx予以設定控制%
pushst=!pcadmxx;
WHEN B"01XX"
=>%若指令碼為01XX時代表JP CC指令故應令pcadmx旗號%
pcadmx=!pcadmxx;
%pcadmx.d=!pcadmxx.q確認非處於定址跳躍指令模式%
WHEN B"10XX"
=> %若指令碼為10XX時代表暫存器運算故應令wen旗號%
wen=!pcadmxx;
%wen.d=!pcadmxx.q確認非處於定址跳躍指令模式%
WHEN B"11XX"
=> %指令碼為11XX時代表暫存器與資料運算故令wen旗號%
wen=!pcadmxx;
% wen.d=!pcadmxx.q確認非處於定址跳躍指令模式%
aldb=VCC;
%並令直接資料控制旗號暫存器aldb.d=VCC設定之%
END CASE;
指令運算多了0000指令之XOR運算而需令對應其指令碼解碼作ALU執行XOR之運算,故予修改如下:
CASE (pdy[15],pdy[13..12])
IS %第14位元pdy[14]可予忽略%
%運算TT為D13,D12位元故由(pdy[13..12])及NOP指令之pdy[15]予以判別%
WHEN B"0XX"
=>%在第2時序作運算判別故由pdy[13..12]內含及pdy[15]%
%判別當為0XX時原NOP指令轉成XOR指令運算故予判別%
%注意!對應其它RET,CALL,JMP,JP
CC等指令因與此運算無關而予忽略%
alo[]=(0,rqab[])$(0,rqbb[]);
%運算輸出alo[].d為(0,rqab[])XOR(0,rqbb[])輸出%
WHEN B"100"
=> %pdy[13..12]=TT=00且pdy[15]=1為加運算ADD共9位元%
alo[]=(0,rqab[])+(0,rqbb[]);
%運算輸出alo[].d為(0,rqab[])加(0,rqbb[])輸出%
WHEN B"101"
=> %pdy[13..12]=TT=01且pdy[15]=1為減運算SUB共9位元%
alo[]=(1,rqab[])-(0,rqbb[]);
%運算輸出alo[].d為(0,rqab[])減(0,rqbb[])輸出%
WHEN B"110"
=> %pdy[13..12]=01且pdy[15]=1為AND運算SUB共9位元%
alo[]=(0,rqab[]&rqbb[]);
%運算輸出alo[].d為(0,rqab[])AND(0,rqbb[])輸出%
WHEN B"111"
=> %pdy[13..12]=TT=01且pdy[15]=1為OR運算SUB共9位元%
alo[]=(0,rqab[]#rqbb[]);
%運算輸出alo[].d為(0,rqab[])OR(0,rqbb[])輸出%
END CASE;
表5-3 修正後之十六個RISC精簡指令格式及對應說明
序
指令及運算子格式
指令符號
指令功能說明
旗號
0
0000
xxxx
yyyy
zzzz
XORX,Y,Z
X與Y作XOR放入Z暫存器
1
0001
----
----
----
RET
回主程式
2
0010
aaaa
aaaa
aaaa
JMP AAAH
無條件跳到AAH相對位址
3
0011
cccc
cccc
cccc
CALL CCCH
無條件呼叫CCCH相對位址
4
0100
zzzz
zzzz
zzzz
JZ ZZZH
當Zf=1跳到ZZZH相對位址
5
0101
zzzz
zzzz
zzzz
JNZ ZZZH
當Zf=0跳到ZZZH相對位址
6
0110
cccc
cccc
cccc
JC CCCH
當Cf=1跳到CCCH相對位址
7
0111
cccc
cccc
cccc
JNC ZZZH
當Cf=0跳到CCCH相對位址
8
1000
xxxx
yyyy
zzzz
ADD X,Y,Z
X與Y內含相加放入Z暫存器
Zf,Cf
9
1001
xxxx
yyyy
zzzz
SUB X,Y,Z
X與Y內含相減放入Z暫存器
Zf,Cf
10
1010
xxxx
yyyy
zzzz
AND X,Y,Z
X與Y作AND放入Z暫存器
Zf
11
1011
xxxx
yyyy
zzzz
OR X,Y,Z
X與Y作OR放入Z暫存器
Zff
12
1100
xxxx
dddd
dddd
ADD X,#DD
X與資料DD直接相加放入X
Zf,Cf
13
1101
xxxx
dddd
dddd
SUB X,#DD
X與資料DD直接相減放入X
Zf,Cf
14
1110
xxxx
dddd
dddd
AND X,#DD
X與資料DD直接AND放入X
Zf
15
1111
xxxx
dddd
dddd
OR X,#DD
X與資料DD直接
OR放入X
Zf
注意!RISC架構CPU由於指令執行採用管線結(PipeLine)之快速排列處理,且真正將指令執行完成是在4個週期以後,因而在指令連續執行時需考慮前指令之暫存器是否已處理完畢而在下個指令對應此暫存器內含是否正確,若上指令仍未處理完成接著下指令對應在第二週期OP/RD讀取暫存器時可能是錯誤的:
綜合上列分析與改進,完整且完美之精簡指令RISC架構CPU之AHDL描述整理列出如下:
INCLUDE "lpm_mux";
INCLUDE "lpm_add_sub";
INCLUDE "lpm_rom";
INCLUDE "lpm_ram_dq";
SUBDESIGN
riscpu4
(
sysclk
: INPUT;
iopt[3..0][7..0]
: BIDIR;
)
VARIABLE
rgg[15..1][7..0]
: DFF;
muxa,muxb:lpm_mux
WITH(LPM_SIZE=16,LPM_WIDTH=8,LPM_WIDTHS=4);
muxstk:lpm_mux
WITH(LPM_SIZE=4,LPM_WIDTH=12,LPM_WIDTHS=2);
pc[11..0]
: DFF;
pcadd : lpm_add_sub
WITH(LPM_WIDTH=12,LPM_DIRECTION="ADD");
pd[15..0],rqb[7..0],alo[8..0],tcnd,rzr
: NODE;
rqab[7..0],rqbb[7..0],rdi[7..0]
: DFF;
wen,aldb,pcadmx,pcmx,pushst
: DFF;
pdx[15..0],pdy[15..0],pcx[11..0],ws[3..0],wsx[3..0]
: DFF;
wenx,weny,pcadmxx,pcmxx,pushstx,swen
: DFF;
stk[3..0][11..0],sp[1..0]
: DFF;
prom :lpm_rom
WITH(LPM_WIDTH=16,LPM_WIDTHAD=8,LPM_FILE="prog5.mif"
,LPM_ADDRESS_CONTROL="UNREGISTERED",LPM_OUTDATA="UNREGISTERED");
sram : lpm_ram_dq
WITH(LPM_WIDTH=8,LPM_WIDTHAD=8,LPM_INDATA="REGISTERED"
,LPM_ADDRESS_CONTROL="UNREGISTERED",LPM_OUTDATA=
"UNREGISTERED");
BEGIN
rqab[].clk=sysclk;
rqab[]=muxa.result[];
rqb[]=muxb.result[];
muxa.sel[]=pdx[11..8];
muxb.sel[]=pdx[7..4];
muxa.data[0][]=sram.q[];
muxb.data[0][]=sram.q[];
sram.address[]=rgg[1][];
sram.data[]=rdi[];
sram.we=swen;
sram.inclock=sysclk;
swen.clk=sysclk;
swen=wenx&(ws[]==0);
FOR i IN 1
TO 11 GENERATE
muxa.data[i][]=rgg[i][];
muxb.data[i][]=rgg[i][];
END GENERATE;
FOR i IN 0
TO 3 GENERATE
muxa.data[i+12][]=iopt[i][];
muxb.data[i+12][]=iopt[i][];
END GENERATE;
rgg[][].clk=sysclk;
FOR i IN
1 TO 15 GENERATE
IF weny
& (wsx[]==i) THEN
rgg[i][]=rdi[];
ELSE
rgg[i][]=rgg[i][];
END IF;
END GENERATE;
pc[].clk=sysclk;
IF pcmxx
THEN
pc[]=muxstk.result[];
ELSE
pc[]=pcadd.result[];
END IF;
pcadd.dataa[]=pc[];
pcx[].clk=sysclk;
pcx[]=pc[];
IF pcadmxx
THEN
pcadd.datab[]=pdy[11..0];
ELSE
pcadd.datab[]=B"000000000001";
END IF;
rqbb[].clk=sysclk;
IF aldb THEN
rqbb[]=pdx[7..0];
ELSE
rqbb[]=rqb[];
END IF;
CASE (pdy[15],pdy[13..12])
IS
WHEN B"0XX"
=>
alo[7..0]=(rqab[]$rqbb[]);
WHEN B"100"
=>
alo[]=(0,rqab[])+(0,rqbb[]);
WHEN B"101"
=>
alo[]=(0,rqab[])-(0,rqbb[]);
WHEN B"110"
=>
alo[7..0]=(rqab[]&rqbb[]);
WHEN B"111"
=>
alo[7..0]=(rqab[]#rqbb[]);
END CASE;
rdi[].clk=sysclk;
rdi[]=alo[7..0];
rzr=(alo[7..0]==0);
(pdx[],pdy[]).clk=sysclk;
pdx[]=pd[];
pdy[]=pdx[];
CASE pdx[14..12]
IS
WHEN B"0XX"
=>
tcnd=VCC;
WHEN B"100"
=>
tcnd=rzr;
WHEN B"101"
=>
tcnd=!rzr;
WHEN B"110"
=>
tcnd=alo[8];
WHEN B"111"
=>
tcnd=!alo[8];
END CASE;
(pcadmx,pcmx,pushst,wen,aldb).clk=sysclk;
CASE pd[15..12]
IS
WHEN B"0000"
=>
wen=!pcadmxx;
WHEN B"0001"
=>
pcmx=!pcadmxx;
pcadmx=!pcadmxx;
WHEN B"0010"
=>
pcadmx=!pcadmxx;
WHEN B"0011"
=>
pcadmx=!pcadmxx;
pushst=!pcadmxx;
WHEN B"01XX"
=>
pcadmx=!pcadmxx;
WHEN B"10XX"
=>
wen=!pcadmxx;
WHEN B"11XX"
=>
wen=!pcadmxx;
aldb=VCC;
END CASE;
pcadmxx.clk=sysclk;
pcadmxx=pcadmx&tcnd&!pcadmxx;
pcmxx.clk=sysclk;
pcmxx=pcmx&!pcadmxx;
pushstx.clk=sysclk;
pushstx=pushst&!pcadmxx;
(wenx,weny).clk=sysclk;
wenx=wen&!pcadmxx;
weny=wenx;
(ws[],wsx[]).clk=sysclk;
IF pdx[14]
THEN
ws[]=pdx[11..8];
ELSE
ws[]=pdx[3..0];
END IF;
wsx[]=ws[];
stk[][].clk=sysclk;
FOR i IN
0 TO 3 GENERATE
IF pushstx
& (sp[]==i) THEN
stk[i][]=pcx[11..0];
ELSE
stk[i][]=stk[i][];
END IF;
END GENERATE;
sp[].clk=sysclk;
IF pcmx&!pcadmxx
THEN
sp[]=sp[]+1;
ELSIF pushstx
THEN
sp[]=sp[]-1;
ELSE
sp[]=sp[];
END IF;
muxstk.data[][]=stk[][];
muxstk.sel[]=sp[];
FOR j IN 3
TO 0 GENERATE
FOR i IN
3 TO 0 GENERATE
iopt[j][i]=TRI(rgg[12+j][i],rgg[11][j*2]);
opt[j][i+4]=TRI(rgg[12+j][i+4],rgg[11][j*2+1]);
END GENERATE;
END GENERATE;
prom.address[]=pc[7..0];
pd[]=prom.q[];
END;
上列RISC CPU之硬體電路設計描述中,其所引含入之程式機械碼是存於引入ROM參數化模組電路lpm-rom 內,其內部資料(DATA)寬為LPM_WIDTH=16而位址寬LPM_WIDTHAD=8,及程式內含長度最多為2^8=256個,其內含資料是存放於LPM_FILE="prog5.mif"而位址輸出入及資料輸出是不需使用暫存器作栓鎖控制即LPM_ADDRESS_CONTROL="UNREGISTERED"及LPM_OUTDATA= "UNREGISTERED",所列舉之prog5.mif 是於主描述檔(File)之下再去開(Open)此檔案作編輯,因未設計組譯器(Compiler)故編寫時也是先以組合語言法編寫再對應機械碼予以對照編輯如下:
DEPTH = 256;
WIDTH = 16;
ADDRESS_RADIX
= HEX;
DATA_RADIX
= HEX;
CONTENT
BEGIN
0 : FBF0;
-- OR B,#F0
1 : E200;
-- AND 2,#00
2 : F201;
-- OR 2,#0 1
3 : EF00;
-- AND F,#00
4 : EE00;
-- AND E,#00
5 : 3009;
-- CALL 10
6 : 82EE;
-- ADD 2,E,E
7 : 7FFC;
-- JNC 5
8 : 82FF;
-- ADD 2,F,F
9 : 7FF9;
-- JNC 4
A : B333;
-- OR 3,3,3 NOP
B
: B333; -- OR 3,3,3 NOP
C : 2FF5;
-- JMP 3
D
: B333; -- OR 3,3,3 NOP
E
: B333; -- OR 3,3,3 NOP
F
: B333; -- OR 3,3,3 NOP
10 :
E300; -- AND 3,#00
11 :
B333; -- OR 3,3,3 NOP
12 :
B3D4; -- OR 3,D,4
13 :
B333; -- OR 3,3,3 NOP
14 :
B3C5; -- OR 3,C,5
15 :
3009; -- call 20
16 :
B333; -- OR 3,3,3 NOP
17 :
B546; -- OR 5,4,6
18 :
4005; -- JZ 1F
19 :
9525; -- SUB 5,2,5
1A :
7FF9; -- JNC 15
1B :
B444; -- OR 4,4,4
1C :
4001; -- JZ 1F
1D :
9424; -- SUB 4,2,4
1E :
7FF5; -- JNC 15
1F :
1000; -- RET
20 :
E700; -- AND 7,#00
21 :
B333; -- OR 3,3,3 NOP
22 :
B333; -- OR 3,3,3 NOP
23 :
F720; -- OR 7,#20
24 :
B333; -- OR 3,3,3 NOP
25 :
B333; -- OR 3,3,3 NOP
26 :
9727; -- SUB 7,2,7
27 :
7FFB; -- JNC 24
28 :
1000; -- RET
[29..FF]
: 0;
END;
5-4 CPLD數位電路設計發展應用(基礎篇)