# 自學筆記(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. ==安裝==
成功下載之後解壓縮
找到檔案之後開啟這個程式

然後開始下載,裡面看到叫你勾選的同意都勾起來。
選第一個WebPACK

這邊我建議是三個都勾起來 因為現在已經沒有供應WinPCap了 所以可以直接一起下載

然後同意之後等待下載完成

然後點開程式(去搜尋找)
3. ==授權==
點開之後會有一個頁面"Manage Xilinx Licenses"叫你授權東西就依照他的指示並點選第二個

會叫你到官方網站註冊帳號,註冊並登入完之後來到授權頁面
找到"ISE WebPACK License"並點選!
完成之後下載一個文件

回到Manage Xilinx Licenses並切到 Manage Licenses點擊左上方Load License...選取剛剛所下載的文件,這樣就可以完成授權了。
### 第二篇 基礎概念
我們所寫得東西叫做Verilog,因為沒有實體的板子,所以我們都是用電腦來做出模擬
我們把基礎分成幾個部分來理解
* ==Verilog的架構==
module 模組名稱(輸入輸出埠清單);
輸入輸出埠的宣告 -> input, output, inout
變數資料型態宣告 -> wire, reg, …
引用較低階的模組
邏輯閘階層之描述
資料流階層之描述
function 或 task 的宣告
行為階層之描述區塊
endmodule
基礎的Verilog語法語C語言相似
* ==Verilog語法==
常見關鍵字

(資料來源:網路)
* ==命名規則==
第一個字元必須是英文字母
第二個之後的字元可以是英文字母、數字、底線、或是$
* ==基本資料型態==
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內任一變化即執行敘述

==case、casex與casez敘述==
1. expr可為定值或變數,可放連結運算子
2. 不允許expr中有x或z
3. 允許casez中的item值除了”0” “1”外,還可以使用z
4. 允許casex中的item值除了”0” “1” “z”外,還可以使用x

應用

==Blocking/Non-Blocking敘述==
1. Blocking ( = ),具有順序性,敘述會與先後有關係 ( 順序處理 )
2. Non-Blocking ( <= ),具有同時性,敘述與先後沒有關係 ( 平行處理 )

應用

(資料來源:[網路](https://hom-wang.gitbooks.io/verilog-hdl/content/Chapter_05.html))
### 第四篇 用加法器來理解基本語法架構
一位元加法器

* ==關鍵字介紹==
module(宣告)
adder1(名字)
input(輸入腳位)-> a, b, cin 三個輸入
output(輸出)-> cout(進位), s(和)
assign(只要打公式都需要在前面加)
endmodule(結束)
^ ->(xor), & ->(and), | ->(or)
用真值表化簡卡諾圖來解釋加法器原理
(圖片來源:網路)
化簡後就是程式裡面的公式


上面兩張圖是兩個公式分別的卡諾圖
S的部分因為是取兩兩不同所以都是用xor
cout的部分經過化簡可以得出上面的公式
再來用一位元加法器去延伸到八位元加法器

* ==關鍵字介紹==
輸入[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的頻率來認我們使用(用於計數時)

inpout clk就是板子所給出的clock,由於頻率過高,所以中間的那個步驟就是對除他
Q從零到24,對他除2共25次讓他的頻率達到我們可以使用的大小(次數會因板子內的clock而異)
always =>類似迴圈,令Q每次都加一

原理就是把clock的週期變長來使他的頻率變小
### 第六篇 比較器(Comparator)
用於比較輸入訊號的大小,並且應應三種不同的情況輸出不同的東西。
舉例:
A,B是輸入,而輸出是0 1 2三地不同的數
* A>B,輸出 0
* A=B,輸出 1
* A<B,輸出 2

### 第七篇 計數器(Counter)
用於計算中所需要用到數字時輸入數字用的,這邊所使用的計數器使用的是用按壓時間來測定的計數器(若是要改成用按壓次數的就直接Q<=Q+1就好了)

en、rst為兩顆按鈕,按下rst時c就會歸零(8'b0是8bit=0的意思),按下en每一個clock所設定的c就會加一,就次達成計數器的功能。
### 第八篇 暫存器(Register)
用於儲存輸入數字用的一組程式碼,可以配合上一篇的計數器來做使用

配合輸入的數字只要按下save那個按紐就會把input的數字紀錄為output。
### 第九篇 多工器四對一(MUX 4X1)
透過select來控制輸出的訊號,可用於多訊號輸入時控制要輸出哪個
並且sel是二進位控制(00,01,10,11會輸出不同的訊號)
 示意圖

上圖的的輸入每個都設定為4位元,所以輸入設定為[15;0] (共16位元)
而輸出為一個4位元訊號所以為[3:0]
### 第十篇 FSM-1(Finite State Machine,有限狀態機)
我們在講道有限狀態機時要先來說一下甚麼是狀態機,一般在網路上分成三種狀態機
* 一段式狀態機:就是將整個狀態機寫到一個always模塊中去,這種情形用於簡單的狀態機的實現。
* 兩段式狀態機:將輸入和狀態跳轉寫到一個模塊中,將輸出寫到另一個模塊中。
* 三段式狀態機:按照狀態機的結構圖來寫,即輸入部分,狀態跳轉部分和輸出部分。
而這邊討論的有限狀態機就是屬於第三種
**Moore型狀態機**
根據需求,可以確定出4個狀態,分別是①其他狀態,②檢測到AAH,③檢測到BBH,④檢測到CCH,將四種狀態分別命名為idle,aa,bb,cc,那麼可以根據需求畫出如下狀態轉移圖。
(圖片來源:網路)
**Mealy型狀態機**
將Moore型狀態機轉換為Mealy型狀態機,可以去掉cc狀態,然後得到如下的狀態轉化圖。
(圖片來源:網路)
Mealy型狀態機的狀態機輸出會比Moore型狀態機來的好。
我們比較常用到的有限狀態機就是Mealy型狀態機,而它的原理簡單來說就是==在幾種有限的狀態內並把狀態編號,用按鈕或其他方式控制是否前往下一個狀態,並在這些狀態內循環。==
### 第十一篇 FSM-(Finite State Machine,有限狀態機)
應用:
流程圖

程式碼

在這之中可以看到要進到下一個狀態用的是按鈕來控制,而如過沒按下按鈕就保持不變。
而如果有些地方想要讓他過一下再就改變狀態的話,我們可以把它改成用clock來判定,那麼每次clock一到就會改變狀態。3