三、VHDL語言基礎


正文:

1 VHDL簡介

VHDL的全稱為VHSIC硬件描述語言(VHSIC Hardware Description Language),VHSIC: Very High Speed Integrated Circuit

1.1 歷史

1980 – 美國國防部設立一個基金,在VHSIC項目之下開設了一個子課題,研究標准的硬件描述語言,1982誕生VHDL。
1987 – IEEE 將其修正為 IEEE 標准:1076
1993 – 修正了VHDL語言,升級至IEEE 1076-1993

1.2 產生原因

為什么使用VHDL ?原理圖圖形化設計缺點?
答:
大型設計,原理圖連接太復雜,檢查錯誤太困難
通過使用高級語言對你的設計做描述,可以分析語法錯誤,綜合后效率可能更高,時間成本更好。

2 VHDL的基本結構

VHDL的基本設計單元結構:程序包說明、實體說明、結構體說明三部分。

-- 庫、程序包的說明調用
Library IEEE;
use IEEE.Std_Logic_1164.ALL;
-- 實體聲明
Entity FreDevider is
port
(
    Clock: IN Std_logic;
    Clkout: OUT Std_logic
);
END;
-- 結構體定義
Architecture Behavior Of FreDevider is
signal Clk:Std_Logic; -- 中間臨時變量
begin
    process(Clock)
    begin
        IF rising_edge(Clock) THEN
            Clk <= NOT Clk;    
        END IF;
    END process;
    Clkout <= Clk;
END
 

2.1 庫和程序包

2.1.1 庫

庫是專門用於存放預先編譯好的程序包的地方,對應一個文件目錄,程序包的文件就放在此目錄中,其功能相當於共享資源的倉庫,所有已完成的設計資源只有存入某個“庫”內才可以被其他實體共享。庫的說明總是放在設計單元的最前面,表示該庫資源對以下的設計單元開放。庫語句格式如下:

LIBRARY 庫名;

常用的庫有IEEE庫、STD庫和WORK庫:

  • IEEE庫:是VHDL設計中最常用的資源庫,包含IEEE標准的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD以及其他一些支持工業標准的程序包。其中最重要和最常用的是STD_LOGIC_1164程序包,大部分程序都是以此程序包中設定的標准為設計基礎。
  • STD庫:是VHDL的標准庫,VHDL在編譯過程中會自動調用這個庫,所以使用時不需要用語句另外說明。
  • WORK庫:是用戶在進行VHDL設計時的現行工作庫,用戶的設計成果將自動保存在這個庫中,是用戶自己的倉庫,同STD庫一樣,使用該庫不需要任何說明。

庫的作用范圍:

  庫說明語句的作用范圍從一個實體說明開始到它所屬的構造體、配置為止。當一個源程序中出現兩個以上的實體時,兩條作為使用庫的說明語句應在每個實體說明語句前重復書寫。

(1)示例1:

  自定義一個庫:

  • decoder2to4.vhd文件

 

 

  • mylib.vhd文件

 

 

  •  expdecoder.vhd文件

 

 

 (2)示例2:

  • my_pack是一個包,里面聲明了一個component myadd。myadd 在另外一個vhd文件中實現。
  • 實現了一個實體mycompadd。注意:實現package my_pack 和 entity mycompadd 時顯示調用了兩次庫。

 

 

  •  實現component myadd

 

 

 

2.1.2 程序包

程序包是用VHDL語言編寫的一段程序,可以供其他設計單元調用和共享,相當於公用的“工具箱”,各種數據類型、子程序等一旦放入了程序包,就成為共享的“工具”,類似於C語言的頭文件,使用它可以減少代碼的輸入量,使程序結構清晰。在一個設計中,實體部分所定義的數據類型、常量和子程序可以在相應的結構體中使用,但在一個實體的聲明部分和結構體部分中定義的數據類型、常量及子程序卻不能被其他設計單元使用。因此,程序包的作用是可以使一組數據類型、常量和子程序能夠被多個設計單元使用。
程序包分為包頭和包體兩部分。包頭(也稱程序包說明)是對包中使用的數據類型、元件、函數和子程序進行定義,其形式與實體定義類似。包體規定了程序包的實際功能,存放函數和過程的程序體,而且還允許建立內部的子程序、內部變量和數據類型。包頭、包體均以關鍵字PACKAGE開頭。程序包格式如下:

--包頭格式:
PACKAGE 程序包名 IS
[包頭說明語句]
END 程序包名;

--包體格式:
PACKAGE BODY 程序包名 IS
[包體說明語句]
END 程序包名;

 

調用程序包的通用模式為:

USE 庫名.程序包名.ALL;

 

常用預定義程序包有以下四個:

  • 1.STD_LOGIC_1164程序包
    STD_LOGIC_1164程序包定義了一些數據類型、子類型和函數。數據類型包括:STD_ULOGIC、STD_ULOGIC _VECTOR、STD_LOGIC和STD_LOGIC _VECTOR,用的最多最廣的是STD_LOGIC和STD_LOGIC_VECTOR數據類型。調用STD_LOGIC_1164程序包中的項目需要使用以下語句:
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    該程序包預先在IEEE庫中編譯,是IEEE庫中最常用的標准程序包,其數據類型能夠滿足工業標准,非常適合CPLD(或FPGA)器件的多值邏輯設計結構。
  • 2.STD_LOGIC_ARITH程序包
    該程序包是美國Synopsys公司的程序包,預先編譯在IEEE庫中。主要是在STD_LOGIC_1164程序包的基礎上擴展了UNSIGNED(無符號)、SIGNED(符號)和SMALL_INT(短整型)三個數據類型,並定義了相關的算術運算符和轉換函數。
  • 3.STD_LOGIC_SIGNED程序包
    該程序包預先編譯在IEEE庫中,也是Synopsys公司的程序包。主要定義有符號數的運算,重載后可用於INTEGER(整數)、STD_LOGIC(標准邏輯位)和STD_LOGIC _VECTOR(標准邏輯位向量)之間的混合運算,並且定義了STD_LOGIC _VECTOR到INTEGER的轉換函數。還定義了STD_LOGIC _VECTOR類型的符號數算數運算子程序。
  • 4.STD_LOGIC_UNSIGNED程序包
    該程序包用來定義無符號數的運算,其他功能與STD_LOGIC_SIGNED相似。


自定義包的實現見2.1.1節庫的示例。

 

 

 

2.2 實體(Entity)

實體描述了設計單元的輸入輸出接口信號或引腳,是設計實體經封裝后對外的一個通信界面。

ENTITY 實體名 IS -- 引導語句
[GENERIC (常數名: 數據類型: 設定值)] -- 類屬表
PORT -- 端口表
(
    端口名1: 端口方向 端口類型;
    端口名2: 端口方向 端口類型;
    端口名3: 端口方向 端口類型;
    ......
    端口名n: 端口方向 端口類型 -- 最后一個一定不能加";",不然會報next process的")" expect ";" or ","
);
END [實體名]; -- 結束語句

 注意:

  1. 端口n的聲明最后一定不能加";",不然會報錯誤:next process的")" expect ";"
  2. port中端口默認類型為signal

2.2.1 類屬:

  • 類屬說明的書寫格式是:

GENERIC(常數名:數據類型:設定值);
  • 其他
    類屬 GENERIC 參量是一種端口界面常數,常以一種說明的形式放在實體或塊結構體前的說明部分。比較常見的情況是利用類屬來動態規定一個實體的端口的大小,或設計實體的物理特性,或結構體中的總線寬度,或設計實體中底層中同種元件的例化數量等等。一般在結構體中,類屬的應用與常數是一樣的,其中的常數名是由設計者確定的類屬常數名,數據類型通常取 INTEGER 或TIME 等類型,設定值即為常數名所代表的數值,但需注意 VHDL 綜合器僅支持數據類型為整數的類屬值。例如:

ENTITY mcu1 IS
GENERIC (addrwidth : INTEGER := 16);
PORT(
    add_bus : OUT STD_LOGIC_VECTOR(addrwidth-1 DOWNTO 0) );
    ...

  在這里 GENERIC 語句對實體 mcu1 作為地址總線的端口 add_bus 的數據類型和寬度作了定義 即定義 add_bus 為一個 16 位的標准位矢量 定義 addrwidth 的數據類型是整數INTEGER 其中 常數名addrwidth減 1 即為 15 所以這類似於將上例端口表寫成PORT (add_bus : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));

2.2.2 端口

  • 端口語句的格式:
PORT(端口信號名:端口模式 數據類型;
端口信號名:端口模式 數據類型);

 

  • 端口模式有:
    • IN : 在實體中只讀,接受外來數據. 只能出現在賦值語句的右側。
    • OUT: 在實體中只能更新,不可讀。只能出現在賦值語句的左側。
    • INOUT: 在實體內部可更新、可讀,可出現在賦值語句的兩側。 
    • BUFFER: 可用作內部賦值,可出現在賦值語句的兩側。在可綜合代碼中不推薦使用。

2.3 結構體

2.3.1 結構體的作用和特點

2.3.1.1 作用

結構體的任務是:定義結構體中的各項內部使用元素,如數據類型(TYPE),常數(CONSTAND),信號(SIGNAL),元件(COMPONENT),過程(POCEDURE),變量(VARIABLE)和進程(PROCESS)等。通過VHDL語句描述實體所要求的具體行為和邏輯功能。描述各元件之間的連接。

2.3.1.2 特點

  1. 用於描述模型的功能
  2. 必須和一個 Entity相關聯
  3. 一個Entity可有多個 Architectures
  4. Architecture 語句並發執行.

2.3.2 結構體的格式:

Architecture 結構體名 OF 實體名 IS
定義語句法;
BEGIN
功能描述語句法;
END 結構體名稱;

 

2.3.3 結構體的四種描述方式

結構化描述、數據流描述、行為描述、混合。

2.3.3.1 結構描述

原件和內聯,通過低級器件的內聯實現。

特點:

  1. 描述電路的功能和結構。
  2. 可調用專用硬件。
  3. 可綜合。
  4. 結構化、模塊化。
  5. 結構化描述易於理解,接近於原理圖,使用簡單的模塊組成邏輯電路,實現邏輯功能。
  6. 組件以層次化相連接。
  7. 結構化描述可以將簡單門、甚至更復雜的邏輯門連接在一起。
  8. 結構化描述在團隊協作時非常有用。

2.3.3.2 RTL(寄存器傳輸級)描述, 又稱數據流描述

描述數據在系統中的流動過程,數據流使用一系列的並發語句實現邏輯,數據流的描述是在控制邏輯函數已經獲得的條件下實現,數據流代碼亦稱為並發代碼。
注意:並發語句在編譯中被同時評估,因此語句的順序無關緊要。

特點:

  1. 直接使用基本門和擴展門實現,沒有結構化。
  2. 邏輯表達式在編碼之前需要寫好。
  3. 沒有特定的硬件約束。
  4. 可以綜合。
  5. 數據流使用一系列的並發語句實現邏輯. 。
  6. 數據流的描述是在控制邏輯函數已經獲得的條件下實現。
  7. 數據流代碼亦稱為並發代碼。

舉例:

  • input: x1, x2, x3, ... , xn;
  • output: y1, y2, y3, ..., yn;
  • 數據流描述:
y1 <= x1 AND x2; y2 = NOT x1; y3 <= x3 OR x2;

 

2.3.3.3 行為描述

順序和並發語句,通過輸入輸出響應描述。

特點:

  1. 電路的功能,無關結構(用於數學模型或系統工作原理的仿真)。
  2. 不面向特定硬件。
  3. 不一定可綜合。
  4. 易於理解,因為行為描述更像人類的語言。
  5. 它精確地表示了在“黑盒子”內部發生的輸入-輸出之間的關系。
  6. 在VHDL中,通常使用PROCESS(進程)實現。

舉例:

  • input: x1, x2, x3, ... , xn;
  • output: y1, y2, y3, ..., yn;
  • 行為描述:
if x1 = '0' then
y1 <= x2 and x3; 
elsif ... 
esle ... 
end if;

 

  

2.3.3.4 舉例說明,下面是一個兩位相等比較器的例子

 

entity equ2 is
port(a,b:in std_logic_vector(1 downto 0);
equ:out std_logic);
end equ2;
--結構體結構描述:用元件例化,即網表形式來實現;
architecture netlist of equ2 is
-- nor 或非
component nor2 port(a,b :in std_logic; c :out std_logic); end component; component xor2
-- xor 異或
port(a,b :in std_logic; c :out std_logic); end component; signal x: std_logic_vector(1 downto 0); begin U1:xor2 port map(a(0),b(0),x(0)); U2:xor2 port map(a(1),b(1),x(1)); U3:nor2 port map(x(0),x(1),equ); end netlist; --結構體數據流描述:用布爾方程來實現: architecture equation of equ2 is begin equ<=(a(0) xor b(0)) nor(a(1) xor b(1)); end equation; --結構體行為描述:用順序語句來實現: architecture con_behave of equ2 is begin process(a,b) begin if a=b then equ<='1'; else equ<='0'; end if; end procerss; end con_behave; --結構體行為描述:用並行語句來實現: architecture seq_behave of equ2 is begin equ<='1' when a=b else '0'; end sqq_behave;

 

用行為描述方式設計的全加器 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY onebitadder IS
PORT(a,b,cin:IN BIT;
Sum,count:OUT BIT);
END onebitadder;

ARCHITECTURE behavior OF onebitadder IS
BEGIN
PROCESS(a,b,cin)
BEGIN
Sum<= a XOR b XOR cin;
Count<=(a AND b) OR ((a XOR b) AND cin);
END PROCESS;
END behavior;

 

2.3.4 塊語句結構:

塊結構名:
BLOCK 
端口說明 類屬說明
BEGIN
並行語句
END BLOCK 塊結構名;

 

2.3.5 進程語句結構:

進程名:
PROCESS(敏感信號表) IS
進程說明
BEGIN
順序描述語句
END PROCESS 進程名;

 

2.4 配置(Configuration)

2.4.1 配置的作用

  • 用於實現模型的關聯,可將一個 Entity 和一個Architecture關聯起來,也可將一個 component 和一個 entity-architecture關聯起來。
  • 目的是為了在一個實體中靈活的使用不同的Architecture。可以在仿真環境中大量使用,但是在綜合環境中限制使用。

2.4.2 配置的格式

Configuration 配置名 of 實體名 IS
    for 結構體名
    end forend;-- 1076-1987 version
end Configuration;-- 1076-1993 version

Configuration <identifier> of <entity_name> IS
    for <architecture_name>
    end forend;-- 1076-1987 version
end Configuration;-- 1076-1993 version

 

2.4.3 配置舉例

2.5 子程序模塊

能被主程序反復調用並能將處理結果傳送到主程序的程序模塊,子程序分為過程語句(Procedure)和函數(Functure)兩種。子程序中的參數說明是局部的,只能在子程序體內起作用。

2.5.1 過程語句(Procedure)

PROCEDURE 過程名(參數1;參數2;----) IS
定義語句;
BEGIN
順序處理語句;
END 過程名;

 

2.5.2 函數(Functure)

FUNCTION 函數名(參數1;參數2;----RETURN 數據類型 IS
定義語句;
BEGIN
順序處理語句;
RETURN 返回變量名;

 

3 VHDL基本語法

3.1 標識符

標識符用來定義常數、變量、信號、端口、子程序或者參數的名字。由字母(A~Z, a~z)、數組(0~9)和下划線(_)字符組成。

3.1.1 標識符規則:

  1. 首字符必須是字母
  2. 末字符不能為下划線
  3. 不允許出現兩個連續的下划線
  4. 不區分大小寫
  5. VHDL定義的保留字(關鍵字),不能用作標識符
  6. 標識符字符最長可以是32個字符
  7. 注釋由兩個連續的下划線(--)引導

3.1.2 關鍵字 (保留字)

關鍵字(keyboard)是VHDL中具有特別含義的單詞,只能作為固定的用途,用戶不能用其做為標識符。

3.2 數據對象

3.2.1 信號(SIGNAL)

為全局變量,在程序包說明、實體說明、結構體描述中使用,用於聲明內部信號,而非外部信號(外部信號為IN、OUT、INOUT、BUFFER),其在元件之間起互聯作用,可以賦值給外部信號。
定義格式:

SIGNAL 信號名: 數據類型[:= 初始值];

舉例:
SIGANL brdy: BIT;
SIGANL output: INTEGER:= 2;

 

賦值格式:

目標信號名<=表達式

 

常在結構體中用賦值語句完成對信號賦初值的任務,因為綜合器往往忽略信號聲名時所賦的值。

3.2.2 變量(VARIABLE)

只在給定的進程(process)中用於聲明局部值或用於子程序中,變量的賦值符號為“:=”,和信號不同,信號是實際的,是內部的一個存儲元件(SIGNAL)或者是外部輸入(IN、OUT、INOUT、BUFFER),而變量是虛的,僅是為了書寫方便而引入的一個名稱,常用在實現某種算法的賦值語句當中。
定義格式:

VARIABLE 變量名: 數據類型[:= 初始值];

舉例:
VARIABLE opcode: BIT_VECTOR(3 downto 0):= "0000";
VARIABLE freq: INTEGER;

 

變量賦值符號":=",變量賦值立刻更新。 

3.2.3 常量(CONSTAT)

在結構體描述、程序包說明、實體說明、過程說明、函數調用說明和進程說明中使用,在設計中描述某一規定類型的特定值不變,如利用它可設計不同模值的計數器,模值存於一常量中,對不同的設計,改變模值僅需改變此常量即可,就如參數化元件。
定義格式:

CONSTANT 常數名:數據類型:= 初始值;

舉例:
CONSTANT rise_fall_time: TIME:= 2ns;
CONSTANT data_bus: INTEGER:= 16;

 

3.2.4 信號與變量的區別

信號與變量最大的不同在於,如果在一個進程中多次為一個信號賦值,只有最后一個值會起作用,而當為變量賦值時,變量的值改變是立即發生的。

3.3 數據類型

VHDL是一種強類型語言,對於每一個常數、變量、信號、函數及設定的各種參量的數據類型(DATA TYPES)都有嚴格要求,相同數據類型的變量才能互相傳遞和作用,標准定義的數據類型都在VHDL標准程序表STD中定義,實際使用中,不需要用USE語句以顯式調用。

VHDL常用的數據類型有三種:

  1. 標准定義的數據類型
  2. IEEE預定義標准邏輯位
  3. 矢量及用戶自定義的數據類型。

3.3.1 標准定義的數據類型

  • 布爾:(Boolean)

Type BOOLEAN IS (FALSE, TRUE);

取值為FALSE和TRUE,不是數值,不能運算,一般用於關系運算符

  • 位:(Bit)

TYPE BIT IS ('0', '1');

取值為0和1,用於邏輯運算

  • 位矢量:(Bit_Vector)

TYPE BIT_VECTOR IS ARRAY(Natural range<>) OF BIT;

基於Bit類型的數組,用於邏輯運算

SIGNAL a: Bit_Vector (0 to 7); Signal a: Bit_Vector (7 to 0);

  • 字符:(character)

TYPE CHARACTER IS (NUL, SOH, STX, ..., '', '!', ...);

通常用''引號引起來,區分大小寫

  • 字符串:(String)

通常用""雙引號引起來,區分大小寫

VARIABLE string_var: STING (1 to 7);

string_var := "ABCD"

  • 整數:(Integer)

取值范圍-(2^{31}-1) to (2^{31}-1),可用32位的有符號的二進制數表示

VARIABLE a: INTEGER -63 to 63

在實際應用中,VHDL仿真器將ITEGER作為有符號數處理,而VHDL綜合器將Integer作為無符號數處理

要求用range子句為所定義的數限定范圍,以便根據范圍來決定表示此信號或變量的二進制的位數。

  • 實數:(real)

實數類型僅能在VHDL仿真器中使用,綜合器不支持

取值范圍 -1.0E38 to +1.0E38

  • 時間:(Time)

物理量數據,包括整數和單位兩個部分

時間類型僅能在VHDL仿真器中使用,綜合器不支持

范圍從-(2^{31} -1)to (2^{31}-1)

表達方法包含數字、(空格)單位兩部分,如(10 PS)

常用單位:fs,ps,ns,us,ms,sec,min,hr

  • 錯誤等級:(severity level)

表示系統狀態

該類型僅能在VHDL仿真器中使用,綜合器不支持

TYPE severity_lever IS (NOTE, WARNING, ERROR, FAILURE)

3.3.2 IEEE預定義的標准邏輯位與矢量

  • STD_LOGIC:工業標准的邏輯類型,取值為‘0’(強制為高)、‘1’(強制為低)、‘Z’(高阻態)、‘X’(強未知)、‘W’(弱未知;弱信號不定)、‘L’(弱0;弱低)、‘H’(弱1;若高)、‘-’(忽略;不關心)、‘U’(未初始化),只有前四種具有實際物理意義,其他的是為了與模擬環境相容才保留的。
  • STD_LOGIC_VECTOR:工業標准的邏輯類型集,STD_LOGIC的組合。

3.3.3 用戶自定義的數據類型

  • 枚舉類型
    • 格式:
      TYPE 數據類型名 IS (枚舉文字,枚舉文字,. . . .)
  • 整數類型和實數類型
    • 整數類型與實數類型是標准包中預定義的整數類型的子集,由於綜合器無法綜合未限定范圍的整數類型的信號或變量,故一定要用RANGE子句為所定義整數范圍限定范圍以使綜合器能決定信號或變量的二進制的位數。
    • 格式:
      TYPE 數據類型名 IS RANGE 約束范圍;(如-10到+10
  • 數組類型
    • 格式:
      TYPE 數據類型名 IS ARRAY(下限 TO 上限) OF 類型名稱
  • 記錄類型
    • 格式:
TYPE 記錄類型名 IS RECODE
元素名: 數據類型名;
元素名: 數據類型名;
END RECODE

 

3.4 運算符

3.4.1 算術運算符

  1. +, -, *, /
  2. MOD: 取模,取模運算(a MOD b)的符號與b相同,其絕對值小於b的絕對值。如:-5 MOD 2 = 1,5 MOD -2 = -1。
  3. REM: 取余,取余運算(a REM b)的符號與a相同,其絕對值小於b的絕對值。如:-5 REW 2 = -1,5 MOD -2 = 1。
  4. 多數語言對取余和取整不區分,比如python都是用%符號。詳情見https://blog.csdn.net/origin_lee/article/details/40541053
  5. SLL(Shift Left Logical): 邏輯左移,將位向量左移,右邊移空位補零。
  6. SRL(Shift Right Logical): 邏輯右移,將位向量右移,左邊移空位補零。
  7. SLA(Shift Left Arithmetic): 算數左移,將位向量左移,右邊第一位數值保持不變。
  8. SRA(Shift Right Arithmetic): 算數右移,將位向量右移,左邊第一位數值保持不變。
  9. ROL(rotate left): 循環左移。
  10. ROR(rotate right): 循環右移。
  11. **: 乘方。
  12. ABS(absolute): 取絕對值。

3.4.2 關系運算符

  1. =,/=,<,>,<=,>=

3.4.3 邏輯運算符

  1. AND, OR
  2. NAND, NOR, NOT
  3. XNOR: 同或, XOR: 異或

3.4.4 賦值運算符

  1. <=: 信號賦值,最后賦值。
  2. :=:邏輯賦值,即時賦值。

3.4.5 關聯運算符

  1. =>

3.4.6 其他運算符

  1. +,-
  2. &:並置操作符

3.4.7 運算符優先級

3.4.8 運算符表格一覽

關於運算符的分類暫不詳究。。。

4 VHDL語句

順序語句和並行語句是VHDL程序設計中兩大基本描述語句系列。順序語句(Sequential Statements)用來實現模型的算法描述;並行語句(Concurrent Statements)用來表示各模型算法描述之間的連接關系,這些語句從多側面完整地描述數字系統的硬件結構和基本邏輯功能,其中包括通信的方式、信號的賦值、多層次的元件例化以及系統行為等。

4.1 並行語句

4.1.1 並行語句的特點

  • 相對於傳統的軟件描述語言,並行語句結構是最具VHDL特色的:並行運行。 
  • 物理意義:硬件連接關系
  • 每一並行語句內部的語句運行方式可以有兩種不同的方式,即並行執行方式(如塊語句)和順序執行方式(如進程語句)。因此,VHDL並行語句勾畫出了一幅充分表達硬件電路的真實的運行圖景。

4.1.2 並行語句的格式

Architecture <architecture_name> of <entity_name> is
說明語句;
begin
    並行語句;
end architecture 結構體名;

 

4.1.3 並行語句的種類及詳解

  1. 並行信號賦值語句(CONCURRENT SIGNAL  ASSIGNMENTS)
  2. 條件/選擇信號賦值語句(CONDITIONAL/SELECTED SIGNAL  ASSIGNMENTS)
  3. 進程語句(PROCESS STATEMENTS)
  4. 塊語句(BLOCK STATEMENTS)
  5. 元件例化語句(COMPONENT INSTANTIATIONS)
  6. 生成語句(GENERATE STATEMENTS)
  7. 並行過程調用語句(CONCURRENT PROCEDURE CALLS)

4.1.3.1 並行信號賦值語句

<signal_name> <= <expression>;

Example:
q <= input1 or input2;
q <= input1 and input2;
-- 最終執行 q <= input1 and input2; 

 

4.1.3.2 條件信號賦值語句

格式:

<signal_name> <= <signal/value> when <condition1> else
                              <signal/value> when <condition2> else
                                                   .
                                                   .
                                                   .
                              <signal/value> when <conditionN> else                                   
                              <signal/value>;                

 

示例:

 

 

 

4.1.3.3 選擇信號賦值語句

with <expression> select
<signal_name> <= <signal/value> when <condition1>,
                 <signal/value> when <condition2>,
                 <signal/value> when others

 

 

 

4.1.3.4 進程語句

有人說:從本質上講VHDL的所有語句都是並行語句。進程(process)語句是用來給並行的硬件提供順序語句,一個結構體可以包含多個進程,多個進程之間並行運行。進程內部的語句順序執行。

 

 

 (1)進程的工作原理:

 

 

 (2)進程與時鍾:

  • 時鍾的上下沿表示方法:

    

 

 

  •  示意圖:

 

    

 

 

(3)敏感表和wait語句

  • 敏感表和WAIT語句等效, 但WAIT語句更多樣化 
  • 一個進程不可既有敏感 表,又有WAIT語句,但 要有一種
  • 邏輯綜合對WAIT有嚴格 的限制(只有wait until語句可以綜合)

       

  • wait until語句
    • 語法:
      wait until condition;
    • 可綜合
    • 示例:
      architecture arc2 of process_wait is 
      begin  
      process    
      begin   
          wait until clk'event and clk = '1';    
           q<=d;  
      end process;
      end architecture; 
  • wait on 語句
    • 語法:
      wait on sensitivity list;
      wait
      on (a,b,c); --敏感表
       
    • sensitivity list信號敏感表里任意一個發生變化才會執行 
    • 不太可能綜合(特別是時序電路,實際電路不可能接受 上升沿和下降沿觸發) 

(4)注意:

  • 進程內部,對同一信號多次賦值,只最后一次起作用,即最靠近end process;的,如:
    process(a,b,s)  
    begin   
        --final results: s<=a+b y<=a+b+1              
        y<=s+1;    
        s<=a;              
        s=a+b;  
    end process; 
  • 進程內部,對同一變量多次賦值,立即執行。如:
    process(a,b)  
    variable ss: std_logic_vector(3 downto 0); 
    begin  
        ss:=a;  
        y<=ss+1;
        ss:=a+b; 
    end process;
    --結果:由於y<=ss+1寫在ss:=a之后,所以將a+1的值賦給y  

4.1.3.5 塊語句

塊(BLOCK)語句是一種將結構體中的並行描述語句進行組合的方法,它的主要目的是改善並行語句及其結構的可讀性,或是利用BLOCK的保護表達式關閉某些信號。 

塊標號:BLOCK [(塊保護表達式)] [IS]
接口說明;
類屬說明;
BEGIN
並行語句; 
END BLOCK [塊標號]; 

 

 

4.1.3.6 元件例化語句 

  • 元件例化就是將預先設計好的設計實體定義為一個元件,然后利用特定的語句將此元件與當前的設計實體中的指定端口相連接,從而為當前設計實體引入一個新的低一級的設計層次。
  • 元件例化語句由兩部分組成,前一部分是將一個現成的設計實體定義為一個元件的語句,第二部分則是此元件與當前設計實體中的連接說明。
COMPONENT  元件名 [IS] 
[GENERIC(類屬表)說明;] 
[PORT (端口名表)說明;] 
END COMPONENT 元件名; 

4.1.3.7 生成語句 

  • 生成語句作用:復制
  • 根據某些條件設置好某一元件或設計單位,可以用生成語句復制一組完全相同的並行元件或設計單元電路 
[標號:]   for 循環變量 in 取值范圍 generate 
[聲明部分] 
begin       
並行語句; 
end generate [標號]; 

 

取值范圍: 表達式 to 表達式   或者    表達式 downto 表達式 

 

4.1.3.8 並行過程調用語句  

  • 並行過程調用語句作為並行語句直接出現在結構體中
  • 調用語句可以為:過程(Procedure)或函數 (Function)
  • 調用的語法格式:過程名/函數名(關聯參數表) 
  • 函數和過程統稱子程序 

(1)過程

  • 特點:
    • 參數可以是 in, out, inout 模式

      • 輸入參數(in)的默認數據類型是constant

      • 輸出參數(out)或者inout參數默認數據類型variable

      • 參數對象可為 constant, variable and signal
      • 過程調用參數需要一一對應,形參為constant, 實參可以為signal、constant或variable;形參若 為signal或variable,則實參需對應一致的類型 

 

    • 其特征是過程中可以修改參數值(out,inout模式 參數)
    • 不需要RETURN語句 
  • 語法:
    PROCEDURE procedure_name (mode_parameters) IS   
    [聲明部分] 
    BEGIN 
    順序語句; 
    END [PROCEDURE ] [procedure_name];  
  • 函數一般定義在包中(聲明及實現)

(2)函數

  • 特點:
    • 產生一個返回值。
    • 參數只能為in模式。
    • 傳遞的參數在函數內部只能使用不能修改(因為參數為in)。
    • 允許的參數數據類型為 constant或signal,默認constant。
    • 形參和實參必須匹配。形參為constant,則實參可以是variable、signal、 constant或表達式;形參為signal,實參要為 signal。
    • 需要一個RETURN 語句 。
  • 語法:
    FUNCTION function_name (input_parameters) 
    RETURN data_type IS   
    [聲明部分]; 
    BEGIN   
    順序語句; 
    RETURN 聲明名; 
    END [FUNCTION] [function_name];
  • 函數一般定義在包中(聲明及實現)

(3)過程與函數的區別:

  • 函數參數只能使用IN。過程中參數為IN、 INOUT、OUT三種。 
  • 函數只有一個返回值。過程可以通過參數返回 多個返回值。

4.2 順序語句

4.2.1 順序語句的特點

  順序語句的特點是執行順序和書寫順序基本一致 。

4.2.2 順序語句的種類及詳解

  1. 順序信號/變量賦值語句
  2. IF-THEN 語句
  3. CASE 語句
  4. LOOP 語句
  5. RETURN語句
  6. NULL語句 

4.2.2.1 順序 信號/變量賦值語句

(1)進程中的順序信號賦值語句:

  • signal<=expression;
  • End process時更新
  • 多次賦值,以最后一次賦值為准

(2)進程中的順序變量賦值語句:

  • variable:= expression;
  • 立刻更新
  • 多次賦值,以最后一次賦值為准 
  • 注意:當含有信號且信號需變量為其賦值時,改變量選用信號賦值語句前的。如該示例

4.2.2.2 if-then 語句

  • 從上到下按照順序評估條件,存在優先級 。
  • 若第一個條件滿足,可以執行對應的順序語句。 其他的都不再執行。
  • 如果所有的條件都不滿足,將執行ELSE之內的語句。
  • 可以嵌套使用。

示例:

4.2.2.3 case語句

  • 條件只被評估一次
  • 沒有優先級必須包括所有的條件(可以沒有when others,但是必須包含所有條件)
  • WHEN OTHERS 語句包括了沒有指定的所有條件

示例:

 with 語句是不能在process 內的。

4.2.2.4 loop 語句

(1)無限 loop 。Loop 將無限執行,除非 EXIT 語句存在 。

(2)WHILE LOOP 。條件滿足,則循環 。

(3)FOR LOOP。迭代 loop 。

 示例:

四位左移:

 

4.2.2.5 return 語句

Return語句是一段子程序結束后,返回主程序的語句。

格式:

return;--只能用於過程,它后面不要有表達式   

return 表達式;--只用於函數,它后面必須有表達式,函數結束必須用return語句

示例:

  • 過程:

  • 函數:

4.2.2.6 NULL語句

空操作。

格式:

NULL

示例:

4.2.3 異步復位與同步復位

(1)異步復位(清零)

process(clk, reset, a)
begin
    if clk'event and clk = '1' then
        q <= a + 1;
   -- 高位復位 elsif reset
= '1' then q <= '0'; end if; end process;

(2)同步復位(清零)

process(clk, reset, a)
begin
   -- 高位復位
   if clk'event and clk = '1' then
        if reset = '1' then
            q <= '0'
        else
            q <= a + 1;
    end if;
end process;        

示例

(1)使用異步reset的8-bit寄存器 

-- 使用異步reset的8-bit寄存器 
LIBRARY ieee;
USE ieee.std_logic_1164.all; 
 
ENTITY reg8 IS  PORT (D : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);    
Resetn, Clock : IN  STD_LOGIC;   
Q : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0) ); 
END reg8; 
 
ARCHITECTURE behavioral OF reg8 IS  
BEGIN  
PROCESS ( Resetn, Clock )  
BEGIN   
IF Resetn = '0' THEN    
    Q <= "00000000";   
ELSIF rising_edge(Clock) THEN    
    Q <= D;   
END IF;  
END PROCESS; 
END behavioral;` 

 

(2)使用異步reset的N-bit寄存器 

-- 使用異步reset的N-bit寄存器 
LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
 
ENTITY regn IS  
GENERIC ( N : INTEGER := 16 );  
PORT ( D : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);    
Resetn, Clock : IN STD_LOGIC;    
Q : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0) 
); 
END regn; 
 
ARCHITECTURE behavioral OF regn IS  
BEGIN  
PROCESS ( Resetn, Clock )  
BEGIN   
IF Resetn = '0' THEN Q <= (OTHERS => '0'); -- 給Q的所有位賦0,方便用於多位信號的賦值操作  
ELSIF rising_edge(Clock) THEN    
    Q <= D;   
END IF;  
END PROCESS ; 
END behavioral ; 

 

4.2.4 計數器

(1)使用變量的計數器 

4.2.5 全加器

示例:

(1)數據流描述

 

 (2)4-bit 帶進位全加器 (結構化描述)

 

   

 

 

 

 (3)4-bit 帶進位全加器 (行為描述)

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity adder4_full is
    port(
        a : in std_logic_vector(3 downto 0);
        b : in std_logic_vector(3 downto 0);
        ci : in std_logic;
        s : out std_logic_vector(3 downto 0);
        co : out std_logic;
    ); 
end adder4_full;
architecture RTL of adder4_full is
begin
    process(a, b, ci)
        variable a_t, b_t, c_t, s_t : std_logic_vector(4 downto 0);
    begin
    -- & 拼接運算符
        a_t:='0'&a;
        b_t:='0'&b;
        c_t:="0000"&ci;
        s_t:=a_t + b_t + c_t;
        co<=s_t(4);
        s<=s_t(3 downto 0);
    end process;
end RTL;

 

4.2.6 總結

在一個進程中,可以有多個語句

需要考慮的問題:

當敏感表中的信號發生變化,此進程將被激活。一旦被激活,在進程中的所有語句都將順序執行一次。

進程中對信號的任何賦值在進程之外是不可見的,直到進程執行結束,才會更新信號。

如果有多個語句對同一個信號賦值,只有最后一個是可見的,或有效的 。 

5 Quartus-II 使用

 

6 有限狀態機

  狀態機由狀態寄存器和組合邏輯電路構成,能夠根據控制信號按照預先設定的狀態進行狀態轉移,是協調相關信號動作,完成特定操作的控制中心。

狀態機分為摩爾(Moore)型狀態機和米莉(Mealy)型狀態機。

  • 摩爾(Moore)型狀態機:若輸出只和狀態有關,與輸入無關,則稱為Moore狀態機。

  

 

 

 

  • 米莉(Mealy)型狀態機:輸出與狀態和輸入有關,則稱為Mealy狀態機。

 

 

 

 

 

 

 

 

6.1 摩爾型狀態機

示例:

 

 

(1)單進程的Moore FSM 

 

 

 

(2)雙進程的Moore FSM 

 

 

 

 

 

 

 

 

 

(3)三進程的Moore FSM 

 

 

6.2 米莉型狀態機

示例1:

示例2:

 

 

 

 

 

 

 

7 常用VHDL

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM