Verilog語法簡介
@author: 紫金港小李
@mail: 3557727504@qq.com
文章目錄
- Verilog語法簡介
- 一、門級建模
- 1.基本定義
- (1)模塊定義
- (2)埠宣告
- (3)門級呼叫
- (4)模塊實體化
- 二、資料流級建模
- 1. assign(類似于賦值陳述句)
- (1) 最簡單的例子莫過于導線了~~
- (2) 與或非門
- 2. 運算元
- (1)數字
- (2)引數
- (3)線網
- (4)暫存器
- 3. Vector (可以理解成陣列)
- Declaring Vectors
- Implicit nets(如果變數未定義即出現,可能出bug)
- Accessing Vector Elements: Part-Select(陣列尋址?)
一、門級建模
1.基本定義
(1)模塊定義
模塊定義以關鍵字module開始,以關鍵字endmodule結束,基本語法結構如下:
module 模塊名 (埠名1,埠名2,...);
...
endmodule
(2)埠宣告
模塊定義中的埠串列中僅僅列出了本模塊具有哪些埠,但是并不標明輸入or輸出,這就需要在模塊中進行宣告:
output Y;
input A,B,C,D;
顧名思義,埠宣告就是宣告埠的型別,寬度等資訊,型別有三種.
| Verilog HDL 關鍵字 | 埠型別 |
|---|---|
| input | 輸入埠 |
| output | 輸出埠 |
| inout | 雙向埠 |
Tips:
也可以埠宣告放入模塊定義中,舉個栗子
module top_module (
input in,
output out);
...
endmodule
(3)門級呼叫
埠宣告后的部分就是門級呼叫,語法格式
邏輯門型別 <實體名稱(可選)> (埠連接)
實體名稱部分在門級建模一般不適用,邏輯門型別指的是常用的基本邏輯門,例如
not (S1n,S1);
not (En_n,En);
and (and1,En_n,S1n,S0n,A);
or (Y,and1,and2,and3);
| 門的名稱 | 門的功能 |
|---|---|
| buf | 緩沖器 |
| not | 非門 |
| and | 與門 |
| nand | 與非門 |
| or | 或門 |
| nor | 或非門 |
| xor | 異或門 |
| xnor | 同或門 |
(4)模塊實體化
把當前模塊(module)中呼叫其他模塊來完成設計的程序稱之為模塊的實體化,語法結構如下:
模塊名稱 實體名稱 (埠連接);
- 模塊名稱即已經定義好的其他模塊的模塊名
- 實體名稱時在本模塊內定義的新名稱
- 埠連接是在當前模塊中把實體化的模塊所包含的埠進行連接,有兩種連接方式
- 按順序連接
- 按名稱連接
下面是一個以16位全加器通過實體化得到32位全加器的例子:
module fadd32b(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout,x;
//add16,16 bits full adder
add16 inst1 (a[15:0],b[15:0],1'b0,sum[15:0],cout);
add16 inst2 (a[31:16],b[31:16],cout,sum[31:16],x);
endmodule
二、資料流級建模
1. assign(類似于賦值陳述句)
(1) 最簡單的例子莫過于導線了~~

assign 線網信號名 = 運算運算式
module top_module (
input in,
output out);
assign out = in;//這里是連續賦值,意即在仿真結束前,out恒等于in
endmodule
(2) 與或非門
Verilog 有兩種非,一種是bitwise-NOT (~),另一種是logical-NOT (!) , like C. 對于一位的運算,這兩種并無區別,
module Inverter(
input in,
output out
);
assign out = ~in;//inverter gate
endmodule
Verilog有兩種與,bitwise-AND (&) and logical-AND (&&) operators, like C. 對于一位的運算,這兩種并無區別,
module AND(
input a,
input b,
output out );
assign out = a&b;//and gate
endmodule
同樣,bitwise-OR (|) and logical-OR (||) operators, like C.
module OR(
input a,
input b,
output out );
assign out = a|b;//or gate
endmodule
2. 運算元
- 運算元有很多資料型別,如parameter,wire等19種,這里介紹常用的4種,
| 資料型別 | 功能 |
|---|---|
| parameter | 用于引數的描述 |
| wire型 | 用于描述線網 |
| reg型 | 用于描述暫存器 |
| integer型 | 用于描述整數型別 |
(1)數字
在運算元中首先要介紹的是數字,數字的基本表示格式如下:
<位寬>'<進制><數值>
在這個格式中,數值是唯一不可缺少的,
- Verilog支持四種進制形式,二進制,八進制,十進制和十六進制,分別用B,O,D,H表示(不區分大小寫),
- 位寬表示一個數字到底包含幾位資訊,指明了數字的精確位數,這個位數是以它華為二進制數之后所具有的寬度來表示的,
還是一樣的,舉一個栗子,
2'b01 //二進制,相當于十進制:1
4'd11
6'o37 //八進制,相當于十進制:3*8+7=31
8'hab
- 位寬缺少或者進制缺少
'o37 //位寬采用默認寬度(一般32位),相當于00000000000000000000000000011111
37 //相當于十進制的37
(2)引數
有時候某些數字或字符需要多次使用,Verilog中可用關鍵字parameter來定義一個引數,用于指代某個常用的數值、字串或運算式,
parameter 引數1 = 運算式1,引數2 = 運算式2 ;
在語法結構中,parameter是關鍵字,后面的引數名是設計者自己定義的一個識別符號,
parameter size = 8;
parameter a=4,b=16;
parameter width = size-1;
parameter clock = a+b;
(3)線網
線網型別采用關鍵字wire來定義,用于描述模塊中可能是連線的情況,其語法如下
wire [寬度申明] 線網名1,線網名2;
Example:
wire x;
wire [3:0] y;
wire [7:1] m,n;
(4)暫存器
在數字電路中有一類器件可以存盤資料值,在Verilog中定義為reg型別
reg x;
reg [3:0] y;
reg [7:1] m,n;
除了表示一位或多位的暫存器,reg還可以用來定義存盤器,語法如下:
reg [n-1:0] 存盤器名稱 [0:m-1];
reg [7:0] mema [0:255]; //這里定義了一個寬度為8位的存盤器,共有256個存盤單元
//每個單元用0~255的數字進行編號
mema[1] 就是指第一個的8位儲存單元,
進行初始化時,初始化的程序中要對每個存盤器單元進行初始化賦值,而不能采用整個存盤器直接賦值的方法.
reg memb [0:255];
memb = 0;(錯誤)
memb[100] = 0;(正確)
整數是一種特殊的資料型別,使用關鍵字integer進行申明,
integer i;
i=-1;
做個題目放松放松?
`default_nettype none//這句的意思是,不允許未定義的變數參與運算,這與C語言類似,必須要先定義變數
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire and_1,and_2,or_1;//define three wire
assign and_1 = a&b;
assign and_2 = c&d;
assign or_1 = and_1|and_2;
assign out = or_1;
assign out_n = ~or_1;
endmodule
3. Vector (可以理解成陣列)
-
Declaring Vectors
Vectors must be declared:
type [upper:lower] vector_name;
//for example:
wire [7:0] w; // 8-bit wire
reg [4:1] x; // 4-bit reg(register:暫存器變數,在后面的always陳述句塊中詳細介紹,如果我還記得的話)
output reg [0:0] y; // 1-bit reg that is also an output port (this is still a vector)
input wire [3:-2] z; // 6-bit wire input (negative ranges are allowed)
output [3:0] a; // 4-bit output wire. Type is 'wire' unless specified otherwise.
wire [0:7] b; // 8-bit wire where b[0] is the most-significant bit.
-
Implicit nets(如果變數未定義即出現,可能出bug)
wire [2:0] a, c; // Two vectors
assign a = 3'b101; // a = 101
assign b = a; // b = 1 implicitly-created wire
assign c = b; // c = 001 <-- bug
my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared. // This could be a bug if the port was intended to be a vector.
Adding ``default_nettype none` would make the second line of code an error, which makes the bug more visible.(建議加上這條陳述句,使得直接報ERROR便于查找錯誤)
-
Accessing Vector Elements: Part-Select(陣列尋址?)
assign w = a;//a:4-bits,w:8-bits.
//the lower 4 bits in w is a ,while the higher 4 bits in zero.
takes the entire 4-bit vector a and assigns it to the entire 8-bit vector w (declarations are taken from above). If the lengths of the right and left sides don’t match, it is zero-extended or truncated as appropriate.
The part-select operator can be used to access a portion of a vector:
w[3:0] // Only the lower 4 bits of w
x[1] // The lowest bit of x
x[1:1] // ...also the lowest bit of x
z[-1:-2] // Two lowest bits of z,like python
b[3:0] // Illegal. Vector part-select must match the direction of the declaration.
b[0:3] // The *upper* 4 bits of b.
assign w[3:0] = b[0:3]; // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc.
在學了,在學了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/224357.html
標籤:其他
