NSLでの非同期回路の書き方


NSLでの非同期回路の書き方について私なりに書いてみたいと思います。
この記事はNSLの構文をある程度知っていることを前提に書いています。
ですが、わからなくても読めるように後日補足説明は入れたいと思っています。

NSLでの非同期回路の書き方

NSLは基本的には単相クロックをサポートするため
同一モジュール内で複数のクロックを記述することはできないそうです。

そのため以下のような2つ以上のクロック(今回はclk1,clk2)を持つ回路を書きたい場合は

以下の図のようにクロックごとにモジュールを分割して

そして、上位の階層(今回はtop)からクロックを供給することで書くことができます。

コードで書くと

declare FF_clk1 {

  input  in1[4];
  output out1[4];

  func_in set(in1);
  func_in get():out1;
}

module FF_clk1 {

  reg FF[4] = 0;

  func set { FF := in1; }
  func get { return FF; }
}

declare FF_clk2 {

  input  in2[4];
  output out2[4];

  func_in set(in2);
  func_in get():out2;
}

module FF_clk2 {

  reg FF[4] = 0;

  func set { FF := in2; }
  func get { return FF; }
}

declare top interface { // interface修飾子を付けることで
                         // クロックとリセットを明示的に宣言することができます。

  input clk1;
  input clk2;
  input p_reset;

  input in1[4];
  input in2[4];

  output out1[4];
  output out2[4];

  func_in set(in1, in2);
  fucn_in get();
}

module top {

  FF_clk1 ff_clk1;
  FF_clk2 ff_clk2;

  ff_clk1.m_clock = clk1; // 重要なのはここ
  ff_clk2.m_clock = clk2;

  func set {
  ff_clk1.set(in1);
  ff_clk2.set(in2);
  }

  func get {
  out1 = ff_clk1.get();
  out2 = ff_clk2.get();
  }
}

そしてこのNSLのソースコードをnsl2vlでコンパイルしてできたVerilogHDLのコードを見ると

(抜粋)
FF_clk2 ff_clk2 (.p_reset(_ff_clk2_p_reset), .m_clock(_ff_clk2_m_clock), .get(_ff_clk2_get), .set(_ff_clk2_set), .out(_ff_clk2_out), .in(_ff_clk2_in));
FF_clk1 ff_clk1 (.p_reset(_ff_clk1_p_reset), .m_clock(_ff_clk1_m_clock), .get(_ff_clk1_get), .set(_ff_clk1_set), .out(_ff_clk1_out), .in(_ff_clk1_in));

   assign  _ff_clk1_p_reset = p_reset;
   assign  _ff_clk2_p_reset = p_reset;
   assign  _ff_clk1_m_clock = clk1;
   assign  _ff_clk2_m_clock = clk2;

各モジュールのm_clockにclk1,clk2が接続されています。

このようにすればNSLでも多相クロックの回路を記述することができます。
今回書いた方法は我流なのでもっとスマートな方法があったら追記したいと思います。

かなりざっくり書いたのでわかりずらいとは思いますので質問がありましたらぜひ聞いてください。
そして、もっとやりやすい方法があったら教えてください。