VHDL 與一般程式之不同點

VHDL 電路設計

簡介

特性

元件

處理器設計

訊息

相關網站

參考文獻

最新修改

簡體版

English

常聽硬體人員說 VHDL 撰寫與一般程式設計不同,但究竟有何不同呢?

1. VHDL 當中的 <= 符號與一般程式語言當中的 = 或 := 符號具有相當不同的意義, VHDL 的 A <= B 代表線路 B 將會被連接到 A 中,因此,連得不好將不只改變 A 的值,同時也會改變 B 的值,因為 兩條線搭接的結果,可能使 B 變成 'U' : undefine.

例如:

    B <= '1';
     A <= B
     A <= '0';

那 B 應該是甚麼呢 ? (結果為 'U' : Undefine)

又若 A 是一個 buffer 型態的變數,輸入 為 '0' ,則 A <= B 相當於將 B 接地,如此、A <= B 的結果當然與一般程式語言有所不同。

2. 邏輯指令必須涵蓋全面的條件設定

  ...
  done : out std_logic
  ...
  done <= '0';
  ...

  if (ifN='1' and isN='0') then
    done <= '1';
  elsif (ifZ='1' and isZ='0') then
        done <= '1';
  else 
    done <= '0'; -- 注意,要補上 done <= 0; , 否則 done 會變成 undefine            
  end if;

3. Variable 與 signal 是不同的東西,勿混淆

Variable 的指定用 :=
Signal 的指定用 <=

Variable 只是做變數用
但 Signal 是電路中的訊號

若所有變數都用 Signal 則會導致 process 的 sensitivity list 會很長,這語意上是不對的。
process 內部才使用的變數必須用 variable , 而非 signal;

4. 不可有多個來源的輸入訊號,否則會有類似下列的訊息:

Error (10028): Can't resolve multiple constant drivers for net "AluOp[2]" at CPU.vhd(73)

ex : 若有多組值可能輸入到同一個目標,則可能會產生不一致的狀況,例如在設計 CPU 匯流排時,用三態開關控制暫純器輸入到匯流排的部分,可能會產生多組輸入的情況,雖然 CPU 設計者不會同時將兩個以上的開關打開,但是編譯器卻無法聰明到偵測出這種設計,因此、必須改用 if … elsif …. elsif … end if; 的方式處理之。

5. 在同一個 Clock 中指定同一變數兩次值會是錯誤的,例如:

a <= '1'
...
a <= '0'

這樣波形圖應該輸出 a=1 或 a=0 呢?

6. inout 與 buffer 的差別在哪裏呢 ?

  • IN 相當於電路中的只允許輸入的管腳;
  • OUT 相當於只允許輸出的管腳;
  • INOUT 相當於雙向管腳,是在普通輸出埠基礎上增加了一個三態輸出緩衝器和一個輸入緩衝器構成的,既可以作輸入埠,也可以作輸出埠;
  • BUFFER 是帶有輸出緩衝器並可以回讀的管腳,是INOUT的子集,BUFFER作輸入埠使用時,信號不是由外部輸入,而是從輸出埠回饋得到,即BUFFER類的信號在輸出到外部電路的同時,也可以被實體本身的結構體讀入,這種類型的信號常用來描述帶回饋的邏輯電路,如計數器等。

inout 與 buffer 的不同在於 inout 變數不可將值輸出給其他變數, ex : out1 = inout1 , 否則、該變數的值將會變成 undefine.

7 Signal 的變數與 Buffer 變數有所不同,Signal 的變數一但流出,自己的值將會消失變成 Undefine, 但 Buffer 變數不會,因此、不可以用 Signal 變數取代 Buffer 變數.

8. (Others => 'Z')

CNT1可能是一個多位元寬的資料,將其所有位元都賦為1 定義了一個多位元寬資料:

singal cnt1: std_logic_vector(3 downto 0)

下麵對他賦值:

cnt1 <= (others => '0');

表示的意思是

cnt1(3) <= '0';
cnt1(2) <= '0';
cnt1(1) <= '0';
cnt1(0) <= '0';

也可以寫成

cnt1 <= "0000";

用OTHERS寫法的好處是,不需要介意位元寬,如果使用下面的方法,這樣如果修改位寬為5位後,“0000”要改成“00000”,而開始的寫法則不用改。

cnt1 <= (1=>'1', others =>'0') 表示的意思是

cnt1(3) <= '0';
cnt1(2) <= '0';
cnt1(1) <= '1';
cnt1(0) <= '0';

Altera Quartus II 的 Bug :

1. 當 vwf Wave 檔中的輸出入型態與宣告型態不合時, 仍然會執行並輸出,此時應檢查修改 wave 檔輸入型態。

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License