FPGA智能傳感系統(一)Verilog基礎入門

  Verilog模塊的基本構成要素有三大部分: 端口信息輸入/輸出說明邏輯功能描述。這裏將其看成一種計算機語言就行了,沒有那麼網上說的什麼花裏胡哨的。計算機語言就是用來實現功能的,我們日常接觸最多的就是c++python這種,做的一般是計算仿真,而這個verilog做的是與硬件相關的,也就是直接控制信號的與或非這種。

  而學習一門計算機語言最快的方式就是直接上手幹,話不多說看個例子:

module block1(a, b, c, d, e);
input a, b, c;
output d, e; .
	assign d=a|(b&~c);
	assign e=(b&~c );
endmodule

  可以看到verilog模塊由兩部分組成:端口信息內部功能。上述代碼所述功能是輸入三個信號a,b,c(這裏沒有指定位寬,說明這裏都是一位位寬信號); 輸出de也是沒有指定位寬,表示一根線輸出。中間assign賦值語句就是內部功能,表示輸入與輸出之間的關係。d信號的輸出等於a或上bc的非,e同理。

Verilog基本模塊

結構

  verilog模塊的結構在moduleenmodule關鍵詞之間,主要有四個主要部分組成。上述是verilog的一個基本的程序模塊,如果我們想要設計一個verilog模塊的話,其大體組成部分如下圖所示:

verilog HDL程序模塊

  1. 模塊端口定義用來聲明設計電路模塊的輸入輸出端口。端口定義格式如:module模塊名(端口1,端口2,端口3,…);。

  任何一個模塊都是以module開頭的。在端口定義的圓括弧中,是設計電路模塊與外界聯繫的全部輸入輸出端口信號或引腳,它是設計實體對外的一個通信界面,是外界可以看到的部分(不包含電源和接地端),多個端口名之間用“,”分隔," ; "結尾。

  1. 模塊內容包括I/O說明、信號類型聲明和功能描述。模塊的I/O說明用來聲明模塊端口定義中各端口數據流動方向包括輸入(input) 、輸出(output) 和雙向(inout) 。I/O說明格式如下:
input ina , inb,cin;
output sum, cont;

  這裏寫成一行的話位寬都是一樣的。所以有時候需要指定位寬的時候我們對每個輸入、輸出單獨寫。

  1. 信號類型聲明用來說明設計電路的功能描述中,所用的信號的數據類型以及函數聲明。信號的數據類型主要有連線(wire) 、寄存器(reg)、整型(integer) 、實型(real) 和時間(time)等類型。在通常設計的時候用的最多的就是連線型(wire)和整型(reg),有時候也會用到整型。

  2. 功能描述Verilog HDL程序設計中最主要的部分,用來描述設計模塊的內部結構和模塊端口間的邏輯關係,在電路上相當於器件的內部電路結構

  功能描述可以用assign語句、元件例化(instantiate) 、always塊語句、initial塊語句等方法來實現,通常把確定這些設計模塊描述的方法稱爲建模。

語句

  (1) 用assign語句建模的方法很簡單,只需要在“assign”後面再加一個表達式即可。assign語句一般適合對組合邏輯進行賦值,稱爲連續賦值方式。

module adder1 (sum, cout, ina, inb, cin) ; //模塊端口定義
	input ina, inb, cin;
	output sum,cout; //I/O聲 明
	assign {cout, sum} = ina+inb+cin; //功能描述語句
endmodule //endmodule後不加分號

  默認的數據類型爲wire (連線)型,{ }爲拼接運算符,是將coutsum這樣兩個1位操作數拼接爲一個2位操作數。

  (2) 元件例化方式建模是利用Verilog HDL提供的元件庫實現的。.例如,用與門例化元件定義一個3輸入端與門可以寫爲and myand3(y,a,b,c); and爲關鍵字,名稱爲myand3

  (3) always塊語句可以產生各種邏輯,常用於時序邏輯的功能描述。一個程序設計模塊中,可以包含一個或多個always語句。程序運行中,在某種條件滿足時,就重複執行一遍always結構中的語句

module cnt8(out,cout,data,load,cin,clk,clr);
	input [7:0] data; // 輸入數據八個比特
	input load, cin, clk, clr; // 一個比特
	output| 7:0] out;
	output cout;
	reg [7:0] out; //寄存器型參量,具有寄存功能
	always @(posedge clk) //時鐘 上升沿,每次上升沿,執行always語句
		begin
			if (clr) out < =8'b0;
			else if (load) out <= data;
			else out <= out+8'b1;
		end
	assign cout = &out & cin; //&out”-與縮減運算式
endmodule

  輸出out八位、cout輸出進位一位、data八位,load置數信號一位,cin輸入進位,clk時鐘,一位,clr復位。這裏輸出信號爲out,之後又將其定義爲寄存器信號。

  always@括號中的是條件,posedge clk表示的時鐘上升沿。也就是時鐘上升沿一進來進開始執行內部語句。如果clr復位信號爲高電平,輸出out就被賦值爲8比特0(這裏的<=就是賦值語句)。當out全爲1且進位cin也爲1的時候cout才爲1

  由於這裏out信號在always塊中賦值,所以必須定義爲寄存器型變量。也就是always塊中的變量必須定義爲寄存器類型assign賦值的變量必須是wire型。

  (4) initial塊語句與always語句類似,不過在程序中它只執行1次就結束了。

詞法、語法

  1. Verilog HDL的常數包括數字未知X高阻z三種。數字可以用二進制、十進制、八進制和十六進制等4種不同數制來表示,完整的數字格式
<位寬>'<進制符號><數字>

  其中,位寬表示數字對應的二進制數的位數寬度; 進制符號包括bB (表示二進制數),dD (表示十進制數),hH (表示十六進制數),oO (表示八進制數)。

  1. 字符串是用雙引號括起來的可打印字符序列,它必須包含在同一行中。

  2. 標識符是用戶編程時爲常量、變量、模塊、寄存器、端口、連線、示例和begin-end塊等元素定義的名稱。標識符可以是字母、數字和下劃線等符號組成的任意序列。

  3. 關鍵字Verilog HDL預先定義的單詞,它們在程序中有不同的使用目的。所有關鍵字都用小寫

  4. 操作符也稱爲運算符,是Verilog HDL預定義的函數名字,這些函數對被操作的對象(即操作數)進行規定的運算,得到一個結果。

  操作符通常由1~3個字符組成,例如,“+”表示加操作,“= =” (兩個=字符)表示邏輯等操作,“===”(3個=字符)表示全等操作。

  有些操作符的操作數只有1個,稱爲單目操作;有些操作符的操作數有2個,稱爲雙目操作;有些操作符的操作數有3個,稱爲三目操作

  1. 常量是-一個恆定不變的值數,一般在程序前部定義。常量定義格式爲
parameter常量名1 =表達式,常量名2 =表達式,...,
常量名n=表達式;

  parameter是常量定義關鍵字,常量名是用戶定義的標識符,表達式是爲常量賦的值。

  1. 變量是在程序運行時其值可以改變的量。在Verilog HDL中,變量分爲網絡型(nets type)和寄存器型(register type)兩種。

  nets型變量是輸出值始終根據輸入變化而更新的變量,它一般用來定義硬件電路中的各種物理連線。常用的是wire類型。

  register型變量是一種數值容器,不僅可以容納當前值,也可以保持歷史值,這一屬性與觸發器或寄存器的記憶功能有很好的對應關係。

  register型變 量與wire型變量的根本區別: register型變量需要被明確地賦值,並且在被重新賦值前–直保持原值。.

  register型變量是在alwaysinitial等 過程語句中定義,並通過過程語句賦值。

常用的register型變量及說明

  integerrealtime等3種 寄存器型變量都是純數學的抽象描述,不對應任何具體的硬件電路,但它們可以描述與模擬有關的許算。例如,可以利用time型變量控制經過特定的時間後關閉顯示等。

  reg型變量是數字系統中存儲設備的抽象,常用於具體的硬件描述,因此是最常用的寄存器型變量。reg型變量定義的關鍵字是reg,定義格式如下:

reg [位寬]變量1, 變量2,...,變量n;

  用reg定義的變量有-一個範圍選項( 即位寬),默認的位寬是1。位寬爲1位的變量稱爲標量,位寬超過1位的變量稱爲向量。

  向量定義時需要位寬選項:

reg[7: 0] data; //定義1個8位寄存器型.變量, 最高有效位是7,最低有效位是0
reg[0: 7] data; //I定義1個8位寄存器型變量,最高有效位是0,最低有效位是7
  1. 數組:若干個相同寬度的向量構成數組。在數字系統中,reg型數組變量即爲memory (存儲器)型變量
mymemory[1023:0];

  上述語句定義了一個1024個字存儲器變量mymemory,每個字的字長爲8位。在表達式中可以用下面的語句來使用存儲器:

mymemory[7]=75; // 存儲器mymemory的第7個字被賦值75。

Verilog語句

  基本邏輯門關鍵字是Verilog HDL預定義的邏輯門,包括andornotxornandnor等。

  1. 過程賦值語句

  過程賦值語句出現在initial和always塊語句中,賦值符號是“=”,格式爲

  賦值變量=表達式;

  在過程賦值語句中,賦值號“=”左邊的賦值變量必須是reg (寄存器)型變量,其值在該語句結束即可得到。如果一個塊語句中包含若干條過程賦值語句,那麼這些過程賦值語句是按照語句編寫的順序由上至下一條一條地執行,前面的語句沒有完成,後面的語句就不能執行,就象被阻塞了一樣。 因此,過程賦值語句也稱爲阻塞賦值語句。

  1. 非阻塞賦值語句

  非阻塞賦值語句也是出現在initialalways塊語句中,賦值符號是“<=”,格式爲

  賦值變量<=表達式;

  在非阻塞賦值語句中,賦值號“<=”左邊的賦值變量也必須是reg型變量其值不象在過程賦值語句那樣,語句結束時即刻得到,而在該塊語句結束纔可得到

  1. 循環語句

  循環語句包含for語句、repeat語句、while語句和forever語句4種。

模塊實例化

  與C語言相比,verilog語句是並行的,比如兩個always塊都是時鐘沿出發的,那麼它們就是並行的。

  特殊符號“#”常用來表示延遲。使用'define編譯引導能提供簡單的文本替代功能。

`define <宏名> <宏文本>

  舉例如下:

`define on 1'b1 // 0比特1定義on
`define off 1'b0 // 0比特0定義off
`define and delay #3 // 定義延時

  使用'include編譯引導在編譯的時候能把其指定的整個文件包括進來一起處理。如’include “global.v"等。

  可以將模塊的實例通過端口連接起來構成一個大的系統或元件。每個實例都有自己的名字。實例名是每個對象唯一的標記,通過這個標記可以查看每個實例的內部。實例中端口的次序與模塊的定義的次序相同。模塊實例化與調用程序不同。每個實例都是模塊的一個完全拷貝,相互獨立、並行。

  在調用模塊時,可以用順序連接和按名連接把模塊定義的端口與外部信號連接起來。

  順序連接:需要連接的信號需要與模塊聲明的端口列表一致;

模塊實例化

  按名連接:端口和外部信號按名字連接在一起。當設計大規模系統時,端口太多,記住端口順序不大可能,可以採用按名連接方法。

  不需要連接的端口直接忽略掉即可:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章