以下の内容はhttps://msyksphinz.hatenablog.com/entry/2025/08/10/040000より取得しました。


Verilog 2001で実装されたBooth乗算器を調査する (3. もう少し実用的なBooth乗算器)

GitHubリポジトリtom01h/yosys_trymul_1.vは32ビット×32ビットの高性能乗算器として設計されており、符号付きおよび符号なし両方の乗算に対応している。

モジュール構成と全体アーキテクチャ

このファイルには2つのモジュールが含まれている:

  1. mulモジュール(メイン乗算器)

    • 32ビット×32ビット → 64ビットの乗算
    • 符号付き/符号なし両対応
    • パイプライン対応(req_valid信号による制御)
  2. boothモジュール(Boothエンコーダ/セレクタ)

    • 3ビット入力によるBooth-2アルゴリズム実装
    • 部分積生成と符号制御

メイン乗算器(mul)の詳細解析

入出力インターフェース

input         clk,            // クロック信号
input         reset,          // リセット信号
input         req_valid,      // リクエスト有効信号
input         req_in_1_signed, // 被乗数の符号フラグ
input         req_in_2_signed, // 乗数の符号フラグ
input [31:0]  req_in_1,       // 32ビット被乗数
input [31:0]  req_in_2,       // 32ビット乗数
output [63:0] resp_result     // 64ビット積

Booth-2エンコーディングの実装

乗数xを2ビットずつ処理するため、17個のBooth群(br0〜br16)に分割している:

wire [2:0] br0 = {x[1:0],1'b0};   // 最下位は0を付加
wire [2:0] br1 = x[3:1];
// ... 中略 ...
wire [2:0] br16 = (x_signed) ? {3{x[31]}} : {2'b00,x[31]};  // 最上位の符号拡張

否定制御(ng)信号の生成

各Booth群に対して否定が必要かを判定する:

wire ng0 = (br0[2:1]==2'b10)|(br0[2:0]==3'b110);

この条件は、Booth-2アルゴリズムにおいて部分積を否定(2の補数)する必要がある場合を示している: - 2'b10: -2倍を示すパターン - 3'b110: -1倍を示すパターン

Boothモジュールの詳細解析

always @(*) begin
   case(br)
     3'b000: by[32:0] =  {33{1'b0}};           // +0倍
     3'b001: by[32:0] =  {y[31]&y_signed,y[31:0]}; // +1倍
     3'b010: by[32:0] =  {y[31]&y_signed,y[31:0]}; // +1倍
     3'b011: by[32:0] =  {y[31:0],1'b0};       // +2倍
     3'b100: by[32:0] = ~{y[31:0],1'b0};       // -2倍(1の補数)
     3'b101: by[32:0] = ~{y[31]&y_signed,y[31:0]}; // -1倍(1の補数)
     3'b110: by[32:0] = ~{y[31]&y_signed,y[31:0]}; // -1倍(1の補数)
     3'b111: by[32:0] =  {33{1'b0}};           // +0倍
   endcase

この実装の特徴: - 符号拡張制御: y[31]&y_signedにより、符号なし数の場合は0拡張 - 1の補数使用: 否定の場合は1の補数を使用し、後で加算器で2の補数に変換

符号ビット生成

wire S = ((br==3'b000)|(br==3'b111)) ? 1'b0 : (y[31]&y_signed)^br[2];

if(i) by[35:33] = {2'b01,~S};
else  by[35:33] = {~S,S,S};

上位ビットの制御により、加算時の符号拡張を適切に処理している。

最終加算器の実装

assign resp_result = (({1'b0,by0}+ng0)) +
                     (({1'b0,by1}+ng1)<<2) +
                     // ... 17項目の加算



以上の内容はhttps://msyksphinz.hatenablog.com/entry/2025/08/10/040000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14