8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HDLAdvent Calendar 2015

Day 3

SystemVerilogって正規分布関数ないんだってよ

Posted at

はじめに

大変ご無沙汰しております。@mizutomo と申します。本当に久しぶりに文を書いています。どれぐらい久しぶりかというと、Qiitaに記事を書くときに、右側にプレビューがon the flyで出てきているのに、びっくりした、というレベルです。

ところで、ランダム検証ってされていますか? 僕は、論理屋じゃないので、使ったこともないです。でも、たまに乱数は使いたくなるんですよね。それで、SystemVerilogで正規分布を生成する関数は。。。。とググったら、「えっ、ないやん><」。

うそ〜ん。ランダム検証とか言ってるぐらいだから、乱数周りに関しては、めちゃくちゃ充実していると思ってた。。。

「安心して下さい。使えます。」

はい。単純にDPI-Cを使えばいいんですね。ないものは、自分で作って組み込め、というのが、SystemVerilogの精神のようです(本当?)。

DPI-Cに関しては、この本を参照して下さい。SystemVerilog設計スタートアップ DPI-Cに関しては、@Vengineer 先生が丁寧に書かれています。

正規分布の生成

さて、乱数を生成する関数は、C言語による乱数生成 こちらのサイトから借用させて頂きます。Mersenne-Twister法を解説されていたりして、非常に助かります。

gauss.c
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <svdpi.h>

double uniform() {
  return ((double)rand() + 1.0)/((double)RAND_MAX + 2.0);
}

double rand_normal(double mu, double sigma) {
  double z = sqrt(-2.0 * log(uniform())) * sin(2.0*M_PI*uniform());
  return mu + sigma*z;
}

ここでは、乱数の生成にCのrand()関数を使っています。先ほどのサイトや、Numerical Recipesに解説があるように、Cのrand()関数は、周期性を持った乱数列なので、実用には適しません。実用としては、メルセーヌ-ツイスター法がいいんでしょうかね。

で、実際にSystemVerilogと絡むところって、**#include <svdpi.h>**を置いたぐらいですよね。

正規分布を呼ぶ側

次は、先ほどのCのコードを呼ぶSystemVerilogのコードです。

gauss.sv
`timescale 1ns/1ns

import "DPI-C" pure function real rand_normal(real mu, real sigma);

module test();
  real rand_val;
  int i;

  initial begin
    for (i = 0; i < 10; i++) begin
      rand_val = rand_normal(0, 1);
      $monitor("%d: %g", i, rand_val);
      #10;
    end
    $finish;
  end
endmodule

おっふ、めちゃくちゃ簡単じゃないですか。実質、Cコードを呼ぶためにやったことは、**import "DPI-C"**としたことぐらいです。

あとは、シミュレータ側で勝手にCのコードをコンパイルして、実行ファイルを作ってくれます。
(昨日、とあるシミュレータで実行したら、稀に共有ライブラリが作成されないことが。そのようなときは、手動で共有ライブラリを作ればよいです。@ginnyu_tei さんの記事が参考になります。)

何に使うの?

私の場合は、デバイス雑音などの効果をデジタルシミュレーションに入れ込むときに、このような方法を使っています。例えば、Kundert先生がVerilog-AMSでモデリングしているVCOの位相雑音のモデルをVerilogで使用する場合ですね。Verilog-AMSには、$rdist_normalというシステムタスクが用意されているので、何も考えずに、正規分布が使えちゃうのですが、それと同じことをVerilogでやろうとすると、、、自分で作らないといけないようです。

何で、Verilog-AMSでできているものを、Verilogシミュレータでやる必要があるの?というと、やっぱり、Verilogシミュレータは高速なんですよね。AMSシミュレータに比べると。でも、HDLシミュレータは、Δ遅延があるので、嫌いです。

ところで、DPI-Cは本当に便利ですね。これだけでも、Verilog HDLを捨てて、SystemVerilogに切り替えるというメリットが有るんじゃないかと思います。みんなが大好きPythonとつなぐのも簡単ですよね〜。ということで、そのうち、誰かがSystemVerilogとPythonをつなぐ記事を書いてくれると期待しています。自分は書きません。

余談

昨日、とあるシミュレータにポーティングしていたのですが、SVには、$absもなかったんですね。かなりびっくりしました。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?