Verilog設計實務_Day1

Verilog設計實務_Day1

更新於 發佈於 閱讀時間約 7 分鐘

前導

Verilog 是一種 硬體描述語言(HDL, Hardware Description Language)。

HDL 類似於一般的電腦程式語言,例如 C 語言,但它專門用於描述硬體結構和邏輯電路的行為。這使得 HDL 與其他用於數值計算的語言有所不同。

  • HDL 模型還可以將大型電路劃分為多個相互連接的小功能單元。
  • 透過電腦模擬來顯示數位系統的行為,這可以幫助檢測設計中的功能錯誤,而無需實際製造電路。
  • 如果在模擬過程中發現錯誤,設計人員可以透過修改 HDL 語句來修正這些錯誤。

Verilog 基本架構

  • Verilog 主要的架構就是模組(module)。
  • 每一個 Verilog 檔案,必須包含一個 Module。
  • 每個模組代表一個硬體單元。模組包含輸入、輸出、內部信號和邏輯行為的描述。
  • Module 就像是積木,而一個大型的數位系統就是由一些特定功能的積木組成。

基本架構如下:

module 模組名稱( 輸出入埠名稱 );
......
endmodule

資料類型

Verilog 中有兩種主要的資料類型:

  • 用於連接硬體元件,例如 wire。本質上是一條導線的意思(電路中的連接線),它不儲存任何數據,只是將一個訊號從一個地方傳遞到另一個地方。
  • 用於暫存資料,例如 reg

識別字與關鍵字

  • 識別字(Identifier): 用來命名變數、模組等,例如 my_signal
  • 關鍵字(Keyword): Verilog 保留的特殊詞,例如 module, input, output, wire

註解與空白

  • 單行註解: // 這是單行註解
  • 多行註解: /* 這是多行註解 */

設計模式

我們要描述模組的電路架構與功能,主要有四種層次的描述:

  • 電晶體層次(Switch Level)
  • 邏輯閘層次(Gate Level)
  • 資料流層次(Dataflow Level)
  • 行為層次(Behavior Level)

行為層次與資料流層次合稱"暫存器轉換層次 RTL(Register Transfer Level )。

另外,在大學中,通常只會接觸到 邏輯閘層次(Gate Level)、資料流層次(Dataflow Level)、行為層次(Behavior Level)。


簡單範例:

假設我今天要描述 全加器(FA) 電路,如下圖:

raw-image

使用 邏輯閘層次(Gate Level)描述電路

以下示範:

module full_adder(x, y, c_in, s, c_out);

input x, y, c_in; // 宣告輸入埠:x、y 為兩個加數,c_in 為來自前一位的進位輸入。
output s, c_out; // 宣告輸出埠:s 為本位的和,c_out 為向高位的進位訊號。

wire s1, c1, c2, c3;

// XOR gate for sum calculation
xor G1 (s1, x, y);
xor G2 (s, s1, c_in);

// AND gates for carry calculation
and G3 (c1, x, y);
and G4 (c2, x, c_in);
and G5 (c3, y, c_in);

// OR gate to get the final carry-out
or G6 (c_out, c1, c2, c3);

endmodule


使用 資料流層次(Dataflow Level)描述電路

指以邏輯運算式的方式來表達輸入與輸出之間的關係,而不涉及閘級或行為描述。在這層次,我們會根據布林代數推導出輸出位元的邏輯關係。

也就是說,我們只需要知道:

  • s(和):
raw-image
  • c_out(進位):
raw-image

最後透過assign來建立輸出與輸入的持續性對應關係。也就是說,只要運算元變化,輸出就會立即更新。

assign 並不是「賦值」的概念,而是建立一條「訊號關係」。

以下示範:

module full_adder (x, y, c_in, s, c_out);

input x,
input y,
input c_in,
output s,
output c_out

assign s = x ^ y ^ c_in;
assign c_out = (x & y) | (x & c_in) | (y & c_in);

endmodule


使用 行為層次(Behavior Level)描述電路

使用 always 區塊,區塊內可以放入複雜的控制結構描述方式來描述電路。

另外,有幾個需要注意的點:

  • 寫在always裡面的被賦值變數必須是宣告成reg的形式。
  • assign不能出現在 always 區塊內。

以下示範:

module full_adder(x, y, c_in, s, c_out);
input x, y, c_in;
output reg s, c_out;

// always 區塊:描述當任何一個輸入變化時,輸出應如何改變。"*" 代表所有輸入。
//​ always @(*) 用於組合邏輯
always @(*) begin
{c_out, s} = x + y + c_in;
end
endmodule

其中:

{c_out, s} = x + y + c_in;
  • {} 為串接運算子,用於將多個信號或數值按指定順序合併成一個更寬的總資料體。
  • 所以這行程次碼表示將 xyc_in 三個 1-bit 值相加。
  • 其結果為一個 2-bit 的總和:高位指派給 c_out(進位),低位指派給 s(和)。
avatar-img
電資鼠 - 您的學習好夥伴
8會員
200內容數
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
留言
avatar-img
留言分享你的想法!