LoginSignup
6
6

More than 5 years have passed since last update.

Chiselで組み合わせ回路

Last updated at Posted at 2015-06-25

ハードウェアの接続状態を記述して、
コンパイルして実行するとverilogコードを吐いてくれる
Chiselをもうちょっと触ってみた。

Scalaをよく知らないので、変な所があればそういうことだと思ってください。

信号のデータ型

チュートリアルに載っている
Chiselで定義済みのデータ型は

  • UInt :符号なし整数
  • SInt :符号あり整数
  • Bool :ブーリアン

UIntSIntは生成時にビット幅を指定できる
他にもFlo(単精度浮動小数点数型)もあるっぽい

定数信号宣言

val foo = UInt(5) // 3bit

ポート宣言

val in = UInt(INPUT,8) // 8bit input port

ちなみにデフォルトで加算などの演算子が定義されている。

Bundleを継承することでデータ型を作成することができる。

class Validatable[T <: Data] (dataSignal: T, validSignal : Bool= Bool(OUTPUT)) extends Bundle {
  val data = dataSignal
  val valid = validSignal
}

val foo = new Validatable(UInt(width = 8))

Vecで配列を作成できる。

val foo = Vec.fill(5){UInt(width=8)} // 8bit x 5
val bar = foo(3)

Vecに対してmapとか使える


val io = new Bundle{
  val x = Vec.fill(3){UInt(INPUT,width = 8)}
  val y = Vec.fill(3){UInt(OUTPUT,width = 8)}
}
io.y := io.x.map(x => x + UInt(10))
/*
       1       4
in ----2-------5----->
       3       6

       11      14
out----12------15----->
       13      16
*/

Enumで列挙型が定義できる

val s_even :: s_odd :: Nil = Enum(UInt(), 2)
io.even := s_even
io.odd := s_odd

モジュール

Moduleを継承して作成。

class Mux2 extends Module {
  val io = new Bundle{
    val sel = UInt(INPUT, 1)
    val in0 = UInt(INPUT, 1)
    val in1 = UInt(INPUT, 1)
    val out = UInt(OUTPUT, 1)
  }

  io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}

:=演算子は verilogのassignに相当。
io.out := ... の部分は

assign io_out = (io_sel & io_in1) | (~io_sel & io_in0)

に相当する。
(実際の変換は一時wireが定義されるのでこの通りにはならない)

サブモジュール

class TopModule extends Module {
  val io = new Bundle{
      val in = UInt(INPUT,1)
      val out = UInt(OUTPUT,1)
  }

  val subModule = Module(new SubModule())
  subModule.io.in := io.in
  io.out := subModule.io.out
}

verilogと似たようなものだが
サブモジュール同士をつなぐ時に一々信号線を用意しなくて済む。

(Rx的な)filter,mapっぽいものを作ってみる

信号線をストリームとみなして、filterやらmapやら作ってみる。

先ほどのValidatable

class Validatable[T <: Data] (dataSignal: T, validSignal : Bool= Bool(OUTPUT)) extends Bundle {
  val data = dataSignal
  val valid = validSignal
}

こんなものを付け足して

  def filter(f: T => Bool) : Validatable[T] ={
    new Validatable[T](this.data, f(this.data) & this.valid)
  }

  def map[S <: Data](f: T => S): Validatable[S] ={
    new Validatable[S](f(this.data), this.valid)
  }

試しに入力ストリームから偶数を通して+10して出力ストリームに流す素敵なモジュールを作ってみる。

class NiceModule extends Module {
  val io = new Bundle{
    val in = new Validatable(UInt(width=8)).asInput
    val out = new Validatable(UInt(width=8)).asOutput
  }
  io.out := io.in.filter(x=> x(0) === UInt(0)).map(x => x + UInt(10))
}

テストを書いて

class NiceModuleTester(c: NiceModule) extends Tester(c) {
  poke(c.io.in.valid,1)

  poke(c.io.in.data,2)
  step(1)
  expect(c.io.out.data, 12)
  expect(c.io.out.valid, 1)

  poke(c.io.in.data,3)
  step(1)
  expect(c.io.out.data, 13)
  expect(c.io.out.valid, 0)

  poke(c.io.in.valid,0)

  poke(c.io.in.data,2)
  step(1)
  expect(c.io.out.data, 12)
  expect(c.io.out.valid, 0)
}
/*
input:
data ---2----3----2---->
valid---T----T----F---->

expected:
data ---12---13---X---->
valid---T----F----F---->

X: don't care
*/

テストが通るのを確認して、verilogに変換すると

module NiceModule(
    input [7:0] io_in_data,
    input  io_in_valid,
    output[7:0] io_out_data,
    output io_out_valid
);

  wire T0;
  wire T1;
  wire T2;
  wire[7:0] T3;


  assign io_out_valid = T0;
  assign T0 = T1 & io_in_valid;
  assign T1 = T2 == 1'h0;
  assign T2 = io_in_data[1'h0:1'h0];
  assign io_out_data = T3;
  assign T3 = io_in_data + 8'ha;
endmodule

自動で定義された内部信号T0~3を、試しに手動で削ってみると

module NiceModule(
    input [7:0] io_in_data,
    input  io_in_valid,
    output[7:0] io_out_data,
    output io_out_valid
);

  wire isEven ;
  assign isEven = (io_in_data[0] == 1'h0);
  assign io_out_valid = isEven & io_in_valid;
  assign io_out_data = io_in_data + 8'ha;
endmodule

一応意味はあっている。

まあ趣味で個人的に使う分には面白いのではないかと。

6
6
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
6
6