新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 跟我寫ARM處理器之一:從寫module arm開始

        跟我寫ARM處理器之一:從寫module arm開始

        作者: 時間:2016-11-10 來源:網絡 收藏
        我決定把我寫ARM處理器的經驗分享給大家。不是自賣自夸,我這個核是非常好的核。一個證明方法是下載入FPGA,看她是不是能工作。這種證明方法,我已經做到了。大家如果可以下載整個工程文件,稍微改造一下,即能驗證是否成功。但是這還不是推廣她的方法。因為對于大多數人來說,只是知其然不知其所以然。人們對于不熟悉、不了解的事情,總是覺得神秘,那么對于她的應用,就會大打折扣。推廣她的最好的方法,就是讓她成為人人能夠輕松寫的核。我希望以此推動大家對于SOC設計的熱情。可以想象,如果最神秘,最復雜的CPU核,都可以輕松的寫出來的話,那么還有什么能夠難得到我們的呢?


        在寫之前,我要申明兩點精神。這兩點精神當然不是我創造的,我只是引用起來,讓大家更能讀下去,能相信我是能創造這個奇跡的,當然你也能創造這個奇跡的。第一點就是毛主席在軍事上經常用的“分而殲之”,在政治上的意思就是“拉一派,打一派”。這一招在毛主席的斗爭生涯中屢試不爽,成就了他成了偉人。這一點國外叫做“divide and conqur(沒拼寫對,懶得查了)",也是很重要的一個方法。所以在面對龐然大物的時候,千萬別害怕,一定要祭起這個”法寶“。第一步,先試著“divide",一定讓這個龐然大物小起來,然后再小下去,先條分縷析了,已經算成功了一大半了;第二步,從最小的開始,一點點的做,做對了,做好了。好到什么程度?好到這一小點絕不會打擾我們繼續征服下一小點為至。那么征服這個龐然大物就只是時間問題了。包括我現在寫這個文章,就得用這個精神,不然的話,千頭萬緒,從哪里說呢?從哪里說的清呢?不用怕,我既然用這個方法征服了ARM core,那么把它講出來,講明白,絕對比寫arm core要簡單,我相信我也能夠完成的。

        但是我缺一點東西:那就是視角問題。因為我是站在我的立場上,我了解一切,我講的時候,只是想當然的從我的角度認為大家該了解什么。但實際上,這中間的差距,就像夢想和現實的差距一樣遠。所以我需要大家有反饋,那一點忽略了,及時提醒我,讓我始終站在大家的立場上,講東西,而不是讓我自說自話。如果我自說自話,效果非常差。所以請大家成全我,成全我就是成全自己。如果可能,請及時提出不明白的地方。讓我把這今天的這一小節征服到不會打擾我征服下一小節,這是符合我上面的精神。

        有網友,可能會問,我費心費力的圖什么?為什么要成全我?我圖啥呢?反正我從小也算一個調皮的孩子,越是大人不讓我干的事情,我還是愿意冒險試一下。當然總體來說,我小時候也算聽話,屬于只做”建設性“破壞的人,掏馬蜂窩、堵煙筒這事不干。現在有一件特別有意義的事情,比如ARM公司的這些達人們,賣ARM7核賣的不亦樂乎。突然,我闖進來,說這東西根本不值錢,你得賣真貨,不是特別有意思么?ARM公司越不爽,其實對于大家來說越是爽。因為大家總體的水平提高了,那么ARM公司就必須努力提高自己的水平,這樣才能凸顯他自己的價值。所以這件事情想起來就特別有意思,所以我就決定做這么一件”建設性“破壞的事情。所以請大家成全我,成全別人其實也是成就自己,請大家和我一起實踐吧。所以,我如果是個軟件工程師,我一定會寫些病毒啥的,有意思呀!但放心我只會做“建設性”的,我做的病毒絕不會給大家帶來太多麻煩,因為這不符合我的風格。但我現在既然是一個硬件工程師,就得想方法在硬件上做一些大事。做一些讓讓某些“大人”不爽的事。人在世上,也就圖一樂嘛。呵呵,說多了。

        說了半天,還沒有說第二點精神。其實第二點也就包括在第一點上了。不過還是有分別的。這第二點精神就是古人的”格物致知“的功夫。古代這些儒學大家們經常對著一花一葉格個半天啥的,就是這種精神的極致。"divide and conqur"只是斗爭原則,但是怎么conqur呢?我覺得要用古人的”格物致知“,也就是耐得煩,從最細小的東西”格“起。我在后面對每一個net,每一個wire都描述出來,就是這樣”格“的結果。cpu是一套復雜的系統,要做的好,就得用net, wire, register搭起來,聽說intel就是這么干的。不過我是和它有分別的。因為我的這一套,還是把很多功夫交給綜合器完成,我只是描述出來,讓綜合器明白而已。

        閑話休提,我希望大家看了我這一系列的文章后,能夠把我的arm核寫出來。當然你能發揮,我希望的是大家發揮,把這個核寫的更好。因為我在做離經叛道的事情,哪能希望別人”墨守成規“把我的核當成標桿?我只是希望拋磚引玉。我要拋出一塊磚,對arm這個皇帝的新衣說出:你根本沒穿衣服!難道我知道這個了,不應該告訴大家么?所以盡情的糟蹋我的arm核吧,因為這樣,它存在的意義更大。

        開始寫了:第一句是: module arm ( 。這恐怕是verilog設計的經典開篇了。然后是什么?是定義接口。接口其實規定了大部分的功能,對于IP核的重用,交代清楚接口,跟下家說明清楚,別人才好用核。

        本文引用地址:http://www.104case.com/article/201611/317303.htm

        module arm (
        clk,
        rst,
        cpu_en,
        clk是時鐘,rst是異步復位信號。這個就不需要我多解釋了。cpu_en是什么?cpu_en是同步使能信號。也就是說只有在cpu_en==1b1時,整個核才工作。如果cpu_en==1b0時,那么這個arm 核就不工作了。簡單的說,就是在這個verilog文件里面的所有register都不做什么改變。這就好像有些童話里面說的“時間停止”,城堡里面的人都靜住了,一切都停止了。那么寄存器就屬于住在城堡里面的人,因為只要他們安靜了,沒有活物了,那些依靠人而存在的工具就不會動了。這個cpu_en對于整個模塊也是重要的,比如你不想讓它工作了,就可讓cpu_en==1b0,那么他就不工作。再讓他工作,只要讓"cpu_en==1b1"就可。我在這個FPGA的項目中,就應用這個輸入連到一個“開關”上。如果扳到"1b1",那系統開始工作;如果扳到"1b0",那它就停住,我就通過串口,把新的code下到它的rom中。

        cpu_restart,
        irq,
        fiq,
        rom_abort,
        ram_abort,
        這是ARM的五個中斷源,具體的可以參考ARM的文檔,我在這里只是簡略帶一遍。cpu_restart相當于一個同步復位,它只要是高電平,那么系統又重頭開始了。irq,fiq是兩個中斷,只要它等于“1b1”如果cpsr沒關掉它,就得執行相應的中斷。rom_abort, ram_abort是對應于rom,ram讀錯誤,則啟動一個中斷來處理這些事情。

        rom_en,
        rom_addr,
        rom_data,
        這三個信號連接到ROM中,是指令的來源。取指令的方法是:rom_en==1b1時,在下一個時鐘,存放在rom_addr位置的code就出現在rom_data了。當然如果rom_en==1b0,則rom_data保持原來的值不變。這是一個非常普通的ROM。取指令的主動權掌握在ARM核中。如果它要處理非常復雜的指令,一個周期根本處理不過來,那怎么辦?那就不啟動rom_en,只有當處理完了,有空閑了再啟動rom_en,更新rom_data。

        ram_cen,
        ram_wen,
        ram_addr,
        ram_wdata,
        ram_rdata,
        ram_flag
        );
        前五個“ram_cen,ram_wen,ram_addr,ram_wdata,ram_rdata”是典型的單端口RAM的接口。功能是:在ram_cen==1b1時,開始執行對RAM的操作,同時ram_wen==1b1,執行寫操作,把ram_wdata寫入ram_addr對應的位置;如果ram_wen==1b0,表示是讀操作,就得在下一個時鐘,把放在ram_addr的數據出現在ram_rdata。
        ram_flag是我新增加的。因為RAM里面出現了LDRB, STRH這樣對字節、字的操作。為了操作簡單,我給每一個字節對應了一個標志位:如果ram_flag[0]==1b1表示第一個字節的操作有效;如果ram_flag[0]==1b1,則讀寫操作對第一個字節無效。比如我執行STRB 0x4000_0000,則ram_flag==4b0001, 表示只對地址0x4000_0000的低8bit進行寫入。如果STRH 0x4000_0002,則ram_flag==4b1100, 表示寫入0x4000_0000的高 2 byte。
        所以我建議連上4塊RAM,每塊RAM的位寬都是8 bit。讓ARM核對每byte的操作是獨立的。那每一塊的cen就是:ram_cen&ram_flag[3]; ram_cen&ram_flag[2]; ram_cen&ram_flag[1]; ram_cen&ram_flag[0]。

        好了,接下來,就是他們位寬的定義:
        input clk;
        input rst;
        input cpu_en;

        input cpu_restart;
        input irq;
        input fiq;
        input rom_abort;
        input ram_abort;

        output rom_en;
        output [31:0] rom_addr;
        input [31:0] rom_data;

        output ram_cen;
        output ram_wen;
        output [31:0] ram_addr;
        output [31:0] ram_wdata;
        input [31:0] ram_rdata;
        output [31:0] ram_flag;

        好了,本篇到此結束,下一節再見!



        關鍵詞: ARM處理器modul

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 枣强县| 宁城县| 墨脱县| 仁化县| 黄陵县| 和田县| 潍坊市| 中山市| 慈利县| 河北省| 鲁山县| 永川市| 吴旗县| 米林县| 黔江区| 大化| 绍兴市| 邛崃市| 黎平县| 金昌市| 扎囊县| 毕节市| 普兰县| 城口县| 峡江县| 湘乡市| 勃利县| 博客| 泌阳县| 青海省| 茂名市| 新绛县| 贵港市| 呼图壁县| 巩义市| 乌恰县| 东台市| 南阳市| 商洛市| 香格里拉县| 舞阳县|