GitHubリポジトリtom01h/yosys_tryのmul_1.vは32ビット×32ビットの高性能乗算器として設計されており、符号付きおよび符号なし両方の乗算に対応している。
モジュール構成と全体アーキテクチャ
このファイルには2つのモジュールが含まれている:
mulモジュール(メイン乗算器)- 32ビット×32ビット → 64ビットの乗算
- 符号付き/符号なし両対応
- パイプライン対応(req_valid信号による制御)
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項目の加算