Verilog数学関数のマスター:効率的なハードウェア設計のために
Verilog数学関数は定数式の代わりに使用でき、整数と実数の両方の数学をサポートしています。
整数数学関数
関数$clog2は、与えられた引数のlog2の天井(切り上げ)を返します。これは通常、与えられたサイズのメモリをアドレッシングするために必要な最小ビット幅を計算するために使用されます。
例えば、設計に7つの並列アダーがある場合、すべての7つのアダーを表現するために必要な最小ビット数は、7の$clog2であり、3になります。
module des #(parameter NUM_UNITS = 7)
// このシステム関数の使用により、このモジュールへの
// 入力ワイヤ数を削減できる
(input [$clog2(NUM_UNITS)-1:0] active_unit);
initial $monitor("active_unit = %d", active_unit);
endmodule
`define NUM_UNITS 5
module tb;
integer i;
reg [`NUM_UNITS-1:0] active_unit;
des #(.NUM_UNITS(`NUM_UNITS)) u0(active_unit);
initial begin
active_unit = 1;
#10 active_unit = 7;
#10 active_unit = 8;
end
endmodule
信号active_unitが全5ユニットを格納するために3ビットであることに注意してください。
xcelium> run active_unit = 001 active_unit = 111 active_unit = 000 xmsim: *W,RNQUIE: Simulation is complete.
実数数学関数
これらのシステム関数は実数引数を受け取り、実数を返します。
| 関数 | 説明 |
|---|---|
| $ln(x) | 自然対数 log(x) |
| $log10(x) | 常用対数 log10(x) |
| $exp(x) | xの指数関数 (ex) ここでe=2.718281828... |
| $sqrt(x) | xの平方根 |
| $pow(x, y) | xy |
| $floor(x) | xの床関数(切り下げ) |
| $ceil(x) | xの天井関数(切り上げ) |
| $sin(x) | xの正弦(xはラジアン) |
| $cos(x) | xの余弦(xはラジアン) |
| $tan(x) | xの正接(xはラジアン) |
| $asin(x) | xのアーク正弦 |
| $acos(x) | xのアーク余弦 |
| $atan(x) | xのアーク正接 |
| $atan2(x, y) | x/yのアーク正接 |
| $hypot(x, y) | xとyの斜辺:sqrt(x2 + y2) |
| $sinh(x) | xの双曲線正弦 |
| $cosh(x) | xの双曲線余弦 |
| $tanh(x) | xの双曲線正接 |
| $asinh(x) | xの逆双曲線正弦 |
| $acosh(x) | xの逆双曲線余弦 |
| $atanh(x) | xの逆双曲線正接 |
module tb;
real x, y;
initial begin
x = 10000;
$display("$log10(%0.3f) = %0.3f", x, $log10(x));
x = 1;
$display("$ln(%0.3f) = %0.3f", x, $ln(x));
x = 2;
$display("$exp(%0.3f) = %0.3f", x, $exp(x));
x = 25;
$display("$sqrt(%0.3f) = %0.3f", x, $sqrt(x));
x = 5; y = 3;
$display("$pow(%0.3f, %0.3f) = %0.3f", x, y, $pow(x, y));
x = 2.7813;
$display("$floor(%0.3f) = %0.3f", x, $floor(x));
x = 7.1111;
$display("$ceil(%0.3f) = %0.3f", x, $ceil(x));
x = 30 * (22.0/7.0) / 180; // 30度をラジアンに変換
$display("$sin(%0.3f) = %0.3f", x, $sin(x));
x = 90 * (22.0/7.0) / 180;
$display("$cos(%0.3f) = %0.3f", x, $cos(x));
x = 45 * (22.0/7.0) / 180;
$display("$tan(%0.3f) = %0.3f", x, $tan(x));
x = 0.5;
$display("$asin(%0.3f) = %0.3f rad, %0.3f deg", x, $asin(x), $asin(x) * 7.0/22.0 * 180);
x = 0;
$display("$acos(%0.3f) = %0.3f rad, %0.3f deg", x, $acos(x), $acos(x) * 7.0/22.0 * 180);
x = 1;
$display("$atan(%0.3f) = %0.3f rad, %f deg", x, $atan(x), $atan(x) * 7.0/22.0 * 180);
end
endmodule
xcelium> run $log10(10000.000) = 4.000 $ln(1.000) = 0.000 $exp(2.000) = 7.389 $sqrt(25.000) = 5.000 $pow(5.000, 3.000) = 125.000 $floor(2.781) = 2.000 $ceil(7.111) = 8.000 $sin(0.524) = 0.500 $cos(1.571) = -0.001 $tan(0.786) = 1.001 $asin(0.500) = 0.524 rad, 29.988 deg $acos(0.000) = 1.571 rad, 89.964 deg $atan(1.000) = 0.785 rad, 44.981895 deg xmsim: *W,RNQUIE: Simulation is complete.
Verilog
- Verilogマスター:デジタル回路設計のための完全チュートリアル
- Verilog連結マスター:実践ガイド
- Verilog代入文の理解:種類、構文、ベストプラクティス
- Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
- Verilog関数のマスター:効率的なRTL設計のために
- Verilogタスクの理解:関数との違い、構文、使用法
- Verilogクロックジェネレータ:設計と実装ガイド
- Verilog $timeformatのマスター:精度と表示制御
- 任意のスコープでのVerilog timescale理解と表示
- VerilogファイルI/Oの完全ガイド:オープン、読み取り、書き込み、クローズ
- Verilog入門:Hello World例で基本をマスター