• 沒有找到結果。

EQT~ C G @ h mWG M09101011 d n t OGqu{t hZ DGebFORTH:SoCX@POJlt ebFORTH: A UNIFORM EMBEDDED SUBSYSTEM FOR INTEGRATION OF SoC TEST RESOURSE h j

N/A
N/A
Protected

Academic year: 2022

Share "EQT~ C G @ h mWG M09101011 d n t OGqu{t hZ DGebFORTH:SoCX@POJlt ebFORTH: A UNIFORM EMBEDDED SUBSYSTEM FOR INTEGRATION OF SoC TEST RESOURSE h j"

Copied!
87
0
0

加載中.... (立即查看全文)

全文

(1)

中 華 大 學

碩 士 論 文

題目:ebFORTH:SoC 測試資源整合的一致性嵌入式子 系統

ebFORTH: A UNIFORM EMBEDDED SUBSYSTEM FOR INTEGRATION OF SoC TEST RESOURSE

系 所 別:電機工程學系 碩士班 學號姓名:M09101011 吳 志 聲 指導教授:陳 竹 一 博 士

中華民國 九十三年 七 月

(2)
(3)
(4)
(5)
(6)
(7)

摘 要

ebFORTH 是一個非常精簡的電腦系統,只有 50 KBYTE 的程式碼,若應 用在嵌入式 SoC 控制器中.更可精簡至 2Kbyte 的程式碼,所以很容易植入 SoC 系 統 晶 片 中 。

這部具有 ebFORTH OS 的 CPU,實際上就是一部小電腦,它擁有兩個堆 疊 :一個是返回堆疊(Return Stack) –在虛擬堆疊中存放程式返回位址,另一 個是資料堆疊(Data Stack)-存放著副程式間傳遞的參數並將數字資料集中 處理,我們將它配上一個結構化的作業系統之後,副程式可以很容易的串 聯起來成為新的程式,這樣建造的副程式可以看作是”虛擬機 ”,他接受 使用者輸入的一串指令系列經直譯器將指令解析後依序執行,此外 ebFORTH 還有一個編譯器允許使用者定義新指令,編成機械碼存在記憶體裡面,所 以佔記憶體空間小,且執行速度快,這種既是虛擬機,又是程式語言的特 性 適 合 嵌 入 式 系 統 單 晶 片 的 開 發 與 測 試 平 台 。

(8)

Abstract

The ebFORTH is a very compact system just with about 50K-byte programming codes. While the system is used as an embedded version, the length of programming codes can reach 2K-byte. Therefore, the ebFORTH is suitable to be embedded in a SOC.

In this thesis, the ebFORTH operation system is used in the CPU, and this co-designed CPU plus OS indeed is a tiny computer. There are two stacks in the computer, where one is Return Stack which stores the return address in the virtual machine and the other is Data Stack which stores the data to be processed and is the confluence of operating data. The CPU structure is modeled hierarchically and it is easy to extend the sub-programming codes. This structure is like to a 〝virtual machine〞and it can interpret the instructions from users. Moreover, in the ebFORTH there is a special compiler which can redefine the new instructions in dictionary memory. Due to the properties of small memory space occupied and fast speed, the virtual machine and operation system are suitable for the development of embedded SOC and testing platform.

(9)

誌 謝

感謝恩師 陳竹一教授的指導,在這求學的二年生涯中您的豐富學養帶 領著我走入測試的領域,深深地被您誠懇.循循善誘的耐心所感動,有如一 盞 明 燈 在 指 引 著 莘 莘 學 子 , 使 我 受 益 良 多 , 老 師 謝 謝 你 。

在這兩年來,陳坤益學長適時地解惑,在我遇到瓶頸不知所措的時候他 總是可以找出頭緒,直指問題徵結所在,我才能迎刃而解,還有易符智慧 科 技 的 吳 建 佳 先 生 , 在 求 教 他 時 , 多 次 闡 述 eForth 的 精 髓 。

淑慧,不知道要如何道出內心的感謝,我只能說有妳的支持真好。

(10)

目 錄

摘 要 ... I Abstract ... II 誌 謝 ... III 目 錄 ... IV 圖 目 錄 ... VIII 表 目 錄 ... X

第一章 緒論 ... 1

1.1研究動機 ……… 1

1.2 研究方法……… 2

第二章 符式嵌入式中央處理器的設計 ……… 3

2.1 ebFORTH 嵌入式中央處理器的設計 ……… 3

2.1.1 CPU 模組……… 3

2.1.2 STACK 模組……… 6

2.1.2.1 DATA STACK 資料堆疊... 7

2.1.2.2 RETURN STACK BLOCK 返回堆疊……… 8

(11)

2.1.3 IR BLOCK 指令解碼模 ……… 9

2.1.4 IP_PC BLOCK 模組... 10

2.1.5 ADDRESS BLOCK 位址及資料匯流排 ... 11

2.1.6 UART BLOCK 介面傳輸模組……… 13

2.1.7 ALU BLOCK 運算邏輯單元……… 15

2.1.8 TEMP_REG BLOCK 輸出埠...16

2.1.9 FLAG_BLOCK 模組...17

第三章 嵌入式符式作業系統的交叉編譯 ……… 18

3.1 ebFORTH 操作系統-組合器(FEOS.ASM)……… 18

3.2 操作系統之作業流程 ……… 20

3.3 FORTH ENGINE 的啟動 … … … 22

3.3.1 系統啟動迴路 COLD ……… 22

3.3.2 ebEFORTH 記憶體組態(MEMORY MAP) ………23

3.3.3 ebFORTH 系統的核心指令 ………25

3.4 變數和常數 ………28

3.4.1 系統變數 ...28

3.4.2 巨集指令 ………29

(12)

3.4.3 組合指令集 ...30

3.4.4 終端機指令 ...31

3.5 系統常用指令 ………32

3.5.1 比較指令...32

3.5.2 乘數指令...32

3.5.3記憶指令... 33

3.5.4 壓縮字串及解壓指令 ………34

3.5.5 數值印出指令 ………35

3.5.6 數值輸入指令……… 36

3.5.7 其他列印指令 ………37

第四章 解碼器相關指令 ……… 38

4.1 解碼器相關指令……… 38

4.1.1 解讀指令… … … 38

4.1.2 查字典指令… … … . 39

4.1.3 詞典中指令的結構 … … … 41

4.1.4 字的資料結構 … … … 42

(13)

4.3 偵錯指令 ………44

4.4 解碼器 ………45

4.5 編碼器(COMPILER)相關指令 … … … 47

4.6 結構化編碼指令 ………51

4.7 其他詞類指令的建造指令 ………54

4.8 工具指令 ………56

4.9 組合指令……… 58

4.10 巨集指令 ………59

4.11 ebFORTH 與 LISP 的比較 ………60

第五章嵌入式 ebFORTH 處理器之效能分析………61

5.1 ebFORTH 處理器之 I/O 架構 … … .… … … .… … ..… … … .62

5.1.1 FORTH ENGIN CORE RESOURCE USAGE………62

5.1.2 系統 PLACE & ROUTE 之後的資源分佈及效能分析………… 63

5.2 ebFORTH 之人機交談介面環境 … …

… … … .… … ...

65

第六章 結 語……… 69

第七章 參考文獻 ……… 70

(14)

圖 目 錄

圖 2-1 MODULE BLOCK … … … 5

圖 2-2 Forth Engine Core ……… 6

圖 2-3 DATA STACK ………7

圖 2-4 RETURN STACK……… 8

圖 2-5 IR BLOCK……… 10

圖 2-6 FSM STAGE FLOW ……… 10

圖 2-7 IP_PC BLOCK……… 11

圖 2-8 ADDRESS BLOCK………12

圖 2-9 UART BLOCK……… 14

圖 2-10 ALU BLOCK ……… 15

圖 2-11 TEMP_REG BLOCK……… 16

圖 3-1 ebFORTH 操作系統簡圖 ……… 19

圖 3-2 ebFORTH 記憶體之配置 ……… 24

圖 4-1 易符字典結構 ……… 41

圖 4-2 字的資料結構 ……… 42

圖 4-3 ERROR LOOP……… 44

(15)

圖 4-4 $INTERPRET LOOP……… 46

圖 4-5 $COMPILER LOOP ………50

圖 5-1 ACTEL APA150 FPGA 系統結構………61

圖 5-2 FORTH ENGINE IN FPGA ARRAY ……… 64

圖 5-3 FORTH ENGINE 功率消耗 ………64

圖 5-4 應用程式下載 ………68

圖5-5 應用程式執行結果 ……… 68

(16)

表 目 錄

表 2-1 FLAG BLOCK 模組 ………17

表 3-1 操作系統之作業流程……… 21

表 3-2 組合器預先規劃好記憶體內容的位址……… 22

表 3-3 記憶體的配置 ………23

表 3-4 Verilog.RTL Primitive 指令參數定義 ………27

表 3-5 系統變數……… 28

表 3-6 組合指令集 ………31

表 3-7 終端機指令……… 31

表 3-8 比較指令 ………32

表 3-9 乘數指令 ………33

表 3-10 記憶指令……… 33

表 3-11 壓縮字串及解壓指令 ………34

表 3-12 數值印出指令……… 35

表 3-13 列印指令………36

(17)

表 3-14 數值輸入指令 ………37

表 3-15 其他列印指令………37

表 4-1 解讀指令 ………38

表 4-2 查字典指令………40

表 4-3 輸入文字序列的指令 ………43

表 4-4 偵錯指令 ………44

表 4-5 解碼器 ………46

表 4-6 編碼器(COMPILER)相關指令 ………49

表 4-7 結構化編碼指令……… 51

表 4-8 無條件迴路……… 52

表 4-9 組合指令 ………52

表 4-10 有條件迴路 ………53

表 4-11 其他詞類指令的建造指令……… 56

表 4-12 工具指令 ………57

表 4-13 組合器指令……… 59

表 5-1 Cell Resource Usage ……… 62

表 5-2 I/O & Register Resource Usag ………62

表 5-3 Performance Summary ………63

(18)

第一章 緒論

1.1 研究動機

由於半導體已進入奈米製程,電路日趨複雜,在 ITRS 的 ROADMAP 上推估的進程,SOC 的測試設備需求越來越難,也越來越無法達成,思 索在 SOC 的測試平台上,若有一個精簡系統,程式碼不大,又包含一 個可以處理人機界面的作業系統,可植入 SOC 平台上,既不佔體積,

反應又快,又具延展性的系統,而 ebforth 所建構的 CPU 及 OS 似乎正 可發揮所長,事實上它就是一部專用型的電腦,可依輸入指令,經規 劃作測試,測試者用組合語言寫程式,經組譯載入 FPGA 中,程式中可 將低階與高階混用,達到可縮放自如的 16 位元晶片核心,與作業系統,

應用在 SoC platform 上,成為一個解決問題為導向的利器。

(19)

1. 2

研 究 方 法

本論文系採用 eforth[1]丁陳漢?博士提出的,雙堆疊虛擬機,架在自 行演譯的 CPU 上,執行一套 Forth 指令集,這套指令集可以無限延伸,由 開機程序到接受外部(Terminal)輸入指令作編譯解碼的工作,遇例外情形 可利用 ERROR 迴路處理。形成一個嵌入式的作業系統。

傳統的電腦語言中,副程式間參數的傳遞是靠著副程式的參數序列,

用參數序列需要很複雜的編譯器來處理,ebFORTH 則是反其道而行,利用 參數的堆疊在副程式中傳遞參數,只需要很簡單的編譯器,使得副程式在 操作系統中都可以成為獨立工作的結構單元,也可以組合成為新的指令或 結構單元,藉由建構 ebFORTH 作業系統使得程式簡化,成為特殊應用問題 而設計的專用型電腦。

(20)

第二章 符式嵌入式中央處理器的設計

2.1 ebFORTH 嵌入式中央處理器的設計

2.1.1 CPU 模組

CPU 模組是 ebFORTH(embedded FORTH)韌體工程中最重要的模組,符式 硬體包含了 Forth_engine_core 及 Block RAM Memory 和輸出埠三大部份。

他的工作就是讀入記憶體中所儲存的指令並依 IP 所指位址循序執行。在執 行指令時 IR 模組會送出控制訊號,如記憶位址,讀寫控制等訊號,也會接 受外部送來的訊號,如重設 RST-n,RS-232IN 等這些訊號的輸入/輸出的方 向邏輯特性及功能如下圖所示。(圖 2-1)

符式引擎核心規劃為 8 大部份如下:

(1) WALU_block: ”W 暫存器”和”算術邏輯單元”等部份。

(2) IP_PC_block: ”直譯指標器”和”程式計數器”。

(3) RS_block: 返迴堆疊含 2 部份,”TOR 暫存器”和”ReturnStack”。

(4) DS_block: 資料堆疊含 2 部份,”TOS 暫存器”和”DataStack”。

(5) IR_block: 內含“IR 暫存器”和”IR 有限狀態機”和”IR 解碼器”。

(6) AddDataBus_block: 內含”資料線多工器”和”位址線多工器”。

(7) UART_block: 內含“鮑率產生器”和”傳送介面”和”接收介面”。

(21)

當主重設訊號 RST-n 是 0 的時候,CPU(Forth Engine)處在重設狀態,

他會將所有暫存器都鎖定在個別重定位址,其中最重要的指令地址暫存器 (IR)會被清為 0,因此 RST_n 回到 1 時,Forth Engine 就會從記憶位址 0

,讀入一個指令組;而在下一個主時鐘的上升沿時,執行指令組中的第 1 個指令(目前系統主時鐘設在 21.4MHz),當發展板 XC2V1000 開機後,將 Program Download SW1 押下,EEPROM 所燒錄之易符操作系統就載入 Forth Engine 的記憶體中,開始執行 ebForth 作業系統指令。

(22)

WMUX

W

ALU

CyReg

DS TOS

0 1

TOS

W_sel

W_ld

TOS

CYflag

W

CY_ld

PCM UX

PC

TOS M

1 0

PC

IPMUX

0 1 2 3

M TOR TOS

PC_sel IP_sel[1:

0]

PC_ld

PC_inc IP

IP

IP_ld IP_inc

DataSta ck

TOS IP

TOR_sel[1:0 ]

TORinc TOR

RSpush RSpop

TOSMUX

0 1 2

RP

RPinc RPdec TORdec

DataSta ck

TOSMUX 0 1 2 3

ALU M TOR

TOS_sel[2:0]

TOS

TOS_ld

RP

4 5

DSMUX DS_sel[1:0 ]

DSpush

DSpo p

0 1 2

ADDRMUX

0 1 2 3

TOS IP RP

TOS

DATAMUX AddDataBus[2:

1]

DataBus Out

0 1 2

IP DS PC

AddDataBus[4:

3]

AddrBu sOut

DECORDER IR_Reg

M

IR_ld

IR_FS M

IR_sigIR_FSM_ sig

tx_ busy_fl ag

StatusF lag [4 :0]

WALU_ctrl[4:0] RS_ctrl[7:0] DS_ctrl[7:0]

IP_PC_ctrl[6:0] AddrDataBus_ctrl[4:0] others_ctrl[6:0]

others_ctrl[6]

RX_U ART BR_

clk_

puls e

TX_U ART

baud_sel

serial_data_in

serial_data_out

rx_data_en rx_data [7:0]

tx_data_en tx_data [7:0]

rx_clr

_clk_pulse

tx_busy_flag

圖 2-1 MODULE BLOCK

(23)

Low_mem

High_mem

ForthEngineCore

TmpReg

RST_n CLK rs_232in

Mdata[15 :0]

Mdata[7:0]

Mdata[7:0]

DIN [15:0]

rs_232 out

0 1 0 1 Mwrite

WE

WE

AddreBusOut

DataBusOut

Load

CLK RST_ n 7

9 RST_

n CL K rs_232i

n

rs_232 out

Port Dout

圖 2-2 ForthEngineCore 2.1.2 STACK 模組

Forth Engine 使用 2 個堆疊器分別為:

1. 資料堆疊 (Data STACK) :作為參數的傳遞及運算之用 2. 返回堆疊 (Return STACK) :存放副程式返回位址

在符式處理器中資料堆疊(DATA STACK)即返回堆疊(Return STACK)

建構出後入先出的堆疊運作方式,每個堆疊都會使用兩個堆疊指標,SP 與 RP,當資料 push 進來的時候 SP,RP 值會加1,直到遞增到堆疊 overflow 為止。而 pop 動作對 SP,RP 值的意義,乃是表示目前有多少筆資料在堆疊 中,而{spinc, spdec}={1,1}{spinc, spdec}={1,1}時,

表示直接載入一值給 SP,RP,也就是直接指定堆疊現在的 SP,RP 值。

(24)

2.1.2.1 DATA STACK 資料堆疊

在執行指令時,許多指令幾乎是以 Data Stack,Return Stack 最上層 的資料作判斷,為增進效能減少資料進出Stack的流量,將其規劃成 TOS(Top of stack)獨立在堆疊最上層,資料寬度為 16bit,堆疊深度為 32 層,可藉 由參數來改變寬度及深度。當有資料 push 進入 Data Stack 時,其內部相 對應的 index 值也相對應加 1,同時 sp 值也增加 1,(sp+1) ,直到堆疊產 生溢位為止,而 index 值表示有多少筆資料在堆疊中。

資料堆疊最主要最為副程式間傳遞參數,使得副程式在操作系統中都 可成為獨立工作的結構單元,也可以組合成為新的指令或結構單元。使得 程式簡化,程式發展的效率提高。

D a t a S t a c k T O S

M U X 3

T O S S I G M U X 7 SEL

D I N 0 D I N 1 D I N 2 D I N 3 D I N 4 D I N 5 D I N 6 T O S _ D S _ c t l

A L U M T O R R P

e d

e d e d e d C L K

T O S _ B C

T O S _ R s h i f t

T O S _ L s h i f t Ww U A R T _ r x d a t a

s e l d i n 0

din1 din2

dout D S _ i n

rst clk D S _ p u s h

DS_pop sp_store

T O S

sp D S _ o u t

D S

TOS

圖 2-3 DATA STACK

(25)

2.1.2.2 RETURN STACK BLOCK 返回堆疊

返回堆疊,在虛擬堆疊機中儲存執行後的返回位址,以方便資料的暫 存。可看作是資料堆疊的延伸,要注意的是,資料壓入返回堆疊中必須在 EXIT 指令被執行之前否則跳到下一個指令時,EXIT 會拿到錯誤的位址,導 致系統毀損。

再將新資料壓入堆疊時,若訊號 RP_PUSH 是 1,則會選擇堆疊指標 RP 為 堆疊位址,將 TOS 資料推入堆疊中,在讀取堆疊頂層資料時,若訊號 RP_POP 是 1,則會選擇堆疊指標 RP 為堆疊的位址將堆疊取出到 TOS 上,同時 RP 值 會加 1。

M U S 3 T O R

R e t u r n S t a c k

RST_n CLK

RP TOR

rst_n clk RS_push

RS_pop rp_inc rp_dec RS_din

TOS

RS_dout RP

sel din0 din1 din2

dout

clk rst_n

up down

TOR

TOR_out

TOS

IP TOR_RS_ctl

圖 2-4 RETURN STACK

(26)

2.1.3 IR BLOCK 指令解碼模組

IR_block 包含 IR Reg,IR_FSM,及 DECORDER 三大部分,可依存入 記憶體指令作不同的解碼控制訊號。當系統 Reset 後的第一個上升沿會將所 有暫存器及堆疊都清為 0,或重設為初值。而欲執行的機器碼,被提取到 IR_Reg 中,同時 IR_FSM 也送出 IR 值到有限狀態處理器中,將提取進來的 指令,依據不同的輸入值跳到不同狀態,IR_FSM 有 5 種狀態,分別是指令 提取便備狀態,Ready,狀態 1(status),狀態 2(status2),下一個指令狀態,

(NEXT)完成後,會回到 Ready 狀態,執行下一個指令。

Decorder 會依據不同的 IR 輸入值,解碼出各種不同指令的控制訊號,

來完成其他模組的控制訊號。

T m p_R e g I R_F S M

D E C O D E R

clk rst_n

load din

clk rst_n tx_flag instruct dout

codeout IRFSM

statusflag

tos_byte_change tos_r_shift

tos_l_shift W_ALU_ctrl adddatabus

IP_PC

TOS_DS_ctrl

TOR_rs_ctrl other_ctl

tos_byte_change tos_r_shift tos_l_shift W_ALU_ctrl

adddatabus IP_PC TOS_DS_ctrl TOR_rs_ctrl

tx_busy_flag

clk

rst_n

Status_flag Statusflag

Other_ctl M

圖 2-5 IR_BLOCK

(27)

@(FETCH)

STATE0

STATE1 STATE2

$NEXT

rst_n

!,NEXT,?BRANCH,SWAP, AND,OR,XOR,TX!

DOLIT,EXIT,DOLIST,CALIST,@,BRANCH

@RP,RP!,R>,>R,R@,DROP,DUP,OVER,<0,

?RX,$NEXT,TX!,SP@,SP!

EXECUTE

TX_flag

!,?BRANCH,UM+AND, OR,XOR,tx_flag,NEXT

圖 2-6 FSM STAGE FLOW

2.1.4 IP_PC BLOCK 模組

PCMUX,PC,IPMUX,IP 是由 IR_BLOCK 之 IP_PC_ctrl 來控制,當 Forth Engine 啟動時 IP 之初值為 2,可預先指到下一個位址執行。每執行一次即 自動+2。

PC 之初值為 0,可從記憶體的 0000H 位址開始執行。以$NEXT 指令為例。

PCß[IP]這個動作是把 IP 的值指到記憶體(RAM)的位址,再以該位址的值 存到 PC 暫存器中。

(28)

P C I P MUX2MUX2

MUX4MUX4

clk rst_n

load up

PC_out 0 1

0 1 2 3

clk rst_n

load up

IP_out

PC_in IP_in

IP_PC_ctl

M

rst_n TOS

clk

IP

TOS M

UN1_PC_SIG

M

TOS

TOR

PC

圖 2-7 IP_PC BLOCK

2.1.5 ADDRESS BLOCK 位址及資料匯流排

資料線和位移線定為 16bit 寬,負責 Forth Engine 與記憶體的溝通。

由 IR_block 發出的 AddrData Bus_ctrl 信號來控制。

(29)

MUX3

MUX4 addr_data_bus

TOS IP DS

PC

RP din3

dout

data_bus_out

addr_bus_out sel

din0 din1 din2 sel din0 din1 din2

dout

圖 2-8 ADDRESS BLOCK

(30)

2.1.6 UART BLOCK 介面傳輸模組

Forth Engine 終端機的信號傳輸是以 RS-232 串列介面,來傳送和接 收資料。由此便可和作業系統(ebFORTH)互動,系統起始後,便由作業系統 負責將數值資料填入傳送,接收暫存器中。以便建立初步的人機溝通管道。

由於 UART 每次傳送資料是低位元的 8bit,而堆疊頂端 TOS 為 16bit 寬,為 解決終端機只顯示低位元的問題,特別增加 Byte-change 指令,配合軟體 指令 C@ (CAT)—將記憶體字元資料送進資料堆疊中,當提取 TOS 低位元(LSB) 值後,將 TOS 作 Byte-change,把 MSB、LSB 資料對調,然後再完整將 TOS 內容提取出來到終端機去顯示字元。

UART 內部包含了部分,

1. BR_CLK_PULSE 依據 BR_VALUE 參數值產生基準時脈。

計算公式為: BR_VALUE=CLK/(Banel Rate * 16)-1 例:系統振盪器使用 20MHz-BR=19200bps 則

BR_CLK_PULSE=20M/(19200*16)-1=40H 因此可將 BR_VALUE 參數設為 40H。

2. TX_UART 模組

以 Band_CLK_Pluse 訊號為觸發脈衝,狀態暫存器之 fx_busy_flag 旗 標為”1”,表示正在傳送資料,”0”表示已傳完資料。

(31)

3. RX_UART 模組

接受狀態暫存器的 rx_data_en 訊號狀態為”1”,表示等待。CPU 未讀 取資料。

BR_clk_pulse TX_UART

RX_UART

CLK RST_N BAUD_SEL

UART_clk_pulse

clk rst_n

UART_clk_pulse tx_data_en tx_data_in

serial_data_out

tx_busy_flag

clk rst_n

UART_clk_pulse

serial_data_en rx_clr

rx_data_valid rx_data serial_data_out

tx_busy_flag

CLK RST_N BAUD_SEL

tx_data tx_data_en

serial_data_in rx_clr

圖 2-9 UART BLOCK

(32)

2.1.7 ALU BLOCK 運算邏輯單元

每一個電路主要由 IR_block 發出的 W_ALU_ctrl 控制,WMUX 會選擇推 入 W 暫存器內容與資料堆疊頂端進行 AND、OR、XOR、ADD、SHL、SHR、MUL、

DIV、UM+,運算,而再下一個主時鐘上升沿;將結果送入資料堆疊中。A,

B 是資料輸入,而 y 是運算結果,進位 cy 則是 UM+加法指令所需的進位輸 出符號,cy flag 經過 D 型正反器閂鎖後,送回解碼器當輸入。因此 Forth Engine 除了作運算以外,也可以產生常數。

T m p R e g

A L U

C Y R e g

cy_id rst_n clk

w_alu_ctl

TOS

DS

cyflag

ALU

W dout

rst_n clk load din clk

rst_n

load din

rst_n a b func sel

din0

din1 MUX2

圖 2-10 ALU BLOCK

(33)

2.1.8 TEMP_REG BLOCK 輸出埠

Forth Engine 資料經由輸出埠的解碼電路送至外部週邊電路,當位址 解碼器解出 0FFFFH 時,表示選到這個輸出埠,並將資料匯流排資料送出輸 出埠。

T M P R E G

clk

din

load

rst_n

D

E

R

Q dout

圖 2-11 TEMP_REG BLOCK

(34)

2.1.9

FLAG_BLOCK 模 組

當 UART 等待外部終端機的輸入時,或堆疊頂端內容變化時產生 5 個旗 標,供 IR block 之 DECORDER 作判斷,主要的 4 個輸入訊號為 TOR,TOS,

Cyflag,UART_rx_flag 進入 flag_block 後,產生狀態旗標給 Decorder。

名稱 旗標訊號 旗標狀態 旗標位元

TORzero UART_rx_flag

TOSzero TOS15 CYflag

TOR 內容為 0 時 UART 有接受到訊號

TOS 內容為 0 時 TOS 的 15bit(MSB)

ALU 的進位旗號

1 1 1 1 1

[4]

[3]

[2]

[1]

[0]

表 2-1 FLAG_BLOCK 模組

(35)

第三章 嵌入式符式作業系統的交叉編譯

十六位元的 FORTH ENGINE 已經完成了,他擁有 64KBYTE 的記憶體,為了 C@及 C!指令可分辨 HIGH/LOW BYTE 字元特別把 BLOCK RAM 分成兩 32K*16bit 的記憶體製作方式,在預先編譯組合器後利用 COREGEN 分別下載 FEOSH.COE 及 FEOSL.COE 機械碼作為記憶體組態,使 CPU 能依照解碼器循序執行這些 指令。

3.1 ebFORTH 操作系統 -組合器 (FEOS.ASM)

組合器是以結構化和最佳化的方式寫成,可以組合 Forth Engine 的機器 碼,能在 16 位元組中塞入 4 個機器碼,用結構化的方式編譯副程式。以建 造高階 Forth 語言程式,因 FEOS.ASM 高階碼是以副程式方式碼編譯的,

所以高階碼可以和低階碼任意混編,因此程式可以自由發揮 ebforth 的優 點,寫出最佳效率的程式。以下是 ebFORTH 的操作系統簡圖:

(36)

$COMPILE NAME?

NUMBER

ok?

compile token

print error message

QUIT EXIT

compile a literal

yes no

yes

no

$INTERPRST NAME?

NUMBER

ok?

EXECUTE

print error message

QUIT EXIT

push to data stack

yes no

yes

no

QUERY START

QUIT

PARSE

Interp?

COLD

EVAL

圖 3-1 ebFORTH 操作系統簡圖

(37)

3.2 操作系統之作業流程

Ebforth 開機進入 COLD 指令,COLD 送出開機訊號後就進入 QUIT,

接受輸入字串,並用 EVAL 指令處理字串,ebforth 預設工作狀態是直譯器

($Interpret)目的在執行使用者輸入的指令序列,當 PARSE 解譯輸入字串 為〝:〞時,系統進入編譯器,建造新指令。由於使用參數堆疊器來傳遞 副程式的參數,使得副程式在操作系統中可成為獨立工作的結構單元,可 組合成新的指令也可以成為結構單元,使得程式簡化,程式發展工作效率 提高,軟體的品質也容易確保,其詳細指令動作如下:

迴路名稱 功 能 說 明 COLD 開機啟動。

QUIT 接受輸入的文字序列,處理其中字串,是個無限迴路。

QUERY 接受輸入可長達 80 字的文字序列。

EVAL 有限迴路,在文字序列中分出一個以空白隔開的字串,並解 讀該字串。

'EVAL 變數,內容為 $INTERPRET 或 $COMPILE,據以決定如何處理 EVAL 所分出的字串。

$INTERPRET 解碼器。在字典中查所給的字串,若是找到即視為指令來執 行。若找不到,則試著轉換為數碼。若亦非數碼,就交給 ERROR 處理。

$COMPILE 編碼器。在字典中查所給的字串,若是被宣告為「立即」屬 性之指令,會立即被執行。若是普通指令則將其編入字典中。

(38)

性之指令,會立即被執行。若是普通指令則將其編入字典中。

若非指令,即試著轉換為數碼,並以數碼結構編入字典,若 非數碼,就交給 ERROR 處理。

NAME? 查字典是否有與字串相符的指令。

NUMBER? 取變數 BASE 內容為基數,將字串轉換成數值。

EXECUTE 執行查到的指令。

COMPILE 將查到的指令地址編成 CALL 碼,編入字典。

LITERAL 將轉換成的數值以數碼結構編入字典。

ERROR 印出無法處理的字串,並跳回 ABORT 再啟動。

表 3-1 操作系統之作業流程

(39)

3.3 FORTH ENGINE 的啟動 3.3.1 系統啟動迴路 COLD

Ebforth 開機啟動指令是 cold,當 xilinx 發展板 xc2v100 開電源後 將 SW1 按下,EEPROM 內容就載入 Forth Engine Block RAM 中,COLD 由記 憶體位址 0 開始執行機器碼,這段機器碼會將系統變數寫入 RAM 區,然後 跳入 COLD 指令。在 Memory 的位址 0000H 必須填入 3 個 word,如下表所示:

表 3-2 組合器預先規劃好記憶體內容的位址

COLD 作的是就是先執行核心指令測試程式(Kernal Test),確定 CPU 的工作正常,後印出 eforth v1.03,告訴使用人,CPU 已開始工作,然後告 訴使用者,CPU 已開始工作,可以進入 QUIT 迴圈,等候使用人,由終端 機上輸入指令文字。

(40)

3.3.2 ebFORTH 記憶體組態 (MEMORY MAP) 組合器預先規劃好記憶體內容的位址

下表是記憶體的配置:

區 域 名 稱 位 址 記憶體內容

Cold boot

Code dictionary Free space

Name dictionary Data stack

TIB

Return stack User variables

100H-17FH 180H-1344H 1346H-33E4H 33E6H-3BFFH 3C00H-3E7FH 3E80H-

-3F7FH

3F80H-3FFFH

? 動程式和變數初始值 Forth 執行碼詞典

詞典擴充區 Forth 名稱詞典 參數堆疊

輸入文字區 返回堆疊 系統參數區

表 3-3 記 憶 體 的 配 置

(41)

USER VARIABLE Return Stack

Terminal Input Buffer

Data Stack

Name Dictionary

Free Space

Code dictionary

COLD Boot Area

EM UP RP0 TIB SP0

NAME

NP

CP

CODEE

ORIG 4000H

3F80H 3E80H 3E80H

3C00H

3380H

1342H

180H

0H

圖 3-2 ebFORTH 記憶體之配置

(42)

3.3.3 ebFORTH 系統的核心指令

要符式處理器認識外部終端機輸入的指令,必須將軟體指令碼參數與 硬體(Forth Engine Core)宣告相同,基本的核心指令有 26 個,共分為 8 大類在硬體 Verilog.RTL Primitive 指令參數定義為:

Verilog RTL Primitive 組合語言 Primitive 指令機械碼定義 /Inner Interpret State

parameter [5:0] NOP = 6'H00;

parameter [5:0] DOLIT = 6'H01;

parameter [5:0] EXIT = 6'H02;

parameter [5:0] EXECUTE = 6'H03;

parameter [5:0] DOLIST = 6'H04;

parameter [5:0] CALIST = 6'H05;

parameter [5:0] NEXTIP = 6'H07;

// Memory Access State parameter [5:0] STORE1 = 6'H08;

parameter [5:0] STORE2 = 6'H09;

parameter [5:0] FETCH = 6'H0A;

parameter [5:0] CSTORE1 = 6'H0B;

parameter [5:0] CSTORE2 = 6'H0C;

parameter [5:0] CFETCH = 6'H0D;

// Loop & Branches State parameter [5:0] NEXT1 = 6'H10;

parameter [5:0] NEXT2 = 6'H11;

; Inner Interpret State _DOLIT equ 01h _EXIT equ 02h _EXECUTE equ 03h _DOLIST equ 04h _CALIST equ 05h

; NEXTIP equ 07h

; Memory Access State _STORE1 equ 08h _STORE2 equ 09h _FETCH equ 0ah _CSTORE1 equ 0bh _CSTORE2 equ 0ch _CFETCH equ 0dh

; Loop & Branches State _NEXT1 equ 10h _NEXT2 equ 11h

(43)

parameter [5:0] QBRAN1 = 6'H12;

parameter [5:0] QBRAN2 = 6'H13;

parameter [5:0] BRANCH = 6'H14;

// Return Stack Operation State parameter [5:0] RPFTCH = 6'H18;

parameter [5:0] RPSTOR = 6'H19;

parameter [5:0] R_TO = 6'H1A;

parameter [5:0] TO_R = 6'H1B;

parameter [5:0] RFETCH = 6'H1C;

// Data Stack Operation State parameter [5:0] DROP = 6'H20;

parameter [5:0] DUP = 6'H21;

parameter [5:0] SWAP1 = 6'H22;

parameter [5:0] SWAP2 = 6'H23;

parameter [5:0] OVER = 6'H16;

parameter [5:0] SPAT = 6'H25;

parameter [5:0] SPSTO = 6'H26;

// ALU Operation State parameter [5:0] UMPLUS1 = 6'H28;

parameter [5:0] UMPLUS2 = 6'H29;

parameter [5:0] UMPLUS3 = 6'H2A;

parameter [5:0] AND1 = 6'H2B;

parameter [5:0] AND2 = 6'H2C;

parameter [5:0] OR1 = 6'H2D;

parameter [5:0] OR2 = 6'H2E;

_QBRAN1 equ 12h _QBRAN2 equ 13h _BRANCH equ 14h

; Return Stack Operation State _RPFTCH equ 18h

_RPSTOR equ 19h _R_TO equ 1ah _TO_R equ 1bh _RFETCH equ 1ch

; Data Stack Operation State _DROP equ 20h _DUP equ 21h _SWAP1 equ 22h _SWAP2 equ 23h _OVER equ 16h _SPAT equ 25h _SPSTO equ 26h

; ALU Operation State _UMPLUS1 equ 28h _UMPLUS2 equ 29h _UMPLUS3 equ 2ah _AND1 equ 2bh _AND2 equ 2ch _OR1 equ 2dh _OR2 equ 2eh

(44)

parameter [5:0] XOR1 = 6'H2F;

parameter [5:0] XOR2 = 6'H30;

parameter [5:0] LZERO = 6'H31;

// I/O function State parameter [5:0] QRX = 6'H38;

parameter [5:0] TXSTOR1 = 6'H39;

parameter [5:0] TXSTOR2 = 6'H3A;

// System Operation State parameter [5:0] IRFETCH = 6'H3B;

_XOR1 equ 2fh _XOR2 equ 30h _LZERO equ 31h

; I/O function State _$RX equ 38h _TXSTORE equ 39h

;_TXSTORE equ 3Ah

; System Operation State

;IRFETCH equ 3Ch

表 3-4

Verilog.RTL Primitive 指令參數定義

(45)

3.4 變數和常數 3.4.1

系 統 變 數

在解碼器和編碼器運作的時候,許多資料要存入記憶體的特殊位址,留 下記錄,或者要從記憶體中取出來參考,這一套相關的系統變數是:

變 數 名 說 明

HLD 將數值轉換成 ASCII 字串時,系統所用暫存字串的指標。

SPAN EXPECT 指令所接受到字串的長度。

>IN 輸入字串中下一個解碼器要處理位置的指標。 #TIB 解碼器 所處理字串的長度。

'TIB 變數,內容為終端機輸入文字的暫存區。 BASE 變數,內容 為數值轉換時所用的基數。

CONTEXT 查字典時的搜尋指標,最先要查之指令名稱欄。 CP 字典上 空白區開始的地址。

'EVAL 變數,內容為$INTERPRET 或 $COMPILE 的地址,用以決定系 統是解碼或編碼。

LAST 字典上最後一指令的名稱欄

'ABORT 變數,內容為 QUIT 的地址,發生錯誤時要執行的指令。 TEXT 文字解壓後儲存的暫存區域。

表 3-5 系統變數

(46)

3.4.2 巨集指令

FORTH ENGINE 的機器碼大部分都是 Forth 的基本指令。但也有一些較 複雜的 Forth 指令,需用幾個機器碼組合而成。這種指令,一般可用副程 式的方式來建造。但是在 FORTH ENGINE 電腦中,一個 16 位元的字碼可以 塞入 4 個機器碼,所以如果一個 Forth 指令可以直接用 4 個或更少的機器 碼來完成,就比用副程式來建造要節省記憶空間。並且運算速度也可以加 快許多。這種 Forth 指令在我們組合器中,就是以巨集的方式來呈現。巨 集指令直接可將機器碼組合起來,避免了副程式呼叫所需進出返回堆疊的 負擔。

有些巨集指令,如 OVER,需要 5 個機器碼,比用副程式好像還要多佔一點 空間,似乎並不很適當。但是,如果它們在編碼中,前後都是機器碼,或 者是其它巨集指令所產生的機器碼,它們即可有效地合併,連續塞入機器 碼,而不必像組合副程式呼叫指令時,要先把未完成的字碼用 NOP 補滿,

因而會節省空間,也可加快執行速度。

使用巨集指令,整個系統會組合得更精簡快速,更能充分發揮 FORTH ENGINE CPU 的功能。唯一的缺點是巨集指令只能在 FORTH ENGINE 的組合器 內工作。在實際操作時,解碼器和編碼器都無法直接利用巨集指令。因此 我們必須在操作系統中,另外加上一套與巨集指令相對應的副程式指令,

專供解碼器和編碼器使用。

(47)

3.4.3 組合指令集

下面這一組指令都是 FORTH ENGINE 的副程式指令,其內部的功能都是 用 FORTH ENGINE 機器碼組合成的。我們為了要 FORTH ENGINE 的運算速度 能再加強到最快的速度,所有副程式可能用機器碼組合的都儘量如此建造 起來。這些指令包括了

指令 疊層表示(輸入-輸出) 說 明

: O< ( n -- f ) 若 n 小於 0,則 f=-1,否則 f=0 OR ( n n -- n )

UM+ ( n1 n2 -- sum carry)算出 n1 加 n2 的和及其溢位號。

?DUP ( n -- n n | 0) 若 n 為 0 則複製一份。

ROT ( n1 n2 n3 -- n2 n3 n2 ) 將堆疊最上三數旋轉。

2DUP ( n1 n2 -- n1 n2 n1 n2 ) 複製堆疊最上二數。

DNEGATE ( d -- d ) 將堆疊上雙數改變數值符號。

ABS ( n -- |n| ) 將堆疊上數值變為絕對值。

= ( n1 n2 -- f ) 若 n1=n2,f=-1;否則 f=0。

2! ( d a -- ) 將雙數 d 存入 a 位址。

(48)

2@ ( a -- d ) 從 a 位址取出雙數 d。

COUNT ( a -- a+1 n ) 從 a 位址取出 n,並將 a 加 1。

B> ( b a -- b+1 a ) 將位址 b 處未壓縮資料字碼取出,移入 a 的最低 8 位元,a 中資料向左移八位 元。這是壓縮字串到 16 位元字碼的基本 指令

表 3-6 組合指令集 3.4.4 終端機指令

指令 疊層表示

(輸入-輸出)

說 明

EMIT ( c -- ) 將 ASCII 碼 c 彈出,到終端機上顯示。

KEY ( -- c ) 等使用者在終端機上按鍵,並將鍵入的 ASCII 碼 c 放到堆疊上。

表 3-7 終端機指令

(49)

FORTH ENGINE 的終端機介面是一個有效又很簡單的設計。在執行 BYTE_CHANGE 指令時,UART 暫存器中的 LOW_BYTE 送出 8 位元資料,此時 HIGH_BYTE 位元即被移到 UART 暫存器。但我們將 W (0)送入一個正反器,

而這個正反器的輸出直接就連到一個輸出腳位上,此即 FORTH ENGINE 的終 端機輸出埠。

當執行 BYTE_CHANGE 指令時,我們將終端機輸入腳位的狀態鎖入 W(16) , 這是 W 暫存器的溢位元【Carry】,此即終端機的輸入埠了。終端機的輸入 和輸出,即全由 EMIT 及 KEY 來操控。EMIT 及 KEY 用 50us 及 100us 兩個指 令來延遲到 19200 Baud 的半位元及 1 位元的時序。

3.5 系 統 常 用 指 令

3.5.1 比 較 指 令

< ( n1 n2 -- f ) 若 n1< 若自然數 n1<="n3< p>

表 3-8 比較指令 3.5.2 乘 數 指 令

UM﹡ ﹙n1 n2 -- d﹚ 將自然數 n1 乘以 n2,得雙數積。

﹡ ﹙n1 n2 -- prod﹚ 乘。

M﹡ ﹙n1 n2 -- d﹚ 算出 48 位元的雙數積。

*/ ﹙n1 n2 n3 -- q﹚ 算出 n1*n2/n3(計算中維持 48 位元)。 */MOD

﹙n1 n2 n3 -- r q﹚算出 n1*n2/n3 最後的餘數

(50)

﹙n1 n2 n3 -- r q﹚算出 n1*n2/n3 最後的餘數 及商。

表 3-9 乘數指令

這是乘法的基本指令,其他乘法指令皆從它衍生而出。FORTH ENGINE 有單步乘法機器碼 MUL。將 W 清作 O,n1 放在 S 內,n2 放在 A 內,重覆執 行 MUL16 次,即可在 T-A 中得到 32 位元的積。

3.5.3 記 憶 指 令

HERE ﹙-- a﹚ 變數,內容為詞典邊界的最高位址。

PAD ﹙-- a﹚ 變數,內容為字串暫存區的位址。

TIB ﹙-- a﹚ 變數,內容為終端機暫存區的位址。

@EXECUTE ﹙a --﹚ 由 a 中取出執行碼欄地址,然後跳到該處去 執行。

CMOVE ﹙a1 a2 n --﹚ 從 a1 搬 n 個 16 位元字碼到 a2 區。

FILL ﹙a n c --﹚ 將 16 位元數值 c 填入 a 起的 n 字碼區。

>CHAR ﹙c -- c﹚ 將不能印出的字符都改為底線符號_,如此為 防止印表機在紙張上印出亂碼。

表 3-10 記憶指令

(51)

3.5.4 壓 縮 字 串 及 解 壓 指 令

PACK$ ﹙b n a -- a﹚ 將在 b 位址的 n 個字符壓縮到 a 區,每 2 個 8 位元字符壓縮到一個 16 位元的字碼中,最 後補 0。

UNPACK$ ﹙a b -- b﹚ 將在 a 地址中的一個壓縮後的字串解壓,並 放在 b 區。

表 3-11 壓縮字串及解壓指令

例如 7 個字符的字串「UNPACK$」,未壓縮時是由 8 個 16 位元之字碼組成,

壓縮後成為 2 個字碼,內容如下:

Bit 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 字碼 0 1 0 1 0 1 0 1 0 1 0 0 1 1 1 0 è 'U' 'N'

字碼 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 è 'A' 'C' 字碼 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 è '$' 0

字串壓縮後不但減少了記憶存儲的空間,也顯著地加速了 Forth 系統查字 典的速度。在比對字串時,可一次比較 2 個字符。

(52)

3.5.5 數 值 印 出 指 令

FORTH ENGINE 的數值都是以 16 位元方式存在記憶體及暫存器中的,只 有在將數字印出時才須要將其轉成為 ASCII 字串,每字符 8 位元。轉換時 用 BASE 裡所存數值作轉換的基數。所以可以很方便地把數值隨時轉成以十 進制,十六進制,或其他基數的字串形式印出。

數字列印的指令常用的有以下幾個:

. ﹙n--﹚ 將 n 轉換成字串顯示在終端機上。

U. ﹙u--﹚ 將自然數 u 顯示在終端機上。

.R ﹙n1 n2 -- ﹚ 將 n1 顯示在 n2 欄位中,靠右對齊。

U.R ﹙u n --﹚ 將 n1 顯示在 n2 欄位中,靠右對齊。

? ﹙u n --﹚ 將自然數 u 顯示在 n 欄位中,靠右對齊。將 a 地 址中的數值取出,顯示在終端機上。

HEX ﹙--﹚ 將 BASE 基數改為 16,以後數字轉換即十六進制。

DECIMAL ﹙--﹚ 將 BASE 基數改為 10,以後數字 轉換即十進制。

表 3-12 數值印出指令

為要完成以上數值列印的功能,FORTH ENGINE 須要有一系列的支援指令。

使用者也可以自行利用這些指令,設計出更適合特殊不同場合應用的列印 指令。

(53)

str ﹙n -- b u﹚ 將數值 n 轉換成字串儲存在 b 區,字串長度是 u。

DIGIT ﹙u -- c﹚ 將一位數的值 u 轉換成其對應的 ASCII 數碼 c。

EXTRACT ﹙n1 base -- n2 c﹚

以基數 BASE 去除 n1,餘數轉成一位的數碼 c,留 下商數 n2,以便繼續數值轉換之程序。

<# ﹙--﹚ 準備轉換,設定 PAD 存所得字串,以 HLD 為指標。

HOLD ﹙c --﹚ 將一位數碼 c 寫到 HLD 所指的位置,並將 HLD 減 1,準備接受下一數碼。

# ﹙u1 -- u2﹚ 由 u1 中轉出一位數碼寫到 PAD 中,商是 u2。

#S ﹙u --o﹚ 將 u 轉出所有數碼字串寫到 PAD 中,最後商是 0。

SIGN﹙n --﹚ 若 n 小於零,則在數碼字串前加負 號。

#> ﹙u1 -- b u2﹚ 丟掉 u1,留下數碼字串的地址 b 及其長度 u2。

表 3-13 列印指令

3.5.6 數 值 輸 入 指 令

由終端機輸入的數字都是 ASCII 數碼字串,須要轉換成對應的 16 位元 數值才能放在堆疊上運用,或是存在記憶體中。將數碼字串轉換成數值的 指令是:

NUMBER? ﹙ a -- n -1 | a 0 ﹚

將在位址 a 的數碼字串轉換成 16 位元的數值 n 及-1 的旗號。若轉換不成功,(字串中有非數字

(54)

a 0 ﹚ 碼的符號),則保留地址 a 並留下 0 的旗號。

DIGITS ﹙ c base -- u f ﹚

將一位數碼字符 c 按基數 BASE 轉為數值 u 及 -1,若 c 不是數碼,則保留 c 並留下 0 的旗號。

表 3-14 數值輸入指令

3.5.7 其 他 列 印 指 令

除了列印數值字串外,FORTH ENGINE 也提供一套相當完整的指令,讓 使用者很方便地在終端機上顯示各樣文字資料,排列成整齊美觀的文件,

這套指令是:

SPACE ﹙--﹚ 輸出一個空格。

CR ﹙--﹚ 換行。

CHARS ﹙n c --﹚ 輸出 n 個 ASCII 碼 c 所對應的字符。

TYPE ﹙a u --﹚ 從地址 a 取 u 個 ASCII 碼字符輸出。

Do$ ﹙-- a﹚ 將編碼在程式中的字串解壓縮到 TEXT 區,並將 TEXT 區的地址 a 放上堆疊。 $"| ﹙-- a﹚ 將編 碼在此指令後的字串解壓,存到 a 區。

." | ﹙--﹚ 將編碼在此指令後的字串解壓,並印出。

表 3-15 其他列印指令

(55)

第四章 解碼器相關指令

4.1 解碼器相關指令

4.1.1 解讀指令

解讀指令是 FORTH ENGINE 系統由輸入的文字序列中,分解出個別字串 的機制。一般文字序列中有許多字串,以空格或某些不能印出的控制字符

﹙ASCII 碼 0 到 31 之間﹚來分割的。字串分割出來後,才交給解碼器

【Interpreter】處理。

PARSE ﹙ c -- b u ﹚ 在從 b 開始長度為 u 的文字序列中取出一個用字 符 c 所分割的字串。

TIB Text Input Buffer

在文字輸入區中取出下一個以字符 c 來分割的字 串。

TOKEN ﹙ -- a ﹚ 在文字輸入區取出用空格字碼分割的下一個字 串。字串存在 a+1,其長度存在 a。

WORD ﹙ c -- a ﹚ 在文字輸入區用字符 c 取出下一個字串。字串存 在 a+1,其長度存在 a。

表 4-1 解讀指令

找到此字串後,將其所在地址 b 及長度 u 留在堆疊上。找到字串後,將字 串長度 delta 取代 c。如果 c 碼是 32﹙空格﹚,則還會將 b 區中起頭的空 格都略過。此時的 b,將是剩下起頭非空格後的字串位址。

(56)

4.1.2 查 字 典 指 令

FORTH ENGINE 的指令,都是存在記憶體中,一個特定區叫做字典的區 域。每個指令中都有三欄:連接欄、名稱欄和執行碼欄。連接欄為一字碼 長度,其中含一個地址,指到上一個指令的名稱欄。名稱欄的長度不定,

存有指令的名稱及其長度,以壓縮字串的形式儲存。執行碼欄內,則存有 可執行的機器碼及相關資料。

這樣所有的指令在字典裡就都連接成一長串的列表。若連接欄中存的 是 0,表示列表的盡頭。解碼器可在這個字典裡,依輸入的名稱尋找到要執 行的指令。查字典時遇到連接欄裡是 0,就知道已查到了字典的盡頭,都還 沒找到所要的指令,表示名稱錯誤或尚未定義。而查字典的最關鍵指令就 是 FIND。FIND 指令係從 CONTEXT 陣列中找到要搜查的字彙,CONTEXT 可以容 納 8 個不同的字彙,讓解碼器依序搜查,編譯器再定義新指令時,係將新指令 加入 CURRENT 所指向的字彙,編譯器查字典的時候,是先搜尋 VOC1 字彙,依 序搜尋 VOC3,FORTH 字彙,再找不到就是碰到錯誤狀況了,編譯器會將新指令 編入 VOC4 字彙。

FIND ﹙ a va -- xt na | a o ﹚

指令名稱字串在位址 a,va 為搜尋起點的指 標,其內容為最後定義而被納入字典之指令的 名稱欄地址。由 va 開始查字典,若找到的指令 其名稱與所給之字串相同,留下該指令執行碼 的地址 xt 及名稱欄的地址 na。若查完字典仍 找不到,則保留原字串位址 a,並給一個 0 的

(57)

旗號表失敗。

NAME? ﹙ a -- xt na | a o ﹚

將系統變數 CONTEXT 作為字典搜尋起點的指 標,從其中可取出字典最後定義的名稱欄地 址,與所給在位址 a 的名稱字串相比,以搜查 字典中該指令的執行碼地址 xt 及名稱欄的地 址 na。

SAME? ﹙ al a2 u -- a1 a2 f ﹚

比較在 a1 區和在 a2 區兩個長度為 u 的字串,

若兩個字串完全相同,則 f=0,若有任何不等 的字碼,f≠0。

NAME> ﹙ na -- xa ﹚ 由指令的名稱欄地址 na 換算出執行碼欄的地 址 xa。

表 4-2 查字典指令

(58)

4.1.3 詞典中指令的結構

call doVOC addr VOC4

VOC3

VOC4

call doVOC addr VOC3

VOC2

VOC3

call doVOC addr VOC2

VOC1

VOC2

call doVOC addr VOC1 FORTH

VOC1

call doVOC addr FORTH

0

FORTH

字典延伸區 字典延伸區

VOC4字彙 VOC4字彙

VOC3字彙 VOC3字彙

VOC2字彙 VOC2字彙

FORTH字彙 FORTH字彙 VOC1

VOC3 FORTH

0 0 0 0 0 0 0

VOC4 VOC4

VOC1字彙 LASTVOC

CONTEXT

CURRENT

系統變數 字彙 字典 (RAM記憶區)

VOC2

VOC4 VOC1 FORTH

VOC3

圖 4-1 易符字典結構

(59)

4.1.4 字的資料結構

Link field Name field Code field

$1000h

$1004h

$1020h

$1000h

$1024h

LINK ADDRESS==>連接欄位址,指向前一個字的name address NAME ADDRESS ==> 名稱欄位址,名稱可以有1-31個位元

CODE ADDRESS ==> 執行欄位址

$00001004h 指向前一個字的Name field

$32317003 code field

$1028h

名稱為cold,第一個位元組是名稱的字元數

CODE ADDRESS

$00001024

$1030h

$332317005

$1034

code field

$103C

指向前一個字的Name field

名稱為p1234,第一個位元組是名稱的字元數

執行欄位址

圖 4-2 字的資料結構

(60)

4.2 輸 入 文 字 序 列 的 指 令

KEY 和 EMIT 是終端機輸入輸出的基本指令。由此二指令衍生出許多高 階的輸出輸入指令,支持 FORTH ENGINE 系統的人機界面。

QUERY ﹙--﹚ 從終端機接受最多達 80 個字符的字串,並將此字 串存入終端機輸入區﹙TIB﹚。

ACCEPT (b u1 -- b u2) 從終端機接受 u1 個字符的字串,並將其存入 b 區。若使用者接收到 u1 字符前按了 RET 鍵,所實 際接受到的字符數是 u2。

EXPECT ( b u -- ) 從終端機接受 u 個字符,存至 b 區,實際所接受 到字串的長度則存於 SPAN 中。

^H ( bot eot cur - bot eot cur )

執行退格清除鍵【Backspace】的功能。若 cur=bot 則三參數保持不變,若 cur>bot,則將 cur 減 1,

同時輸出三個 ASCII 字碼 Backspace、Space、

Backspace,以清除終端機上才輸入的字符。

TAP (bot eotcur–

bot eot cur )

接受一個字符 c,存入記憶區,並將 cur 加 1。

KTAP (bot eot cur- bot eot cur)

接受一個字符 c,存入記憶並處理 CR、BS、及其 他 ASCII 控制符號。

表 4-3 輸入文字序列的指令

(61)

4.3 偵 錯 指 令

當 FORTH ENGINE 執行一連串指令,若在半途發生錯誤,必須立即反應,

停止後續的動作,將系統重設到正常的執行狀態,等候使用者輸入新的指 令。最關鍵的偵錯指令即是 ABORT。

ABORT ( -- ) 停止現在執行的指令,跳到 QUIT 重新開動

INTERPRETER 解碼器等候輸入下一輪的新指令。

ERROR ( a -- ) a 指到目前所執行指令的名稱字串,將此字串印出並 附加「?」字符,再經由 ABORT 跳回 QUIT。

abort" ( f -- ) 若 f≠0,則印出編碼在此指令後的字串,並由 ABORT 跳回 QUIT。若 f=0,則執行後續的指令。

表 4-4 偵錯指令

ERROR

WARNING=-1? ABORT

Print error message

Clear data stack Push and

pop

QUIT

圖 4-3 ERROR LOOP

(62)

4.4 解 碼 器

解碼器是 FORTH ENGINE 操作系統的核心。它由終端機接受使用者鍵 入的文字序列,將其中的字串分解出來,然後依序處理這些字串。有些字 串是指令,在字典中查到後即去執行。有些字串是數字,即轉換成數值放 到堆疊上。全部文字序列如此處理完畢,就等下一輪再接受新的文字序列 來處理,如此週而復始,直到關機。執行指令或處理字串時若有錯誤,則 重新開動解碼器。

QUIT ( -- ) 解碼器。設定終端機輸入區後進入迴路,接受文字序 列並處理序列中的指令。

EVAL ( -- ) 本身也是一個迴路,在已經輸入的文字序列中分解字 串。然後將字串交給 'EVAL 中存的指令處理。當文字 序列處理完畢,則由 .OK 指令印出「OK」字樣。解碼 時,'EVAL 中存的是 $INTERPRET。編碼時,則 'EVAL 中是 $COMPILE。

.OK ( -- ) 在解碼操作時,印出「OK」字樣,顯示一組文字序列 已經處理完。若在編碼操作時,則不印,並繼續編碼 工作。

[ ( -- ) 將 $INTERPRET 指令的執行碼欄地址存入 'EVAL 變數 中,如此系統即由解碼器來處理指令字串。

$INTERPRET ( a -- ) 根據存在地址 a 的名稱字串查字典,若找到與名稱相 符的指令,即執行該指令。若字典中沒有此指令,則 將字串當作數目字轉換成一個數值,留在堆疊上。若

(63)

字串不是數目字,則交由 ERROR 處理此錯誤情況。

表 4-5 解碼器

$Interpret

NAME?

EXECUTE NUMBER

OK?

EXIT

Print error message

QUIT Push to data

stack

圖 4-4 $INTERPRET LOOP

(64)

4.5 編 碼 器 (COMPILER)相 關 指 令

編碼器指令

FORTH ENGINE 中的解碼器和編碼器是一對孿生兄弟,他們用相同的 QUIT 機制,接受終端機輸入的文字序列。用相同的解讀指令 PARSE 分解出 指令字串,再由指令字串去查字典。不同的是當解碼器找到了指令時即去 執行,而編碼器找到指令時,不會直接執行,而是將指令的執行碼欄地址,

編入字典邊界頂端所正在定義的新指令中。新指令建造完成後,在被點名 執行時,編入的執行碼就會被依序執行了。

在 EVAL 的迴路中有一段是 'EVAL @EXECUTE,即將 'EVAL 變數中所存的地址 叫出來執行。解碼器工作時,'EVAL 中所存的是 $INTERPRET 指令的執行碼 欄地址,若是編碼器在工作,'EVAL 中存的則是 $COMPILE 的執行碼欄地址。

改變 'EVAL 中所存的地址,就會讓 FORTH ENGINE 或做編碼的工作,或做解 碼的工作。

$COMPILE ( a -- )

根據 a 區中的名稱字串查字典。若找到與名稱字串相符的指令,即將此指 令的執行碼地址,編入字典邊界頂端正在定義的新指令中。但假若此指令 名稱欄中最高位($800000)不是零,這個指令即屬立即執行【Immediate】

類,這類指令會隨即被執行而不被編碼。若字串不是一個指令,則將它當 作數值轉換,而將數值以 Literal 形式編入新指令。若不是指令,也不是 數字,則跳到 ERROR,處理此錯誤情況。

LITERAL( n -- )

參考文獻

相關文件

之意,此指依照命令動作的意義。所謂伺服 系統,就是依照指示命令動作所構成的控制

(A)SQL 指令是關聯式資料庫的基本規格(B)只有 SQLServer 2000 支援 SQL 指令(C)SQL 指令 複雜難寫,適合程式進階者使用(D)是由 Oracle

一般而言,信用卡主可直接 在櫃員機提取現金或以其他 轉賬方式動用信用限額內的 現金,這是一種便利但相當 昂貴的借貸方法. 利息

MASS::lda(Y~.,data) Linear discriminant analysis MASS::qda(Y~.,data) Quadratic Discriminant Analysis class::knn(X,X,Y,k,prob) k-Nearest Neighbour(X 為變數資料;Y 為分類)

(11)※群組化物件(使用 Flash 工具列所繪製之物件):Ctrl-G 或功能

Windows 95 後的「命令提示字 元」就是執行 MS-DOS 指令的應用

The purpose of this research is to develop an optimum automatic formation model of the golf club head by using the optimal designing techniques to combine the techniques of the

本論文首先將討論以及研究 80x86 的 FORTH Virtual Machine【3】來分析 FORTH 的 Primitive 指令,因此 FORTH Engine 的 Primitive 指令將依照 80x86 FORTH