【小梅哥FPGA進階教程】MC8051軟核在FPGA上的使用

10、MC8051軟核在FPGA上的使用異步

本教程內容力求以詳細的步驟和講解讓讀者以最快的方式學會 MC8051 IP core 的應用以及相關設計軟件的使用,並激起讀者對 SOPC 技術的興趣。本實驗重點講 8051Core 的應用,並經過一個簡單 C51 程序對 51Core 進行硬件測試。ide

本實驗教程的內容編排以下:工具

第 1 章簡單的描述了 MC8051 IP core 的基本結構及一些應用說明。性能

第 2 章詳細的介紹 8051Core 綜合、編譯應用。包括 Quartus II軟件的基本應用,ROM、RAM 模塊的生成,8051Core 的封裝及應用測試。 附錄 A 爲 MC8051 IP Core 的指令集。學習

在閱讀本教程的過程當中,請讀者注意如下幾點:測試

本教程在編寫時充分借鑑了周立功編寫的mc8051 IP核教程,同時針對其中較爲落後的一些內容進行了更新(周立功的教程使用的仍是Cyclone系列的器件,軟件版本也很低,不少操做與目前使用的主流版本有較大區別),同時刪除了其教程中使用Synplicity對工程進行綜合的部分,轉而使用Quartus II軟件直接綜合。網站

本實驗教程的 MC8051 IP Core (V1.6) 源於 http://oregano.at/ip/8051.htm 網站,讀者若有須要可到該網站下載。ui

1章 MC8051 的基本結構

這一章將簡單的介紹 MC8051 IP Core 的基本硬件結構和一些設計應用的注意事項,具spa

體內容包括:設計

1. 功能特色

2. 頂層結構

3. 設計層次

4. 硬件配置

5. 並行 I/O 口

6. 其它說明

本章介紹的內容可能過於簡略,若是要更詳細的資料可參考 mc8051_user_guide.pdf

文檔(位於:「mc8051_v1.6源碼.zip\Version1_6\doc」文件夾裏面)。

1.1 功能特色

● 採用徹底同步設計

● 指令集和標準 8051 微控制器徹底兼容

● 指令執行時間爲 1~4 個時鐘週期,執行性能優於標準 8051 微控制器 8 倍左右

● 用戶可選擇定時器/計數器、串行接口單元的數量

● 新增了特殊功能寄存器用於選擇不一樣的定時器/計數器、串行接口單元

● 可選擇是否使用乘法器(乘法指令 MUL)

● 可選擇是否使用除法器(除法指令 DIV)

● 可選擇是否使用十進制調整功能(十進制調整指令 DA)

● I/O 口不復用

● 內部帶 256Bytes RAM

● 最多可擴展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

● 最多可擴展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

1.2 頂層結構

MC8051 IP Core 頂層結構圖如圖 1.1 所示,圖中指示了 mc8051_core 的頂層結構以及同 三個存儲模塊的鏈接關係,同時顯示了頂層的輸入輸出 I/O 口,各 I/O 信號的描述如表 1.1 所示。定時器/計數器和串行接口單元對應於圖中的 mc8051_tmrctr 和 mc8051_siu 模塊,數量是可選擇的,在圖中用虛線表示。

圖片1

圖 1.1 MC8051 IP Core 頂層結構圖

 

表 1.1 頂層信號名

圖片2

1.3 設計層次

MC8051 IP Core 的層次結構及對應的 VHDL 文件如圖 1.2 所示。

VHDL 源文件的命名格式以下:

圖片3

核心由定時器/計數器、ALU、串行接口和控制單元各模塊組成。ROM 和 RAM 模塊不

包括於核心內,處於設計的頂層,方便於不一樣的應用設計及仿真。

圖片4

圖 1.2 MC8051 IP Core 的設計層次

1.4 硬件配置

1.4.1 定時器/計數器、串口和中斷

標準的 8051 核只有兩個定時器/計數器,一個串口和兩個外部中斷源。而在 MC8051 IPCore 中,這些單元最多可增長到 256 組,只須要在 VHDL 源程序文件 mc8051_p.vhd 中,更改C_IMPL_N_TMR、C_IMPL_N_SIU、C_IMPL_N_EXT的常量值就能夠了,範圍是1~256。相關的代碼如程序清單 1.1 所示。

程序清單 1.1 定時器/計數器、串口及中斷的配置程序

  --------------------------------------------------------------------
  -- Select how many timer/counter units should be implemented
  -- Default: 1
  constant C_IMPL_N_TMR : integer := 1;
  --------------------------------------------------------------------

  --------------------------------------------------------------------
  -- Select how many serial interface units should be implemented
  -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---            
  constant C_IMPL_N_SIU : integer := C_IMPL_N_TMR;
  --------------------------------------------------------------------

  --------------------------------------------------------------------
  -- Select how many external interrupt-inputs should be implemented
  -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---
  constant C_IMPL_N_EXT : integer := C_IMPL_N_TMR;
  --------------------------------------------------------------------

 

圖片5

C_IMPL_N_TMR、C_IMPL_N_SIU、C_IMPL_N_EXT 這三個常量是不能獨立修改數值的,也就是說只能同時增減。C_IMPL_N_TMR 加一,就意味 IP Core 中同時添加了兩個定時器/計數器,一個串口單元和兩個外部中斷源。 爲了控制這些新增的控制單元,微控制器在特殊寄存器內存空間增長了兩個寄存器。分別是 TSEL(定時器/計數器選擇寄存器,地址爲 0X8E)和 SSEL(串口選擇寄存器,地址爲 0X9A),若是沒有對這兩個寄存器賦值,其缺省值爲 1。電路結構如圖 1.3 所示。

 

圖片6-1圖片6-2

圖 1.3 使用附加的 TSEL 寄存器選擇 TCON 寄存器

若是在中斷髮生期間設備(寄存器)沒被選中(好比 TSEL),那麼相應的中斷標誌位將保持置位,直到中斷服務程序被執行。

1.4.2 可選擇的指令

在某些場合,有些指令是用不到的,所以能夠經過禁用這些指令來節省片上(好比 FPGA)資源。這些指令有 8 位乘法器(MUL)、8 位除法器(DIV)和 8 位十進制調整器(DA)。禁用時只須要在 VHDL 源程序文件 mc8051_p.vhd 中將 C_IMPL_MUL(乘法指令 MUL)、 C_IMPL_DIV(除法指令 DIV)或 C_IMPL_DA(十進制調整指令 DA)的常量值設置爲 0。相應的 VHDL 程序代碼段如所示。

程序清單 1.2 可選指令配置程序

  --------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the multiplier
  -- Default: 1
  constant C_IMPL_MUL : integer := 1;
  --------------------------------------------------------------------

  --------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the divider
  -- Default: 1
  constant C_IMPL_DIV : integer := 1;
  --------------------------------------------------------------------
                   
  --------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the decimal adjustment command
  -- Default: 1
  constant C_IMPL_DA  : integer := 1;
  --------------------------------------------------------------------

這三條可選擇指令若是沒被設置執行,芯片(FPGA)可節省將近 10%的空間(資源)。

1.5 並行 I/O 口

爲了便於 IC 設計,MC8051 IP Core 的 I/O 口不提供複用功能,包括 4 個 8 位輸入輸出口、串行接口、計數器輸入端和擴展存儲器接口。若是 I/O 要作爲雙向口應用,其基本電路

結構圖如圖 1.4 所示。

圖片8

圖1.4 並行I/O口基本結構

1.4 中的兩個 D 觸發器起同步輸入信號的做用(mc8051_core 的輸入 I/O 無作同步處理),也能夠不用。上拉電阻是必要的,由於 I/O 口輸出高電平是靠上拉電阻實現的。

1.6 其它說明

(1) MC8051 IP Core 的定時器和串口波特率的計算和標準 8051 同樣,計數時鐘也是由系 統時鐘經 12 分頻獲得。

(2) 外部中斷信號是經兩級寄存器作同步處理後輸入的。

(3) MC8051_core 的輸入 I/O 沒有作同步處理,必要時可本身添加,如圖 1.4 所示。

(4) 寫應用程序時,I/O 口若是沒有作成雙向口(如圖 1.4 所示),而是輸入和輸出分開的,那麼要特別注意,像 P1=~P一、P1^0=P1^0 這樣的 I/O 取反操做是無效(不起做用)的,由於讀回來的值不是 I/O 寄存器的值,而是輸入引腳的狀態。

(5) MC8051 IP Core 經 Quartus II 綜合編譯後,觀看時序分析報告,其最高運行頻率爲 32MHz(每次編譯均可能不一樣,I/O 分配不一樣結果可能不一樣),所以系統時鐘不能超過期序報告的時鐘最高頻率(即 fmax)。

2章 MC8051 的硬件運行

本實驗的硬件平臺是採用芯航線FPGA學習套件,關於本實驗套件的的詳細介紹,請參看《芯航線FPGA學習平臺用戶手冊》,這裏就不重複說明。這裏只簡單說一些本實驗用到的硬件資源以及相關軟件的基本操做。

本章咱們主要講述 MC8051 core 的生成及封裝,最後進行硬件下載運行並測試 I/O 口、 UART 及定時器。用到的硬件資源有爲開發套件核心板上的LED0~LED3 、USB轉串口接口。 本章將分如下幾部分來說述:

1. MC8051 中 ROM、RAM 模塊的生成;

2. MC8051 core RTL 的封裝;

3. MC8051 core 在 Quartus II 中的應用;

4. 測試 MC8051 的 I/O、UART 和定時器功能。 本實驗力求以詳細的步驟和講解讓讀者以最快的方式學會 MC8051 IP core 的應用以及

相關設計軟件的使用,並激起讀者對 SOPC 技術的興趣。

2.1 MC8051 中 ROM、RAM 模塊的生成

本節的內容是創建一個 Quartus II 應用工程,並利用 Quartus II 自身集成的 Megawizard Plug_in Manager 工具(/在Quartus II 14.0版本及之後,名字改成了IP Catlog)來生成 MC8051 中所需的內部 RAM、外擴 RAM 及 ROM。

2.1.1 創建 Quartus II 工程

【開始】>>【程序】>>Altera>>Quartus II 13.0或直接雙擊桌面的Quartus II軟件圖標圖片9打開 Quartus II 13.0 軟件,軟件界面如圖 2.1 所示。

圖片10

圖 2.1 Quartus II 軟件界面

在圖 2.1 中從【File】>>【New】打開新建文件選項卡,在選項卡中選擇【New Quartus II Project】來新建一項工程,軟件界面如圖 2.2 所示。

圖片11

圖 2.2 新建Quartus II 文件

打開後顯示界面以下所示:

圖片12

圖 2.3 新建工程路徑、名稱、頂層實體指定對話框

clip_image016 不要將文件夾設在計算機已有的安裝目錄中,更不要將工程文件直接放在安裝目錄中。文件夾所在路徑名和文件夾名中不能用中文,不能用空格,不能用括號(),可用下劃線_,最好也不要以數字開頭。

2.3 第一欄用於指定工程所在的工做庫文件夾;第二欄用於指定工程名,工程名能夠取任何名字,也能夠直接用頂層文件的實體名做爲工程名(建議使用);第三欄用於指定頂層文件的實體名。本例工程的路徑爲 E:\CoreCourse_fpga\mc8051_test文件夾,工程名與頂層文件的實體名同名爲 mc8051_test。

接着單擊圖片13進入2.4所示的添加文件對話框。

圖片14

圖 2.4 新建工程添加文件對話框

因爲是新建工程,暫無輸入文件,因此直接單擊圖片15,進入圖2.5所示的指定目標器件對話框。這裏咱們選擇芯航線FPGA核心板上使用的Cyclone IV系列的EP4CE10F17C8

圖片16

圖 2.5 新建工程器件選擇對話框

在圖 2.5 右邊的過濾器欄(Filters)中,設計者能夠經過指定封裝、管腳數以及器件速

度等級來加快器件查找的速度。

指定完器件後,單擊圖片17進入圖2.6所示的自定EDA工具對話框。

圖片18

圖 2.6 新建工程 EDA 工具設置對話框

本實驗利用 QuartusII 的集成環境進行開發,不進行仿真驗證,故不使用任何 EDA 工具,所以這裏不做任何改動。圖 2.6 中單擊圖片19 進入圖 2.7 所示的工程信息報告對話框。從工程信息報告對話框,設計者能夠看到工程文件配置信息報告。點擊圖片20,完成新建工程的創建。 須要注意的是,創建工程後,還能夠根據設計中的實際狀況對工程進行從新設置,可選擇Assignments>> Settings…進行設置,也能夠選擇工具欄上的圖片21按鈕。

圖片22

圖 2.7 新建工程配置信息報告對話框

2.1.2 創建工程頂層文件

在Quartus II中,常見的頂層文件有原理圖形式和Verilog/VHDL形式,早期高校教學多選擇以原理圖形式爲主。採用原理圖形式做爲工程頂層,在工程並不複雜的狀況下,方便清晰的展現設計結構。可是當設計變的複雜,頂層中須要添加的模塊愈來愈多以後,原理圖形式的頂層文件,弱點也明顯的暴露出來,主要表現爲連線複雜,容易出錯,可讀性差,不便於修改。同時,隨着Quartus II新版本軟件的推出,不一樣版本間對於原理圖形式的文件解析方式有差別,致使同一工程在不一樣的軟件版本中打開的樣式並不一致,在升級中很容易出錯。所以這裏採用Verilog/VHDL的形式建立文件頂層。

因爲目前Verilog的普及率愈來愈高,熟悉Verilog的人遠遠大於熟悉VHDL的人,所以這裏咱們使用Verilog格式的文件來做爲工程頂層。

點擊File>>New…】,選擇Verilog HDL File,如圖 2.8 所示:

圖片23

圖 2.8 新建Verilog HDL文件對話框

點擊OK便可建立一個新的Verilog文件。

接着點擊File>>Save As…將文件存儲爲」 mc8051_test.v」, 如圖 2.9 所示:

圖片24

圖 2.9 保存Verilog文件

該文件就將做爲咱們工程的頂層文件

2.1.3 ROM 和 RAM 模塊的生成

MC8051 中所須要的存儲模塊有,內部 RAM、擴展 RAM 和 ROM。其中內部RAM 和ROM 是必要的,內部 RAM 固定爲 128Bytes,ROM 最大可選 64KBytes,鑑於 FPGA(這裏咱們選用 EP4CE10)片上 RAM 資源有限(EP4CE10的片上 RAM 約 51.75KBytes,這裏咱們選擇 4Kbytes(可根據本身須要修改);擴展 RAM 是可選,最大也能夠達到 64KBytes,這裏咱們選擇 2Kbytes。

(1)建立一個ROM模塊所需使用的初始化文件

這裏首先建立該文件是爲了使後面建立ROM模塊時可以順利進行。由於在生成ROM模塊時,若是不指定一個存在的hex或mif格式的初始化文件,生成過程是沒法順利完成的。

點擊File>>New…】,選擇Hexadecimal (Intel-Format)File。而後點擊OK。如圖 2.10所示:

圖片25

圖 2.10 新建hex文件

在彈出的對話框中,設置Number of words爲4096,Word size爲8,而後點擊OK,便可建立一個新的hex文件,如圖 2.11所示:

圖片26

圖 2.11 設置hex文件大小

接着點擊File>>Save As…將文件存儲爲」 mcu_test.hex」。 如圖 2.12所示:

圖片27

圖 2.12 保存hex文件

(2) 生成ROM模塊

(1) 從Tools>>MegaWizard Plug-In Manager…打開如圖 2.13 所示添加兆功能模塊嚮導。選擇【Create a new custom megafunction variation】新建一個新的兆功能模塊。而後點擊圖片28進入嚮導 page2。

圖片29

圖 2.13 添加兆功能模塊嚮導對話框

(2) 在 page2,在搜索框中輸入「rom」,選擇搜索結果中的ROM:1-PORT,而後指定生成這個ROM 的器件系列(默認已是Cyclone IV E),硬件描述語言(VHDL)和輸出文件存放路徑及名字(mc8051_rom),如圖2.14所示。

圖片30

圖 2.14 page2建立ROM IP核

(3) 在 page3 上,設置 ROM 的信息:數據寬度 8bits,數據個數 4069。其他默認就好了。如圖 2.15 所示。

圖片31

圖 2.15 page3 設置存儲器大小

(4) 在 page4 上,取消 ROM 的輸出寄存器,時鐘使能信號及異步清零信號不用選,如圖2.16所示

圖片32

圖 2.16 page4 取消輸出寄存器

(5) 如圖 2.17 所示在 page5 上指定 ROM 的初始化數據文件(也即單片機程序的機器碼.hex 文件)。初始化數據文件能夠是.mif 或.Hex 文件。對於 ROM 模塊,是必定要指定初始化數據的,要否則嚮導就不能完成。這裏咱們選擇以前建立的那個空白hex文件mcu_test.hex 文件(這裏咱們是先先隨便找了個.hex 文件填進去,到後面再更換成咱們所要的測試文件)。

而後咱們勾選「Allow In-System Memory Content Editor to capture and update content independently of the system clock」,這樣,當咱們更改了咱們的軟件代碼並生成了新的Hex文件時,就能夠直接使用In-System Memory Content Editor工具來在線將新的hex文件下載到ROM中,從而避開在工程中從新替換hex文件並編譯工程的工做。

圖片33

圖 2.17 page5 指定ROM的初始化hex文件

(6) 在 page6 上,不須要進行任何更改

(7) 在page7上,選擇須要生成的文件,這裏咱們勾選上mc8051_rom_inst.vhd。而後點「finish」便可生成 ROM 宏單元了。其中 mc8051_rom.vhd 爲生成的VHDL 源文件。如圖 2.18 所示

圖片34

圖 2.18 page7 指定須要生成的文件

(2) 生成RAM模塊

MC8051 中 RAM 模塊包括內部 RAM 和擴展 RAM,其生成方法和 ROM 的生成方法差很少。這裏只簡單的說一下參數設置,詳細的步驟可參考 ROM 模塊的生成這一部分的內容。

(1) 內部 RAM 的參數設置 在如圖 2.14 所示的對話框中輸入ram,在搜索結果中選擇 RAM:1-PORT 模塊,並將其命名爲 mc8051_ram;設置數據寬度爲 8bits,數據個數爲 128;取消 RAM 的數據輸出寄存器,同時選中時鐘使能信號端,如圖 2.19所示;勾選上生成mc8051_ram_inst.vhd文件,其它的選項默認不變。

圖片35

圖 2.19 page7 RAM設置

(2) 擴展 RAM 的參數設置 在如圖 2.14 所示的對話框中輸入ram,在搜索結果中選擇 RAM:1-PORT 模塊,並將其命名爲 mc8051_ramx;設置數據寬度爲 8bits,數據個數爲 2048;取消 RAM 的數據輸出寄存器;不須要選中時鐘使能信號端,如圖 2.20所示;勾選上生成mc8051_ramx_inst.vhd文件,其它的選項默認不變。

圖片36

圖 2.20 page7 RAM設置

至此咱們已經完成了 mc8051 中 ROM、RAM 模塊的生成。下面將介紹如何對 mc8051

core 進行封裝,也能夠說是對 mc8051 core 進行打包,方便於之後的設計調用。

2.2 MC8051 core 的組裝

到如今爲止,MC8051核RTL級實現的全部模塊都已經具有了,接下來就使用將這些模塊組裝到一塊兒,獲得一個含完整mc8051核的Quartus· II工程,在新建工程以前咱們還要對一些 mc8051 core 的源文件進行更新修改,使之符合咱們的設計。

2.2.1 更新 mc8051 core 的頂層源文件

因爲默認提供的源碼中的頂層設計文件中的存儲模塊(ROM、RAM)是仿真時使用的, 如今要進行硬件測試,因此必須改爲咱們實際用到的 ROM、RAM 模塊(也就是前一節咱們生成的 ROM、RAM 模塊)。

(1) 首先在工程目錄下新建一個 mc8051core 的文件夾,將 mc8051 core 的源代碼文件(位於:\mc8051_Source\VHDL 目錄)拷貝到 mc8051core 文件夾。

(2) 打開 mc8051_Source\VHDL 目錄下的 mc8051_p.vhd 文件,將原文件中 ROM、RAM 模塊調用的代碼(如程序清單 2.1 所示)所有替換爲符合本設計的程序代碼(如程序清單 2.2 所示)。

程序清單 2.1 mc8051_p.vhd 文件代修改代碼

  --------------------------------------------------------------------
  -- START: Component declarations for simulation models
  --------------------------------------------------------------------
  component mc8051_ram
    port (
        clk        : in  std_logic;
        reset      : in  std_logic;
        ram_data_i : in  std_logic_vector(7 downto 0);
        ram_data_o : out std_logic_vector(7 downto 0);
        ram_adr_i  : in  std_logic_vector(6 downto 0);
        ram_wr_i   : in  std_logic;
        ram_en_i   : in  std_logic);
  end component;

  component mc8051_ramx
    port (
        clk        : in  std_logic;
        reset      : in  std_logic;
        ram_data_i : in  std_logic_vector(7 downto 0);
        ram_data_o : out std_logic_vector(7 downto 0);
        ram_adr_i  : in  std_logic_vector(15 downto 0);
        ram_wr_i   : in  std_logic);
  end component;

  component mc8051_rom
    port (
        clk        : in  std_logic;
        reset      : in  std_logic;
        rom_data_o : out std_logic_vector(7 downto 0); 
        rom_adr_i  : in  std_logic_vector(15 downto 0)); 
  end component;
  --------------------------------------------------------------------
  -- END: Component declarations for simulation models
  --------------------------------------------------------------------

程序清單 2.2 mc8051_p.vhd 文件更新的源代碼

  --------------------------------------------------------------------
  -- START: Component declarations for simulation models
  --------------------------------------------------------------------
    component mc8051_ram 
    port ( 
        clock   : in  std_logic;      
        data    : in  std_logic_vector(7 downto 0);            
        q       : out std_logic_vector(7 downto 0);            
        address : in  std_logic_vector(6 downto 0);            
        wren    : in  std_logic;            
        clken   : in  std_logic);   
    end component; 

    component mc8051_ramx     
    port ( 
        clock   : in  std_logic;      
        data    : in  std_logic_vector(7 downto 0);            
        q       : out std_logic_vector(7 downto 0);            
        address : in  std_logic_vector(10 downto 0);            
        wren    : in  std_logic);   
    end component;
    
    component mc8051_rom     
    port ( 
        clock   : in  std_logic; 
        q       : out std_logic_vector(7 downto 0);  
        address : in  std_logic_vector(11 downto 0));   
    end component;

  --------------------------------------------------------------------
  -- END: Component declarations for simulation models
  --------------------------------------------------------------------

(3) 打開 mc8051core目錄下的 mc8051_top_struc.vhd 文件,首先作如程序清單 2.3 所示修改,其中行末標註「--new」的行爲新增長的內容。而後將原文件中 ROM、RAM 模塊調用部分的代碼修改爲如程序清單 2.4 所示的代碼。這樣就完成了源文件更新修改。

程序清單 2.3 mc8051_top_struc.vhd 文件新增的代碼

architecture struc of mc8051_top is

  signal s_rom_adr_sml:   std_logic_vector(11 downto 0);  -- new
  signal s_ramx_adr_sml:   std_logic_vector(10 downto 0);  -- new
    
  signal s_rom_adr:      std_logic_vector(15 downto 0);  -- Programmcounter =
                                                         -- ROM-adress
  signal s_rom_data:     std_logic_vector(7 downto 0);   -- data input from ROM
  signal s_ram_data_out: std_logic_vector(7 downto 0);   -- data output to
                                                         -- internal RAM
  signal s_ram_data_in:  std_logic_vector(7 downto 0);   -- data input from
                                                         -- internal RAM
  signal s_ram_adr:      std_logic_vector(6 downto 0);   -- internal RAM-adress
  signal s_ram_wr:       std_logic;                      -- read (0)/write (1)
                                                         -- internal RAM
  signal s_ram_en:       std_logic;                      -- RAM-block enable
  signal s_ramx_data_out: std_logic_vector(7 downto 0);  -- data output to
                                                         -- ext. RAM
  signal s_ramx_data_in:  std_logic_vector(7 downto 0);  -- data input from
                                                         -- ext. RAM
  signal s_ramx_adr:      std_logic_vector(15 downto 0); -- ext. RAM-adress
  signal s_ramx_wr:       std_logic;                     -- read (0)/write (1)
                                                         -- ext. RAM
                                                    

begin                 -- architecture structural
    s_rom_adr_sml <= std_logic_vector(s_rom_adr(11 downto 0));  -- *** new    
    s_ramx_adr_sml <= std_logic_vector(s_ramx_adr(10 downto 0));  -- *** new   

  i_mc8051_core : mc8051_core
    port map(clk         => clk,
             reset       => reset,
             rom_data_i  => s_rom_data,

其中,

 

 

圖片40

 

圖片41

就是新增長的內容

程序清單 2.4 mc8051_top_struc.vhd 文件中更新的源代碼

  --------------------------------------------------------------------
  -- Hook up the general purpose 128x8 synchronous on-chip RAM. 
  i_mc8051_ram : mc8051_ram     
    port map ( 
        clock       => clk, 
        data        => s_ram_data_in,     
        q           => s_ram_data_out, 
        address     => s_ram_adr,
        wren        => s_ram_wr,
        clken       => s_ram_en);

  -- THIS RAM IS A MUST HAVE!!
  --------------------------------------------------------------------


  --------------------------------------------------------------------
  -- Hook up the (up to) 64kx8 synchronous on-chip ROM.
    i_mc8051_rom : mc8051_rom
        port map (
            clock   => clk,
            q       => s_rom_data,
            address => s_rom_adr_sml);
  -- THE ROM OF COURSE IS A MUST HAVE, ALTHOUGH THE SIZE CAN BE SMALLER!!
  --------------------------------------------------------------------
  
    
  --------------------------------------------------------------------
  -- Hook up the (up to) 64kx8 synchronous RAM.
    i_mc8051_ramx : mc8051_ramx
        port map ( 
            clock   => clk,
            data    => s_ramx_data_out,
            q       => s_ramx_data_in,
            address => s_ramx_adr_sml,
            wren    => s_ramx_wr);
  -- THIS RAM (IF USED) CAN BE ON OR OFF CHIP, THE SIZE IS ARBITRARY.
  --------------------------------------------------------------------

2.2.2 添加mc8051 Core相關文件到Quartus II工程中

在將mc8051的源碼添加到Quartus II工程前,咱們須要首先對部分文件的文件名進行更改。原版的VHDL源碼,部分文件的文件名末尾加了有「_」,而實際源碼中的模塊名沒有加「_」,所以,若是將這些文件直接添加到Quartus II工程中,編譯就會報錯,提示找不到模塊。

 

圖片43

所以咱們首先將源碼文件以「_」結尾的文件名中的「_」所有去掉,例如,將「addsub_core_.vhd」更改成「addsub_core.vhd」。當全部的文件名更改完成以後,方可添加這些文件到工程中。

在Quartus II軟件中,點擊【Project】>>Add/Remove Files in Project】,在彈出的對話框中,點擊瀏覽文件符號,如圖 2.21 所示:

 

圖片44

圖 2.21 添加文件按鈕

選擇mc8051core文件夾下的全部非配置文件(即以cfg結尾的文件不用選中),而後點擊打開按鈕,便可將文件添加到工程中來。如圖 2.22 所示:

 

圖片45

圖 2.22 選擇須要添加的文件

點「OK」完成文件的添加。

2.2.3設置工程頂層文件

在Files欄中,選中mc8051_top.vhd文件,點擊右鍵,選擇「Set as Top-Level Entity」,便可將mc8051_top.vhd設置爲工程的頂層文件,(這裏設置爲頂層主要是爲了封裝IP核方便,臨時性的,並非最終做爲工程頂層)。如圖 2.23 所示:

 

圖片46

圖 2.23 選擇須要添加的文件

2.2.4 綜合工程文件

(1) 綜合工程

在 Quartus II 軟件的主界面,點擊分析和綜合按鈕圖片47(或者直接按鍵盤組合鍵ctrl+k),便可開始對工程進行分析和綜合。這個過程大概須要幾分鐘到十幾分鍾,視軟件版本和電腦配置,耗費時間有差別。

(2) 查看RTL圖

綜合編譯後咱們須要檢查頂層設計是否正確,這時能夠經過 RTL 圖來檢查,雙擊RTL Viewer,如圖2.24 所示

圖片48

圖 2.24 點擊打開RTL Viewer

按鈕能夠打開 RTL 圖,咱們能夠很清晰的看到 8051 core 的頂層結構圖,如圖 2.25所示。若是沒問題咱們就能夠進行下一步的設計了。

圖片49

圖 2.25 mc8051 core RTL 圖

2.3 MC8051 core 在 Quartus II 中的應用

在看這節內容以前建議你們先看一下 2.4 節,瞭解一下單片機的應用測試程序及測試流

程,由於這兩部份內容是同時進行,密切關聯。

在這一節咱們將對 2.1 節創建的 Quartus 工程作進一步的設計,並將 mc8051 core 應用

於設計中。同時對 Quartus 的簡單應用作進一步的學習。具體包括如下內容:

1. 創建 PLL 數字鎖相環模塊;

2. mc8051 core 在 Quartus II 中的應用設計;

3. FPGA 參數設置;

4. 下載硬件設計到目標 FPGA。

2.3.1 創建 PLL 數字鎖相環模塊

衆所周知,單片機須要時鐘信號才能運行,那怎樣才能獲得一個穩定而可靠的時鐘源呢?咱們的實驗板上有一個 50MHz 的有源晶振,但對於 mc8051core 來講,頻率比較高,須要分頻,這時能夠用 FPGA 自帶的 PLL 調整時鐘頻率,PLL 輸出的時鐘頻率、相位均可調並且精度很高,下面咱們將介紹如何在 Quartus II 中調用 PLL 模塊。

(1) 打開咱們在 2.1 節創建的 QuartusII 工程,從【Tool】>>【MegaWizard Plug-In Manager…打開如圖 2.13 所示的添加宏單元的嚮導。

(2) 在圖 2.13 中按圖片50進入嚮導第 2 頁,按圖 2.26 所示輸入「pll」選擇 ALTPLL,並選擇器件類型及存放路徑,注意標記部分。

圖片51

圖 2.26 MegeWizard Plug-In Manager page2

(3) 在圖 2.26 中按圖片52進入嚮導第 3 頁,按圖 2.27 所示選擇和設置,注意標記部分。因爲電路板上的有源晶振頻率爲 50MHz,因此輸入頻率設爲 50MHz。

圖片53

圖 2.27 page3 設置輸入時鐘頻率

(4) 在圖 2.27 中按圖片54進入嚮導第 4 頁,在圖 2.28 所示的窗口選擇 PLL 的控制信號,如 PLL 使能控制「pllena」;異步復位「areset」;鎖相輸出「locked」等。這裏咱們不選任何控制信號。

圖片55

圖 2.28 page4 設置控制信號

(5) 在圖 2.28中按連續按下圖片56直到進入嚮導第8頁,按圖2.30所示選擇c0輸出頻率爲18MHz,時鐘相移和佔空比不改變。

圖片57

圖 2.29 page8 設置時鐘輸出頻率

(6) 在圖 2.29 中按圖片58進入嚮導第 9 頁 c1 的設置界面,因爲c1以及後續其餘輸出都再也不使用,所以,這裏能夠直接跳過其餘全部輸出的配置,直到最後按圖片59完成 PLL 兆功能模塊的定製。

在完成定製 PLL 後,在 Quartus II工程文件夾中將產生 pll.bsf文件和 pll.v 的Verilog HDL源文件。

2.3.2 創建MC8051應用工程,

這一小節將講述如何使用以上移植的mc8051的核創建一個實際的Quartus II 工程並可以在芯航線FPGA學習套件的主板上運行。 具體步驟以下:

(1) 在工程頂層中例化mc8051核

(2) 在工程頂層中例化pll

(3) 對工程進行分析和綜合

(4) 分配引腳

(5) 編譯並生成FPGA配置文件

(6) 使用USB Blaster配置FPGA

打開以前創建的Quartus II工程,打開mc8051_test.v文件,首先編寫模塊的端口,這個模塊的端口也是工程最終的對外引腳,這裏直接設置模塊端口爲mc8051的IO。 如程序清單2.5的第1行至第23行所示。

接着在工程中例化mc8051核,這裏就是例化mc8051_top。Quartus II中,能夠直接在Verilog文件中例化使用VHDL編寫的模塊,所以這裏直接按照Verilog的格式例化mc8051_top便可,如程序清單2.5的第33行至第56行所示。注意,mc8051核的復位端口是高電平復位,而咱們開發板上是將復位信號接到了輕觸按鍵上,輕觸按鍵在沒有被按下時,輸出的是高電平,所以該信號不能直接接到mc8051的復位輸入端,須要先將其取反,所以直接在例化時將Rst_n取反後鏈接到mc8051的reset端便可(第36行)。

而後在工程中例化pll核,例化pll的代碼如程序清單2.5的第27行至第31行所示,pll的時鐘輸入端鏈接到芯片的時鐘輸入信號Clk50M上,c0輸出爲18M,鏈接到mc8051的時鐘輸入端口clk上。

程序清單 2.5 mc8051_test.v 文件的源代碼

01  module mc8051_test(
02      input Clk50M,//板級時鐘源,50M
03      input Rst_n,    //復位端口
04      input int0_i,   //mc8051外部中斷0輸入
05      input int1_i,   //mc8051外部中斷1輸入
06      input all_t0_i, //mc8051計數器0輸入
07      input all_t1_i, //mc8051計數器1輸入 
08
09      input [7:0]p0_i,    //mc8051端口0輸入 
10      input [7:0]p1_i,    //mc8051端口1輸入 
11      input [7:0]p2_i,    //mc8051端口2輸入 
12      input [7:0]p3_i,    //mc8051端口3輸入 
13
14      output [7:0]p0_o,   //mc8051端口0輸出      
15      output [7:0]p1_o,   //mc8051端口1輸出      
16      output [7:0]p2_o,   //mc8051端口2輸出      
17      output [7:0]p3_o,   //mc8051端口3輸出
18
19      input all_rxd_i, //mc8051串口接收端口     
20      output all_rxd_o,   //mc8051串口方式0時輸出端口
21      output all_txd_o,   //mc8051串口發送端口 
22      output all_rxdwr_o  //rxd 輸入/輸出方向控制信號(高電平輸出)
23  );
24
25      wire Clk18M;
26
27  //例化PLL模塊   
28      pll pll(
29          .inclk0(Clk50M),
30          .c0(Clk18M)
31      );
32
33  //例化mc8051核   
34      mc8051_top mc8051_top_inst(
35          .clk(Clk18M),       
36          .reset(~Rst_n), //mc8051爲高電平復位,所以將復位按鍵狀態取反接到reset上
37          .int0_i(int0_i),
38          .int1_i(int1_i),
39          .all_t0_i(all_t0_i),
40          .all_t1_i(all_t1_i),  
41
42          .p0_i(p0_i),      
43          .p1_i(p1_i),     
44          .p2_i(p2_i),      
45          .p3_i(p3_i),      
46
47          .p0_o(p0_o),      
48          .p1_o(p1_o),      
49          .p2_o(p2_o),      
50          .p3_o(p3_o),
51
52          .all_rxd_i(all_rxd_i),      
53          .all_rxd_o(all_rxd_o),
54          .all_txd_o(all_txd_o),
55          .all_rxdwr_o(all_rxdwr_o)
56      );
57
58  endmodule

接着咱們將mc8051_test.v文件設置爲工程頂層,而後點擊分析和綜合按鈕(或者按下鍵盤組合鍵ctrl+k)來對工程進行分析和綜合。

分析和綜合完成後,咱們打開Pin planner,進行引腳的鎖定。依次點擊【Assignments】>>【Pin Planner】,如圖 2.30所示:

圖片61

圖 2.30 打開引腳分配卡

這裏,咱們只須要分配咱們使用到的部分外設,沒有使用到的暫不作引腳分配。本例中,咱們將在Keil中編寫軟件代碼測試mc8051的定時器、串口和P1口。咱們使用開發板上板載的4個led燈進行測試P1口P1_o[0:3]的測試。所以咱們須要分配引腳的端口有P1_o[0:3],all_rxd_i,all_txd_o,Clk50M以及Rst_n。其餘沒有使用的端口暫不分配引腳。引腳分配表以下所示:

圖片62

將以上引腳對應分配給相應的信號便可。分配結果如圖 2.31所示:

圖片63

圖 2.31 引腳分配結果

引腳分配完畢後,關閉Pin Planner,點擊Start Compilation(或者鍵盤組合鍵ctrl+L)·來對工程進行全編譯並生成FPGA配置文件(.sof)。

編譯完畢後,使用USB Mini線鏈接芯航線FPGA開發板,鏈接上USB Blaster,而後打開Programmer,在Hardware Setup中選擇USB Blaster。添加mc8051_test.sof文件,而後點擊start便可將生成的配置文件下載到FPGA芯片中。如圖 2.32所示:

圖片64

圖 2.32 引腳分配結果

2.4 測試 MC8051 的 I/O、UART 和定時器功能

在這一節中咱們將經過一個簡單的流水燈、UART 程序驗證咱們的 mc8051 core。

2.4.1 Keil C 測試程序

咱們的 mc8051 core 已經創建起來了,如今須要一個程序進行硬件測試,這裏的程序

是指普通的 51 程序,能夠用 Keil C 或其它工具來編譯咱們寫的測試程序,並生成.HEX 文件具體的操做過程就不用作介紹了。

如程序清單 2.6 所示是一個簡單的測試程序,用於測試 I/O、定時器和 UART。定時器 0 用來作流水燈控制,從 P1 口輸出;串口波特率(9600b/s)由定時器 1 決定 。

程序清單 2.6 mc8051 IP核測試程序

/*************************************************
*           mc8051 IP核I/O、Timer、UART 測試程序 
*                時鐘頻率:18MHz 
*                文件名:main.c                    
*************************************************/
#include<reg51.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
char xdata Xcount _at_ 0x500; //定義外部 RAM 變量
uchar led=0xff;  //LED 初化值
uchar counter; //500ms 計數器
//*************************** 延時程序
void delay(uint n)
{
    uint k;
    while(n--);
    {
        for (k=0;k<40000;k++)
        {;}
    }
}
//*************************** 定時器中斷 0 程序
void timer0(void) interrupt 1
{
    ET0=0;  //關定時器 0 中斷
    TR0=0;  //不容許定時器 0 計數
    TH0=0x8a; //重裝定時初值(18MHz)
    TL0=0xd0;
    TR0=1;  //容許時器 0 計數
    if(++counter==25) //500ms 計數
    {
        counter=0;
        if(led==0xf0)
            led=0xff;
        else
            led<<=1; //左移 1 位
    }
        P1=led; //輸出到 P0 口
    ET0=1;
}
//*************************** UART 程序
char putchar(char c)
{
    SBUF = c;
    if (c == '\n') SBUF = 0x0D;
    while (!TI);
    TI = 0;
    return (c);
}
//*************************** 主程序
main()
{
    SCON = 0x50; //選擇模式 1, 8 位數據格式,使能 UART
    PCON |= 0x80; //波特率加倍
    TMOD = 0x21; //定時器 0:模式 1;定時器 1:模式 2
    TH0=0x8a; //20ms 定時初值(18MHz)
    TL0=0xd0;
    TH1 = 0xF6; //定時器 1 自動裝載初值, 時鐘頻率 18MHz, 0xF6(9600bps)
    TL1 = 0xF6;
    TR0=1; //容許定時器 0 計數
    TR1 = 1; //定時器 1 計數使能
    ET0=1; //容許定時器 0 中斷
    EA=1; //開總中斷
    Xcount=0;
    while(1)
    {
        printf("Xiao MeiGe 8051 System On FPGA\n");
        printf("Xin Hangxian Starter Board\n");
        printf("http://xiaomeige.taobao.com/\n");
        printf("This is the UART and led experiment\n");
        printf("Xcount = %02bX\n",Xcount++);
        printf("20160101\n");
        printf("\n\n\n\n");
        printf("hello world\n");
        delay(30000);
        delay(30000);
        delay(30000);
        delay(30000);
        delay(30000);
        delay(30000);
    }
}

2.4.2 測試步驟

將程序清單 2.6 的程序進行編譯並生成.hex 文件,爲了方便你們測試,咱們提供了一個建立好的Keil工程,在「mc8051_test\Cproject\uart_led」目錄下,使用Keil C51 v4打開。

在Quartus II軟件中,依次選擇【Tools】>>【In-System Memory Content Editor】,打開In-System Memory Content Editor工具,右側選擇Hardware爲USB-Blaster [USB-0],如圖 2.33所示:

圖片66

圖 2.33 選擇下載器

而後工具會自動搜索到器件和器件中存在的支持該工具的節點,搜索完成後整個工具界面如圖 2.34所示:

圖片67

圖 2.34 In-System Memory Content Editor界面

鼠標選中ROM0(這裏是我在配置ROM核的時候修改的索引名,若是你在配置的時候忘了修改索引名,則這裏默認顯示的名字應該是NONE),點擊右鍵,選擇Import Data From File。定位到C工程目錄下,我這裏爲:E:\CoreCourse_fpga\mc8051_test\Cproject\uart_led,選擇uart_led_test.hex文件並打開。這時候咱們能夠看到,工具下方已經有數據了,咱們點擊圖片68下傳按鈕以將數據傳輸進FPGA中的ROM中。如圖 2.35所示:

圖片69

圖 2.35 下載程序到mc8051的ROM中

而後,咱們打開電腦上的串口調試工具(任意一個你熟悉的就行),我這裏使用友善串口調試助手,選擇板子端口對應串口,設置波特率爲9600,數據位爲8位,無校驗位,1位中止位,接收格式爲ASCII。而後點擊打開串口,則能夠看到串口接收窗口中接收到了開發板傳輸過來的數據。同時板子開發板上的4個LED燈循環依次點亮。如圖 2.36所示:

圖片70

圖 2.36 串口接收的數據

當咱們的程序調試無誤後須要固定到芯片中永久使用時,就將編譯好的hex文件名稱修改成mcu_test.hex,替換工程目錄下原有的mcu_test.hex文件,而後從新編譯文件,而後配置FPGA便可。

 

 

小梅哥

2016年2月26日星期五

芯航線電子工做室

 

 

小梅哥店鋪連接:https://xiaomeige.taobao.com/

關於學習資料,小梅哥系列全部可以開放的資料和更新(包括視頻教程,程序代碼,教程文檔,工具軟件,開發板資料)都會發布在個人雲分享。(記得訂閱)連接:http://yun.baidu.com/share/home?uk=402885837&view=share#category/type=0

贈送芯航線AC6102型開發板配套資料預覽版下載連接:連接:http://pan.baidu.com/s/1slW2Ojj 密碼:9fn3

贈送SOPC公開課連接和FPGA進階視頻教程。連接:http://pan.baidu.com/s/1bEzaFW 密碼:rsyh

 

附錄 A MC8051 指令表

附表 1 MC8051 指令表

圖片72-1圖片72-2圖片72-3圖片72-4圖片72-5圖片72-6圖片72-7

相關文章
相關標籤/搜索