FPGA Lesson 1 ─ 全加器及漣波進位加法器Verilog實作

前言

本文整理了一系列有關加法的相關數位電路,雖然即使作為數位IC工程師或是FPGA工程師並不會實際創建這些電路,通常是編譯工具進行整合,但作為硬體描述語言的基本是重中之重。

全加器

全加器是初學數位電路設計的基本電路,也是最容易入門的電路。初學者可以先了解全加器的工作原理,再去延伸到其他電路,可以學習到僅僅是通過簡單幾個邏輯閘就能完成許多工程。但實際上FPGA設計者並不會寫一個加法器模組進行調用,編譯軟體運算子已經足夠聰明能夠幫助我們進行整合,但依舊是一個很好入門的數位電路。

從真值表可以化簡為的布林代數,再變成由邏輯閘構成的數位電路(原理圖)

Verilog程式碼 :

module Full_adder(
	input  A_i,
 	input  B_i,
 	input  Cin_i,
	output sum_o,
 	output carry_o
  );

  assign sum_o   = A_i ^ B_i ^ Cin_i;
  assign carry_o = ((A_i ^ B_i) & Cin_i) | (A_i & B_i);

endmodule

如果單位元的全加器了解之後,可以去HDLBits刷題網的全加器試題電路嘗試看看,這邊也一併介紹HDLBits全加器試題電路。

可以看到原理圖有2個16位元的加法器做連接,已經有漣漣波加法器的雛型了。可以看到有各32位元的輸入A,B及32位元的SUM及進位連接。這邊HDLBits已經提供了16位元的加法器能夠調用,這樣調用已完成模組的程式碼,能更貼近FPGA設計人員的程式風格。

Verilog程式碼 :

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
  wire cin;
    
  add16 u0(.a(a[15:0]),.b(b[15:0]),.cin(0),.sum(sum[15:0]),.cout(cin));
  add16 u1(.a(a[31:16]),.b(b[31:16]),.cin(cin),.sum(sum[31:16]),.cout());

endmodule

仿真圖 :

漣波進位加法器

漣波進位加法器是延伸全加器的基本電路,由多級的全加器在一起構成。這邊

由HDLBits的試題進行實作。

這題是上一題的內部細化,需要用單位元的加法器組成16位元的加法器,再調用兩次模組構成32位元加法器,那麼64位元、128位元也是一樣的原理。

可以看到原理圖是由最頂層TOP_Module及第二層的兩個add16及第三層的32個add1所構成的,輸入為2組32位元的a,b,輸出為32位元的sum,進位連接在第三層的內部漣波組成16位元的add16兩組,同時第二層也有add16進位連接構成TOP_Module。一層一層的設計方式也是初學者需要適應的地方,這樣程式碼易讀性才高。這邊HDLBits給了我們add1的模組進行調用,也是單位元的加法器。

Verilog程式碼 :

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
	  wire cout;

    add16 add16_lo(.a(a[15:0]),.b(b[15:0]),.cin(0),.sum(sum[15:0]),.cout(cout));
    add16 add16_hi(.a(a[31:16]),.b(b[31:16]),.cin(cout),.sum(sum[31:16]),.cout()); 
endmodule
	

module add1 ( input a, input b, input cin,   output sum, output cout );

// Full adder module here
    assign {cout,sum} = a + b + cin; 
endmodule

仿真圖:

以上就是這次的教學,也可以嘗試看看更多級的加法電路,但漣波進位會導致電路的延遲變高、工作頻率下降,因為後一級等前一級,如果千級以上的加法不就是需要等待千個延遲時間,所以在設計多級加法電路的時候,需要考慮工作頻率是否在工作範圍內,才不會出事!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *