# 自學筆記(FPGA) ## 目錄 * [第一篇 安裝FPGA程式](https://hackmd.io/@KevinT/S14wiUnO3) * [第二篇 基礎概念](https://hackmd.io/@KevinT/H1a0sUh_2) * [第三篇 在c語言中沒有的東西](https://hackmd.io/@KevinT/SkizRGKo2) * [第四篇 用加法器來理解基本語法架構](https://hackmd.io/@KevinT/rJvT1_3_2) * [第五篇 除頻器(Frequency Divider)](https://hackmd.io/@KevinT/HJCkmRPoh) * [第六篇 比較器(Comparator)](https://hackmd.io/@KevinT/HyDin7Ks3) * [第七篇 計數器(Counter)](https://hackmd.io/@KevinT/rkDEH1_in) * [第八篇 暫存器(Register)](https://hackmd.io/@KevinT/HkqN_1Osh) * [第九篇 多工器四對一(MUX 4X1)](https://hackmd.io/@KevinT/S1yNdxuin) * [第十篇 FSM-1(Finite State Machine,有限狀態機)](https://hackmd.io/@KevinT/HyT4kQtj2) * [第十一篇 FSM-2(Finite State Machine,有限狀態機)](https://hackmd.io/@KevinT/BJ1lvXFsn) ### 第一篇 安裝FPGA程式 我們選用的程式是 ISE14.7 Windows 8/8.1/10 OS 1. ==下載== 從此處下載 (https://www.google.com/url?q=https%3A%2F%2Fwww.xilinx.com%2Fmember%2Fforms%2Fdownload%2Fxef.html%3Ffilename%3DXilinx_ISE_DS_Win_14.7_1015_1.tar&sa=D&sntz=1&usg=AOvVaw1QNKdV3hWOsKrqhSTQn69I) 2. ==安裝== 成功下載之後解壓縮 找到檔案之後開啟這個程式 ![](https://hackmd.io/_uploads/rJI6rSju3.png) 然後開始下載,裡面看到叫你勾選的同意都勾起來。 選第一個WebPACK ![](https://hackmd.io/_uploads/S1d2ZInd3.png) 這邊我建議是三個都勾起來 因為現在已經沒有供應WinPCap了 所以可以直接一起下載 ![](https://hackmd.io/_uploads/r1_nb8nu3.png) 然後同意之後等待下載完成 ![](https://hackmd.io/_uploads/HydhW83O2.png) 然後點開程式(去搜尋找) 3. ==授權== 點開之後會有一個頁面"Manage Xilinx Licenses"叫你授權東西就依照他的指示並點選第二個 ![](https://hackmd.io/_uploads/BkcjMUnOh.png) 會叫你到官方網站註冊帳號,註冊並登入完之後來到授權頁面 找到"ISE WebPACK License"並點選! 完成之後下載一個文件 ![](https://hackmd.io/_uploads/BySdm83On.jpg) 回到Manage Xilinx Licenses並切到 Manage Licenses點擊左上方Load License...選取剛剛所下載的文件,這樣就可以完成授權了。 ### 第二篇 基礎概念 我們所寫得東西叫做Verilog,因為沒有實體的板子,所以我們都是用電腦來做出模擬 我們把基礎分成幾個部分來理解 * ==Verilog的架構== module 模組名稱(輸入輸出埠清單); 輸入輸出埠的宣告 -> input, output, inout 變數資料型態宣告 -> wire, reg, … 引用較低階的模組 邏輯閘階層之描述 資料流階層之描述 function 或 task 的宣告 行為階層之描述區塊 endmodule 基礎的Verilog語法語C語言相似 * ==Verilog語法== 常見關鍵字 ![](https://hackmd.io/_uploads/B1460InOh.png) (資料來源:網路) * ==命名規則== 第一個字元必須是英文字母 第二個之後的字元可以是英文字母、數字、底線、或是$ * ==基本資料型態== wire:代表一條接線 wand:Wired-AND wor:Wired-OR reg:暫存器 主要功能為用於維持電路中的某個值(always中) integer, real, …:用於計算的過程 <font color="#f00">**wire 的特性**</font> 連接硬體元件之連接線 變數必須被驅動,才能改變它的內容 除非被宣告為一向量,否則wire 型態的變數內定為一個位元的值,且其內定值為Z <font color="#f00">**reg 的特性**</font> 功能和一般程式語言中的變數類似,可以直接給定一個數值 除非被宣告為一向量,否則reg 型態的變數內定為 <font color="#f00">**使用 wire 或 reg 的時機**</font> 使用wire所宣告的變數必須配合assign敘述來改變其值,且不能在always區塊中作為敘述的左值(Lvalue) 使用reg所宣告的變數必須使用在always區塊中作為敘述的左值 * ==輸入輸出埠== 在Verilog 在Verilog Verilog 中,所有輸入輸出埠 所有輸入輸出埠(input、output、inout)的內定資料型態為wire 若需將訊號的值存起來,則必須將其資料型態宣告為reg 由於輸出入埠(inout)可用於與其他模組進行連接,因此可以將其視為在模組內外相互連接的兩個部分 * ==資料流模型的敘述== 在此模型中,常用的敘述:assign :assign 驅動某個值到wire、wand、wor 或tri 用於描述組合邏輯電路 必須避免使用迴路式的寫法:assign a = b + a; (我們用的是這個) 可用預算子與邏輯設計相同(需要時再查詢即可) * ==行為模型的敘述== 只需考慮電路模組的功能,而不需考慮其硬體的 ,而不需考慮其硬體的詳細內容 以事件為基礎的時序控制 事件: 接線或暫存器的值被改變 模組的輸入埠接收到新的值 可電路合成的控制方式:正緣、負緣、訊號值改變 ### 第三篇 在c語言中沒有的東西 ==always敘述== 1. 驅動某值至reg( 等號的左式必為reg,右式可為net 或 reg ) 2. 行為層次的描述方式,可用於敘述組合邏輯和序向邏輯 3. 事件與事件之間需用”or”或”逗號 , ”分開 4. 當”事件”有變化時( 0→1、1→0 ),則會執行”敘述” 5. 事件中可以使用正緣觸發posedge(0→1)和負緣觸發negedge(1→0) 6. 若寫成always @(* ) 或 always @* 代表always內任一變化即執行敘述 ![](https://hackmd.io/_uploads/SkreaGtjn.png) ==case、casex與casez敘述== 1. expr可為定值或變數,可放連結運算子 2. 不允許expr中有x或z 3. 允許casez中的item值除了”0” “1”外,還可以使用z 4. 允許casex中的item值除了”0” “1” “z”外,還可以使用x ![](https://hackmd.io/_uploads/BkPW6MKo2.png) 應用 ![](https://hackmd.io/_uploads/rkg6TfFih.png) ==Blocking/Non-Blocking敘述== 1. Blocking ( = ),具有順序性,敘述會與先後有關係 ( 順序處理 ) 2. Non-Blocking ( <= ),具有同時性,敘述與先後沒有關係 ( 平行處理 ) ![](https://hackmd.io/_uploads/B1wrTzFon.png) 應用 ![](https://hackmd.io/_uploads/H1dy0zFin.png) (資料來源:[網路](https://hom-wang.gitbooks.io/verilog-hdl/content/Chapter_05.html)) ### 第四篇 用加法器來理解基本語法架構 一位元加法器 ![](https://hackmd.io/_uploads/r1AcIwn_n.png) * ==關鍵字介紹== module(宣告) adder1(名字) input(輸入腳位)-> a, b, cin 三個輸入 output(輸出)-> cout(進位), s(和) assign(只要打公式都需要在前面加) endmodule(結束) ^ ->(xor), & ->(and), | ->(or) 用真值表化簡卡諾圖來解釋加法器原理 ![](https://hackmd.io/_uploads/Bk_70P2uh.png)(圖片來源:網路) 化簡後就是程式裡面的公式 ![](https://hackmd.io/_uploads/SJDlhP3O2.png) ![](https://hackmd.io/_uploads/BySqhDnuh.png) 上面兩張圖是兩個公式分別的卡諾圖 S的部分因為是取兩兩不同所以都是用xor cout的部分經過化簡可以得出上面的公式 再來用一位元加法器去延伸到八位元加法器 ![](https://hackmd.io/_uploads/Syz7-dnO2.png) * ==關鍵字介紹== 輸入[7:0] a 和 [7:0] b代表的是腳位總共8個 0~7總共八個位元輸入 輸出[7:0] sum也是共八個位元輸出 wire(接線) c0~6總共六個去做延伸到下一個位元 而下面用到的公式則是套用了一位元加法器的公式 adder1後面的a0~7則是每個一位元加法器的名字 adder1裡面的東西需要與一位元加法器內每個宣告的東西對應上 從a[0], b[0]開始加上cin 並輸出c0(進位)與[0] 裡面的cin則是用c0~6一一個個延續到下一個加法器 加到a[7], b[7]並最後得出cout 和sum[0~7]就完成了八位元加法器 ### 第五篇 除頻器(Frequency Divider) 因為所使用的FPGA板內置的clock頻率過高(大多為MegaHz) 所以必須使用除頻器去降低clock的頻率來認我們使用(用於計數時) ![](https://hackmd.io/_uploads/SJWACpwsn.png) inpout clk就是板子所給出的clock,由於頻率過高,所以中間的那個步驟就是對除他 Q從零到24,對他除2共25次讓他的頻率達到我們可以使用的大小(次數會因板子內的clock而異) always =>類似迴圈,令Q每次都加一 ![](https://hackmd.io/_uploads/SJxieRvo2.png) 原理就是把clock的週期變長來使他的頻率變小 ### 第六篇 比較器(Comparator) 用於比較輸入訊號的大小,並且應應三種不同的情況輸出不同的東西。 舉例: A,B是輸入,而輸出是0 1 2三地不同的數 * A>B,輸出 0 * A=B,輸出 1 * A<B,輸出 2 ![](https://hackmd.io/_uploads/ByiInQKj3.png) ### 第七篇 計數器(Counter) 用於計算中所需要用到數字時輸入數字用的,這邊所使用的計數器使用的是用按壓時間來測定的計數器(若是要改成用按壓次數的就直接Q<=Q+1就好了) ![](https://hackmd.io/_uploads/BJ4XJJush.png) en、rst為兩顆按鈕,按下rst時c就會歸零(8'b0是8bit=0的意思),按下en每一個clock所設定的c就會加一,就次達成計數器的功能。 ### 第八篇 暫存器(Register) 用於儲存輸入數字用的一組程式碼,可以配合上一篇的計數器來做使用 ![](https://hackmd.io/_uploads/rJWaSJuo3.png) 配合輸入的數字只要按下save那個按紐就會把input的數字紀錄為output。 ### 第九篇 多工器四對一(MUX 4X1) 透過select來控制輸出的訊號,可用於多訊號輸入時控制要輸出哪個 並且sel是二進位控制(00,01,10,11會輸出不同的訊號) ![](https://hackmd.io/_uploads/BkNPLxdsn.png) 示意圖 ![](https://hackmd.io/_uploads/rkYZUl_j2.png) 上圖的的輸入每個都設定為4位元,所以輸入設定為[15;0] (共16位元) 而輸出為一個4位元訊號所以為[3:0] ### 第十篇 FSM-1(Finite State Machine,有限狀態機) 我們在講道有限狀態機時要先來說一下甚麼是狀態機,一般在網路上分成三種狀態機 * 一段式狀態機:就是將整個狀態機寫到一個always模塊中去,這種情形用於簡單的狀態機的實現。 * 兩段式狀態機:將輸入和狀態跳轉寫到一個模塊中,將輸出寫到另一個模塊中。 * 三段式狀態機:按照狀態機的結構圖來寫,即輸入部分,狀態跳轉部分和輸出部分。 而這邊討論的有限狀態機就是屬於第三種 **Moore型狀態機** 根據需求,可以確定出4個狀態,分別是①其他狀態,②檢測到AAH,③檢測到BBH,④檢測到CCH,將四種狀態分別命名為idle,aa,bb,cc,那麼可以根據需求畫出如下狀態轉移圖。 ![](https://hackmd.io/_uploads/rkdwVGKo2.png)(圖片來源:網路) **Mealy型狀態機** 將Moore型狀態機轉換為Mealy型狀態機,可以去掉cc狀態,然後得到如下的狀態轉化圖。 ![](https://hackmd.io/_uploads/SJYC4zYjn.png)(圖片來源:網路) Mealy型狀態機的狀態機輸出會比Moore型狀態機來的好。 我們比較常用到的有限狀態機就是Mealy型狀態機,而它的原理簡單來說就是==在幾種有限的狀態內並把狀態編號,用按鈕或其他方式控制是否前往下一個狀態,並在這些狀態內循環。== ### 第十一篇 FSM-(Finite State Machine,有限狀態機) 應用: 流程圖 ![](https://hackmd.io/_uploads/rkFnXQFi2.png) 程式碼 ![](https://hackmd.io/_uploads/H18-HQtsn.png) 在這之中可以看到要進到下一個狀態用的是按鈕來控制,而如過沒按下按鈕就保持不變。 而如果有些地方想要讓他過一下再就改變狀態的話,我們可以把它改成用clock來判定,那麼每次clock一到就會改變狀態。3