數字IC設計 FPGA——再談乘法器設計(使用Verilog 原語 LUT 進行四位乘法器設計)

擺渡滄桑發表於2019-11-06

數字IC設計 FPGA——再談乘法器設計(使用Verilog 原語 LUT 進行四位乘法器設計)

乘法器同加法器一樣,在數字訊號的各種演算法中被頻繁的使用,並且對於整個系統的速度的影響是很大的。那麼如何實現快速高效的乘法器關係著整個系統的運算速度和資源效率最大化的利用。

乘法操作分為有符號操作和無符號操作兩大類,無符號操作相對於有符號乘法操作相對簡單,但也只需要簡單的變換就能有符號乘法器變換為無符號乘法器。

本次主要是基於Verilog 原語LUT 進行乘法器的設計。
相關的乘法器知識可以參考之前的博文:

數位電路基礎知識——組合邏輯電路之乘法器的設計(一)—— 並行、移位相加、加法樹、查詢表乘法器
數位電路基礎知識——乘法器的設計(二)( 序列、流水線、有符號數八位乘法器)

一、乘法器架構
  1. 乘法器
    由於乘數和被乘數都是二進位制,所以利用人工計算來分析,所以利用乘數從最後一位到第第一位每一位依次與被乘數相乘,從第二位開始每一位都要依次左移一位,形成一個陣列的式。而由於兩個一位二進位制數相乘,實際上是做與運算,所以就將乘法操作簡化為了與運算、移位操作以及加法操作。比如 1011與 1101相 乘,如圖,實際上可看作 1011+00000+101100+1011000四個數相加。
    在這裡插入圖片描述
  2. 乘法器結構
    乘法運算是由與、或、非等基本邏輯組合而成的,如下圖所示是乘法器內部結構圖
    在這裡插入圖片描述
二、乘法器的 Verilog 原語設計
  1. 設計思路
    使乘法器的輸入分別為A[3:0]和B[3:0],設計思路先計算出相與的結果,將相與的結果一次移位相加得到最後的結果。移位相加所使用的全加器是之前在下面這篇部落格中以LUT3設計的一位全加器。
    數字IC設計 FPGA——再談加法器設計(使用Verilog 原語 進行四位加法器設計)
    並設定中間變數:
    t0,t1,t2,t3:第一行至第四行相與的結果
    ts0,ts1,ts2,ts3:第一行至第四行的結果輸出
    tc0,tc1,tc2,tc3:第一行至第四行的進位輸出
  2. Verilog程式碼
module addr_4bit(
A,B,Y
    );

input [3:0] A,B;
output [7:0] Y;

wire [3:0] t0,t1,t2,t3; //每一行相與結果
wire [3:0] ts0,ts1,ts2,ts3; //每一行的相加的結果輸出
wire [3:0] tc0,tc1,tc2,tc3; //每一行的進位輸出

genvar i;
generate
   for (i=0;i<4;i=i+1)
   begin: label1  
        assign t0[i] = A[i] & B[0];
        assign t1[i] = A[i] & B[1];
        assign t2[i] = A[i] & B[2];
        assign t3[i] = A[i] & B[3];
   end  
endgenerate

genvar j;
generate
    for (j=0;j<4;j=j+1)
    begin:label2
        assign ts0[j]= t0[j];
        assign tc0[j] = 1'b0;
    end
endgenerate

genvar m;
generate
   for (m=0;m<3;m=m+1)
   begin: label3
        addr_bit u1(
        .A(t1[m]),
        .B(ts0[m+1]),
        .S(ts1[m]),
        .Cout(tc1[m]),
        .Cin(tc0[m])
        ); 
   end  

   for (m=0;m<3;m=m+1)
   begin: label4
        addr_bit u2(
        .A(t2[m]),
        .B(ts1[m+1]),
        .S(ts2[m]),
        .Cout(tc2[m]),
        .Cin(tc1[m])
        ); 
   end  

   for (m=0;m<3;m=m+1)
   begin: label5
        addr_bit u3(
        .A(t3[m]),
        .B(ts2[m+1]),
        .S(ts3[m]),
        .Cout(tc3[m]),
        .Cin(tc2[m])
        ); 
   end  
endgenerate


assign ts1[3]=t1[3];
assign ts2[3]=t2[3];
assign ts3[3]=t3[3];

wire [3:0] rac,ras;

assign rac[0]= 1'b0;

genvar n;
generate
    for (n=0;n<3;n=n+1)
    begin :label6
        addr_bit u4(
        .A(rac[n]),
        .B(ts3[n+1]),
        .S(ras[n]),
        .Cin(tc3[n]),
        .Cout(rac[n+1])
        );
    end
endgenerate

assign Y[0]=ts0[0];
assign Y[1]=ts1[0];
assign Y[2]=ts2[0];
assign Y[3]=ts3[0];


genvar p;
generate
    for (p=4;p<7;p=p+1)
    begin:label7
        assign Y[p]=ras[p-4];
    end
endgenerate

assign Y[7]=rac[3];
endmodule

rac和ras是高四位的進位輸出和結果輸出相與的結果。必須要想加才能得到正確的結果。

  1. RTL結構圖
    在這裡插入圖片描述
  2. 模擬結果如下:
    可以看到有正確的輸出結果和進位輸出
    在這裡插入圖片描述
  3. 綜合之後資源的利用在這裡插入圖片描述
    40LUT包括24個LUT3和16個LUT2(與門)
三、總結
  1. 使用該乘法器能夠擴充為其他新的位寬的乘法器。該乘法器可能不是最好的乘法器架構。
  2. 如果再不採用原語進行設計的情況下,直接編寫加法器Verilog程式碼,綜合工具會根據自己的演算法給出一個比較合理的電路,可能會比我們採用後一種方法設計的要更好,這需要依賴EDA綜合工具。
  3. 但是通過了解CLB的不同的基本配置方式以及內部資源分佈,對於更好理解軟體綜合過程和設計具有更好的指導意義
  4. 如果能再關鍵的位置手動配置硬體資源,可能會改善區域性效能,這對於高效能運算硬體有重要意義,尤其是底層的硬體加法等部件。

相關文章