fpga 之多核心處理器設計...

152
電子工程系四技部 FPGA 之多核心處理器設計- LED 交通號誌燈之應用為例 學生: 郭美君、蔡景翔 指導教授: 林明權 老師

Upload: others

Post on 19-Apr-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

  • 崑 山 科 技 大 學

    電子工程系四技部

    專 題 研 究 報 告

    FPGA 之多核心處理器設計-

    以 LED 交通號誌燈之應用為例

    學生: 郭美君、蔡景翔

    指導教授: 林明權 老師

    中 華 民 國 九 十 九 年 五 月

  • 1

  • 電崑

    子山

    系科

    四技

    技大

    部學

    FPGA

    之 多 核 心 處 理 器 設 計 | 以

    LED

    交 通 號 誌 燈 之 應 用 為 例

    郭蔡 美景 君翔

    九 十 九 年 五

  • i

    FPGA 之多核心處理器設計- 以 LED 交通號誌燈之應用為例

    摘 要

    本文提出內嵌多核心處理器系統的設計方法,不用重新設計內嵌處理

    器的 I/O Bus 與指令群,而是運用 BI-FIFO 做為內嵌處理器的訊息交換通

    道,搭配處理器的硬體中斷信號,成功的設計出內嵌多核心處理器系統。

    展示則係用一種內嵌多核心處理器(Xilinx-PicoBlaze)的設計方法,來

    取代傳統單晶片控制交通號誌燈系統。FPGA的平行處理硬體架構,在訊

    號處理速度上絕對比單晶片快,而且各個功能獨立的訊號處理硬體方塊,

    在同一個系統時脈下很容易達成同步動作。每個訊號處理硬體方塊再搭配

    一個處理器核心單獨控制,使其輸出入控制更加靈活,不但不會影響整體

    系統之績效,而且也不會受其他功能方塊之牽制。因此,利用PicoBlaze

    結合FPGA再透過BI-FIFO使兩核心溝通之方式,相較於傳統單獨使用

    FPGA撰寫程式,可降低晶片使用率,即可更有效率的使用來呈現多核心

    處理器系統之特色。

    關鍵字: PicoBlaze、BI-FIFO、多核心處理器、SPI、交通號誌

  • ii

    目 錄

    頁數

    摘要 -------------------------------------------------------------------- i.

    目錄 -------------------------------------------------------------------- ii.

    表目錄 -------------------------------------------------------------------- iii.

    圖目錄 -------------------------------------------------------------------- iii.

    一、 緒論-------------------------------------------------------------- 1 1.1 研究動機與問題----------------------------------------------- 1 1.2 文獻回顧與探討----------------------------------------------- 1 1.3 研究方法及步驟----------------------------------------------- 2 1.4 實體驗證平台-------------------------------------------------- 3

    二、 FPGA 內嵌 Dual core 8-bit 微處理器---------------------- 4 2.1 Single core------------------------------------------------------- 4

    2.1-1 KCPSM3 指令集----------------------------------------------- 6 2.2 CPU I/O 設計--------------------------------------------------- 9

    2.2-1 Component 與模組化------------------------------------------ 12 2.3 Dual core--------------------------------------------------------- 14

    三、 驗證與結果----------------------------------------------------- 18

    四、 結論-------------------------------------------------------------- 25

    參考文獻 -------------------------------------------------------------------- 25

    附錄一 FPGA結合PicoBlaze之間透過FIFO ---------------------- 26

    附錄二 純 FPGA--------------------------------------------------------- 87

  • iii

    表 目 錄

    頁數

    表 2.1 指令表-------------------------------------------------------------- 6

    表 3.1 FPGA結合PicoBlaze之間透過FIFO之數據表------------- 23

    表 3.2 純FPGA之數據表------------------------------------------------ 23

    圖 目 錄

    頁數

    圖 1.1 規劃圖-------------------------------------------------------------- 2

    圖 1.2 應用模組----------------------------------------------------------- 2

    圖 1.3 Xilinx 的 Spartan-3AN XC3S50AN FPGA------------ 3

    圖 2.1 PicoBlaze 8bit 嵌入式微控制器方塊圖----------------------- 4

    圖 2.2 KCPSM3 核心結構圖-------------------------------------------- 5 圖 2.3 PicoBlaze 核心架構圖------------------------------------------- 6

    圖 2.4 CPU I/O 模組化--------------------------------------------------- 9

    圖 2.5 CPU I/O------------------------------------------------------------ 9

    圖 2.6 顯示 DOS 模擬器------------------------------------------------- 10 圖 2.7 撰寫的 PicoBlze 轉成 VHDL----------------------------------- 10

    圖 2.8 轉檔失敗----------------------------------------------------------- 10

    圖 2.9 轉檔成功----------------------------------------------------------- 11

    圖 2.10 CPU I/O 運用檔--------------------------------------------------- 12

    圖 2.11 interrupt結合FIFO中斷觸發 sw1------------------------------ 14

    圖 2.12 interrupt結合FIFO中斷觸發 sw2------------------------------ 15

    圖 2.13 interrupt結合 FIFO模組化-------------------------------------- 17

    圖 3.1 狀態機-------------------------------------------------------------- 19

    圖 3.2 驗證之基本架構設計-------------------------------------------- 19

    圖 3.3 動作示意圖-------------------------------------------------------- 20

    圖 3.4 小綠人、小紅人展示圖------------------------------------------ 20

    圖 3.5 其他展示圖(1)---------------------------------------------------- 20

    圖 3.6 其他展示圖(2)---------------------------------------------------- 20

    圖 3.7 其他展示圖(3)---------------------------------------------------- 20

    圖 3.8 PICO-1 驗證系統程式設計流程------------------------------- 21

    圖 3.9 PICO-2 驗證系統程式設計流程------------------------------- 22

    圖 3.10 PICO-3 驗證系統程式設計流程------------------------------- 23

    圖 3.11 成果展示(1)------------------------------------------------------- 24

    圖 3.12 成果展示(2)------------------------------------------------------- 24

  • 1

    一、 緒論

    1.1 研究動機與問題

    多核心處理器已經是目前 PC 的主流,但是 PC 的 CPU 是 32/64-bit 的

    INTEL 或 AMD 晶片,對於嵌入式系統的應用,就會受限於成本的考量,

    而需要另謀低價格的多核心處理器晶片。

    目前的 8-bit 微處理器,如要設計一個 6-軸機器人,需要多個 8-bit

    微處理器才能完成,在設計上,需要再設計出每一個微處理器間的資訊傳

    遞通道,訊息交換資料區,以及需要另行開發通訊連絡通道與資訊存取信

    號協定,所以我們設計將利用於FPGA上設計8-bit RISC CPU的Multi-core

    BUS 修改,來作為 BI-FIFO 的資料進出,利於提供 Multi-core 8-bit RISC

    CPU 之間的訊息交換平台。

    然而有一顆 8 核心單片機之 FPPA 正在推廣,雖受限於成本考量,但

    是可以見得多核心 8-bit 處理器可應用的園地是很廣泛的,然而 FPGA 的

    可重規劃性、可擴充性、可再使用性的超彈性技術應用晶片設計,相當適

    合用於多核心 8-bit 處理器的晶片開發設計,因此本計畫擬於 FPGA 晶片

    上,開發出一個可擴充成 n-核心處理器的 IP,且以一個實作應用系統,

    證實本設計的可行與可用性,藉此以上動機與原因來設計基於 FPGA 之多

    核心處理器設計技術。

    1.2 文獻回顧與探討

    目前在多核心處理器的設計上,有 5 種架構被提出[1,2],而另一種有

    專利之 FPPATM : Filed Programmable Processor Array[3],也正努力的推展

    應用中[4],不過 FPGA 上之多核心處理器的開發,尚方興未艾,值得進

    行研究。

  • 2

    1.3 研究方法及步驟

    研究方法:

    圖 1.1 為多核心處理器設計上的 1 種之 BI-FIFO 架構,也是本文計畫

    的系統方塊圖,本文將就圖 1.1 之架構為出發點,於 FPGA 上設計 8-bit

    RISC CPU 的 Multi-core BUS,作為 BI-FIFO 的資料進出,提供 Multi-core

    8-bit RISC CPU 間的訊息交換平台,然後將開發完成之 Multi-core 核心,

    假設先命名為 KSU,設計出圖 1.2 的應用展示系統。

    圖 1.1 規劃圖

    圖 1.2 應用模組

  • 3

    1.4 實體驗證平台

    我們所採用的實體驗證平台為 Xilinx 的 Spartan-3AN XC3S50AN

    FPGA Starter Kit[5],此實驗模組之相關硬體如下:

    5 萬邏輯閘的 Xilinx Spartan-3AN XC3S50AN FPGA 包裝為 TQFP

    144 隻腳位(XC3S50AN-4-TQ144)

    o 內含 3 個 18k-bit 的 Block Ram(共 54kbits)

    o 內含 3 個 18x18 bit 硬體乘法器

    o 內含 2 個 Digital Clock Managers(DCMs)

    o 內含 108 個可用腳位

    o 內含 1M bits Flash (User Flash bits ~627kbits)

    40MHz 的振盪晶體 •兩個使用者振盪晶體的 Socket

    64 個 User IO •8 個 DIP Switch •10 個 LED 輸出界面

    8 個 Push Button •4 個七段顯示器

    單一電源輸入(+5V):提供實驗板兩組電源使用(1.2V 與 3.3V)

    JTAG 界面: 提供燒錄程式的介面

    Ulinx Spartan3AN 發展板採用 Xilinx 最新一代 Spartan-3AN-XC3S50AN

    FPGA 晶片,除了提供作為一般 VHDL / VERILOG 驗證的發展板以外,

    搭配使用者擴充插槽,將可自行開發與應用在不同的應用領域。此發展板

    除了包含 5 萬邏輯閘的 FPGA 之外,板子上亦包含 I/O、DIP switch、Push

    button、LED、7_Segment 等相關的週邊設備,如下圖 1.3 所示。

    圖 1.3 Xilinx 的 Spartan-3AN XC3S50AN FPGA

  • 4

    二、 FPGA 內嵌 Dual core 8-bit 微處理器

    2.1 Single core

    PicoBlaze 是由 Xilinx 公司的 Ken Chapman 設計並維護的一款 8bit 的

    微控制單元軟核,可以嵌入到 Cool Runner II,Virtex-E,Virtex-II(Pro) 和

    Spartan3(E)的 CPLD 以及 FPGA 中。

    Xilinx 主推的 32-bit RISC 嵌入式系統叫 MicroBlaze,非官方有時也可

    寫成 uBlaze,用來表示該軟核非常之小。Xilinx 推出比它更小的軟核就是

    PicoBlaze 了。我們學過電路的人都知道,電容單位裡有個量級叫 pF。這

    裡的 p 就是 Pico-的意思,它表示 10 的負 12 次方這樣一個數量級。而

    PicoBlaze 這個軟核呢,也的確是名符其實。將它實現下 XC3S500E 的

    FPGA 中,只用到了 96 個 SLICE,也就是只佔用到了 5%的邏輯資源。

    不過它雖然小,但性能卻挺強大的。對於整個指令集,PicoBlaze 執

    行一條指令需要 2 個時脈週期。即使這樣,在 Spartan-3AN XC3S50AN

    Starter Kit 板上以 40MHz 或可擴充 50MHz 的時脈為例,PicoBlaze 也能達

    到 25MIPS 的性能,對於要求不是太高的應用場合,PicoBlaze 是一個不

    錯的選擇。而且在某些特殊的應用場合下,還可以實現例化多個 PicoBlaze

    軟核來達到設計目的,其設計 PicoBlaze 方塊圖如圖 2.1。

    圖 2.1 PicoBlaze 8bit 嵌入式微控制器方塊圖

  • 5

    儘管 PicoBlaze 的定義是 Microcontroller(ug129 是這樣寫的),但是根

    據 Ken Chapman 在 PicoBlaze 的參考設計裡提到的,PicoBlaze 實際上是

    常數碼可編程的狀態機(KCPSM, short for Konstant Code Programmable

    State Machine)。巧合的是,我們也可將其稱之為 Ken Chapman's

    Programmable State Machine, 以示紀念。從它參考設計中附帶的 PSM 代

    碼中可以看到,針對 PicoBlaze 編寫的代碼大部分都是由 Constant,各個

    函數段間的 JUMP 以及中斷服務例程(ISR, Interrupt Service Routine)構成

    的。這些代碼的執行都是順序的,儘管這似乎與 FPGA 能有效執行操作的

    特點不同,但是在某些場合,用 PicoBlaze 卻能夠簡化設計,而又不失性

    能。

    使用過 8051 或者其他的 8/16 位的單片機的話就應該知道,主要的開

    發模式就是對其進行編程並將程式燒寫進 Flash 中。基於 PicoBlaze 的開

    發模式也是也大致如此,稍有差別的就是需要將 PicoBlaze 認識並執行的

    程式經過 Assembler轉換成相應的 HDL文件以存放在 FPGA內部的 Block

    Memory 中(也正因為如此,PicoBlaze 執行一條指令所需的時脈週期也是

    固定的)。圖 2.2 是 KCPSM3 核心結構圖︰

    圖 2.2 KCPSM3 核心結構圖

  • 6

    圖 2.3 中,微控制單元核心 KCPSM3 從 Block Memory 裡面讀取程式

    並按順序執行。在這裡我們可以看到 PicoBlaze 的存儲空間為 1024x18bit,

    也就是能夠存放 1024 條位長為 18 的指令。而 PicoBlaze 支持的指令集也

    很精簡,只有 57 條,包含了程式控制類(JUMP,CALL,RETURN),算

    數類(ADD,SUB,COMPARE),邏輯類(AND,OR,XOR),中斷類

    (ENABLE/DISABLE INTERRUPT),移位/旋轉類(SR/SL,RR/RL),輸入/

    輸出類(INPUT,OUTPUT)。

    圖 2.3 PicoBlaze 核心架構圖

    暫存器:KCPSM3中一共有16個長度為8位的通用暫存器,每個暫存器都

    可以在彙編代碼中分別命名。

    中斷:KCPSM3只支援1個中斷信號,但實際上可以將多個中斷信號用邏

    輯組合的模式變成一個來用。

    Scratch Pad Memory:它的大小為 64 Bytes,作用相當於一塊臨時存儲區,

    比如在中斷例程 ISR 中可以將其作為臨時變量適用。

    2.1-1 KCPSM3 指令集

    表 2.1 指令表 Instruction Function

    ADD sX, kk sX ← sX + kk

    ADD sX, sY sX ← sX + sY

    ADDCY sX, kk sX ← sX + kk + CARRY

    ADDCY sX, sY sX ← sX + sY + CARRY

  • 7

    AND sX, kk sX ← sX AND kk

    AND sX, sY sX ← sX AND sY

    CALL aaa TOS ← PC

    PC ← aaa

    CALL C, aaa If CARRY=1, {TOS ← PC,

    PC ← aaa}

    CALL NC, aaa f CARRY=0, {TOS ← PC,

    PC ← aaa}

    CALL NZ, aaa If ZERO=0, {TOS ← PC,

    PC ← aaa}

    CALL Z, aaa If ZERO=1, {TOS ← PC,

    PC ← aaa}

    COMPARE sX, kk If sX=kk, ZERO ← 1

    If sX

  • 8

    RETURN PC ← TOS+1

    RETURN NC If CARRY=0, PC ← TOS+1

    RETURN NZ If ZERO=0, PC ← TOS+1

    RETURN Z If ZERO=1, PC ← TOS+1

    RETURNI DISABLE

    PC ← TOS

    ZERO ← Preserved ZERO

    CARRY ← Preserved CARRY

    INTERRUPT_ENABLE ← 0

    RETURNI ENABLE

    PC ← TOS

    ZERO ← Preserved ZERO

    CARRY ← Preserved CARRY

    INTERRUPT_ENABLE ← 1

    RL sX sX ← {sX[6:0],sX[7]}

    CARRY ← sX[7]

    RR sX sX ← {sX[0],sX[7:1]}

    CARRY ← sX[0]

    SL0 sX sX ← {sX[6:0],0}

    CARRY ← sX[7]

    SL1 sX sX ← {sX[6:0],1}

    CARRY ← sX[7]

    SLA sX sX ← {sX[6:0],CARRY}

    CARRY ← sX[7]

    SLX sX sX ← {sX[6:0],sX[0]}

    CARRY ← sX[7]

    SR0 sX sX ← {0,sX[7:1]}

    CARRY ← sX[0]

    SR1 sX sX ← {1,sX[7:1]}

    CARRY ← sX[0]

    SRA sX sX ← {CARRY,sX[7:1]}

    CARRY ← sX[0]

    SRX sX sX ← {sX[7],sX[7:1]}

    CARRY ← sX[0]

    STORE sX, (sY) RAM[(sY)] ← sX

    STORE sX, ss RAM[ss] ← sX

    SUB sX, kk sX ← sX – kk

    SUB sX, sY sX ← sX – sY

  • 9

    TEST sX, kk If (sX AND kk) = 0, ZERO ← 1

    CARRY ← odd parity of (sXAND kk)

    TEST sX, sY If (sX AND sY) = 0, ZERO ← 1

    CARRY ← odd parity of (sXAND kk)

    XOR sX, kk sX ← sX XOR kk

    XOR sX, sY sX ← sX XOR sY

    2.2 CPU I/O 設計

    要先將PicoBlaze認識並執行的程式中要經過Assembler轉換成相應的

    VHDL 文件以存放在 FPGA 內部的 Block Memory 中,才可執行。

    簡易範例(資料抓進丟出)

    圖 2.4 CPU I/O 模組化

    圖 2.5 CPU I/O

  • 10

    PicoBlaze 轉成 VHDL:

    圖 2.6 顯示 DOS 模擬器

    圖 2.7 撰寫的 PicoBlaze 轉成 VHDL

    圖 2.8 轉檔失敗

  • 11

    圖 2.9 轉檔成功

    VHDL(dip 對應 led)

    input: process(clk)

    begin

    if rising_edge(clk) then

    case port_if(7 downto 0) is

    when x”02” =>

    in_port

    NULL;

    end case;

    end if;

    end process;

    output:process(clk)

    begin

    if rising_edge(clk) then

    if write_strobe=‟1‟ then

    if port_if=x”04” then

    led(3 downto 0)

  • 12

    2.2-1 Component 與模組化

    圖 2.10 CPU I/O 運用檔

    Componentcomponent 與接腳運用

    component kcpsm3

    Port ( address : out std_logic_vector(9 downto 0);

    instruction : in std_logic_vector(17 downto 0);

    port_id : out std_logic_vector(7 downto 0);

    write_strobe : out std_logic;

    out_port : out std_logic_vector(7 downto 0);

    read_strobe : out std_logic;

    in_port : in std_logic_vector(7 downto 0);

    interrupt : in std_logic;

    interrupt_ack : out std_logic;

    reset : in std_logic;

    clk : in std_logic);

    end component;

    component test

    Port (address : in std_logic_vector(9 downto 0);

    instruction : out std_logic_vector(17 downto 0);

    clk : in std_logic);

    end component;

    component in_out

    Port ( clk : in std_logic;

    dip : in std_logic_vector(3 downto 0);

    sw : in std_logic;

    out_port : in std_logic_vector(7 downto 0);

  • 13

    port_id : in std_logic_vector(7 downto 0);

    write_strobe : in std_logic;

    led : out std_logic_vector(4 downto 0);

    in_port : out std_logic_vector(7 downto 0));

    end component;

    begin

    Inst_kcpsm3: kcpsm3 port map(

    address => address,

    instruction => instruction,

    port_id => port_id,

    write_strobe => write_strobe,

    out_port => out_port,

    read_strobe => read_strobe,

    in_port => in_port,

    interrupt => interrupt,

    interrupt_ack => interrupt_ack,

    reset => „0‟,

    clk => clk);

    Inst_test: test port map(

    address => address,

    instruction => instruction,

    clk => clk);

    Inst_in_out: in_out port map (

    clk => clk,

    dip => dip,

    sw => sw,

    led => led,

    in_port => in_port,

    out_port => out_port,

    port_id => port_id,

    write_strobe => write_strobe);

    end Behavioral;

  • 14

    2.3 Dual core

    interrupt 結合 FIFO

    ※sw1 判斷 ASCII 要數到幾,而 sw2 是顯現 LCD 的字母與 LED 是多少(二

    進制表示)

    假設 1:中斷觸發(按鈕 sw1)第一下,中斷觸發(按鈕 sw2)一次,LCD 上顯

    示 A,當中斷(按鈕 sw1)第二下,中斷(按鈕 sw2)一次,LCD 上顯

    示 B C,(sw1)第三下,(sw2)一次,顯示 D E F,以此類推…。

    假設 2:中斷觸發(按鈕 sw1)直接按三下,中斷觸發(按鈕 sw2)一次,LCD

    上顯示 A B C D E F,以此類推…。

    ※ A(41) B(42) C(43) D(44) E(45) F(46)…是經過 ASCII 轉換

    圖 2.11 interrupt 結合 FIFO 中斷觸發 sw1

  • 15

    圖 2.12 interrupt 結合 FIFO 中斷觸發 sw2

    Component接腳運用

    entity kcp_fifo_kcp is

    Port ( clk : in STD_LOGIC;

    lcd_d : inout std_logic_vector(7 downto 4);

    lcd_rs : out std_logic;

    lcd_e : out std_logic;

    led : out std_logic_vector(7 downto 0) : =(others=>‟0‟);

    sw1,sw2,reset : in STD_LOGIC );

    end kcp_fifo_kcp;

    architecture Behavioral of kcp_fifo_kcp is

    one_kcpsm3: kcpsm3

    port map( address => address1,

    instruction => instruction1,

    port_id => port_id1,

    write_strobe => write_strobe1,

    out_port => out_port1,

    read_strobe => read_strobe1,

    in_port => in_port1,

    interrupt => interrupt1,

    interrupt_ack => interrupt_ack1,

    reset => „0‟,

    clk => clk);

    Inst_bbfifo_16x8 : bbfifo_16x8

  • 16

    data_in => data_in,

    reset => reset,

    write => write_strobe1,

    read => sww,

    clk => iclk,

    data_out => data_out,

    full => full,

    half_full => half_full,

    data_present => data_present);

    two_kcpsm3: kcpsm3

    port map( address => address2,

    instruction => instruction2,

    port_id => port_id2,

    write_strobe => write_strobe2,

    out_port => out_port2,

    read_strobe => read_strobe2,

    in_port => in_port2,

    interrupt => interrupt2,

    interrupt_ack => interrupt_ack2,

    reset =>‟0‟,

    clk => clk);

    VHDL(中斷觸發(按鈕 sw1),做 PicoBlaze 的數的動作,中斷觸發(按

    鈕 sw2),將 PicoBlaze 的動作顯示在 LCD 與 LED 上)

    interrupt1

  • 17

    read_fifo:process(clk)

    begin

    if riding_edge(clk) then

    if read_stribe2=‟1‟ then

    if port_id2=x”34” then

    sww

  • 18

    三、 驗證與結果

    根據本文要求,修改於 FPGA 上設計 8-bit RISC CPU 的 Multi-core

    BUS,作為 BI-FIFO 的資料進出,提供 Multi-core 8-bit RISC CPU 間的訊

    息交換平台,此設計的擴展性非常良好,在實際設計過程中,可根據不同

    的要求在不同規模的 FPGA 上加以實現,FPGA 之多核心處理器設計-以

    LED 交通號誌燈之應用為例。

    為驗證本文所提出之BI-FIFO-Based 嵌入式多核心處理器系統架構的

    功能,本文特以Xilinx公司提供之PicoBlaze 8-bit 處理器為核心處理器,

    此8-bit處理器的核心程式相當簡潔,能夠擴充出256 個In與256個Out,而

    且執行clk可高達50MHz以上。

    圖3.2 為本系統採用Xilinx Spartan-3AN XC3S50AN FPGA 晶片所設

    計實驗板為驗證之基本架構設計,PICO-1主要是執行狀態機的程序,利

    用1/100sec使PICO-1中斷,計算每100次為一秒,精確計算時間,使狀態

    機(如圖3.1)能正確的判斷何時改變,再將狀態機狀態以及秒數透過FIFO

    給PICO-3處理,而PICO-3接收到狀態處理,來控制幹道、支道的16x16矩陣

    為小綠人、小紅人(如圖3.4),還可選擇變換其他圖(如圖3.5、3.6、3.7),

    以及各別七段顯示和紅綠燈的亮滅,如圖3.3之動作示意圖,PICO-2主要

    控制人工切換與更改初始值,使用到兩個指撥開關,一個來控制鎖定與確

    認,當中配合三顆按鈕,各別是幹道支道選擇、上數、下數,而另一指撥

    結合按鈕可直接控制任意一邊為小紅人,而PICO-4利用多核心擴充優

    勢,來達到使用者更多的需求,達到其要求功能。

  • 19

    圖 3.1 狀態機

    圖3.2 驗證之基本架構設計

  • 20

    圖 3.3 動作示意圖

    圖 3.4 小綠人、小紅人展示圖 圖 3.5 其他展示圖(1)

    圖 3.6 其他展示圖(2) 圖 3.7 其他展示圖(3)

  • 21

    圖3.8、3.9、3.10分別為PICO-1、PICO-2、PICO-3功能驗證系統的軟

    體設計流程,經過該本文基本架構設計相互配合可再擴充新的多核心(如

    PICO-4),且為更證明本文提出之多核心處理器的雛型架構,確實相當適

    合FPGA-based Multi-core MCU系統設計與應用,本文係撰寫FPGA結合

    PicoBlaze之間透過FIFO(表3.1)與純FPGA(表3.2)同功能之數據比較證

    明,PicoBlaze可作時間控制進而搭配只做單純互通功能的FPGA,FPGA

    不需要再寫任何時間控制,即可動作。使用純FPGA撰寫,則程式會較複

    雜,且需外加功能時,就必須變動程式,所以PicoBlaze搭配FPGA會比純

    FPGA佔用晶片效率少,該設計佔用晶片可節省效率近20%。

    圖 3.8 PICO-1 驗證系統程式設計流程

  • 22

    圖 3.9 PICO-2 驗證系統程式設計流程

  • 23

    圖 3.10 PICO-3 驗證系統程式設計流程

    表 3.1 FPGA 結合 PicoBlaze 之間透過 FIFO 之數據表

    表 3.2 純 FPGA 之數據表

  • 24

    圖 3.11 成果展示(1)

    圖 3.12 成果展示(2)

  • 25

    四、 結論

    本文提出內嵌多核心處理器系統的設計方法,不用重新設計內嵌處理

    器的指令群與 I/O Bus,而是運用 BI-FIFO 做為內嵌處理器的訊息交換通

    道,搭配處理器的硬體中斷信號,以及 I/O 指令,來成功的設計出內嵌 n-

    個多核心處理器的設計方法應用與實體,(如圖 17)所示。

    在交通號誌系統的設計上,使用 PicoBlaze 搭配 FPGA 可將順序式的

    指令取代 FSM 狀態機,介面由一顆 CPU 獨立負責,調整中不會影響其它

    控處理器的正常運作,使其指令變得更簡易,空間更節省,進而空間方面

    的控制性、變化性更為靈活、彈性。

    參考文獻

    [1]. Kyeong Keol Ryu, Eung Shin, Vincent J. Mooney, “A Comparison of

    Five Different Multiprocessor SoC Bus Architectures”, Euromicro

    Symposium on Digital Systems Design (DSD'01), p. 0202, 2001.

    [2]. A. A. Jerraya, A. Baghdadi, W. Cesário, L. Gauthier, D. Lyonnard, G.

    Nicolescu, Y. Paviot, Sungjoo Yoo, “ Application-specific

    multiprocessor Systems-on-Chip”, Microelectronics Journal Volume 33,

    Issue 11, November 2002, Pages 891-898.

    [3]. http://www.padauk.com.tw/corporate-profile.php.

    [4]. http://www.gkong.com/blog/more.asp?name=gongkong&id=7789.

    [5]. http://www.ulinx.com.tw/main36.htm (Ulinx Spartan3AN Development Kit)

    [6]. 蔡國端、林明權.著,VHDL數位系統設計專案導向學習法,學貫行

    銷公司

    http://www.sciencedirect.com/science/journal/00262692http://www.sciencedirect.com/science?_ob=PublicationURL&_tockey=%23TOC%235748%232002%23999669988%23363229%23FLA%23&_cdi=5748&_pubType=J&_auth=y&_acct=C000050221&_version=1&_urlVersion=0&_userid=10&md5=df7d742d8a19f76fd95991bfa48f8183http://www.sciencedirect.com/science?_ob=PublicationURL&_tockey=%23TOC%235748%232002%23999669988%23363229%23FLA%23&_cdi=5748&_pubType=J&_auth=y&_acct=C000050221&_version=1&_urlVersion=0&_userid=10&md5=df7d742d8a19f76fd95991bfa48f8183http://www.padauk.com.tw/corporate-profile.phphttp://www.gkong.com/blog/more.asp?name=gongkong&id=7789http://www.ulinx.com.tw/main36.htmhttp://www.ulinx.com.tw/main36.htm

  • 26

    附錄一:FPGA 結合 PicoBlaze 之間透過 FIFO FPGA: library IEEE;

    use IEEE.STD_LOGIC_1164.ALL;

    use IEEE.STD_LOGIC_ARITH.ALL;

    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity ledgreenred is

    Port ( led : out std_logic_vector(7 downto 0);

    switch : in std_logic_vector(1 downto 0);

    btn : in std_logic_vector(5 downto 0);

    clk : in std_logic;

    gyr: out STD_LOGIC_VECTOR(7 downto 0);

    vccout : out STD_LOGIC_VECTOR(1 downto 0);

    sevenout : out STD_LOGIC_VECTOR(3 downto 0);

    SK : out STD_LOGIC;

    R1 : out STD_LOGIC;

    G1 : out STD_LOGIC;

    EN : out STD_LOGIC;

    LA,LB,LC,LD : out STD_LOGIC;

    LT : out STD_LOGIC);

    end ledgreenred;

    --*************************************************************

    signal x : integer range 0 to 39 :=0;

    signal ccc : integer range 0 to 300 :=32;

    signal y : STD_LOGIC_VECTOR(4 downto 0):="00000";

    signal sk1 : STD_LOGIC:='1';

    signal lt1 : STD_LOGIC:='0';

    signal en1 : STD_LOGIC:='1';

    signal speed: STD_LOGIC:='0';

    signal a,b,c,d,e,iclk,cclk,iiclk,iiiclk,iiiiclk : STD_LOGIC:='0';

    signal div : STD_LOGIC_VECTOR(30 downto

    0):="0000000000000000000000000000000";

    signal count,f : integer range 0 to 300:=0;

    signal ddd,ddd0,ddd1 : integer range 0 to 20:=0;

    signal state: STD_LOGIC_VECTOR(7 downto 0):="00100100";

    signal s0: STD_LOGIC_VECTOR(1 downto 0):="00";

    signal c0: STD_LOGIC_VECTOR (3 downto 0):="0000";

    signal jbtn,love: STD_LOGIC_VECTOR (1 downto 0):="00";

    signal n0,n1,n2,n3 : STD_LOGIC_VECTOR(3 downto 0):="0000";

    type display is (an1,an2,an3,an4);

    signal stt : display;

    signal A10 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A11 : STD_LOGIC_VECTOR(0 to

  • 27

    31):="11111111111111111111111111111111";

    signal A12 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A13 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A14 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A15 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A16 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A17 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A18 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A19 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A110 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A111 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A112 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A113 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A114 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal A115 : STD_LOGIC_VECTOR(0 to

    31):="11111111111111111111111111111111";

    signal G10 : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G12 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G13 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G14 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G15 : STD_LOGIC_VECTOR(0 to 15):="1111111001111111";

    signal G16 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G17 : STD_LOGIC_VECTOR(0 to 15):="1111000000001111";

    signal G18 : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G19 : STD_LOGIC_VECTOR(0 to 15):="1100110000110011";

    signal G110 : STD_LOGIC_VECTOR(0 to 15):="1100110000110011";

    signal G111 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G112 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G113 : STD_LOGIC_VECTOR(0 to 15):="1111001111001111";

    signal G114 : STD_LOGIC_VECTOR(0 to 15):="1111001111001111";

    signal G115 : STD_LOGIC_VECTOR(0 to 15):="1110001111000111";

  • 28

    signal G10a : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11a : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12a : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13a : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14a : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15a : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G16a : STD_LOGIC_VECTOR(0 to 15):="1111100000001111";

    signal G17a : STD_LOGIC_VECTOR(0 to 15):="1111000000100111";

    signal G18a : STD_LOGIC_VECTOR(0 to 15):="1110011000110011";

    signal G19a : STD_LOGIC_VECTOR(0 to 15):="1100111000111001";

    signal G110a : STD_LOGIC_VECTOR(0 to 15):="1001111000111100";

    signal G111a : STD_LOGIC_VECTOR(0 to 15):="1111110010011111";

    signal G112a : STD_LOGIC_VECTOR(0 to 15):="1111110011001111";

    signal G113a : STD_LOGIC_VECTOR(0 to 15):="1111100111100011";

    signal G114a : STD_LOGIC_VECTOR(0 to 15):="1111001111111001";

    signal G115a : STD_LOGIC_VECTOR(0 to 15):="1000011111110011";

    signal G10b : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11b : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12b : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13b : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14b : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15b : STD_LOGIC_VECTOR(0 to 15):="1111100001111111";

    signal G16b : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G17b : STD_LOGIC_VECTOR(0 to 15):="1111100001001111";

    signal G18b : STD_LOGIC_VECTOR(0 to 15):="1111100000100111";

    signal G19b : STD_LOGIC_VECTOR(0 to 15):="1111100000100111";

    signal G110b : STD_LOGIC_VECTOR(0 to 15):="1111001100011111";

    signal G111b : STD_LOGIC_VECTOR(0 to 15):="1111111000011111";

    signal G112b : STD_LOGIC_VECTOR(0 to 15):="1111110011001111";

    signal G113b : STD_LOGIC_VECTOR(0 to 15):="1111100001100011";

    signal G114b : STD_LOGIC_VECTOR(0 to 15):="1111111001111001";

    signal G115b : STD_LOGIC_VECTOR(0 to 15):="1111100001111001";

    signal G10c : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11c : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12c : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13c : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14c : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15c : STD_LOGIC_VECTOR(0 to 15):="1111100111111111";

    signal G16c : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G17c : STD_LOGIC_VECTOR(0 to 15):="1111100001111111";

    signal G18c : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G19c : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G110c : STD_LOGIC_VECTOR(0 to 15):="1111111000011111";

  • 29

    signal G111c : STD_LOGIC_VECTOR(0 to 15):="1111110000011111";

    signal G112c : STD_LOGIC_VECTOR(0 to 15):="1111100110001111";

    signal G113c : STD_LOGIC_VECTOR(0 to 15):="1111111110001111";

    signal G114c : STD_LOGIC_VECTOR(0 to 15):="1111111101101111";

    signal G115c : STD_LOGIC_VECTOR(0 to 15):="1111111100001111";

    signal G10d : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11d : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12d : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13d : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14d : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15d : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G16d : STD_LOGIC_VECTOR(0 to 15):="1111100000000111";

    signal G17d : STD_LOGIC_VECTOR(0 to 15):="1111000000110011";

    signal G18d : STD_LOGIC_VECTOR(0 to 15):="1110011000111001";

    signal G19d : STD_LOGIC_VECTOR(0 to 15):="1100111000111100";

    signal G110d : STD_LOGIC_VECTOR(0 to 15):="1001111000111111";

    signal G111d : STD_LOGIC_VECTOR(0 to 15):="1111110010011111";

    signal G112d : STD_LOGIC_VECTOR(0 to 15):="1111110011001111";

    signal G113d : STD_LOGIC_VECTOR(0 to 15):="1111100111100011";

    signal G114d : STD_LOGIC_VECTOR(0 to 15):="1100001111111001";

    signal G115d : STD_LOGIC_VECTOR(0 to 15):="1111111111111001";

    signal G10e : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11e : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12e : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13e : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14e : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15e : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G16e : STD_LOGIC_VECTOR(0 to 15):="1111100000000111";

    signal G17e : STD_LOGIC_VECTOR(0 to 15):="1111000000110011";

    signal G18e : STD_LOGIC_VECTOR(0 to 15):="1110011000111001";

    signal G19e : STD_LOGIC_VECTOR(0 to 15):="1100111000110011";

    signal G110e : STD_LOGIC_VECTOR(0 to 15):="1111111000011111";

    signal G111e : STD_LOGIC_VECTOR(0 to 15):="1111111001001111";

    signal G112e : STD_LOGIC_VECTOR(0 to 15):="1111111001001111";

    signal G113e : STD_LOGIC_VECTOR(0 to 15):="1111110011100011";

    signal G114e : STD_LOGIC_VECTOR(0 to 15):="1111110011111001";

    signal G115e : STD_LOGIC_VECTOR(0 to 15):="1111000011110001";

    signal G10f : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11f : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12f : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13f : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14f : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15f : STD_LOGIC_VECTOR(0 to 15):="1111100001111111";

  • 30

    signal G16f : STD_LOGIC_VECTOR(0 to 15):="1111100000011111";

    signal G17f : STD_LOGIC_VECTOR(0 to 15):="1111100001001111";

    signal G18f : STD_LOGIC_VECTOR(0 to 15):="1111100000100111";

    signal G19f : STD_LOGIC_VECTOR(0 to 15):="1111100000100111";

    signal G110f : STD_LOGIC_VECTOR(0 to 15):="1111001100011111";

    signal G111f : STD_LOGIC_VECTOR(0 to 15):="1111111000001111";

    signal G112f : STD_LOGIC_VECTOR(0 to 15):="1111100011000011";

    signal G113f : STD_LOGIC_VECTOR(0 to 15):="1111100001110011";

    signal G114f : STD_LOGIC_VECTOR(0 to 15):="1111111001100011";

    signal G115f : STD_LOGIC_VECTOR(0 to 15):="1111100001111111";

    signal G10g : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11g : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12g : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13g : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14g : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15g : STD_LOGIC_VECTOR(0 to 15):="1111100111111111";

    signal G16g : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G17g : STD_LOGIC_VECTOR(0 to 15):="1111100001111111";

    signal G18g : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G19g : STD_LOGIC_VECTOR(0 to 15):="1111110000111111";

    signal G110g : STD_LOGIC_VECTOR(0 to 15):="1111111000011111";

    signal G111g : STD_LOGIC_VECTOR(0 to 15):="1111110000011111";

    signal G112g : STD_LOGIC_VECTOR(0 to 15):="1111100110001111";

    signal G113g : STD_LOGIC_VECTOR(0 to 15):="1111111110001111";

    signal G114g : STD_LOGIC_VECTOR(0 to 15):="1111111101101111";

    signal G115g : STD_LOGIC_VECTOR(0 to 15):="1111111100001111";

    signal G10h : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11h : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G12h : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G13h : STD_LOGIC_VECTOR(0 to 15):="1110000011111111";

    signal G14h : STD_LOGIC_VECTOR(0 to 15):="1111000111111111";

    signal G15h : STD_LOGIC_VECTOR(0 to 15):="1111100011111111";

    signal G16h : STD_LOGIC_VECTOR(0 to 15):="1111100000000111";

    signal G17h : STD_LOGIC_VECTOR(0 to 15):="1111000000110011";

    signal G18h : STD_LOGIC_VECTOR(0 to 15):="1110011000111001";

    signal G19h : STD_LOGIC_VECTOR(0 to 15):="1100111000111100";

    signal G110h : STD_LOGIC_VECTOR(0 to 15):="1001111000111111";

    signal G111h : STD_LOGIC_VECTOR(0 to 15):="1111110010011111";

    signal G112h : STD_LOGIC_VECTOR(0 to 15):="1111110011001111";

    signal G113h : STD_LOGIC_VECTOR(0 to 15):="1111100111100011";

    signal G114h : STD_LOGIC_VECTOR(0 to 15):="1100001111111001";

    signal G115h : STD_LOGIC_VECTOR(0 to 15):="1111111111111001";

    signal G10i : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

  • 31

    signal G11i : STD_LOGIC_VECTOR(0 to 15):="1100011111100011";

    signal G12i : STD_LOGIC_VECTOR(0 to 15):="1101101111011011";

    signal G13i : STD_LOGIC_VECTOR(0 to 15):="1101110000111011";

    signal G14i : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

    signal G15i : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G16i : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G17i : STD_LOGIC_VECTOR(0 to 15):="1011011111101101";

    signal G18i : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G19i : STD_LOGIC_VECTOR(0 to 15):="1011110000111101";

    signal G110i : STD_LOGIC_VECTOR(0 to 15):="1011101001011101";

    signal G111i : STD_LOGIC_VECTOR(0 to 15):="1011100000011101";

    signal G112i : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

    signal G113i : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G114i : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G115i : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G10j : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11j : STD_LOGIC_VECTOR(0 to 15):="1100011111100011";

    signal G12j : STD_LOGIC_VECTOR(0 to 15):="1101101111011011";

    signal G13j : STD_LOGIC_VECTOR(0 to 15):="1101110000111011";

    signal G14j : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

    signal G15j : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G16j : STD_LOGIC_VECTOR(0 to 15):="1011011111101101";

    signal G17j : STD_LOGIC_VECTOR(0 to 15):="1010101111010101";

    signal G18j : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G19j : STD_LOGIC_VECTOR(0 to 15):="1011100000011101";

    signal G110j : STD_LOGIC_VECTOR(0 to 15):="1011101001011101";

    signal G111j : STD_LOGIC_VECTOR(0 to 15):="1011110000111101";

    signal G112j : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

    signal G113j : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G114j : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G115j : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G10k : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11k : STD_LOGIC_VECTOR(0 to 15):="1100011111100011";

    signal G12k : STD_LOGIC_VECTOR(0 to 15):="1101101111011011";

    signal G13k : STD_LOGIC_VECTOR(0 to 15):="1101110000111011";

    signal G14k : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

    signal G15k : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G16k : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G17k : STD_LOGIC_VECTOR(0 to 15):="1010001111000101";

    signal G18k : STD_LOGIC_VECTOR(0 to 15):="1011111111111101";

    signal G19k : STD_LOGIC_VECTOR(0 to 15):="1011110000111101";

    signal G110k : STD_LOGIC_VECTOR(0 to 15):="1011101001011101";

    signal G111k : STD_LOGIC_VECTOR(0 to 15):="1011100000011101";

    signal G112k : STD_LOGIC_VECTOR(0 to 15):="1101111111111011";

  • 32

    signal G113k : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G114k : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G115k : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G10l : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11l : STD_LOGIC_VECTOR(0 to 15):="1111110111011111";

    signal G12l : STD_LOGIC_VECTOR(0 to 15):="1111110111011111";

    signal G13l : STD_LOGIC_VECTOR(0 to 15):="1111000000000111";

    signal G14l : STD_LOGIC_VECTOR(0 to 15):="1110110111011011";

    signal G15l : STD_LOGIC_VECTOR(0 to 15):="1101110111011011";

    signal G16l : STD_LOGIC_VECTOR(0 to 15):="1101110111011111";

    signal G17l : STD_LOGIC_VECTOR(0 to 15):="1101110111011111";

    signal G18l : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G19l : STD_LOGIC_VECTOR(0 to 15):="1111110111011011";

    signal G110l : STD_LOGIC_VECTOR(0 to 15):="1111110111011011";

    signal G111l : STD_LOGIC_VECTOR(0 to 15):="1111110111011011";

    signal G112l : STD_LOGIC_VECTOR(0 to 15):="1101110111010111";

    signal G113l : STD_LOGIC_VECTOR(0 to 15):="1110000000001111";

    signal G114l : STD_LOGIC_VECTOR(0 to 15):="1111110111011111";

    signal G115l : STD_LOGIC_VECTOR(0 to 15):="1111110111011111";

    signal G10m : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11m : STD_LOGIC_VECTOR(0 to 15):="1111111001111111";

    signal G12m : STD_LOGIC_VECTOR(0 to 15):="1111111001111111";

    signal G13m : STD_LOGIC_VECTOR(0 to 15):="1111000000000111";

    signal G14m : STD_LOGIC_VECTOR(0 to 15):="1110111001111011";

    signal G15m : STD_LOGIC_VECTOR(0 to 15):="1101111001111011";

    signal G16m : STD_LOGIC_VECTOR(0 to 15):="1101111001111111";

    signal G17m : STD_LOGIC_VECTOR(0 to 15):="1101111001111111";

    signal G18m : STD_LOGIC_VECTOR(0 to 15):="1110000000000111";

    signal G19m : STD_LOGIC_VECTOR(0 to 15):="1111111001111011";

    signal G110m : STD_LOGIC_VECTOR(0 to 15):="1111111001111011";

    signal G111m : STD_LOGIC_VECTOR(0 to 15):="1111111001111011";

    signal G112m : STD_LOGIC_VECTOR(0 to 15):="1101111001110111";

    signal G113m : STD_LOGIC_VECTOR(0 to 15):="1110000000001111";

    signal G114m : STD_LOGIC_VECTOR(0 to 15):="1111111001111111";

    signal G115m : STD_LOGIC_VECTOR(0 to 15):="1111111001111111";

    signal G10n : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11n : STD_LOGIC_VECTOR(0 to 15):="1111111110011111";

    signal G12n : STD_LOGIC_VECTOR(0 to 15):="1111100000000111";

    signal G13n : STD_LOGIC_VECTOR(0 to 15):="1000001110000111";

    signal G14n : STD_LOGIC_VECTOR(0 to 15):="1000100011100111";

    signal G15n : STD_LOGIC_VECTOR(0 to 15):="1000100100010111";

    signal G16n : STD_LOGIC_VECTOR(0 to 15):="1001101010001111";

    signal G17n : STD_LOGIC_VECTOR(0 to 15):="1010010001010011";

  • 33

    signal G18n : STD_LOGIC_VECTOR(0 to 15):="1110011000110001";

    signal G19n : STD_LOGIC_VECTOR(0 to 15):="1010000001100001";

    signal G110n : STD_LOGIC_VECTOR(0 to 15):="1010001111000001";

    signal G111n : STD_LOGIC_VECTOR(0 to 15):="1001100000011111";

    signal G112n : STD_LOGIC_VECTOR(0 to 15):="1000110001101101";

    signal G113n : STD_LOGIC_VECTOR(0 to 15):="1000011011110011";

    signal G114n : STD_LOGIC_VECTOR(0 to 15):="1111111111111011";

    signal G115n : STD_LOGIC_VECTOR(0 to 15):="1111111111100001";

    signal G10o : STD_LOGIC_VECTOR(0 to 15):="1111111111111111";

    signal G11o : STD_LOGIC_VECTOR(0 to 15):="1111111110011111";

    signal G12o : STD_LOGIC_VECTOR(0 to 15):="1111100000000111";

    signal G13o : STD_LOGIC_VECTOR(0 to 15):="1000001110000111";

    signal G14o : STD_LOGIC_VECTOR(0 to 15):="1000100011100111";

    signal G15o : STD_LOGIC_VECTOR(0 to 15):="1000100100010111";

    signal G16o : STD_LOGIC_VECTOR(0 to 15):="1001101010001111";

    signal G17o : STD_LOGIC_VECTOR(0 to 15):="1010010101010011";

    signal G18o : STD_LOGIC_VECTOR(0 to 15):="1110011000110001";

    signal G19o : STD_LOGIC_VECTOR(0 to 15):="1010000000100001";

    signal G110o : STD_LOGIC_VECTOR(0 to 15):="1010001111000001";

    signal G111o : STD_LOGIC_VECTOR(0 to 15):="1001100000011101";

    signal G112o : STD_LOGIC_VECTOR(0 to 15):="1000110001101011";

    signal G113o : STD_LOGIC_VECTOR(0 to 15):="1000011011110110";

    signal G114o : STD_LOGIC_VECTOR(0 to 15):="1111111111000001";

    signal G115o : STD_LOGIC_VECTOR(0 to 15):="1111111111111101";

    component kcpsm3

    Port ( address : out std_logic_vector(9 downto 0);

    instruction : in std_logic_vector(17 downto 0);

    port_id : out std_logic_vector(7 downto 0);

    write_strobe : out std_logic;

    out_port : out std_logic_vector(7 downto 0);

    read_strobe : out std_logic;

    in_port : in std_logic_vector(7 downto 0);

    interrupt : in std_logic;

    interrupt_ack : out std_logic;

    reset : in std_logic;

    clk : in std_logic);

    end component;

    -------------------------------

    COMPONENT bbfifo_16x8

    PORT( data_in : IN std_logic_vector(7 downto 0);

    reset : IN std_logic;

    write : IN std_logic;

    read : IN std_logic;

    clk : IN std_logic;

    data_out : OUT std_logic_vector(7 downto 0);

  • 34

    full : OUT std_logic;

    half_full : OUT std_logic;

    data_present : OUT std_logic);

    END COMPONENT;

    -------------------------------

    COMPONENT pico01

    Port (address : in std_logic_vector(9 downto 0);

    instruction : out std_logic_vector(17 downto 0);

    clk : in std_logic);

    END COMPONENT;

    -----------------------------

    COMPONENT pico02

    PORT(address : IN std_logic_vector(9 downto 0);

    clk : IN std_logic;

    instruction : OUT std_logic_vector(17 downto 0));

    END COMPONENT;

    -----------------------------

    COMPONENT pico03

    PORT(address : IN std_logic_vector(9 downto 0);

    instruction : OUT std_logic_vector(17 downto 0);

    clk : IN std_logic );

    END COMPONENT;

    --*************************************************************

    -- Signals used to connect KCPSM3 to program ROM and I/O logic

    --*************************************************************

    signal address1 : std_logic_vector(9 downto 0);

    signal instruction1 : std_logic_vector(17 downto 0);

    signal port_id1 : std_logic_vector(7 downto 0);

    signal out_port1 : std_logic_vector(7 downto 0);

    signal in_port1 : std_logic_vector(7 downto 0);

    signal write_strobe1 : std_logic;

    signal read_strobe1 : std_logic;

    signal interrupt1 : std_logic :='0';

    signal interrupt_ack1 : std_logic;

    signal kcpsm3_reset : std_logic;

    ----------------------------------------

    signal address2 : std_logic_vector(9 downto 0);

    signal instruction2 : std_logic_vector(17 downto 0);

    signal port_id2 : std_logic_vector(7 downto 0);

    signal out_port2 : std_logic_vector(7 downto 0);

    signal in_port2 : std_logic_vector(7 downto 0);

    signal write_strobe2 : std_logic;

    signal read_strobe2 : std_logic;

    signal interrupt2 : std_logic :='0';

    signal interrupt_ack2 : std_logic;

    ----------------------------------------

  • 35

    signal address3 : std_logic_vector(9 downto 0);

    signal instruction3 : std_logic_vector(17 downto 0);

    signal port_id3 : std_logic_vector(7 downto 0);

    signal out_port3 : std_logic_vector(7 downto 0);

    signal in_port3 : std_logic_vector(7 downto 0);

    signal write_strobe3 : std_logic;

    signal read_strobe3 : std_logic;

    signal interrupt3 : std_logic :='0';

    signal interrupt_ack3 : std_logic;

    -- Signals used to generate interrupt 1

    signal int_count1 : integer range 0 to 49999999 :=0;

    signal event_1hz : std_logic;

    -- Signals used to generate interrupt 2

    signal int_count2 : integer range 0 to 49999999 :=0;

    signal event_6hz : std_logic;

    -- Signals used to generate interrupt 3

    signal int_count3 : integer range 0 to 49999999 :=0;

    signal event_8khz : std_logic;

    -----------------------------------------

    signal swap : std_logic;

    -----------------------------------------

    signal data_in1 : std_logic_vector(7 downto 0):=(others=>'0');

    signal data_out1 : std_logic_vector(7 downto 0):=(others=>'0');

    signal reset1 : std_logic;

    signal full1 : std_logic;

    signal half_full1 : std_logic;

    signal data_present1 : std_logic;

    signal read1 : std_logic;

    signal write1 : std_logic;

    ----------------------------------------

    signal data_in2 : std_logic_vector(7 downto 0):=(others=>'0');

    signal data_out2 : std_logic_vector(7 downto 0):=(others=>'0');

    signal reset2 : std_logic;

    signal full2 : std_logic;

    signal half_full2 : std_logic;

    signal data_present2 : std_logic;

    signal read2 : std_logic;

    signal write2 : std_logic;

    ----------------------------------------

    begin

    --*************************************************************

    -- KCPSM3 and the program memory

    --*************************************************************

    one_kcpsm3: kcpsm3

    port map( address => address1,

    instruction => instruction1,

  • 36

    port_id => port_id1,

    write_strobe => write_strobe1,

    out_port => out_port1,

    read_strobe => read_strobe1,

    in_port => in_port1,

    interrupt => interrupt1,

    interrupt_ack => interrupt_ack1,

    reset => kcpsm3_reset,

    clk => clk);

    -------------------------------------------

    two_kcpsm3: kcpsm3

    port map( address => address2,

    instruction => instruction2,

    port_id => port_id2,

    write_strobe => write_strobe2,

    out_port => out_port2,

    read_strobe => read_strobe2,

    in_port => in_port2,

    interrupt => interrupt2,

    interrupt_ack => interrupt_ack2,

    reset => kcpsm3_reset,

    clk => clk);

    -------------------------------------------

    three_kcpsm3: kcpsm3

    port map( address => address3,

    instruction => instruction3,

    port_id => port_id3,

    write_strobe => write_strobe3,

    out_port => out_port3,

    read_strobe => read_strobe3,

    in_port => in_port3,

    interrupt => interrupt3,

    interrupt_ack => interrupt_ack3,

    reset => kcpsm3_reset,

    clk => clk);

    -------------------------------------------

    one_fifo: bbfifo_16x8

    PORT MAP(data_in => data_in1,

    data_out => data_out1,

    reset => reset1,

    write => write1,

    read => read1,

    full => full1,

    half_full => half_full1,

    data_present => data_present1,

    clk => clk);

  • 37

    -------------------------------------------

    two_fifo: bbfifo_16x8

    PORT MAP(data_in => data_in2,

    data_out => data_out2,

    reset => reset2,

    write => write2,

    read => read2,

    full => full2,

    half_full => half_full2,

    data_present => data_present2,

    clk => clk);

    -------------------------------------------

    Inst_pico01: pico01

    PORT MAP ( address => address1,

    instruction => instruction1,

    clk => clk);

    -------------------------------------------

    Inst_pico02: pico02

    PORT MAP ( address => address2,

    instruction => instruction2,

    clk => clk);

    -------------------------------------------

    Inst_pico03: pico03

    PORT MAP( address => address3,

    instruction => instruction3,

    clk => clk);

    gyr

  • 38

    G1

  • 39

    ="01000100")) then

    R1

  • 40

    elsif (x>16 and x

  • 41

    end if;

    elsif (x>16 and x

  • 42

    G1

  • 43

    if ddd = 0 then

    G1

  • 44

    then

    if ddd1 = 0 then

    G1

  • 45

    G1

  • 46

    elsif love="11" then

    if (x16 and x

  • 47

    end if;

    elsif love="01" then

    if (x16 and x

  • 48

    G1

  • 49

    "10000010")) or (x

  • 50

    G1

  • 51

    end if;

    elsif (x>16 and x

  • 52

    end if;

    elsif (x>16 and x

  • 53

    G1 16 and x

  • 54

    G1

  • 55

    if ddd = 0 then

    G1

  • 56

    if ddd1 = 0 then

    G1

  • 57

    elsif ddd = 7 then

    G1

  • 58

    then

    if ddd1 = 0 then

    G1

  • 59

    then

    if ddd0 = 0 then

    G1

  • 60

    when "01101" =>

    if love="00" then

    if (x16 and x

  • 61

    end if;

    elsif love="10" then

    if (x16 and x

  • 62

    elsif ddd = 5 then

    G1

  • 63

    G1

  • 64

    G1

  • 65

    else

    G1

  • 66

    if ddd1 = 2 then

    ddd1

  • 67

    case s0 is

    when "00" => state state state state null;

    end case;

    end process;

    process(iiiclk)

    begin

    if iiiclk'event and iiiclk = '1' then

    case stt is

    when an1 =>

    vccout

  • 68

    -- divide 50MHz by 500000 to form 100Hz pulses

    if int_count1 = 500000 then

    int_count1

  • 69

    event_8khz

  • 70

    end if;

    --*********FIFO_read**********

    if port_id1 = x"B0" then

    read2

  • 71

    --*************************************************************

    -- KCPSM3 input(3)

    --*************************************************************

    case port_id3 is

    when x"B4" => in_port3 in_port3 in_port3 in_port3 in_port3

  • 72

    end if;

    if port_id3 = x"82" then

    n2(0)

  • 73

    LOAD sB,05

    STORE sB,ST2_L

    STORE sB,ST4_L

    STORE sB,ST2_COUNT_L

    STORE sB,ST4_COUNT_L

    LOAD sB,1E ;30

    STORE sB,ST3_L

    STORE sB,ST3_COUNT_L

    STORE sB,USER_MODE_C

    warm_start: LOAD sF, FF ;flag set and wait for interrupt to be serviced

    ENABLE INTERRUPT ;Interrupts define 8KHz sample rate

    wait_int:

    COMPARE sF, FF

    JUMP Z, wait_int ;interrupt clears the flag

    JUMP warm_start ;wait for next interrupt

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FIFO:

    OUTPUT sA,FIFO_Data

    LOAD s5 ,01

    OUTPUT s5,FIFO_write

    LOAD s5 ,00

    OUTPUT s5,FIFO_write

    FETCH sA,USER_MODE_C

    OUTPUT sA,FIFO_Data

    LOAD s5 ,01

    OUTPUT s5,FIFO_write

    LOAD s5 ,00

    OUTPUT s5,FIFO_write

    RETURN

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FIFO_data_in:

    CALL FIFO_IN

    ;-------------------------

    LOAD s3,01

    OUTPUT s3, FIFO_reset

    LOAD s3,00

    OUTPUT s3, FIFO_reset

    RETURN

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FIFO_IN: INPUT s9, FIFO_Data_IN

    LOAD s3,01

  • 74

    OUTPUT s3, FIFO_read

    LOAD s3,00

    OUTPUT s3, FIFO_read

    RETURN

    ;===================手動切換紅綠燈模式====================

    USER_CONTROL: TEST s9,02

    CALL c,DIR_CHANGE_MODE

    TEST s7,20

    CALL c,DIR_CHANGE_FIR

    TEST s7,20

    CALL z,DIR_CHANGE_SEC

    RETURN

    ;***********************

    DIR_CHANGE_MODE:

    ADD s7,01

    RETURN

    ;***********************先黃燈五秒後,在持續幹道綠燈,支道紅燈模式

    DIR_CHANGE_SEC:

    COMPARE s8,01

    JUMP Z,YELLOW_OVER_SEC

    FETCH s1,ST2_COUNT_L

    FETCH s3,ST2_L

    LOAD sA,41

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING5

    LOAD s6,00

    SUB s1,01

    STORE s1,ST2_COUNT_L

    NOTHING5: COMPARE s1,00

    JUMP NZ, NE_T1

    LOAD s1,00

    LOAD s8,01

    STORE s3,ST2_COUNT_L

    JUMP NE_T1

    YELLOW_OVER_SEC:

    LOAD sA,81

    STORE sA,USER_MODE_C

    LOAD sA,00

    CALL FIFO

  • 75

    JUMP NE_T1

    NE_T1:

    RETURN

    ;***********************先黃燈五秒後,在持續幹道紅燈,支道綠燈模式

    DIR_CHANGE_FIR:

    COMPARE s8,02 ;給 pico3 的狀態

    JUMP Z,YELLOW_OVER_FIR

    FETCH s1,ST4_COUNT_L

    FETCH s3,ST4_L

    LOAD sA,C1

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING6

    LOAD s6,00

    SUB s1,01

    STORE s1,ST4_COUNT_L

    NOTHING6:

    COMPARE s1,00

    JUMP NZ, NE_T2

    LOAD s8,02

    LOAD s1,00

    STORE s3,ST4_COUNT_L

    JUMP NE_T2

    YELLOW_OVER_FIR:

    LOAD sA,01

    STORE sA,USER_MODE_C

    LOAD sA,00

    CALL FIFO

    JUMP NE_T2

    NE_T2:

    RETURN

    ;=========================================手動更變秒數模式

    USER_CHANGE:

    TEST s9,10

    CALL c,DIR_COUNT_MODE

    TEST s9,20

    CALL c,DIR_COUNT_ADD

    TEST s9,40

    CALL C,DIR_COUNT_SUB

  • 76

    TEST s7,20

    JUMP z,FIR_SHOW

    FETCH s1,ST1_L

    LOAD sA,44

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    JUMP OK_SHOW

    FIR_SHOW: FETCH s3,ST3_L

    LOAD sA,C2

    STORE sA,USER_MODE_C

    LOAD sA,s3

    CALL FIFO

    OK_SHOW:

    RETURN

    ;**************************************切換更改幹道還是支道秒數

    DIR_COUNT_MODE:

    ADD s7,01

    RETURN

    ;***************************************************秒數加一區

    DIR_COUNT_ADD:

    TEST sB,01

    JUMP C,WAIT_NEXT

    TEST s7,20 ;判斷要加幹道還是支道

    JUMP z,FIR_ADD

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~幹道

    FETCH s1,ST1_L

    ADD s1,01

    COMPARE s1,63

    JUMP NZ,OVERLOOP

    LOAD s1,63

    OVERLOOP: STORE s1,ST1_L

    STORE s1,ST1_COUNT_L

    LOAD sA,44

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    JUMP OK_ADD

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~支道

    FIR_ADD: FETCH s3,ST3_L

    ADD s3,01

    COMPARE s3,63

  • 77

    JUMP NZ,OVERLOOP1

    LOAD s3,63

    OVERLOOP1:

    STORE s3,ST3_L

    STORE s3,ST3_COUNT_L

    LOAD sA,C2

    STORE sA,USER_MODE_C

    LOAD sA,s3

    CALL FIFO

    JUMP OK_ADD

    OK_ADD: LOAD sB,01

    WAIT_NEXT:

    RETURN

    ;************************************************秒數減一區

    DIR_COUNT_SUB:

    TEST sB,01

    JUMP C,WAIT_NEXT1

    TEST s7,20 ;判斷要減支道還是幹道

    JUMP z,FIR_SUB

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~幹道

    FETCH s1,ST1_L

    COMPARE s1,00

    JUMP Z,OVERLOOP2

    SUB s1,01

    JUMP NONOVERLOOP

    OVERLOOP2: LOAD s1,00

    NONOVERLOOP: STORE s1,ST1_L

    STORE s1,ST1_COUNT_L

    LOAD sA,44

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    JUMP OK_SUB

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~支道

    FIR_SUB: FETCH s3,ST3_L

    COMPARE s3,00

    JUMP Z,OVERLOOP3

    SUB s3,01

    JUMP NONOVERLOOP1

    OVERLOOP3: LOAD s3,00

    NONOVERLOOP1: STORE s3,ST3_L

    STORE s3,ST3_COUNT_L

    LOAD sA,C2

  • 78

    STORE sA,USER_MODE_C

    LOAD sA,s3

    CALL FIFO

    JUMP OK_SUB

    OK_SUB: LOAD sB,01

    WAIT_NEXT1:

    RETURN

    ;==================每 10ms 中斷一次========================

    ISR:

    ;***************************************在更變秒數區,消除中斷使

    按鈕有連續彈跳的狀態

    ADD sC,01

    COMPARE sC,32

    JUMP NZ,NON_RES

    LOAD sB,00

    LOAD sC,00

    ;***************************************

    NON_RES:

    CALL FIFO_data_in

    TEST s9,01 ;接收道 pico2 值,判斷指撥 1、2 是否有按

    JUMP NZ,USER_CONTROL_MODE

    TEST s9,80

    JUMP NZ,USER_CHANGE_COUNT_MODE

    ;********************************************

    COMPARE s0,00 ;狀態機 四個狀態輪流

    JUMP Z,ST1

    COMPARE s0,01

    JUMP Z,ST2

    COMPARE s0,02

    JUMP Z,ST3

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~狀態4

    ST4: FETCH s1,ST4_COUNT_L

    FETCH s3,ST4_L

    LOAD sA,C0

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING4

    LOAD s6,00

    SUB s1,01

    STORE s1,ST4_COUNT_L

  • 79

    NOTHING4: COMPARE s1,00

    JUMP NZ, NE_T

    LOAD s0,00

    LOAD s1,00

    STORE s3,ST4_COUNT_L

    JUMP NE_T

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~狀態3

    ST3: FETCH s1,ST3_COUNT_L

    FETCH s3,ST3_L

    LOAD sA,80

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING3

    LOAD s6,00

    SUB s1,01

    STORE s1,ST3_COUNT_L

    NOTHING3:

    COMPARE s1,00

    JUMP NZ, NE_T

    LOAD s0,03

    LOAD s1,00

    STORE s3,ST3_COUNT_L

    JUMP NE_T

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~狀態2

    ST2: FETCH s1,ST2_COUNT_L

    FETCH s3,ST2_L

    LOAD sA,40

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING2

    LOAD s6,00

    SUB s1,01

    STORE s1,ST2_COUNT_L

    NOTHING2: COMPARE s1,00

    JUMP NZ, NE_T

    LOAD s0,02

  • 80

    LOAD s1,00

    STORE s3,ST2_COUNT_L

    JUMP NE_T

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~狀態1

    ST1: FETCH s1,ST1_COUNT_L ;秒

    FETCH s3,ST1_L ;初始值

    LOAD sA,00

    STORE sA,USER_MODE_C

    LOAD sA,s1

    CALL FIFO

    ADD s6,01

    COMPARE s6,64

    JUMP NZ,NOTHING1

    LOAD s6,00

    SUB s1,01

    STORE s1,ST1_COUNT_L

    NOTHING1:

    COMPARE s1,00

    JUMP NZ, NE_T

    LOAD s0,01

    LOAD s1,00

    STORE s3,ST1_COUNT_L

    JUMP NE_T

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    USER_CONTROL_MODE:

    CALL USER_CONTROL

    JUMP NE_T

    USER_CHANGE_COUNT_MODE:

    CALL USER_CHANGE

    JUMP NE_T

    NE_T:

    LOAD sF, 00 ;clear flag

    RETURNI ENABLE

    ADDRESS 3FF

    JUMP ISR

    PICO-2: CONSTANT switch_port,00

    CONSTANT BTN_LEFT,08

    CONSTANT BTN_RIGHT,02

    CONSTANT LED,88

    CONSTANT FIFO_write, A0

    CONSTANT FIFO_Data , A1

  • 81

    CONSTANT MATRIX_MODE,87

    CONSTANT delay_1us_constant, 0B

    LOAD s6,0F

    warm_start: LOAD sF, FF

    ENABLE INTERRUPT ;開啟中斷

    wait_int ;判斷所以指撥即按鈕是否有按,有按即跳到該目的地

    INPUT sE, switch_port

    TEST sE, 01

    JUMP nz, GO_MODE

    TEST sE, 02

    JUMP nz, GO_RED

    TEST sE, 04

    JUMP nz, GO_CHANGE

    TEST sE, 08

    JUMP nz, GO_GREEN

    TEST sE, 40

    JUMP nz, GO_CHAN_MATRIX

    COMPARE sF, FF

    JUMP wait_int

    FIFO:

    OUTPUT s6,FIFO_Data

    LOAD s5 ,01

    OUTPUT s5,FIFO_write

    LOAD s5 ,00

    OUTPUT s5,FIFO_write

    RETURN

    ;

    delay_1us: LOAD s0, delay_1us_constant

    wait_1us: SUB s0, 01

    JUMP NZ, wait_1us

    RETURN

    delay_40us: LOAD s1, 28 ;40 x 1us = 40us

    wait_40us: CALL delay_1us

    SUB s1, 01

    JUMP NZ, wait_40us

    RETURN

    delay_1ms: LOAD s2, 19 ;25 x 40us = 1ms

    wait_1ms: CALL delay_40us

    SUB s2, 01

    JUMP NZ, wait_1ms

  • 82

    RETURN

    delay_20ms: LOAD s3, 14 ;20 x 1ms = 20ms

    wait_20ms: CALL delay_1ms

    SUB s3, 01

    JUMP NZ, wait_20ms

    RETURN

    delay_1s: LOAD s4, 05 ;5 x 20ms = 100ms

    wait_1s: CALL delay_20ms

    SUB s4, 01

    JUMP NZ, wait_1s

    RETURN

    GO_MODE:

    DISABLE INTERRUPT

    ;關閉中斷,等執行完彈跳時間過了以後,才再開啟中斷

    COMPARE s9,80

    JUMP NZ,NO0

    load s6,90

    CALL FIFO

    OUTPUT s6,LED

    CALL delay_1s

    NO0:

    JUMP warm_start

    GO_RED:

    DISABLE INTERRUPT

    COMPARE s9,80

    JUMP NZ,NO1

    load s6,C0

    CALL FIFO

    OUTPUT s6,LED

    NO1:

    JUMP warm_start

    GO_GREEN:

    DISABLE INTERRUPT

    COMPARE s9,80

    JUMP NZ,NO2

    load s6,A0

    CALL FIFO

    OUTPUT s6,LED

    NO2:

    JUMP warm_start

  • 83

    GO_CHANGE:

    DISABLE INTERRUPT

    COMPARE s9,01

    JUMP NZ,NO3

    load s6,03

    CALL FIFO

    OUTPUT s6,LED

    CALL delay_1s

    NO3:

    JUMP warm_start

    GO_CHAN_MATRIX:

    DISABLE INTERRUPT

    TEST s9,80

    JUMP C,NO4

    TEST S9,01

    JUMP C,NO4

    ADD s7,01

    OUTPUT s7,MATRIX_MODE

    CALL delay_1s

    NO4:

    JUMP warm_start

    ;=====================每 1.2ms 中斷一次====================

    ISR:

    INPUT sA,switch_port

    TEST sA,10 ;判斷指撥 1 on 或 off

    JUMP C,USER_CH

    TEST sA,20 ;判斷指撥 2 on 或 off

    JUMP C,USER_CON

    JUMP NO

    USER_CH: LOAD s9,01 ;將指撥 1 值由 fifo 傳給 pico1

    LOAD s6,s9

    CALL FIFO

    OUTPUT s6,LED

    JUMP FIN

    USER_CON: LOAD s9,80 ;將指撥 2 值由 fifo 傳給 pico1

    LOAD s6,s9

    CALL FIFO

  • 84

    OUTPUT s6,LED

    JUMP FIN

    NO: LOAD s9,00 ;將值由 fifo 傳給 pico1

    LOAD s6,s9

    CALL FIFO

    OUTPUT s6,LED

    FIN:

    LOAD sF, 00 ;clear flag

    RETURNI ENABLE

    ADDRESS 3FF

    JUMP ISR

    PICO-3: CONSTANT FIFO_read,B0

    CONSTANT FIFO_Data,B2

    CONSTANT FIFO_reset,B3

    CONSTANT LED_port,80

    CONSTANT BCD_CODE1,81

    CONSTANT BCD_CODE2,82

    CONSTANT STATE,83

    CONSTANT ST1_S,21

    CONSTANT ST2_S,22

    CONSTANT ST3_S,23

    CONSTANT ST4_S,24

    CONSTANT ST1C_S,25

    CONSTANT ST2C_S,26

    CONSTANT ST3C_S,27

    CONSTANT ST4C_S,28

    CONSTANT SPEED,29

    LOAD s8,3C

    STORE s8,ST1_S

    STORE s8,ST1C_S

    LOAD s8,05

    STORE s8,ST2_S

    STORE s8,ST2C_S

    STORE s8,ST4_S

    STORE s8,ST4C_S

    LOAD s8,1E

    STORE s8,ST3_S

    STORE s8,ST3C_S

    load s9,3C

  • 85

    warm_start: LOAD sF, FF ;flag set and wait for interrupt to be serviced

    ENABLE INTERRUPT ;Interrupts define 8KHz sample rate

    wait_int:

    COMPARE sF, FF

    JUMP Z, wait_int ;interrupt clears the flag

    JUMP warm_start

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FIFO_data_in:

    CALL FIFO

    OUTPUT s9, LED_port

    ;-------------------------

    LOAD s3,01

    OUTPUT s3, FIFO_reset

    LOAD s3,00

    OUTPUT s3, FIFO_reset

    RETURN

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FIFO: INPUT s9, FIFO_Data

    LOAD s3,01

    OUTPUT s3, FIFO_read

    LOAD s3,00

    OUTPUT s3, FIFO_read

    INPUT s8, FIFO_Data

    LOAD s3,01

    OUTPUT s3, FIFO_read

    LOAD s3,00

    OUTPUT s3, FIFO_read

    RETURN

    ;======================轉 bcd 碼==========================

    TO_BCD: LOAD sA,s6

    LOAD sB,0A

    LOAD sC,00

    LOAD sD,00

    AA2:

    SUB sA,sB

    JUMP C,AA1

    ADD sC,10

    ADD sD,0A

    JUMP AA2

    AA1:

    LOAD sA,s6

    SUB sA,sD

    ADD sA,sC

    RETURN

  • 86

    ;=======================控制小綠人走速====================

    SPEED: LOAD s2,s1

    SUB s2,06

    JUMP NC,SLOW

    LOAD s3,01

    OUTPUT s3,SPEED

    JUMP SS

    SLOW: LOAD s3,00

    OUTPUT s3,SPEED

    SS:

    RETURN

    ;==================每 10ms 中斷一次========================

    ISR: CALL FIFO_data_in

    LOAD s4,s8

    AND s4,C0

    OUTPUT s4,STATE ;將目前狀態輸出對應相對值(VHDL 的 led)

    ;*******************************

    TEST s8,01 ;對應狀態判斷七斷相對值

    JUMP C,DOWN_FIVE

    TEST s8,02

    JUMP C,SEC_NUM

    TEST s8,04

    JUMP C,FIR_NUM

    COMPARE s4,40

    JUMP Z,DOWN_FIVE

    COMPARE s4,C0

    JUMP Z,DOWN_FIVE

    COMPARE s4,80

    JUMP Z,DOWN_30

    ;*******************************

    LOAD s1,s9 ;幹道比支道慢五秒

    CALL SPEED

    LOAD s6,s1

    CALL TO_BCD

    OUTPUT sA,BCD_CODE1

    ADD s6,05

    CALL TO_BCD

    OUTPUT sA,BCD_CODE2

    JUMP NEXT

    DOWN_30: LOAD s1,s9 ;幹道比支道快五秒

    CALL SPEED

    LOAD s6,s1

    CALL TO_BCD

    OUTPUT sA,BCD_CODE2

  • 87

    ADD s6,05

    CALL TO_BCD

    OUTPUT sA,BCD_CODE1

    JUMP NEXT

    DOWN_FIVE: LOAD s1,s9 ;幹道與支道相等秒

    LOAD s6,s1

    CALL TO_BCD

    OUTPUT sA,BCD_CODE1

    OUTPUT sA,BCD_CODE2

    JUMP NEXT

    FIR_NUM: LOAD s1,s9 ;幹道亮,支道滅

    LOAD s6,s1

    CALL TO_BCD

    OUTPUT sA,BCD_CODE1

    LOAD sA,FF

    OUTPUT sA,BCD_CODE2

    JUMP NEXT

    SEC_NUM: LOAD s1,s9 ;幹道滅,支道亮

    LOAD s6,s1

    CALL TO_BCD

    OUTPUT sA,BCD_CODE2

    LOAD sA,FF

    OUTPUT sA,BCD_CODE1

    JUMP NEXT

    NEXT:

    LOAD sF, 00 ;clear flag

    RETURNI ENABLE

    ADDRESS 3FF

    JUMP ISR

    附錄二:純 FPGA library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity pig_need is Port ( clk : in std_logic; switch2 : in std_logic; btn5,btn3,btn2,btn1 : in std_logic; vccout : out STD_LOGIC_VECTOR(1 downto 0); sevenout : out STD_LOGIC_VECTOR(3 downto 0); SK : out STD_LOGIC; R1 : out STD_LOGIC; G1 : out STD_LOGIC; EN : out STD_LOGIC; ccled : out std_logic_vector(3 downto 0); led : out std_logic_vector(5 downto 0); hcled : out std_logic_vector(3 downto 0); LA,LB,LC,LD : out STD_LOGIC;

  • 88

    LT : out STD_LOGIC); end pig_need; architecture Behavioral of pig_need is signal x : integer range 0 to 39 :=0; signal ccc : integer range 0 to 300 :=32; signal y : STD_LOGIC_VECTOR(4 downto 0):="00000"; signal sk1 : STD_LOGIC:='1'; signal lt1 : STD_LOGIC:='0'; signal en1 : STD_LOGIC:='1'; signal a,b,c,d,e,iclk,cclk,iiclk,iiiclk,iiiiclk : STD_LOGIC:='0'; signal div : STD_LOGIC_VECTOR(30 downto 0):="0000000000000000000000000000000"; signal count,llllcount,lllcount,llcount,lcount,hhhhcount,hhhcount,hhcount,hcount,f,cc : integer range 0 to 300:=0; signal ddd,ddd0,ddd1,change,swcount : integer range 0 to 20:=0; signal iclk1s,iclk125ms,iclk500ms,iclk250ms : integer range 0 to 50000000; signal count1 : STD_LOGIC_VECTOR(3 downto 0):="0101"; signal count2 : STD_LOGIC_VECTOR(3 downto 0):="0110"; signal count3 : STD_LOGIC_VECTOR(3 downto 0):="0000"; signal count4 : STD_LOGIC_VECTOR(3 downto 0):="0110"; signal count21,count43 : STD_LOGIC_VECTOR(7 downto 0):="00000000"; signal aa,bb : STD_LOGIC:='0'; type display is (an1,an2,an3,an4); signal state : display; signal A10 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A11 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A12 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A13 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A14 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A15 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A16 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A17 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A18 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A19 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A110 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A111 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A112 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A113 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A114 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; signal A115 : STD_LOGIC_VECTOR(0 to 31):="11111111111111111111111111111111"; ----------------------------------------------------------:="0000000000000000";

  • 89

    signal G10 : STD_LOGIC_VECTOR(0 to 15):="1111111111111111"; signal G11 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111"; signal G12 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111"; signal G13 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111"; signal G14 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111"; signal G15 : STD_LOGIC_VECTOR(0 to 15):="1111111001111111"; signal G16 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111"; signal G17 : STD_LOGIC_VECTOR(0 to 15):="1111000000001111"; signal G18 : STD_LOGIC_VECTOR(0 to 15):="1110000000000111"; signal G19 : STD_LOGIC_VECTOR(0 to 15):="1100110000110011"; signal G110 : STD_LOGIC_VECTOR(0 to 15):="1100110000110011"; signal G111 : STD_LOGIC_VECTOR(0 to 15):="1111110000111111"; signal G112 : STD_LOGIC_VECTOR(0 to 15):="1111100000011111"; signal G113 : STD_LOGIC_VECTOR(0 to 15):="1111001111001111"; signal G114 : STD_LOGIC_VECTOR(0 to 15):="1111001111001111"; signal G115 : STD_LOGIC_VECTOR(0 to 15):="1110001111000111"; -----------------------------------------------------------:="0000000000000000"; signal G10a : STD_LOGIC_VECTOR(0 to 15):="1111111111111111"; signal G11a : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G12a : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G13a : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G14a : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G15a : STD_LOGIC_VECTOR(0 to 15):="1111100011111111"; signal G16a : STD_LOGIC_VECTOR(0 to 15):="1111100000001111"; signal G17a : STD_LOGIC_VECTOR(0 to 15):="1111000000100111"; signal G18a : STD_LOGIC_VECTOR(0 to 15):="1110011000110011"; signal G19a : STD_LOGIC_VECTOR(0 to 15):="1100111000111001"; signal G110a : STD_LOGIC_VECTOR(0 to 15):="1001111000111100"; signal G111a : STD_LOGIC_VECTOR(0 to 15):="1111110010011111"; signal G112a : STD_LOGIC_VECTOR(0 to 15):="1111110011001111"; signal G113a : STD_LOGIC_VECTOR(0 to 15):="1111100111100011"; signal G114a : STD_LOGIC_VECTOR(0 to 15):="1111001111111001"; signal G115a : STD_LOGIC_VECTOR(0 to 15):="1000011111110011"; -----------------------------------------------------------:="0000000000000000"; signal G10b : STD_LOGIC_VECTOR(0 to 15):="1111111111111111"; signal G11b : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G12b : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G13b : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G14b : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G15b : STD_LOGIC_VECTOR(0 to 15):="1111100001111111"; signal G16b : STD_LOGIC_VECTOR(0 to 15):="1111100000011111"; signal G17b : STD_LOGIC_VECTOR(0 to 15):="1111100001001111"; signal G18b : STD_LOGIC_VECTOR(0 to 15):="1111100000100111"; signal G19b : STD_LOGIC_VECTOR(0 to 15):="1111100000100111"; signal G110b : STD_LOGIC_VECTOR(0 to 15):="1111001100011111"; signal G111b : STD_LOGIC_VECTOR(0 to 15):="1111111000011111"; signal G112b : STD_LOGIC_VECTOR(0 to 15):="1111110011001111"; signal G113b : STD_LOGIC_VECTOR(0 to 15):="1111100001100011"; signal G114b : STD_LOGIC_VECTOR(0 to 15):="1111111001111001"; signal G115b : STD_LOGIC_VECTOR(0 to 15):="1111100001111001"; -----------------------------------------------------------:="0000000000000000"; signal G10c : STD_LOGIC_VECTOR(0 to 15):="1111111111111111"; signal G11c : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G12c : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G13c : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G14c : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G15c : STD_LOGIC_VECTOR(0 to 15):="1111100111111111"; signal G16c : STD_LOGIC_VECTOR(0 to 15):="1111100011111111"; signal G17c : STD_LOGIC_VECTOR(0 to 15):="1111100001111111"; signal G18c : STD_LOGIC_VECTOR(0 to 15):="1111110000111111"; signal G19c : STD_LOGIC_VECTOR(0 to 15):="1111110000111111"; signal G110c : STD_LOGIC_VECTOR(0 to 15):="1111111000011111";

  • 90

    signal G111c : STD_LOGIC_VECTOR(0 to 15):="1111110000011111"; signal G112c : STD_LOGIC_VECTOR(0 to 15):="1111100110001111"; signal G113c : STD_LOGIC_VECTOR(0 to 15):="1111111110001111"; signal G114c : STD_LOGIC_VECTOR(0 to 15):="1111111101101111"; signal G115c : STD_LOGIC_VECTOR(0 to 15):="1111111100001111"; -----------------------------------------------------------:="0000000000000000"; signal G10d : STD_LOGIC_VECTOR(0 to 15):="1111111111111111"; signal G11d : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G12d : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G13d : STD_LOGIC_VECTOR(0 to 15):="1110000011111111"; signal G14d : STD_LOGIC_VECTOR(0 to 15):="1111000111111111"; signal G15d : STD_LOGIC_VECTOR(0 to 15):="1111100011111111"; signal G16d : STD_LOGIC_VECTOR(0 to 15):="1111100000000111"; signal G17d : STD_LOGIC_VECTOR(0 to