最新文章
XILINX Spartan?-3開(kāi)發(fā)板上的新型處理器
幾年前,我的朋友Paul Reed建議我重新修訂并再次出版這本書(shū),不僅因?yàn)檫@本書(shū)對(duì)系統(tǒng)設(shè)計(jì)教學(xué)具有重要價(jià)值,同時(shí)還因?yàn)檫@本書(shū)可以作為良好的切入點(diǎn),幫助那些想要成為創(chuàng)新者的人們從零基礎(chǔ)構(gòu)建可靠的系統(tǒng)。
然而,我當(dāng)時(shí)實(shí)際上是遇到了很大的困難。我最初開(kāi)發(fā)的編譯器是將已基本消失了的處理器作為目標(biāo)。因此,我的解決辦法就是為現(xiàn)代處理器重新編寫(xiě)編譯器。但在做了不少研究之后,我無(wú)法找到一款能夠在清晰度、規(guī)律性和簡(jiǎn)潔性上符合我標(biāo)準(zhǔn)的處理器。因此,我自己設(shè)計(jì)了這款編譯器。而我之所以能夠?qū)⒃撓敕ǜ吨T實(shí)現(xiàn),都是因?yàn)楝F(xiàn)代FPGA能夠幫助我設(shè)計(jì)硬件以及系統(tǒng)軟件。
選擇賽靈思 FPGA能幫助我更新系統(tǒng),同時(shí)讓設(shè)計(jì)盡可能接近自1990年以來(lái)的原始版本。更重要的是,選擇賽靈思FPGA 能幫助我更新系統(tǒng),同時(shí)讓設(shè)計(jì)盡可能接近自1990年以來(lái)的原始版本。
實(shí)現(xiàn)在低成本Digilent Spartan?-3開(kāi)發(fā)板上的新型處理器RISC負(fù)責(zé)托管1MB靜態(tài)RAM (SRAM)內(nèi)存。我唯一添加的系統(tǒng)硬件就是一個(gè)鼠標(biāo)接口和一個(gè)用來(lái)替換舊系統(tǒng)中硬盤驅(qū)動(dòng)器的SD卡。
這本書(shū)和面向整個(gè)系統(tǒng)的源代碼可在projectoberon.com[3,4,5]中查閱,也可在該網(wǎng)站上名為 S3RISCinstall.zip.的單個(gè)文件中進(jìn)行查閱。該文件包含指令、SD卡文件系統(tǒng)圖像和FPGA配置比特文件(對(duì)于Spartan-3開(kāi)發(fā)板的 Platform Flash,此為PROM文件形式),以及SD卡/鼠標(biāo)接口硬件的構(gòu)造詳圖。
RISC處理器
該處理器由算術(shù)邏輯單元、由16個(gè)32位寄存器組成的陣列和帶指令寄存器、IR及程序計(jì)數(shù)器PC的控制單元組成。Verilog模塊RISC5就是該處理器的典型代表。
該處理器具有20種指令:4種用于移動(dòng)、偏移和旋轉(zhuǎn);4種用于邏輯運(yùn)算;4種用于整數(shù)運(yùn)算;4種用于浮點(diǎn)運(yùn)算;2種用于存儲(chǔ)器訪問(wèn);2種用于分支。
RISC5通過(guò)運(yùn)行環(huán)境RISC5Top導(dǎo)入。該運(yùn)行環(huán)境包括到各種(內(nèi)存映射)器件和SRAM(256M×32 位)的接口。
整個(gè)系統(tǒng)(圖1)包括以下Verilog模塊(見(jiàn)行統(tǒng)計(jì))
RISC5Top | 運(yùn)行環(huán)境 | 194 |
RISC5 | 處理器 | 201 |
乘法器 | 整數(shù)運(yùn)算 | 47 |
除法器 | 24 | |
FP加法器 | 浮點(diǎn)運(yùn)算 | 98 |
FP乘法器 | 33 | |
FP除法器 | 35 | |
SPI | SD卡和發(fā)送器/接收器 | 25 |
VID | 1024×768 視頻控制器 | 73 |
PS2 | 鍵盤 | 25 |
鼠標(biāo) | 鼠標(biāo) | 95 |
RS232T | RS232 發(fā)送器 | 23 |
RS232R | RS232 接收器 | 25 |
圖1 – 該系統(tǒng)及其所含Verilog模塊的方框圖
我將內(nèi)存映射到黑白VGA顯示器中,這樣它只占用1024×768×1 位/像素=98304字節(jié),基本上
占 1 MB可用主內(nèi)存的10%。該SD卡將取代初始系統(tǒng)中80MB的硬盤驅(qū)動(dòng)器,其可通過(guò)能夠接受并序列化字節(jié)或32位字的標(biāo)準(zhǔn)SPI接口進(jìn)行存取。鍵盤和鼠標(biāo)通過(guò)標(biāo)準(zhǔn)PS-2串行接口連接。此外,還提供一根串行異步的RS-232線和一個(gè)通用8位并行的I/O接口。模塊RISC5Top還帶有一個(gè)每毫秒采用增量式計(jì)數(shù)的計(jì)數(shù)器。
OBERON操作系統(tǒng)
該操作系統(tǒng)軟件由包括內(nèi)存分配器(帶垃圾回收器)的內(nèi)核、文件系統(tǒng)以及引導(dǎo)載入程序、文本系統(tǒng)、瀏覽器系統(tǒng)和文本編輯器組成。
名為“Oberon”的模塊是中心任務(wù)調(diào)度程序,而“System”是基礎(chǔ)命令模塊。通過(guò)點(diǎn)擊顯示器上任何瀏覽器文本“M.P”上的中間按鈕即可觸發(fā)動(dòng)作,其中P是模塊M聲明的程序名。如果M不存在,則會(huì)自動(dòng)加載。但是,大多數(shù)文本編輯命令是通過(guò)簡(jiǎn)單的鼠標(biāo)點(diǎn)擊觸發(fā)的。
其中,左邊一欄按鈕用來(lái)設(shè)置"脫字"符,標(biāo)記文本位置,右邊一欄按鈕用來(lái)選擇文本字段(text stretch)。
“Kernel”模塊包括磁盤存儲(chǔ)管理和垃圾回收器。我保證觀察瀏覽器是平鋪的,不重疊。標(biāo)準(zhǔn)布局顯示了多個(gè)瀏覽器的兩條垂直軌跡。只需拖動(dòng)標(biāo)題欄,就可以放大、縮小或移動(dòng)它們。圖2顯示了在顯示器上運(yùn)行的用戶界面以及Spartan-3開(kāi)發(fā)板、鍵盤及鼠標(biāo)。
圖2 - 顯示用戶界面的顯示器(Spartan-3開(kāi)發(fā)板在右側(cè))
加載時(shí)系統(tǒng)占用模塊空間112640字節(jié)(21%),占堆(heap)的16128字節(jié)(3%)。系統(tǒng)包括所以下幾個(gè)模塊(見(jiàn)行統(tǒng)計(jì)),如圖3所示:
內(nèi)核 | 271 | (內(nèi)核) |
文件目錄 | 352 | |
文件 | 505 | |
模塊(引導(dǎo)載入程序) | 226 | |
瀏覽器 | 216 | (外核) |
文本 | 532 | |
Oberon | 411 | |
菜單瀏覽器 | 208 | |
文本幀 | 874 | |
系統(tǒng) | 420 | |
編輯 | 233 | |
圖3 - 系統(tǒng)及其模塊
值得注意的是,該系統(tǒng)在加電或重置時(shí),完成初始化僅需兩秒鐘。這包括文件目錄中垃圾回收掃描。
OBERON編譯器
系統(tǒng)自帶的編譯器采用簡(jiǎn)單的自上而下遞歸下降分析法。用戶使用ORP.Compile @命令即可激活模塊選定的源文本上的編譯器。
包解析器通過(guò)掃描儀輸入各種符號(hào),包括識(shí)別符、數(shù)字和特殊符號(hào)(如BEGIN、END、+等)。該方案已被證明在許多應(yīng)用中有效且均表現(xiàn)不凡。這點(diǎn)在我著的書(shū)《編譯器結(jié)構(gòu)》[6,7]中有詳細(xì)說(shuō)明。
該包解析器調(diào)用代碼生成程序模塊中的程序。這些程序直接將指令添加在代碼陣列上。如果已知所有分支目的地,向前跳轉(zhuǎn)指令(forward-branch instructions)在模塊編譯結(jié)束時(shí)則會(huì)提供跳轉(zhuǎn)地址(修正)。
所有可變地址都與基址寄存器關(guān)聯(lián)。這就是用于局部變量(運(yùn)行時(shí)設(shè)置在程序輸入)的R14(堆棧指示器)或用于全局和輸入變量的R13。
基址地址按要求通過(guò)地址保存在寄存器R12內(nèi)的系統(tǒng)全局模塊表載入。R15用于RISC架構(gòu)確定的返回地址(鏈接)。因此,R0-R11可用于表達(dá)式評(píng)估和傳遞過(guò)程參數(shù)。
整個(gè)編譯器由4個(gè)相對(duì)較小的有效模塊組成(見(jiàn)行統(tǒng)計(jì)):
ORP | 包解析器 | 968 |
ORG | 代碼生成器 | 1120 |
ORB | base def | 435 |
ORS | 掃描儀 | 311 |
編譯器占用115912字節(jié)(22%)的模塊空間和17508字節(jié)(4%)的堆空間(編譯之前)。其源代碼長(zhǎng)約65KB。編譯器自身的編譯在25 MHz RISC處理器上只需幾秒鐘[8]。
Lola HDL及Verilog翻譯
名為L(zhǎng)ola的硬件描述語(yǔ)言(HDL)于1990年作為硬件設(shè)計(jì)基礎(chǔ)教學(xué)的一種方式開(kāi)發(fā)。這一時(shí)期,文本定義開(kāi)始替代電路圖,首個(gè)FPGA開(kāi)始應(yīng)用,盡管尚未達(dá)到主流設(shè)計(jì)。Lola由生成位流文件(被加載到FPGA)的編譯器執(zhí)行。位流文件格式由Algotronix公司和 Concurrent Logic 公司共同開(kāi)發(fā)。這兩家公司提供的存儲(chǔ)單元結(jié)構(gòu)都比較簡(jiǎn)單,看起來(lái)好像是自動(dòng)布局布線的最佳選擇。
在我的項(xiàng)目之后,緊接著是在FPGA上重新實(shí)現(xiàn)Oberon系統(tǒng),現(xiàn)在突然出現(xiàn)這種想法以喚醒Lola。由于賽靈思 FPGA存儲(chǔ)單元結(jié)構(gòu)相當(dāng)簡(jiǎn)單,所以我們沒(méi)有冒險(xiǎn)實(shí)現(xiàn)布局布線,更何況賽靈思因?qū)@蚨芙^透露其位流文件格式這一事實(shí)。
很明顯,要建立不生成專有位流文件但翻譯成賽靈思能為其提供綜合工具的語(yǔ)言的Lola編譯器。我們選擇了Verilog。這種解決方法意味著迂回繞路相當(dāng)浪費(fèi):首先,Lola模塊已經(jīng)經(jīng)過(guò)包解析,然后翻譯,然后再次包解析。通過(guò)所有這些措施,我們確信Lola編譯器具有適當(dāng)?shù)腻e(cuò)誤報(bào)告和類型一致性檢查功能。
為促進(jìn)Lola-2的開(kāi)發(fā),我們決心用Lola重新定義所有RISC5處理器模塊。現(xiàn)在,這已經(jīng)實(shí)現(xiàn)了。
LOLA語(yǔ)言
Lola是一種Oberon風(fēng)格的短小而精煉的程序語(yǔ)言(見(jiàn)http://www.inf.ethz.ch/personal/wirth/Lola/Lola2.pdf)。為簡(jiǎn)單起見(jiàn),我們?cè)谶@里只展示一個(gè)簡(jiǎn)單的Lola文本實(shí)例。源文本單元被稱為模塊。其報(bào)頭規(guī)定了名稱及其輸入和輸出參數(shù),以及各參數(shù)的名稱和類型。
MODULE Counter0 (IN CLK50M, rstIn: BIT;
IN swi: BYTE; OUT leds: BYTE);
TYPE IBUFG: = MODULE (IN I: BIT; OUT O: BIT)^; VAR clk, tick0, tick1: BIT;
clkInBuf: IBUFG; REG (clk) rst: BIT;
cnt0: [16] BIT; (*半毫秒*)
cnt1: [10] BIT; (*半秒*)
cnt2: BYTE;
BEGIN leds:= swi.7 ->swi : swi.0 -> cnt1[9:2]:cnt2;
tick0:= (cnt0 = 49999);
tick1:= tick0 & (cnt1 =499); rst:= ~rstIn;
cnt0:= ~rst -> 0: tick0 ->0 : cnt0 + 1; cnt1 := ~rst -> 0 : tick1 -> 0 : cnt1 +tick0; cnt2 := ~rst -> 0 : cnt2 + tick1;
clkInBuf (CLK50M,clk) END Counter0.
編譯器通常使用值為NIL的指示檢查數(shù)組索引和基準(zhǔn)值。如果違反規(guī)定,這會(huì)造成陷阱。這種技術(shù)具有高度的安全性,防止錯(cuò)誤和崩潰。事實(shí)上,只能通過(guò)采用偽模塊SYSTEM中的操作,即PUT和COPY,才能防礙系統(tǒng)的完整性。
這些操作必須局限于接入器件接口的驅(qū)動(dòng)模塊。在輸入列表中,通過(guò)SYSTEM很容易識(shí)別它們。整個(gè)系統(tǒng)采用Oberon編程,無(wú)需使用匯編碼。
我選擇Digilent Spartan-3 開(kāi)發(fā)板是由于其成本低、操作簡(jiǎn)便,這使其適于教育機(jī)構(gòu),以獲得整套課堂教學(xué)套件。
一個(gè)重大優(yōu)勢(shì)就是該開(kāi)發(fā)板上有靜態(tài)RAM,使得接口連接非常簡(jiǎn)單直觀(甚至用于字節(jié)選擇)。遺憾的是,所有新開(kāi)發(fā)板均采用動(dòng)態(tài)RAM,雖然存儲(chǔ)空間更大,但接口連接復(fù)雜得多,因此刷新和初始化(校準(zhǔn))需要電路。這一電路與帶靜態(tài)RAM的整個(gè)處理器一樣復(fù)雜。即使控制器以單片式提供,這有悖于我們的開(kāi)放檢查原則。
報(bào)頭之后是一段包含本地對(duì)象(如變量和寄存器)的聲明。之后一段通過(guò)賦值規(guī)定變量和寄存器數(shù)值。BYTE表示一個(gè)8位陣列。
每一個(gè)變量和寄存器通過(guò)唯一一種表達(dá)式(組合電路)進(jìn)行定義。多重賦值沒(méi)有任何意義??梢韵胂?,每個(gè)HDL程序包含在一個(gè)大的永遠(yuǎn)重復(fù)子句中,因?yàn)榧拇嫫骱妥兞抠x值會(huì)在每一個(gè)同步時(shí)鐘脈沖周期內(nèi)重復(fù)。
LOLA編譯器
編譯器采用簡(jiǎn)單的自上而下遞歸下降分析法。通過(guò)LSC.Compile @命令在所選Lola源文本上激活該編譯器。包分析器包解析器通過(guò)掃描儀輸入各種符號(hào),包括識(shí)別符、數(shù)字和特殊符號(hào)(如BEGIN、END、+等)。該方案已被證明在許多應(yīng)用中有效且表現(xiàn)不凡。這在我著的書(shū)《編譯器結(jié)構(gòu)》 (第1部分和第2部分)中有詳細(xì)說(shuō)明。
而不是直接即時(shí)生成Verilog文本,作為語(yǔ)法分析的一種意外結(jié)果,包分析器中會(huì)出現(xiàn)語(yǔ)句,從而生成樹(shù)形結(jié)構(gòu),以適當(dāng)方式表示輸入文本,以便進(jìn)一步處理。這種結(jié)構(gòu)具有一個(gè)優(yōu)點(diǎn),即通過(guò)調(diào)用不同翻譯程序很容易生成各種不同的輸出。其中一個(gè)就是Verilog翻譯程序。命令為 LSV. List outputfile.v。另一個(gè)命令可能翻譯至VHDL或簡(jiǎn)單地列出樹(shù)形結(jié)構(gòu)。但也有可能生成網(wǎng)表,以便通過(guò)布局器和布線器進(jìn)行進(jìn)一步處理。
因此,整個(gè)編譯器至少包括4個(gè)相對(duì)較小的高效模塊組成(線數(shù)顯示):
掃描儀 | 159 | ||
LSB | 基址 | 52 | |
LSC | 編譯器/包解析器 | 503 | |
LSV | Verilog 生成器 | 215 | |