ご存知かもしれませんが、MIPS命令セットは次のようにclz(先行ゼロのカウント)をサポートしています。
clz $ t0、$t1先行ゼロをカウントt0=t1の先行ゼロの数
私はVerilogでシングルサイクルデータパスを書いていますが、これを行うためにALUが何をサポートする必要があるのか疑問に思っていました...何かアイデアはありますか?
考えられるアプローチは次のとおりです(入力が0の場合は無視します。これは、おそらく特別な場合として最も適切に扱われます)。
Verilogでは、次のようになります。
result[4] = (value[31:16] == 16'b0);
val16 = result[4] ? value[15:0] : value[31:16];
result[3] = (val16[15:8] == 8'b0);
val8 = result[3] ? val16[7:0] : val16[15:8];
result[2] = (val8[7:4] == 4'b0);
val4 = result[2] ? val8[3:0] : val8[7:4];
result[1] = (val4[3:2] == 2'b0);
result[0] = result[1] ? ~val4[1] : ~val4[3];
私が考えることができる最も単純な実装(あまり最適化されていない)は、32(32ビットの場合)マスクに対して単語をチェックし、最も長いものを最初にチェックし、どちらが最初に適合するかを決定し、その番号を返すことです。
(擬似コード)のようなもの:
if word == 0: return 32
elsif (word & 1) == 0: return 31
elsif (word & 3) == 0: return 30
等
16ビットを調べ、4ビットの結果(0..15)と「allzero」出力を持つclz16ユニットを構築します。これらのうちの2つを組み合わせてclz32を作成します。マルチプレクサを使用して、下位4ビットと上位2出力ビットのロジックを選択する必要があります。
clz16は、同じように2つのclz8で構成されています。clz8は2つのclz4で構成されています。clz4は、<= 4入力の3つのブール関数であるため、どのように実行するかはそれほど重要ではありません。synthはそれをいくつかのゲートに要約します。
この階層的アプローチは、カスケードされたマルチプレクサを使用したMatthew Slatteryのソリューションよりも大きいですが、おそらくそれほどではなく(マルチプレクサを切り替えるために広いゲートは必要ありません)、より低いプロップが可能になると思います。遅れ。どちらのアプローチも、遅延プロップを使用して、より大きなサイズ(64、128ビットなど)に適切に拡張できます。log2(n)に。