2019年4月10日 星期三

Verilog 入門 (三)

描述電路

在說明如何描述一個電路之前,先來提到電路主要可以分成2種電路

1. 組合邏輯電路
2. 循序邏輯電路

組合邏輯電路最大的一個特性就是,輸入到輸出的響應是沒有等待的,主要只有電路的延遲,最大的例子就是 各種邏輯的組合
如:
一個 and 閘,從左邊輸入直到右邊輸出,只會經過電路本身的延遲,這種就是組合邏輯電路


接著循序邏輯電路主要是有著clock訊號的,而且可儲存數值。
最簡單的例子就是 D Flip Flop
經過clock正緣觸發,才將資料輸出至輸出端。 這種電路就是循序電路






再來描述電路的方式主要可以分成3種

1. Gate Level
2. Data Flow
3. Behavior


1. Gate Level

首先 Gate Level的描述方式主要使用邏輯來描述 如 and  or  nor not ...

Ex:

module test1
(
input a1, a2, a3,
output o1, o2
);

and (o1 , a1, a2);     // 內建語法 宣告一個and閘 a1, a2 為輸入 o1 為輸出
and(o2, a1, a2, a3); // 也不限於2輸入 也可以增加輸入訊號

endmodule


不過這種方式幾乎沒在使用,最主要使用的都是後2種方式

2. Data flow

Data flow描述電路的方式主要是用資料的流向來設計電路,主要使用assign這個語法

EX:
假如要設計一個and閘用這種方式快速許多

module test1
(
input a1, a2, a3,
output o1, o2
);

assign o1 = a1 & a2;   // 設定o1 為 a1 and a2
assign o2 = (a1 &  a2) | a3;   // 也可以使用不同的邏輯組合再一起

endmodule

另外運算子也可以使用在data flow 的描述上


assign sum = A1 + A2 + C;  // 描述一個加法器
assign out = ( sel ) ? in1 : in2 ;  // 利用 if else 描述一個多工器


主要data flow使用在描述組合邏輯電路上


3. Behavior 描述方式

Behavior描述的方式更為高階,語法上類似於C語言
主要使用的是 always block來描述電路

首先介紹always block

always 宣告如下,事件觸發的地方填入要何時去觸發always  block的內容
電路內容則是開始描述你的電路,另外再always block中要給予值的訊號都要宣告成reg
取值的訊號不用

always @( 事件觸發  )
     begin
     電路內容

     end

Ex :

wire a , b; // 取值的訊號可以是 wire 也可以是 reg
reg c;       // 給予值的才要宣告成 reg

always @(a, b, c)  // 描述一個 當 a , b ,c訊號其中一個有變化時則執行以下步驟
     begin
           c = a | b;    // 設定 c的數值 為 a | b
      end

再來 Behavior描述電路則是兩種電路階可以描述,組合邏輯以及循序電路。




組合邏輯電路描述方式

在always 描述組合邏輯電路的方式主要使用blocking的描述 使用的是 " = "符號
那甚麼是blocking的描述呢  ?  那是不是還有non-blocking?

blocking的描述方式如名子所述 在執行這一行的時候會卡住就像一般的程式語言

像是 一開始 a = 1  b = 0

a = b; // 模擬時先執行這行  a = 0
b = a; // 再執行這行  最終 a = 0 ,b = 0

non-blocking的描述則是使用 " <= " 注意這不是小於等於

假設像上面 a = 1 b = 0

a <= b; //在模擬的時候則是 2行同時執行
b <= a; // 最終則是 a = 0,  b = 1

好 再來回到描述組合邏輯的電路,那是不是很那笨上面2種的描述跟電路有啥關係?

上面提到的描述主要是會跟模擬時的優先順序有關,你只要記住組合邏輯使用 " = "
循序使用 " <= " 就可以了

Ex :
那我們現在來描述一個多工器使用always可以寫成

wire a1, a2 , sel;  // 宣告訊號線
reg out;               // 宣告多工器輸出

always @(a1, a2, sel) //事件觸發為 輸入訊號3個
begin

  if(sel)          //使用 if else 描述 多工器
    out = a1;  // sel == 1 輸出 = a1
  else
    out = a2; // sel == 0 輸出 = a2

end

如此一來便完成一個多工器了  另外組合邏輯如果訊號越來越多,事件觸發要寫的數量就會越來越多
為了節省手指的疲勞程度
通常會寫成 always @(*) 使用" * "來代表所有的訊號

Verilog 入門 (二)

今天來說明一些verilog宣告一的些資料型態以及運算子說明以及描述電路的方式


數字表示法
在verilog中主要都是二進位的世界,不像C語言有浮點數、正負數、字元等等
主要只有 2進位 8進位 10進位 16進位  但在儲存方式上都是使用二進位儲存

宣告數字型態主要有分成幾個部分
Ex:

8'b0000_1111

這裡宣告了一個二進位的數字,首先" 8 "代表著幾個位元
" 'b "則是宣告了為2進位表示法
後面的0000_1111則是數值 = 十進位的15
"_"則是方便使用者分辨位元的符號 也可以不寫 像是 8'b00000000

8進位則是使用" o "來表示如 :  9'o175     //8進位最高數字到7
10進位則是使用" d " 如 : 10'd1024           //高位元如果是0可以省略
16進位則是使用" h " 如 : 16'hffff             // 16進位最高數字到 f

另外在verilog中有著4種型態的數值  0  1  X  Z

0在電路中代表著 LOW 低電位

1在電路中代表著HIGH 高電位

X則是在模擬時使用的資料型態表示 unknown 未知訊號
表示這時不知道是高電位還是低電位
例如 : 同時給予1以及0的訊號就會產生出 X

Z則是代表著高阻抗 也就是浮接的訊號 多在雙向的IO會出現




運算子介紹
在verilog中也有許多運算子可以使用


運算元優先表
----------------------------------
!   ~   +  - (unary) (highest)    1位元運算  反向   多位元反向    加  減
----------------------------------
**                                           次方運算  如 2**5  =  32
----------------------------------
*   /   %                                   承 除  取餘數
----------------------------------
+   -   (binary)                         多位元  加  減
----------------------------------
<<   >>   <<<     >>>              位元左移  右移  算數左移 算數右移
----------------------------------
<    <=    >    >=                       比較運算  小於  小於等於 大於  大於等於
----------------------------------
==    !=    ===     !==               比較運算   等於  不等於  算數等於  算術不等於 (算數包含x , z)
----------------------------------
&    ^    |                                    位元運算  等同於邏輯的 and   xor or
----------------------------------
&&                                            邏輯運算  用在條件與條件之間的關係
----------------------------------
||                                                 邏輯運算  用在條件與條件之間的關係
----------------------------------
?:    (lowest)                               if else的符號 使用在data flow宣告
----------------------------------


Data Type

在介紹後種方式之前,先來介紹2種data type : reg , wire

wire 顧名思義,主要就是宣告一條線,需要不斷驅動這條線才會有數值,簡單說就是一條電線沒有給電就不會有電

reg 則是宣告一個暫存器,可以儲存數值沒有給值的時候,數值並不會消失
要注意的是,雖說是暫存器,但在不同的地方是會有不同的效果的,後面begavior描述會在解釋

再來宣告的方式主要可以分成 1 位元以及多位元宣告 如

Ex :

wire a;  宣告一個1位元的訊號 a

reg [15:0] b; 宣告一個 16 位元的 b



2016年11月4日 星期五

Verilog 入門 (ㄧ)



Verilog 在網路上可以找到很多資料,也是目前很熱門的硬體描述語言

我是個研究生,同時也發現很多人不太了解對於verilog跟程式語言之間的不同

一直以來都想把自己所學的東西記錄下來,所以就從簡單的開始

當然寫的時間不一定,有空才會在繼續寫,另外我還是學生,還在學習,也可能會有錯誤


------------------------------------------------------------------------------------------------------------------------
首先,Verilog 是硬體描述語言的一種,顧名思義就是用來述說一個電路的語言

語法是跟C語言規則近乎相同的,而描述的大多都是純數位的電路,所以跟C語言上是有很大的不同的

那首先就先從語法開始


一開始,最重要的是你要思考一個數位電路,然後將其描寫出來

以下範例就是每個verilog的開始,要了解的就是你是在描述一個電路

所撰寫出來的verilog就如同右邊的chip一樣


module   電路名稱( 輸入輸出IO port 名稱宣告  );

input     IO名稱; // 定義IO類型
output   IO名稱;

電路內容



endmodule

ex: 1 bit 加法器

module adder 電路名稱
(
input  in1,  in2,  carry_in,  輸入輸出IO port 名稱宣告 
output  out , carry_out
);


assign {carry_out, out} = in1 + in2 + carry_in;//電路內容


endmodule