我的 FPGA 學習歷程(15)—— Verilog 的 always 語句綜合


在本篇里,我們討論 Verilog 語言的綜合問題,Verilog HDL (Hardware Description Language) 中文名為硬件描述語言,而不是硬件設計語言。這個名稱提醒我們是在描述硬件,即用代碼畫圖。

在 Verilog 語言中,always 塊是一種常用的功能模塊,也是結構最復雜的部分。筆者初學時經常為 always 語句的編寫而苦惱,不知道使用哪種賦值語句,不了解兩種賦值之間的區別。究其本質是對 always 語句的綜合一知半解,常年使用軟件思維編寫代碼所致。

現在我總結出:always 塊的綜合可以分為至少三類電路,由於歷史原因,三種電路均使用 always 關鍵字。

此外 reg 關鍵字也存在一些迷惑性,綜合器並不一定生成寄存器。
reg 在 verilog 語法中的定義為變量,它有可能是寄存器,也有可能是連線。

第一類就是組合邏輯,如代碼 1-1 和 代碼 1-2

// 1-1 組合邏輯 
always @ (*)
begin
    if(a>b)
        q = 1;
    else    
        q = 0;
end

代碼 1-1 是展示了一個簡單組合邏輯的 always 塊,它應該被綜合成一個一位的比較器。

// 1-2 組合邏輯,缺少敏感信號
always @ (a)
begin
    if(a>b)
        q = 1;
    else    
        q = 0;
end

代碼 1-2 也是一個組合邏輯,與 1-1 不同的是,敏感信號列表中沒有 b。

我們知道,在 Verilog 語法中, always 塊的含義是一個重復執行的語句。

那么 1-2 會綜合成一個比較器:

  • 當 a 發生變化時,q 發生變化
  • 當 b 發生變化,由於 b 不再敏感信號列表中,所以 q 不變

這是一個徹頭徹尾的軟件思維,世界上不存在這種電路,綜合器多半會綜合一個與代碼 1-1 一樣的電路,然后報一個警告。

編寫組合邏輯的 always 塊,使用 * 代替敏感信號列表是一個簡單方便而且不容易出錯的好辦法。

第二類就是時序邏輯

// 2-1 時序邏輯
reg [1:0] q;
always @ (posedge clk)
begin
    q <= q + 1'b1;
end

注意:這里使用的是阻塞賦值,我們的 q 這個時候被綜合成一個寄存器,而不是一個軟件上的變量。

代碼 2-1 是一個時序邏輯單元,它應該被綜合成一個計數器,每當時鍾的上升沿,q 自增一。綜合后的 部分 RTL 圖如下:

我們可以看到,q 通過了一個加法器,加法器是兩位的。

而關鍵的 always 塊的綜合結果如下圖所示:

我們可以看到,always 塊綜合了一個時鍾上升沿觸發的 D 觸發器。每當時鍾的上升沿,D 觸發器就把輸入 D 傳遞到另一側 Q。

綜合器就這樣完成了我們的設計意圖:D 的左側總是等於 Q+1,只有在 時鍾的上升沿,才完成值的傳遞。完整的RTL 圖如下:

// 2-2 時序邏輯,帶異步復位
reg [1:0] q;
always @ (posedge clk or negedge rst_n)
begin
    if(!rst_n)
        q <= 2'b00;
    else
        q <= q + 1'b1;
end

綜合后的 RTL 圖如下:

代碼2-2綜合成一個帶有清零端的 D 觸發器,其余與 2-1 無異。

// 2-3 時序邏輯,帶同步置位
reg [1:0] q;
always @ (posedge clk or posedge set)
begin
	if(set)
		q <= 2'b11;
	else    
		q <= q + 1'b1;
end

代碼 2-3 綜合成一個帶有同步置位的 D 觸發器,其余與 2-1 無異。

// 2-4 時序邏輯,帶同步置位和異步復位
reg [1:0] q;
always @ (posedge clk or posedge set or negedge rst_n)
begin
	if(!rst_n)
		q <= 2'b00;
	else if(set)
		q <= 2'b11;
	else    
		q <= q + 1'b1;
end

RTL 圖:

可以看到多了個與門,代碼 2-4 是代碼 2-2 和 代碼 2-3 的組合結果。

當然咯,這里的綜合是指的邏輯綜合,而實際上的綜合和具體實現與邏輯無關。比如在 FPGA 芯片使用的是查找表LUT,並沒有獨立的組合邏輯。而仿真器則使用編譯方法,仿真器把 verilog 語言編譯為 x86 匯編並直接在 CPU 上運行。

好啦,本篇到這里就結束了,下一篇會深入討論綜合工具的一些其他細節。🤭


免責聲明!

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



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